aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.gitlab/issue_templates/mytemplate.md3
-rw-r--r--.gitlab/merge_request_templates/mytemplate.md3
-rwxr-xr-xautobuild/agl/autobuild104
-rwxr-xr-xautobuild/linux/autobuild104
-rw-r--r--package.json44
-rw-r--r--proto/types.proto288
-rw-r--r--proto/val.proto115
-rw-r--r--src/appinfo.json11
-rw-r--r--src/config.xml23
-rw-r--r--src/images/dashboardTextures.svg2527
-rw-r--r--src/index.html36
-rw-r--r--src/index.js14
-rw-r--r--src/js/app.js33
-rw-r--r--src/js/kuksa.js229
-rw-r--r--src/js/paths.js18
-rw-r--r--src/js/volume.js (renamed from src/js/sliders.js)36
-rw-r--r--src/styles/app.scss8
-rw-r--r--src/styles/landscape.scss5
-rw-r--r--src/styles/main.scss9
-rw-r--r--src/styles/portrait.scss5
-rw-r--r--webpack.config.js100
22 files changed, 3333 insertions, 383 deletions
diff --git a/.gitignore b/.gitignore
index b887236..cbad92c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ $RECYCLE.BIN/
.sourcemaps/
package-lock.json
build
+src/generated
.DS_Store
Thumbs.db
diff --git a/.gitlab/issue_templates/mytemplate.md b/.gitlab/issue_templates/mytemplate.md
new file mode 100644
index 0000000..25d91d8
--- /dev/null
+++ b/.gitlab/issue_templates/mytemplate.md
@@ -0,0 +1,3 @@
+**Please use https://gerrit.automotivelinux.org for code contributions.**
+See also: https://docs.automotivelinux.org/ chapter "How to contribute".
+
diff --git a/.gitlab/merge_request_templates/mytemplate.md b/.gitlab/merge_request_templates/mytemplate.md
new file mode 100644
index 0000000..25d91d8
--- /dev/null
+++ b/.gitlab/merge_request_templates/mytemplate.md
@@ -0,0 +1,3 @@
+**Please use https://gerrit.automotivelinux.org for code contributions.**
+See also: https://docs.automotivelinux.org/ chapter "How to contribute".
+
diff --git a/autobuild/agl/autobuild b/autobuild/agl/autobuild
deleted file mode 100755
index fa1d1c2..0000000
--- a/autobuild/agl/autobuild
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/make -f
-# Copyright (C) 2015 - 2018 "IoT.bzh"
-# Copyright (C) 2020 Konsulko Group
-# Author "Romain Forlot" <romain.forlot@iot.bzh>
-#
-# 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.
-
-THISFILE := $(lastword $(MAKEFILE_LIST))
-ROOT_DIR := $(abspath $(dir $(THISFILE))/../..)
-
-# Build directory
-# Note that unlike the autobuild makefiles for other types of widget,
-# for NPM based builds the BUILD_DIR is only used for copying the final
-# widget to, as building outside of the source tree is non-trivial to
-# make work with NPM. As such, the default location is the root of the
-# source tree.
-#
-# Additionally, there is no real need for a debug build for these
-# applications, so no separate directory is defined, and all the related
-# debug targets are stubbed out.
-BUILD_DIR = $(ROOT_DIR)
-
-# Output directory variable for use in pattern rules.
-# This is intended for internal use only, hence the explicit override
-# definition.
-override OUTPUT_DIR = $(BUILD_DIR)
-
-# Final install directory for widgets
-DEST = $(OUTPUT_DIR)
-
-.PHONY: all help update install distclean
-.PHONY: clean clean-release clean-debug clean-all
-.PHONY: configure configure-release configure-debug
-.PHONY: build build-release build-debug build-all
-.PHONY: package package-release package-debug package-all
-
-help:
- @echo "List of targets available:"
- @echo ""
- @echo "- all"
- @echo "- help"
- @echo "- clean"
- @echo "- distclean"
- @echo "- configure"
- @echo "- build: compilation, link and prepare files for package into a widget"
- @echo "- package: output a widget file '*.wgt'"
- @echo "- install: install in $(DEST) directory"
- @echo ""
- @echo "Usage: ./autobuild/agl/autobuild package DEST=${HOME}/opt"
- @echo "Don't use your build dir as DEST as wgt file is generated at this location"
-
-all: package-all
-
-clean-release:
- @rm -rf $(ROOT_DIR)/node_modules $(ROOT_DIR)/package $(ROOT_DIR)/package-lock.json
-
-clean: clean-release
-
-clean-debug: ;
-
-clean-all: clean-release
-
-distclean: clean-all
-
-configure-release: clean-release
- @rm -rf node_modules
- @npm install
-
-configure: configure-release
-
-configure-debug: ;
-
-build-release: build-%: configure-%
- npm run build
-
-build: build-release
-
-build-debug: ;
-
-build-all: build-release
-
-package-release: package-%: build-%
- @cp $(ROOT_DIR)/package/*.wgt $(OUTPUT_DIR)/
- @if [ "$(abspath $(DEST))" != "$(abspath $(OUTPUT_DIR))" ]; then \
- mkdir -p $(DEST) && cp $(OUTPUT_DIR)/*.wgt $(DEST); \
- fi
-
-package: package-release
-
-package-debug: ;
-
-package-all: package-release
-
-install: package
diff --git a/autobuild/linux/autobuild b/autobuild/linux/autobuild
deleted file mode 100755
index fa1d1c2..0000000
--- a/autobuild/linux/autobuild
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/make -f
-# Copyright (C) 2015 - 2018 "IoT.bzh"
-# Copyright (C) 2020 Konsulko Group
-# Author "Romain Forlot" <romain.forlot@iot.bzh>
-#
-# 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.
-
-THISFILE := $(lastword $(MAKEFILE_LIST))
-ROOT_DIR := $(abspath $(dir $(THISFILE))/../..)
-
-# Build directory
-# Note that unlike the autobuild makefiles for other types of widget,
-# for NPM based builds the BUILD_DIR is only used for copying the final
-# widget to, as building outside of the source tree is non-trivial to
-# make work with NPM. As such, the default location is the root of the
-# source tree.
-#
-# Additionally, there is no real need for a debug build for these
-# applications, so no separate directory is defined, and all the related
-# debug targets are stubbed out.
-BUILD_DIR = $(ROOT_DIR)
-
-# Output directory variable for use in pattern rules.
-# This is intended for internal use only, hence the explicit override
-# definition.
-override OUTPUT_DIR = $(BUILD_DIR)
-
-# Final install directory for widgets
-DEST = $(OUTPUT_DIR)
-
-.PHONY: all help update install distclean
-.PHONY: clean clean-release clean-debug clean-all
-.PHONY: configure configure-release configure-debug
-.PHONY: build build-release build-debug build-all
-.PHONY: package package-release package-debug package-all
-
-help:
- @echo "List of targets available:"
- @echo ""
- @echo "- all"
- @echo "- help"
- @echo "- clean"
- @echo "- distclean"
- @echo "- configure"
- @echo "- build: compilation, link and prepare files for package into a widget"
- @echo "- package: output a widget file '*.wgt'"
- @echo "- install: install in $(DEST) directory"
- @echo ""
- @echo "Usage: ./autobuild/agl/autobuild package DEST=${HOME}/opt"
- @echo "Don't use your build dir as DEST as wgt file is generated at this location"
-
-all: package-all
-
-clean-release:
- @rm -rf $(ROOT_DIR)/node_modules $(ROOT_DIR)/package $(ROOT_DIR)/package-lock.json
-
-clean: clean-release
-
-clean-debug: ;
-
-clean-all: clean-release
-
-distclean: clean-all
-
-configure-release: clean-release
- @rm -rf node_modules
- @npm install
-
-configure: configure-release
-
-configure-debug: ;
-
-build-release: build-%: configure-%
- npm run build
-
-build: build-release
-
-build-debug: ;
-
-build-all: build-release
-
-package-release: package-%: build-%
- @cp $(ROOT_DIR)/package/*.wgt $(OUTPUT_DIR)/
- @if [ "$(abspath $(DEST))" != "$(abspath $(OUTPUT_DIR))" ]; then \
- mkdir -p $(DEST) && cp $(OUTPUT_DIR)/*.wgt $(DEST); \
- fi
-
-package: package-release
-
-package-debug: ;
-
-package-all: package-release
-
-install: package
diff --git a/package.json b/package.json
index fdaa1a7..011b82d 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,17 @@
{
"name": "agl-mixer",
"version": "0.0.0",
- "description": "HVAC project for AGL based on html5 technologies",
+ "description": "Mixer for AGL based on html5 technologies",
"scripts": {
"webpack": "webpack",
"build": "webpack",
- "start": "webpack-dev-server"
+ "start": "webpack-dev-server",
+ "generate-grpc": "mkdirp ./src/generated && protoc -I./proto types.proto val.proto --js_out=import_style=commonjs:./src/generated --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./src/generated"
},
- "homepage": "https://github.com/AGL-web-applications/mixer",
+ "homepage": "https://git.automotivelinux.org/apps/html5-mixer",
"repository": {
"type": "git",
- "url": "git@github.com:AGL-web-applications/mixer.git"
+ "url": "https://gerrit.automotivelinux.org/gerrit/apps/html5-mixer"
},
"keywords": [
"agl",
@@ -18,24 +19,25 @@
"automotivegradelinux"
],
"devDependencies": {
- "clean-webpack-plugin": "^1.0.1",
- "copy-webpack-plugin": "^4.6.0",
- "css-loader": "^2.1.0",
- "file-loader": "^4.0.0",
- "html-webpack-plugin": "^3.2.0",
- "image-webpack-loader": "^5.0.0",
- "mini-css-extract-plugin": "^0.5.0",
- "node-sass": "^4.12.0",
- "sass-loader": "^7.1.0",
- "style-loader": "^0.23.1",
- "uglifyjs-webpack-plugin": "^2.1.1",
- "webpack": "^4.29.5",
- "webpack-cli": "^3.2.3",
- "webpack-dev-server": "^3.7.2",
- "zip-webpack-plugin": "^3.0.0"
+ "clean-webpack-plugin": "^4.0.0",
+ "copy-webpack-plugin": "^10.2.4",
+ "css-loader": "^6.7.1",
+ "file-loader": "^6.2.0",
+ "html-webpack-plugin": "^5.5.0",
+ "mini-css-extract-plugin": "^2.6.0",
+ "node-sass": "^7.0.1",
+ "sass-loader": "^12.6.0",
+ "style-loader": "^3.3.1",
+ "uglify-js": "^3.15.4",
+ "webpack": "^5.72.0",
+ "webpack-cli": "^4.9.2",
+ "webpack-dev-server": "^4.8.1"
},
"dependencies": {
- "mustache": "^3.1.0",
- "agl-js-api": "https://github.com/AGL-web-applications/agl-js-api.git#master"
+ "google-protobuf": "^3.21.2",
+ "grpc-web": "^1.5.0",
+ "mustache": "^4.2.0",
+ "protoc-gen-grpc-web": "^1.4.2",
+ "protoc-gen-js": "^3.21.2"
}
}
diff --git a/proto/types.proto b/proto/types.proto
new file mode 100644
index 0000000..8914e7a
--- /dev/null
+++ b/proto/types.proto
@@ -0,0 +1,288 @@
+/********************************************************************************
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License 2.0 which is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ ********************************************************************************/
+
+syntax = "proto3";
+
+// I added V1 as in databroker. Is this good practice?
+package kuksa.val.v1;
+import "google/protobuf/timestamp.proto";
+
+option go_package = "kuksa/val/v1";
+
+// Describes a VSS entry
+// When requesting an entry, the amount of information returned can
+// be controlled by specifying either a `View` or a set of `Field`s.
+message DataEntry {
+ // Defines the full VSS path of the entry.
+ string path = 1; // [field: FIELD_PATH]
+
+ // The value (datapoint)
+ Datapoint value = 2; // [field: FIELD_VALUE]
+
+ // Actuator target (only used if the entry is an actuator)
+ Datapoint actuator_target = 3; // [field: FIELD_ACTUATOR_TARGET]
+
+ // Metadata for this entry
+ Metadata metadata = 10; // [field: FIELD_METADATA]
+}
+
+message Datapoint {
+ google.protobuf.Timestamp timestamp = 1;
+
+ oneof value {
+ string string = 11;
+ bool bool = 12;
+ sint32 int32 = 13;
+ sint64 int64 = 14;
+ uint32 uint32 = 15;
+ uint64 uint64 = 16;
+ float float = 17;
+ double double = 18;
+ StringArray string_array = 21;
+ BoolArray bool_array = 22;
+ Int32Array int32_array = 23;
+ Int64Array int64_array = 24;
+ Uint32Array uint32_array = 25;
+ Uint64Array uint64_array = 26;
+ FloatArray float_array = 27;
+ DoubleArray double_array = 28;
+ }
+}
+
+message Metadata {
+ // Data type
+ // The VSS data type of the entry (i.e. the value, min, max etc).
+ //
+ // NOTE: protobuf doesn't have int8, int16, uint8 or uint16 which means
+ // that these values must be serialized as int32 and uint32 respectively.
+ DataType data_type = 11; // [field: FIELD_METADATA_DATA_TYPE]
+
+ // Entry type
+ EntryType entry_type = 12; // [field: FIELD_METADATA_ENTRY_TYPE]
+
+ // Description
+ // Describes the meaning and content of the entry.
+ optional string description = 13; // [field: FIELD_METADATA_DESCRIPTION]
+
+ // Comment [optional]
+ // A comment can be used to provide additional informal information
+ // on a entry.
+ optional string comment = 14; // [field: FIELD_METADATA_COMMENT]
+
+ // Deprecation [optional]
+ // Whether this entry is deprecated. Can contain recommendations of what
+ // to use instead.
+ optional string deprecation = 15; // [field: FIELD_METADATA_DEPRECATION]
+
+ // Unit [optional]
+ // The unit of measurement
+ optional string unit = 16; // [field: FIELD_METADATA_UNIT]
+
+ // Value restrictions [optional]
+ // Restrict which values are allowed.
+ // Only restrictions matching the DataType {datatype} above are valid.
+ ValueRestriction value_restriction = 17; // [field: FIELD_METADATA_VALUE_RESTRICTION]
+
+ // Entry type specific metadata
+ oneof entry_specific {
+ Actuator actuator = 20; // [field: FIELD_METADATA_ACTUATOR]
+ Sensor sensor = 30; // [field: FIELD_METADATA_SENSOR]
+ Attribute attribute = 40; // [field: FIELD_METADATA_ATTRIBUTE]
+ }
+}
+
+///////////////////////
+// Actuator specific fields
+message Actuator {
+ // Nothing for now
+}
+
+////////////////////////
+// Sensor specific
+message Sensor {
+ // Nothing for now
+}
+
+////////////////////////
+// Attribute specific
+message Attribute {
+ // Nothing for now.
+}
+
+// Value restriction
+//
+// One ValueRestriction{type} for each type, since
+// they don't make sense unless the types match
+//
+message ValueRestriction {
+ oneof type {
+ ValueRestrictionString string = 21;
+ // For signed VSS integers
+ ValueRestrictionInt signed = 22;
+ // For unsigned VSS integers
+ ValueRestrictionUint unsigned = 23;
+ // For floating point VSS values (float and double)
+ ValueRestrictionFloat floating_point = 24;
+ }
+}
+
+message ValueRestrictionInt {
+ optional sint64 min = 1;
+ optional sint64 max = 2;
+ repeated sint64 allowed_values = 3;
+}
+
+message ValueRestrictionUint {
+ optional uint64 min = 1;
+ optional uint64 max = 2;
+ repeated uint64 allowed_values = 3;
+}
+
+message ValueRestrictionFloat {
+ optional double min = 1;
+ optional double max = 2;
+
+ // allowed for doubles/floats not recommended
+ repeated double allowed_values = 3;
+}
+
+// min, max doesn't make much sense for a string
+message ValueRestrictionString {
+ repeated string allowed_values = 3;
+}
+
+// VSS Data type of a signal
+//
+// Protobuf doesn't support int8, int16, uint8 or uint16.
+// These are mapped to int32 and uint32 respectively.
+//
+enum DataType {
+ DATA_TYPE_UNSPECIFIED = 0;
+ DATA_TYPE_STRING = 1;
+ DATA_TYPE_BOOLEAN = 2;
+ DATA_TYPE_INT8 = 3;
+ DATA_TYPE_INT16 = 4;
+ DATA_TYPE_INT32 = 5;
+ DATA_TYPE_INT64 = 6;
+ DATA_TYPE_UINT8 = 7;
+ DATA_TYPE_UINT16 = 8;
+ DATA_TYPE_UINT32 = 9;
+ DATA_TYPE_UINT64 = 10;
+ DATA_TYPE_FLOAT = 11;
+ DATA_TYPE_DOUBLE = 12;
+ DATA_TYPE_TIMESTAMP = 13;
+ DATA_TYPE_STRING_ARRAY = 20;
+ DATA_TYPE_BOOLEAN_ARRAY = 21;
+ DATA_TYPE_INT8_ARRAY = 22;
+ DATA_TYPE_INT16_ARRAY = 23;
+ DATA_TYPE_INT32_ARRAY = 24;
+ DATA_TYPE_INT64_ARRAY = 25;
+ DATA_TYPE_UINT8_ARRAY = 26;
+ DATA_TYPE_UINT16_ARRAY = 27;
+ DATA_TYPE_UINT32_ARRAY = 28;
+ DATA_TYPE_UINT64_ARRAY = 29;
+ DATA_TYPE_FLOAT_ARRAY = 30;
+ DATA_TYPE_DOUBLE_ARRAY = 31;
+ DATA_TYPE_TIMESTAMP_ARRAY = 32;
+}
+
+// Entry type
+enum EntryType {
+ ENTRY_TYPE_UNSPECIFIED = 0;
+ ENTRY_TYPE_ATTRIBUTE = 1;
+ ENTRY_TYPE_SENSOR = 2;
+ ENTRY_TYPE_ACTUATOR = 3;
+}
+
+// A `View` specifies a set of fields which should
+// be populated in a `DataEntry` (in a response message)
+enum View {
+ VIEW_UNSPECIFIED = 0; // Unspecified. Equivalent to VIEW_CURRENT_VALUE unless `fields` are explicitly set.
+ VIEW_CURRENT_VALUE = 1; // Populate DataEntry with value.
+ VIEW_TARGET_VALUE = 2; // Populate DataEntry with actuator target.
+ VIEW_METADATA = 3; // Populate DataEntry with metadata.
+ VIEW_FIELDS = 10; // Populate DataEntry only with requested fields.
+ VIEW_ALL = 20; // Populate DataEntry with everything.
+}
+
+// A `Field` corresponds to a specific field of a `DataEntry`.
+//
+// It can be used to:
+// * populate only specific fields of a `DataEntry` response.
+// * specify which fields of a `DataEntry` should be set as
+// part of a `Set` request.
+// * subscribe to only specific fields of a data entry.
+// * convey which fields of an updated `DataEntry` have changed.
+enum Field {
+ FIELD_UNSPECIFIED = 0; // "*" i.e. everything
+ FIELD_PATH = 1; // path
+ FIELD_VALUE = 2; // value
+ FIELD_ACTUATOR_TARGET = 3; // actuator_target
+ FIELD_METADATA = 10; // metadata.*
+ FIELD_METADATA_DATA_TYPE = 11; // metadata.data_type
+ FIELD_METADATA_DESCRIPTION = 12; // metadata.description
+ FIELD_METADATA_ENTRY_TYPE = 13; // metadata.entry_type
+ FIELD_METADATA_COMMENT = 14; // metadata.comment
+ FIELD_METADATA_DEPRECATION = 15; // metadata.deprecation
+ FIELD_METADATA_UNIT = 16; // metadata.unit
+ FIELD_METADATA_VALUE_RESTRICTION = 17; // metadata.value_restriction.*
+ FIELD_METADATA_ACTUATOR = 20; // metadata.actuator.*
+ FIELD_METADATA_SENSOR = 30; // metadata.sensor.*
+ FIELD_METADATA_ATTRIBUTE = 40; // metadata.attribute.*
+}
+
+// Error response shall be an HTTP-like code.
+// Should follow https://www.w3.org/TR/viss2-transport/#status-codes.
+message Error {
+ uint32 code = 1;
+ string reason = 2;
+ string message = 3;
+}
+
+// Used in get/set requests to report errors for specific entries
+message DataEntryError {
+ string path = 1; // vss path
+ Error error = 2;
+}
+
+message StringArray {
+ repeated string values = 1;
+}
+
+message BoolArray {
+ repeated bool values = 1;
+}
+
+message Int32Array {
+ repeated sint32 values = 1;
+}
+
+message Int64Array {
+ repeated sint64 values = 1;
+}
+
+message Uint32Array {
+ repeated uint32 values = 1;
+}
+
+message Uint64Array {
+ repeated uint64 values = 1;
+}
+
+message FloatArray {
+ repeated float values = 1;
+}
+
+message DoubleArray {
+ repeated double values = 1;
+}
diff --git a/proto/val.proto b/proto/val.proto
new file mode 100644
index 0000000..2d65b7c
--- /dev/null
+++ b/proto/val.proto
@@ -0,0 +1,115 @@
+/********************************************************************************
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License 2.0 which is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ ********************************************************************************/
+
+syntax = "proto3";
+
+package kuksa.val.v1;
+
+option go_package = "kuksa/val/v1";
+
+import "types.proto";
+
+// Note on authorization:
+// Tokens (auth-token or auth-uuid) are sent as (GRPC / http2) metadata.
+//
+// The auth-token is a JWT compliant token as the examples found here:
+// https://github.com/eclipse/kuksa.val/tree/master/kuksa_certificates/jwt
+//
+// See also https://github.com/eclipse/kuksa.val/blob/master/doc/jwt.md
+//
+// Upon reception of auth-token, server shall generate an auth-uuid in metadata
+// that the client can use instead of auth-token in subsequent calls.
+
+service VAL {
+ // Get entries
+ rpc Get(GetRequest) returns (GetResponse);
+
+ // Set entries
+ rpc Set(SetRequest) returns (SetResponse);
+
+ // Subscribe to a set of entries
+ //
+ // Returns a stream of notifications.
+ //
+ // InvalidArgument is returned if the request is malformed.
+ rpc Subscribe(SubscribeRequest) returns (stream SubscribeResponse);
+
+ // Shall return information that allows the client to determine
+ // what server/server implementation/version it is talking to
+ // eg. kuksa-databroker 0.5.1
+ rpc GetServerInfo(GetServerInfoRequest) returns (GetServerInfoResponse);
+}
+
+// Define which data we want
+message EntryRequest {
+ string path = 1;
+ View view = 2;
+ repeated Field fields = 3;
+}
+
+// Request a set of entries.
+message GetRequest {
+ repeated EntryRequest entries = 1;
+}
+
+// Global errors are specified in `error`.
+// Errors for individual entries are specified in `errors`.
+message GetResponse {
+ repeated DataEntry entries = 1;
+ repeated DataEntryError errors = 2;
+ Error error = 3;
+}
+
+// Define the data we want to set
+message EntryUpdate {
+ DataEntry entry = 1;
+ repeated Field fields = 2;
+}
+
+// A list of entries to be updated
+message SetRequest {
+ repeated EntryUpdate updates = 1;
+}
+
+// Global errors are specified in `error`.
+// Errors for individual entries are specified in `errors`.
+message SetResponse {
+ Error error = 1;
+ repeated DataEntryError errors = 2;
+}
+
+// Define what to subscribe totime
+message SubscribeEntry {
+ string path = 1;
+ View view = 2;
+ repeated Field fields = 3;
+}
+
+// Subscribe to changes in datapoints.
+message SubscribeRequest {
+ repeated SubscribeEntry entries = 1;
+}
+
+// A subscription response
+message SubscribeResponse {
+ repeated EntryUpdate updates = 1;
+}
+
+message GetServerInfoRequest {
+ // Nothing yet
+}
+
+message GetServerInfoResponse {
+ string name = 1;
+ string version = 2;
+}
diff --git a/src/appinfo.json b/src/appinfo.json
new file mode 100644
index 0000000..26d9191
--- /dev/null
+++ b/src/appinfo.json
@@ -0,0 +1,11 @@
+{
+ "id": "webapps-mixer",
+ "title": "MIXER",
+ "description": "HTML5 MIXER demo",
+ "version": "0.0.0",
+ "vendor": "Igalia, S.L.",
+ "type": "web",
+ "main": "index.html",
+ "uiRevision": "2",
+ "icon": "icon.svg"
+}
diff --git a/src/config.xml b/src/config.xml
deleted file mode 100644
index 2af506d..0000000
--- a/src/config.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns="http://www.w3.org/ns/widgets" id="webapps-mixer" version="0.0.0">
- <name>MIXER</name>
- <icon src="icon.svg"/>
- <content src="index.html" type="text/html"/>
- <description>HTML5 MIXER demo</description>
- <author>Igalia, S.L.</author>
- <license>APL 2.0</license>
- <feature name="urn:AGL:widget:required-permission">
- <param name="urn:AGL:permission::public:no-htdocs" value="required" />
- <param name="urn:AGL:permission::public:display" value="required" />
- <param name="urn:AGL:permission::public:audio" value="required" />
- <param name="urn:AGL:permission:afm:system:widget" value="required" /> <!-- list available apps -->
- <param name="urn:AGL:permission:afm:system:runner" value="required" /> <!-- run other apps -->
- <param name="urn:AGL:permission::public:applications:read" value="required" /> <!-- get app icons -->
- </feature>
- <feature name="urn:AGL:widget:required-api">
- <param name="windowmanager" value="ws" />
- <param name="homescreen" value="ws" />
- <param name="afm-main" value="ws" />
- <param name="audiomixer" value="ws" />
- </feature>
-</widget>
diff --git a/src/images/dashboardTextures.svg b/src/images/dashboardTextures.svg
new file mode 100644
index 0000000..04b8767
--- /dev/null
+++ b/src/images/dashboardTextures.svg
@@ -0,0 +1,2527 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="1080.0001"
+ height="918.05273"
+ viewBox="0 0 1080.0001 918.05273"
+ fill="none"
+ version="1.1"
+ id="svg402"
+ sodipodi:docname="dashboardTextures.svg"
+ inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview402"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:zoom="0.89541239"
+ inkscape:cx="497.53611"
+ inkscape:cy="478.55045"
+ inkscape:window-width="2560"
+ inkscape:window-height="1371"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg402" />
+ <path
+ d="M 1080.0001,0 V 918.05276 H 0 L 5.87481e-5,0 Z"
+ fill="url(#paint0_radial_129_2056)"
+ fill-opacity="0.3"
+ id="path1"
+ style="fill:url(#paint0_radial_129_2056);stroke-width:0.826484" />
+ <g
+ opacity="0.5"
+ id="g68"
+ transform="translate(5.87481e-5,-921.94724)">
+ <path
+ d="m 412,1072 h -1 v 648 h 1 z"
+ fill="url(#paint2_radial_129_2056)"
+ id="path3"
+ style="fill:url(#paint2_radial_129_2056)" />
+ <path
+ d="m 812,1072 h -1 v 648 h 1 z"
+ fill="url(#paint3_radial_129_2056)"
+ id="path4"
+ style="fill:url(#paint3_radial_129_2056)" />
+ <path
+ d="m 962,1072 h -1 v 648 h 1 z"
+ fill="url(#paint4_radial_129_2056)"
+ id="path5"
+ style="fill:url(#paint4_radial_129_2056)" />
+ <path
+ d="m 1037,1072 h -1 v 648 h 1 z"
+ fill="url(#paint5_radial_129_2056)"
+ id="path6"
+ style="fill:url(#paint5_radial_129_2056)" />
+ <path
+ d="m 312,1072 h -1 v 648 h 1 z"
+ fill="url(#paint6_radial_129_2056)"
+ id="path7"
+ style="fill:url(#paint6_radial_129_2056)" />
+ <path
+ d="m 712,1072 h -1 v 648 h 1 z"
+ fill="url(#paint7_radial_129_2056)"
+ id="path8"
+ style="fill:url(#paint7_radial_129_2056)" />
+ <path
+ d="m 862,1072 h -1 v 648 h 1 z"
+ fill="url(#paint8_radial_129_2056)"
+ id="path9"
+ style="fill:url(#paint8_radial_129_2056)" />
+ <path
+ d="m 362,1072 h -1 v 648 h 1 z"
+ fill="url(#paint9_radial_129_2056)"
+ id="path10"
+ style="fill:url(#paint9_radial_129_2056)" />
+ <path
+ d="m 762,1072 h -1 v 648 h 1 z"
+ fill="url(#paint10_radial_129_2056)"
+ id="path11"
+ style="fill:url(#paint10_radial_129_2056)" />
+ <path
+ d="m 912,1072 h -1 v 648 h 1 z"
+ fill="url(#paint11_radial_129_2056)"
+ id="path12"
+ style="fill:url(#paint11_radial_129_2056)" />
+ <path
+ d="m 987,1072 h -1 v 648 h 1 z"
+ fill="url(#paint12_radial_129_2056)"
+ id="path13"
+ style="fill:url(#paint12_radial_129_2056)" />
+ <path
+ d="m 262,1072 h -1 v 648 h 1 z"
+ fill="url(#paint13_radial_129_2056)"
+ id="path14"
+ style="fill:url(#paint13_radial_129_2056)" />
+ <path
+ d="m 662,1072 h -1 v 648 h 1 z"
+ fill="url(#paint14_radial_129_2056)"
+ id="path15"
+ style="fill:url(#paint14_radial_129_2056)" />
+ <path
+ d="m 387,1072 h -1 v 648 h 1 z"
+ fill="url(#paint15_radial_129_2056)"
+ id="path16"
+ style="fill:url(#paint15_radial_129_2056)" />
+ <path
+ d="m 787,1072 h -1 v 648 h 1 z"
+ fill="url(#paint16_radial_129_2056)"
+ id="path17"
+ style="fill:url(#paint16_radial_129_2056)" />
+ <path
+ d="m 937,1072 h -1 v 648 h 1 z"
+ fill="url(#paint17_radial_129_2056)"
+ id="path18"
+ style="fill:url(#paint17_radial_129_2056)" />
+ <path
+ d="m 1012,1072 h -1 v 648 h 1 z"
+ fill="url(#paint18_radial_129_2056)"
+ id="path19"
+ style="fill:url(#paint18_radial_129_2056)" />
+ <path
+ d="m 287,1072 h -1 v 648 h 1 z"
+ fill="url(#paint19_radial_129_2056)"
+ id="path20"
+ style="fill:url(#paint19_radial_129_2056)" />
+ <path
+ d="m 687,1072 h -1 v 648 h 1 z"
+ fill="url(#paint20_radial_129_2056)"
+ id="path21"
+ style="fill:url(#paint20_radial_129_2056)" />
+ <path
+ d="m 837,1072 h -1 v 648 h 1 z"
+ fill="url(#paint21_radial_129_2056)"
+ id="path22"
+ style="fill:url(#paint21_radial_129_2056)" />
+ <path
+ d="m 337,1072 h -1 v 648 h 1 z"
+ fill="url(#paint22_radial_129_2056)"
+ id="path23"
+ style="fill:url(#paint22_radial_129_2056)" />
+ <path
+ d="m 737,1072 h -1 v 648 h 1 z"
+ fill="url(#paint23_radial_129_2056)"
+ id="path24"
+ style="fill:url(#paint23_radial_129_2056)" />
+ <path
+ d="m 887,1072 h -1 v 648 h 1 z"
+ fill="url(#paint24_radial_129_2056)"
+ id="path25"
+ style="fill:url(#paint24_radial_129_2056)" />
+ <path
+ d="m 237,1072 h -1 v 648 h 1 z"
+ fill="url(#paint25_radial_129_2056)"
+ id="path26"
+ style="fill:url(#paint25_radial_129_2056)" />
+ <path
+ d="m 637,1072 h -1 v 648 h 1 z"
+ fill="url(#paint26_radial_129_2056)"
+ id="path27"
+ style="fill:url(#paint26_radial_129_2056)" />
+ <path
+ d="m 212,1072 h -1 v 648 h 1 z"
+ fill="url(#paint27_radial_129_2056)"
+ id="path28"
+ style="fill:url(#paint27_radial_129_2056)" />
+ <path
+ d="m 612,1072 h -1 v 648 h 1 z"
+ fill="url(#paint28_radial_129_2056)"
+ id="path29"
+ style="fill:url(#paint28_radial_129_2056)" />
+ <path
+ d="m 112,1072 h -1 v 648 h 1 z"
+ fill="url(#paint29_radial_129_2056)"
+ id="path30"
+ style="fill:url(#paint29_radial_129_2056)" />
+ <path
+ d="m 512,1072 h -1 v 648 h 1 z"
+ fill="url(#paint30_radial_129_2056)"
+ id="path31"
+ style="fill:url(#paint30_radial_129_2056)" />
+ <path
+ d="m 162,1072 h -1 v 648 h 1 z"
+ fill="url(#paint31_radial_129_2056)"
+ id="path32"
+ style="fill:url(#paint31_radial_129_2056)" />
+ <path
+ d="m 562,1072 h -1 v 648 h 1 z"
+ fill="url(#paint32_radial_129_2056)"
+ id="path33"
+ style="fill:url(#paint32_radial_129_2056)" />
+ <path
+ d="m 62,1072 h -1 v 648 h 1 z"
+ fill="url(#paint33_radial_129_2056)"
+ id="path34"
+ style="fill:url(#paint33_radial_129_2056)" />
+ <path
+ d="m 462,1072 h -1 v 648 h 1 z"
+ fill="url(#paint34_radial_129_2056)"
+ id="path35"
+ style="fill:url(#paint34_radial_129_2056)" />
+ <path
+ d="m 187,1072 h -1 v 648 h 1 z"
+ fill="url(#paint35_radial_129_2056)"
+ id="path36"
+ style="fill:url(#paint35_radial_129_2056)" />
+ <path
+ d="m 587,1072 h -1 v 648 h 1 z"
+ fill="url(#paint36_radial_129_2056)"
+ id="path37"
+ style="fill:url(#paint36_radial_129_2056)" />
+ <path
+ d="m 87,1072 h -1 v 648 h 1 z"
+ fill="url(#paint37_radial_129_2056)"
+ id="path38"
+ style="fill:url(#paint37_radial_129_2056)" />
+ <path
+ d="m 487,1072 h -1 v 648 h 1 z"
+ fill="url(#paint38_radial_129_2056)"
+ id="path39"
+ style="fill:url(#paint38_radial_129_2056)" />
+ <path
+ d="m 137,1072 h -1 v 648 h 1 z"
+ fill="url(#paint39_radial_129_2056)"
+ id="path40"
+ style="fill:url(#paint39_radial_129_2056)" />
+ <path
+ d="m 537,1072 h -1 v 648 h 1 z"
+ fill="url(#paint40_radial_129_2056)"
+ id="path41"
+ style="fill:url(#paint40_radial_129_2056)" />
+ <path
+ d="m 37,1072 h -1 v 648 h 1 z"
+ fill="url(#paint41_radial_129_2056)"
+ id="path42"
+ style="fill:url(#paint41_radial_129_2056)" />
+ <path
+ d="m 437,1072 h -1 v 648 h 1 z"
+ fill="url(#paint42_radial_129_2056)"
+ id="path43"
+ style="fill:url(#paint42_radial_129_2056)" />
+ <path
+ d="M 1052,1095.04 H 20 v 1 h 1032 z"
+ fill="url(#paint43_radial_129_2056)"
+ id="path44"
+ style="fill:url(#paint43_radial_129_2056)" />
+ <path
+ d="M 1052,1295.34 H 20 v 1.01 h 1032 z"
+ fill="url(#paint44_radial_129_2056)"
+ id="path45"
+ style="fill:url(#paint44_radial_129_2056)" />
+ <path
+ d="M 1052,1495.65 H 20 v 1.01 h 1032 z"
+ fill="url(#paint45_radial_129_2056)"
+ id="path46"
+ style="fill:url(#paint45_radial_129_2056)" />
+ <path
+ d="M 1052,1195.19 H 20 v 1 h 1032 z"
+ fill="url(#paint46_radial_129_2056)"
+ id="path47"
+ style="fill:url(#paint46_radial_129_2056)" />
+ <path
+ d="M 1052,1395.5 H 20 v 1 h 1032 z"
+ fill="url(#paint47_radial_129_2056)"
+ id="path48"
+ style="fill:url(#paint47_radial_129_2056)" />
+ <path
+ d="M 1052,1595.81 H 20 v 1 h 1032 z"
+ fill="url(#paint48_radial_129_2056)"
+ id="path49"
+ style="fill:url(#paint48_radial_129_2056)" />
+ <path
+ d="M 1052,1145.11 H 20 v 1 h 1032 z"
+ fill="url(#paint49_radial_129_2056)"
+ id="path50"
+ style="fill:url(#paint49_radial_129_2056)" />
+ <path
+ d="M 1052,1345.42 H 20 v 1 h 1032 z"
+ fill="url(#paint50_radial_129_2056)"
+ id="path51"
+ style="fill:url(#paint50_radial_129_2056)" />
+ <path
+ d="M 1052,1545.73 H 20 v 1 h 1032 z"
+ fill="url(#paint51_radial_129_2056)"
+ id="path52"
+ style="fill:url(#paint51_radial_129_2056)" />
+ <path
+ d="M 1052,1245.27 H 20 v 1 h 1032 z"
+ fill="url(#paint52_radial_129_2056)"
+ id="path53"
+ style="fill:url(#paint52_radial_129_2056)" />
+ <path
+ d="M 1052,1445.58 H 20 v 1 h 1032 z"
+ fill="url(#paint53_radial_129_2056)"
+ id="path54"
+ style="fill:url(#paint53_radial_129_2056)" />
+ <path
+ d="M 1052,1645.89 H 20 v 1 h 1032 z"
+ fill="url(#paint54_radial_129_2056)"
+ id="path55"
+ style="fill:url(#paint54_radial_129_2056)" />
+ <path
+ d="M 1052,1120.07 H 20 v 1.01 h 1032 z"
+ fill="url(#paint55_radial_129_2056)"
+ id="path56"
+ style="fill:url(#paint55_radial_129_2056)" />
+ <path
+ d="M 1052,1320.38 H 20 v 1 h 1032 z"
+ fill="url(#paint56_radial_129_2056)"
+ id="path57"
+ style="fill:url(#paint56_radial_129_2056)" />
+ <path
+ d="M 1052,1520.69 H 20 v 1 h 1032 z"
+ fill="url(#paint57_radial_129_2056)"
+ id="path58"
+ style="fill:url(#paint57_radial_129_2056)" />
+ <path
+ d="M 1052,1220.23 H 20 v 1 h 1032 z"
+ fill="url(#paint58_radial_129_2056)"
+ id="path59"
+ style="fill:url(#paint58_radial_129_2056)" />
+ <path
+ d="M 1052,1420.54 H 20 v 1 h 1032 z"
+ fill="url(#paint59_radial_129_2056)"
+ id="path60"
+ style="fill:url(#paint59_radial_129_2056)" />
+ <path
+ d="M 1052,1620.85 H 20 v 1 h 1032 z"
+ fill="url(#paint60_radial_129_2056)"
+ id="path61"
+ style="fill:url(#paint60_radial_129_2056)" />
+ <path
+ d="M 1052,1170.15 H 20 v 1 h 1032 z"
+ fill="url(#paint61_radial_129_2056)"
+ id="path62"
+ style="fill:url(#paint61_radial_129_2056)" />
+ <path
+ d="M 1052,1370.46 H 20 v 1 h 1032 z"
+ fill="url(#paint62_radial_129_2056)"
+ id="path63"
+ style="fill:url(#paint62_radial_129_2056)" />
+ <path
+ d="M 1052,1570.77 H 20 v 1 h 1032 z"
+ fill="url(#paint63_radial_129_2056)"
+ id="path64"
+ style="fill:url(#paint63_radial_129_2056)" />
+ <path
+ d="M 1052,1270.31 H 20 v 1 h 1032 z"
+ fill="url(#paint64_radial_129_2056)"
+ id="path65"
+ style="fill:url(#paint64_radial_129_2056)" />
+ <path
+ d="M 1052,1470.62 H 20 v 1 h 1032 z"
+ fill="url(#paint65_radial_129_2056)"
+ id="path66"
+ style="fill:url(#paint65_radial_129_2056)" />
+ <path
+ d="M 1052,1670.92 H 20 v 1.01 h 1032 z"
+ fill="url(#paint66_radial_129_2056)"
+ id="path67"
+ style="fill:url(#paint66_radial_129_2056)" />
+ <path
+ d="M 1052,1695.96 H 20 v 1 h 1032 z"
+ fill="url(#paint67_radial_129_2056)"
+ id="path68"
+ style="fill:url(#paint67_radial_129_2056)" />
+ </g>
+ <defs
+ id="defs402">
+ <radialGradient
+ id="paint0_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-601.44751,540,0,540.00006,601.44746)">
+ <stop
+ stop-color="#2962FF"
+ id="stop134" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop135" />
+ </radialGradient>
+ <radialGradient
+ id="paint1_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,406,-406,0,540,634)">
+ <stop
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop136" />
+ <stop
+ offset="0.513053"
+ stop-color="#2962FF"
+ stop-opacity="0.782292"
+ id="stop137" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop138" />
+ </radialGradient>
+ <radialGradient
+ id="paint2_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop139" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop140" />
+ </radialGradient>
+ <radialGradient
+ id="paint3_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop141" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop142" />
+ </radialGradient>
+ <radialGradient
+ id="paint4_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop143" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop144" />
+ </radialGradient>
+ <radialGradient
+ id="paint5_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop145" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop146" />
+ </radialGradient>
+ <radialGradient
+ id="paint6_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop147" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop148" />
+ </radialGradient>
+ <radialGradient
+ id="paint7_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop149" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop150" />
+ </radialGradient>
+ <radialGradient
+ id="paint8_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop151" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop152" />
+ </radialGradient>
+ <radialGradient
+ id="paint9_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop153" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop154" />
+ </radialGradient>
+ <radialGradient
+ id="paint10_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop155" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop156" />
+ </radialGradient>
+ <radialGradient
+ id="paint11_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop157" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop158" />
+ </radialGradient>
+ <radialGradient
+ id="paint12_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop159" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop160" />
+ </radialGradient>
+ <radialGradient
+ id="paint13_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop161" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop162" />
+ </radialGradient>
+ <radialGradient
+ id="paint14_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop163" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop164" />
+ </radialGradient>
+ <radialGradient
+ id="paint15_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop165" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop166" />
+ </radialGradient>
+ <radialGradient
+ id="paint16_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop167" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop168" />
+ </radialGradient>
+ <radialGradient
+ id="paint17_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop169" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop170" />
+ </radialGradient>
+ <radialGradient
+ id="paint18_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop171" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop172" />
+ </radialGradient>
+ <radialGradient
+ id="paint19_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop173" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop174" />
+ </radialGradient>
+ <radialGradient
+ id="paint20_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop175" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop176" />
+ </radialGradient>
+ <radialGradient
+ id="paint21_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop177" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop178" />
+ </radialGradient>
+ <radialGradient
+ id="paint22_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop179" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop180" />
+ </radialGradient>
+ <radialGradient
+ id="paint23_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop181" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop182" />
+ </radialGradient>
+ <radialGradient
+ id="paint24_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop183" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop184" />
+ </radialGradient>
+ <radialGradient
+ id="paint25_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop185" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop186" />
+ </radialGradient>
+ <radialGradient
+ id="paint26_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop187" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop188" />
+ </radialGradient>
+ <radialGradient
+ id="paint27_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop189" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop190" />
+ </radialGradient>
+ <radialGradient
+ id="paint28_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop191" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop192" />
+ </radialGradient>
+ <radialGradient
+ id="paint29_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop193" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop194" />
+ </radialGradient>
+ <radialGradient
+ id="paint30_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop195" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop196" />
+ </radialGradient>
+ <radialGradient
+ id="paint31_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop197" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop198" />
+ </radialGradient>
+ <radialGradient
+ id="paint32_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop199" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop200" />
+ </radialGradient>
+ <radialGradient
+ id="paint33_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop201" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop202" />
+ </radialGradient>
+ <radialGradient
+ id="paint34_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop203" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop204" />
+ </radialGradient>
+ <radialGradient
+ id="paint35_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop205" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop206" />
+ </radialGradient>
+ <radialGradient
+ id="paint36_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop207" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop208" />
+ </radialGradient>
+ <radialGradient
+ id="paint37_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop209" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop210" />
+ </radialGradient>
+ <radialGradient
+ id="paint38_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop211" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop212" />
+ </radialGradient>
+ <radialGradient
+ id="paint39_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop213" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop214" />
+ </radialGradient>
+ <radialGradient
+ id="paint40_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop215" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop216" />
+ </radialGradient>
+ <radialGradient
+ id="paint41_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop217" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop218" />
+ </radialGradient>
+ <radialGradient
+ id="paint42_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop219" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop220" />
+ </radialGradient>
+ <radialGradient
+ id="paint43_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop221" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop222" />
+ </radialGradient>
+ <radialGradient
+ id="paint44_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop223" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop224" />
+ </radialGradient>
+ <radialGradient
+ id="paint45_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop225" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop226" />
+ </radialGradient>
+ <radialGradient
+ id="paint46_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop227" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop228" />
+ </radialGradient>
+ <radialGradient
+ id="paint47_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop229" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop230" />
+ </radialGradient>
+ <radialGradient
+ id="paint48_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop231" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop232" />
+ </radialGradient>
+ <radialGradient
+ id="paint49_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop233" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop234" />
+ </radialGradient>
+ <radialGradient
+ id="paint50_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop235" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop236" />
+ </radialGradient>
+ <radialGradient
+ id="paint51_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop237" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop238" />
+ </radialGradient>
+ <radialGradient
+ id="paint52_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop239" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop240" />
+ </radialGradient>
+ <radialGradient
+ id="paint53_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop241" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop242" />
+ </radialGradient>
+ <radialGradient
+ id="paint54_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop243" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop244" />
+ </radialGradient>
+ <radialGradient
+ id="paint55_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop245" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop246" />
+ </radialGradient>
+ <radialGradient
+ id="paint56_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop247" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop248" />
+ </radialGradient>
+ <radialGradient
+ id="paint57_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop249" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop250" />
+ </radialGradient>
+ <radialGradient
+ id="paint58_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop251" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop252" />
+ </radialGradient>
+ <radialGradient
+ id="paint59_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop253" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop254" />
+ </radialGradient>
+ <radialGradient
+ id="paint60_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop255" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop256" />
+ </radialGradient>
+ <radialGradient
+ id="paint61_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop257" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop258" />
+ </radialGradient>
+ <radialGradient
+ id="paint62_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop259" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop260" />
+ </radialGradient>
+ <radialGradient
+ id="paint63_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop261" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop262" />
+ </radialGradient>
+ <radialGradient
+ id="paint64_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop263" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop264" />
+ </radialGradient>
+ <radialGradient
+ id="paint65_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop265" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop266" />
+ </radialGradient>
+ <radialGradient
+ id="paint66_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop267" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop268" />
+ </radialGradient>
+ <radialGradient
+ id="paint67_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,536,1396)">
+ <stop
+ stop-color="#2962FF"
+ id="stop269" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop270" />
+ </radialGradient>
+ <radialGradient
+ id="paint68_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop271" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop272" />
+ </radialGradient>
+ <radialGradient
+ id="paint69_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop273" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop274" />
+ </radialGradient>
+ <radialGradient
+ id="paint70_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop275" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop276" />
+ </radialGradient>
+ <radialGradient
+ id="paint71_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop277" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop278" />
+ </radialGradient>
+ <radialGradient
+ id="paint72_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop279" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop280" />
+ </radialGradient>
+ <radialGradient
+ id="paint73_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop281" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop282" />
+ </radialGradient>
+ <radialGradient
+ id="paint74_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop283" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop284" />
+ </radialGradient>
+ <radialGradient
+ id="paint75_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop285" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop286" />
+ </radialGradient>
+ <radialGradient
+ id="paint76_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop287" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop288" />
+ </radialGradient>
+ <radialGradient
+ id="paint77_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop289" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop290" />
+ </radialGradient>
+ <radialGradient
+ id="paint78_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop291" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop292" />
+ </radialGradient>
+ <radialGradient
+ id="paint79_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop293" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop294" />
+ </radialGradient>
+ <radialGradient
+ id="paint80_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop295" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop296" />
+ </radialGradient>
+ <radialGradient
+ id="paint81_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop297" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop298" />
+ </radialGradient>
+ <radialGradient
+ id="paint82_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop299" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop300" />
+ </radialGradient>
+ <radialGradient
+ id="paint83_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop301" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop302" />
+ </radialGradient>
+ <radialGradient
+ id="paint84_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop303" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop304" />
+ </radialGradient>
+ <radialGradient
+ id="paint85_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop305" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop306" />
+ </radialGradient>
+ <radialGradient
+ id="paint86_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop307" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop308" />
+ </radialGradient>
+ <radialGradient
+ id="paint87_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop309" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop310" />
+ </radialGradient>
+ <radialGradient
+ id="paint88_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop311" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop312" />
+ </radialGradient>
+ <radialGradient
+ id="paint89_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop313" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop314" />
+ </radialGradient>
+ <radialGradient
+ id="paint90_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop315" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop316" />
+ </radialGradient>
+ <radialGradient
+ id="paint91_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop317" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop318" />
+ </radialGradient>
+ <radialGradient
+ id="paint92_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop319" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop320" />
+ </radialGradient>
+ <radialGradient
+ id="paint93_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop321" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop322" />
+ </radialGradient>
+ <radialGradient
+ id="paint94_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop323" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop324" />
+ </radialGradient>
+ <radialGradient
+ id="paint95_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop325" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop326" />
+ </radialGradient>
+ <radialGradient
+ id="paint96_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop327" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop328" />
+ </radialGradient>
+ <radialGradient
+ id="paint97_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop329" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop330" />
+ </radialGradient>
+ <radialGradient
+ id="paint98_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop331" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop332" />
+ </radialGradient>
+ <radialGradient
+ id="paint99_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop333" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop334" />
+ </radialGradient>
+ <radialGradient
+ id="paint100_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop335" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop336" />
+ </radialGradient>
+ <radialGradient
+ id="paint101_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop337" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop338" />
+ </radialGradient>
+ <radialGradient
+ id="paint102_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop339" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop340" />
+ </radialGradient>
+ <radialGradient
+ id="paint103_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop341" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop342" />
+ </radialGradient>
+ <radialGradient
+ id="paint104_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop343" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop344" />
+ </radialGradient>
+ <radialGradient
+ id="paint105_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop345" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop346" />
+ </radialGradient>
+ <radialGradient
+ id="paint106_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop347" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop348" />
+ </radialGradient>
+ <radialGradient
+ id="paint107_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop349" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop350" />
+ </radialGradient>
+ <radialGradient
+ id="paint108_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop351" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop352" />
+ </radialGradient>
+ <radialGradient
+ id="paint109_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop353" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop354" />
+ </radialGradient>
+ <radialGradient
+ id="paint110_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop355" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop356" />
+ </radialGradient>
+ <radialGradient
+ id="paint111_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop357" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop358" />
+ </radialGradient>
+ <radialGradient
+ id="paint112_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop359" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop360" />
+ </radialGradient>
+ <radialGradient
+ id="paint113_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop361" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop362" />
+ </radialGradient>
+ <radialGradient
+ id="paint114_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop363" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop364" />
+ </radialGradient>
+ <radialGradient
+ id="paint115_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop365" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop366" />
+ </radialGradient>
+ <radialGradient
+ id="paint116_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop367" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop368" />
+ </radialGradient>
+ <radialGradient
+ id="paint117_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop369" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop370" />
+ </radialGradient>
+ <radialGradient
+ id="paint118_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop371" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop372" />
+ </radialGradient>
+ <radialGradient
+ id="paint119_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop373" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop374" />
+ </radialGradient>
+ <radialGradient
+ id="paint120_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop375" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop376" />
+ </radialGradient>
+ <radialGradient
+ id="paint121_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop377" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop378" />
+ </radialGradient>
+ <radialGradient
+ id="paint122_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop379" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop380" />
+ </radialGradient>
+ <radialGradient
+ id="paint123_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop381" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop382" />
+ </radialGradient>
+ <radialGradient
+ id="paint124_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop383" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop384" />
+ </radialGradient>
+ <radialGradient
+ id="paint125_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop385" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop386" />
+ </radialGradient>
+ <radialGradient
+ id="paint126_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop387" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop388" />
+ </radialGradient>
+ <radialGradient
+ id="paint127_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop389" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop390" />
+ </radialGradient>
+ <radialGradient
+ id="paint128_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop391" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop392" />
+ </radialGradient>
+ <radialGradient
+ id="paint129_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop393" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop394" />
+ </radialGradient>
+ <radialGradient
+ id="paint130_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop395" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop396" />
+ </radialGradient>
+ <radialGradient
+ id="paint131_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop397" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop398" />
+ </radialGradient>
+ <radialGradient
+ id="paint132_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop399" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop400" />
+ </radialGradient>
+ <radialGradient
+ id="paint133_radial_129_2056"
+ cx="0"
+ cy="0"
+ r="1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,324,-516,0,540,638)">
+ <stop
+ stop-color="#2962FF"
+ id="stop401" />
+ <stop
+ offset="1"
+ stop-color="#2962FF"
+ stop-opacity="0"
+ id="stop402" />
+ </radialGradient>
+ </defs>
+</svg>
diff --git a/src/index.html b/src/index.html
index 5dac7c5..e94c770 100644
--- a/src/index.html
+++ b/src/index.html
@@ -26,26 +26,26 @@
Mixer
</h1>
<div id="SliderContainer" class="sliderContainer"></div>
- <script id="slider-template" type="x-tmpl-mustache">
- <div class="entry" id="slider-{{id}}" slider-id="{{ id }}" value="{{ value }}">
- <div class="label">
- {{ name }}: <span class="value"> {{ value }}%</span>
- </div>
- <a href="#" class="button" onclick="window.decrease(this);">
- <span class="icon-volume-decrease"></span>
- </a>
- <div class="slider">
- <input type="range" min="1" value="{{ value }}" max="100" oninput="window.change(this);">
- <progress value="{{ value }}" max="100"></progress>
- </div>
- <a href="#" class="button" onclick="window.increase(this);">
- <span class="icon-volume-increase"></span>
- </a>
- </div>
- </script>
</div>
<div class="log" id="log">
</div>
+ <script id="slider-template" type="x-tmpl-mustache">
+ <div class="entry" id="slider-{{ id }}" slider-id="{{ id }}" value="{{ value }}">
+ <div class="label">
+ {{ name }}: <span class="value"> {{ value }}%</span>
+ </div>
+ <a id="decrease-{{id}}" class="button" onclick="VOLUME.decrease(this);">
+ <span class="icon-volume-decrease"></span>
+ </a>
+ <div class="slider">
+ <input id="progress-{{id}}" type="range" min="1" value="{{ value }}" max="100" oninput="VOLUME.change(this);">
+ <progress value="{{ value }}" max="100"></progress>
+ </div>
+ <a id="increase-{{id}}" class="button" onclick="VOLUME.increase(this);">
+ <span class="icon-volume-increase"></span>
+ </a>
+ </div>
+ </script>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/src/index.js b/src/index.js
index 37b78c4..4db937f 100644
--- a/src/index.js
+++ b/src/index.js
@@ -14,15 +14,13 @@
* limitations under the License.
*/
-/* JS */
-import { init } from './js/app';
-import { increase, decrease, change } from './js/sliders';
-
/* CSS */
import './styles/app.scss';
+document.addEventListener('DOMContentLoaded', function(){
+ APP.init();
-window.increase = increase;
-window.decrease = decrease;
-window.change = change;
-init(); \ No newline at end of file
+ KUKSA.init([
+ [PATHS.volume, VOLUME],
+ ], VOLUME.init);
+});
diff --git a/src/js/app.js b/src/js/app.js
index a26f137..d4cc919 100644
--- a/src/js/app.js
+++ b/src/js/app.js
@@ -1,40 +1,21 @@
import Mustache from 'mustache';
-import { audiomixer, api } from 'agl-js-api';
-import { setValue } from './sliders';
var template;
+var controls = [
+ { id: 'MAIN', name: 'Main', volume: 50 },
+];
+
function render_sliders(sliders) {
var sliderContainer = document.getElementById('SliderContainer');
for( var i=0; i<sliders.length; i++) {
var node = Mustache.render(template, sliders[i]);
sliderContainer.innerHTML += node;
+ console.log(sliderContainer.innerHTML)
}
}
export function init() {
- api.init();
template = document.getElementById('slider-template').innerHTML;
- Mustache.parse(template);
-
- audiomixer.list_controls().then(function(result) {
- var sliders = [];
- for( var i=0; i<result.length; i++) {
- sliders.push({
- id: result[i].control,
- name: result[i].control,
- value: Math.floor(result[i].volume*100)
- });
- }
-
- render_sliders(sliders);
- }).catch(function(error) {
- console.error('ERROR loading sliders', error);
- });
-
- audiomixer.on_volume_changed(function(data){
- setValue(document.getElementById("slider-"+data.control), Math.ceil(data.value*100), true);
- }).then(function(result) {
- console.log("SUBSCRIBED TO VOLUME CHANGED");
- });
-} \ No newline at end of file
+ render_sliders(controls);
+}
diff --git a/src/js/kuksa.js b/src/js/kuksa.js
new file mode 100644
index 0000000..8542dcb
--- /dev/null
+++ b/src/js/kuksa.js
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2022 Igalia, S.L.
+ *
+ * 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 { v4 as uuidv4 } from 'uuid';
+
+const DEFAULT_TARGET = "https://localhost:8888";
+
+// TODO: use an application token when needed
+// currently using https://github.com/eclipse/kuksa.val/blob/master/kuksa_certificates/jwt/super-admin.json.token
+const TEST_TOKEN =
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA';
+
+var kuksa_context = {
+ authToken: TEST_TOKEN,
+ client: undefined,
+ target: DEFAULT_TARGET,
+ subscribe_entries: [],
+ subscribe_stream: null,
+ locks: new Map()
+}
+
+var pathToHandler = null;
+
+function updateVehicleInfo(path, dp) {
+ if (!pathToHandler.has(path)) {
+ console.log('Handler not found for', path);
+ return;
+ }
+
+ var handler = pathToHandler.get(path);
+ handler.update(path, dp)
+}
+
+function send(action, values) {
+}
+
+function add_subscribe_entry(path) {
+ console.log('Adding subscribe entry for ' + path + '...')
+ var entry = new VAL.SubscribeEntry();
+ entry.setPath(path);
+ entry.setView(TYPES.View.VIEW_ALL);
+ entry.addFields(TYPES.Field.FIELD_PATH);
+ entry.addFields(TYPES.Field.FIELD_VALUE);
+ kuksa_context.subscribe_entries.push(entry);
+}
+
+function subscribe() {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var request = new VAL.SubscribeRequest();
+ for (var i in kuksa_context.subscribe_entries) {
+ var entry = kuksa_context.subscribe_entries[i];
+ entry.setView(TYPES.View.VIEW_CURRENT_VALUE);
+ request.addEntries(entry);
+ }
+
+ kuksa_context.subscribe_stream = kuksa_context.client.subscribe(request, metadata);
+
+ kuksa_context.subscribe_stream.on('data', function(response) {
+ var updates = response.getUpdatesList();
+ for (var i in updates) {
+ var update = updates[i];
+ var entry = update.getEntry();
+ var path = entry.getPath();
+ var dp = entry.getValue();
+
+ if (!(entry && path && dp)) {
+ continue;
+ }
+
+ lock(path);
+ updateVehicleInfo(path, dp);
+ unlock(path);
+ }
+ });
+
+ kuksa_context.subscribe_stream.on('error', function(error) {
+ console.log("Error code: " + error.code + " message: " + error.message);
+ // if an error happens here, the databroker will drop the subscriber, so
+ // we need to subscribe again
+ subscribe();
+ });
+}
+
+// TODO: investigate why an empty response is always being returned on the
+// response
+export function get(path) {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ if (isLocked(path)) {
+ return;
+ }
+
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var request = new VAL.GetRequest();
+ var entry = new VAL.EntryRequest();
+ entry.setPath(path);
+ entry.setView(TYPES.View.VIEW_ALL);
+ entry.addFields(TYPES.Field.FIELD_METADATA);
+ entry.addFields(TYPES.Field.FIELD_VALUE);
+ request.addEntries(entry);
+
+ kuksa_context.client.get(request, metadata, function(error, response) {
+ if (error) {
+ console.log("Get error, code: " + error.code);
+ return;
+ }
+ if (!response) {
+ return;
+ }
+ var entries = response.getEntriesList();
+ for (var i in entries) {
+ var entry = entries[i];
+ var path = entry.getPath();
+ var dp = entry.getValue();
+
+ if (!(entry && path && dp)) {
+ continue;
+ }
+ lock(path);
+ updateVehicleInfo(path, dp);
+ unlock(path);
+ }
+ });
+}
+
+export function set(path, dp) {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ if (isLocked(path)) {
+ return;
+ }
+ lock(path);
+
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var entry = new TYPES.DataEntry();
+ entry.setPath(path);
+ entry.setValue(dp);
+
+ var update = new VAL.EntryUpdate();
+ update.addFields(TYPES.Field.FIELD_PATH);
+ update.addFields(TYPES.Field.FIELD_VALUE);
+ update.setEntry(entry);
+
+ var request = new VAL.SetRequest();
+ request.addUpdates(update);
+
+ kuksa_context.client.set(request, metadata, function(error, response) {
+ // don't unlock updates here, only when we get a value from
+ // the subscription updates
+ });
+}
+
+export function init(handlers) {
+ console.log("Initializing kuka-val module...");
+ pathToHandler = new Map(handlers);
+ pathToHandler.forEach(function(handler, path) {
+ add_subscribe_entry(path);
+ });
+
+ if (kuksa_context.client == undefined) {
+ console.log("Creating kuksa-val client...");
+ kuksa_context.client = new VAL_WEB.VALClient(kuksa_context.target);
+
+ subscribe();
+ }
+}
+
+export function setInt32(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setInt32(value);
+ set(path, dp);
+}
+
+export function setUInt32(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setUint32(value);
+ set(path, dp);
+}
+
+export function setBool(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setBool(value);
+ set(path, dp);
+}
+
+export function setString(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setString(value);
+ set(path, dp);
+}
+
+export function lock(path) {
+ kuksa_context.locks[path] = true;
+}
+
+export function unlock(path) {
+ kuksa_context.locks[path] = false;
+}
+
+export function isLocked(path) {
+ if (!kuksa_context.locks.has(path)) {
+ kuksa_context.locks[path] = false;
+ }
+ return kuksa_context.locks[path];
+}
diff --git a/src/js/paths.js b/src/js/paths.js
new file mode 100644
index 0000000..a065036
--- /dev/null
+++ b/src/js/paths.js
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2022 Igalia, S.L.
+ *
+ * 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.
+ */
+
+// https://github.com/COVESA/vehicle_signal_specification/blob/master/spec/Cabin/Infotainment.vspec
+export const volume = 'Vehicle.Cabin.Infotainment.Media.Volume';
diff --git a/src/js/sliders.js b/src/js/volume.js
index 7208a85..749496b 100644
--- a/src/js/sliders.js
+++ b/src/js/volume.js
@@ -1,11 +1,9 @@
-import { audiomixer } from 'agl-js-api';
-
function getRootNode(node) {
- while(!node.hasAttribute('slider-id') && node.parentNode) {
+ while (!node.hasAttribute('slider-id') && node.parentNode) {
return getRootNode(node.parentNode);
}
- if( node.hasAttribute('slider-id') ) {
+ if (node.hasAttribute('slider-id')) {
return node;
} else {
return false;
@@ -14,35 +12,45 @@ function getRootNode(node) {
function getValue(node) {
node = getRootNode(node);
- if( node ) {
+ if (node) {
return parseInt(node.getAttribute('value'));
} else {
return false;
}
}
-export function setValue(node, value, notUpdate) {
+export function setValue(node, value) {
node = getRootNode(node);
- if( node ){
+ if (node) {
value = Math.max(Math.min(value, 100), 0);
node.setAttribute('value', value);
node.getElementsByTagName('progress')[0].value = value;
node.getElementsByTagName('input')[0].value = value;
node.getElementsByClassName('value')[0].innerHTML = value+'%';
- if( !notUpdate ) {
- audiomixer.set_volume(node.getAttribute('slider-id'), value/100);
- }
}
}
+// TODO: right now there's only one PATHS
+// if it gets update to use multiple volume controls
+// all the below functions need to be update to use
+// the correct paths/elements
export function increase(node) {
- setValue(node, getValue(node)+5);
+ KUKSA.setUInt32(PATHS.volume, getValue(node)+5);
}
export function decrease(node) {
- setValue(node, getValue(node)-5);
+ KUKSA.setUInt32(PATHS.volume, getValue(node)-5);
}
export function change(node) {
- setValue(node, node.value);
-} \ No newline at end of file
+ KUKSA.setUInt32(PATHS.volume, node.value);
+}
+
+export function update(path, dp) {
+ var value = dp.getUint32();
+ setValue(document.getElementById('progress-MAIN'), value);
+}
+
+export function init() {
+ KUKSA.setUInt32(PATHS.volume, 20);
+}
diff --git a/src/styles/app.scss b/src/styles/app.scss
index cbba7fc..18af381 100644
--- a/src/styles/app.scss
+++ b/src/styles/app.scss
@@ -1,7 +1,7 @@
$colors: (
- primary: #00ADDC,
- font: #FFFFFF,
- grey: #848286
+ primary: #2962ff,
+ font: #c1d8ff,
+ grey: #1c2d92
);
@media (max-device-width: 720px) and (orientation: portrait) {
@import "main.scss";
@@ -27,4 +27,4 @@ $colors: (
@import "1080.scss";
}
-@import "style.css"; \ No newline at end of file
+@import "style.css";
diff --git a/src/styles/landscape.scss b/src/styles/landscape.scss
index d215960..ee504e9 100644
--- a/src/styles/landscape.scss
+++ b/src/styles/landscape.scss
@@ -1,7 +1,8 @@
@media (orientation: landscape) {
html {
- background-image: url('../images/horizontal_background.png');
+ background-image: url('../images/dashboardTextures.svg');
+ background-color: black;
}
body {
@@ -14,4 +15,4 @@
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/styles/main.scss b/src/styles/main.scss
index 8f388c9..d45f2bb 100644
--- a/src/styles/main.scss
+++ b/src/styles/main.scss
@@ -53,6 +53,13 @@ html {
height: 100%;
background-size: cover;
-webkit-overflow-scrolling: touch;
+ user-select: none;
+}
+
+img {
+ user-select: none !important;
+ touch-action: none;
+ pointer-events: none;
}
body {
@@ -143,4 +150,4 @@ body {
background: white;
font-size: 1.5rem;
}
-} \ No newline at end of file
+}
diff --git a/src/styles/portrait.scss b/src/styles/portrait.scss
index eff553c..ab28917 100644
--- a/src/styles/portrait.scss
+++ b/src/styles/portrait.scss
@@ -1,7 +1,8 @@
@media (orientation: portrait) {
html {
- background-image: url('../images/vertical_background.png');
+ background-image: url('../images/dashboardTextures.svg');
+ background-color: black;
}
body {
@@ -9,4 +10,4 @@
width: 100%;
}
}
-} \ No newline at end of file
+}
diff --git a/webpack.config.js b/webpack.config.js
index 68999df..483e600 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,16 +1,21 @@
const path = require('path');
-const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
-const CleanWebpackPlugin = require('clean-webpack-plugin');
+const TerserPlugin = require('terser-webpack-plugin');
+const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
const CopyPlugin = require('copy-webpack-plugin');
-const ZipPlugin = require('zip-webpack-plugin');
-
module.exports = {
mode: 'production',
entry: {
- index: './src/index.js'
+ index: './src/index.js',
+ APP: './src/js/app.js',
+ PATHS: './src/js/paths.js',
+ KUKSA: './src/js/kuksa.js',
+ VAL_WEB: './src/generated/val_grpc_web_pb.js',
+ VAL: './src/generated/val_pb.js',
+ TYPES: './src/generated/types_pb.js',
+ VOLUME: './src/js/volume.js'
},
output: {
path: __dirname + '/dist',
@@ -20,30 +25,34 @@ module.exports = {
library: '[name]'
},
optimization: {
- minimizer: [new UglifyJsPlugin()],
+ minimize: true,
+ minimizer: [
+ new TerserPlugin({
+ minify: TerserPlugin.uglifyJsMinify,
+ terserOptions: {}
+ })
+ ],
},
plugins: [
- new CleanWebpackPlugin(['dist']),
- new CopyPlugin([
- {
- from: 'src/icon.*',
- flatten: true
- },
- {
- from: 'src/config.xml',
- flatten: true
- },
- {
- from: 'src/mockups/*',
- to: 'mockups/',
- flatten: true
- },
- {
- from: 'src/images/*',
- to: 'images/',
- flatten: true
- }
- ]),
+ new CleanWebpackPlugin({
+ cleanAfterEveryBuildPatterns: ['dist']
+ }),
+ new CopyPlugin({
+ patterns: [
+ {
+ from: 'src/icon.*',
+ to: "[name][ext]"
+ },
+ {
+ from: 'src/appinfo.json',
+ to: "appinfo.json"
+ },
+ {
+ from: 'src/images/*',
+ to: 'images/[name][ext]'
+ }
+ ]
+ }),
new HtmlWebpackPlugin({
template: 'src/index.html',
filename: 'index.html',
@@ -51,13 +60,6 @@ module.exports = {
}),
new MiniCSSExtractPlugin({
filename: 'app.css',
- path: __dirname + '/dist'
- }),
- new ZipPlugin({
- path: __dirname + '/package',
- filename: 'mixer',
- extension: 'wgt',
- exclude: []
})
],
module: {
@@ -78,35 +80,21 @@ module.exports = {
]
},
{
- test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- name: '[name].[ext]',
- outputPath: 'fonts/'
- }
- }
- ]
+ test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
+ type: 'asset/resource',
+ generator: {
+ filename: 'fonts/[name][ext]'
+ }
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
- use: [
- 'file-loader',
- {
- loader: "image-webpack-loader",
- options: {
- bypassOnDebug: true, // webpack@1.x
- disable: true, // webpack@2.x and newer
- },
- }
- ]
+ type: 'asset/resource'
}
]
},
devServer: {
- contentBase: path.join(__dirname, 'dist'),
+ static: path.join(__dirname, 'dist'),
compress: true,
port: 9000
}
-};  \ No newline at end of file
+};