diff --git a/Birdmap.API/ClientApp/package-lock.json b/Birdmap.API/ClientApp/package-lock.json index 506d86f..cf85909 100644 --- a/Birdmap.API/ClientApp/package-lock.json +++ b/Birdmap.API/ClientApp/package-lock.json @@ -1733,6 +1733,11 @@ "@types/node": "*" } }, + "@types/googlemaps": { + "version": "3.40.3", + "resolved": "https://registry.npmjs.org/@types/googlemaps/-/googlemaps-3.40.3.tgz", + "integrity": "sha512-ivlG5S0LlnQgpgPnQCUNAs7kjBtO367ZwDmuK+ggsQfW+w4N0RyWbxWZ6vPwegDe50Du3Xbb5+QVwJuB/U1XpA==" + }, "@types/history": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.3.tgz", @@ -6321,6 +6326,19 @@ } } }, + "google-maps": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/google-maps/-/google-maps-4.3.3.tgz", + "integrity": "sha512-MQbEgBNQbGyV7mfS2tlFgW4EoGKLia24BvAl4a+kgsYWt4283kyPpaay/yKIsScQLr7nSUONaLNfOdMsCuJDEw==", + "requires": { + "@types/googlemaps": "^3.39.1" + } + }, + "google-maps-react": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/google-maps-react/-/google-maps-react-2.0.6.tgz", + "integrity": "sha512-M8Eo9WndfQEfxcmm6yRq03qdJgw1x6rQmJ9DN+a+xPQ3K7yNDGkVDbinrf4/8vcox7nELbeopbm4bpefKewWfQ==" + }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", diff --git a/Birdmap.API/ClientApp/package.json b/Birdmap.API/ClientApp/package.json index e5fe9fd..462cb73 100644 --- a/Birdmap.API/ClientApp/package.json +++ b/Birdmap.API/ClientApp/package.json @@ -8,6 +8,8 @@ "@material-ui/lab": "^4.0.0-alpha.56", "bootstrap": "^4.3.1", "connected-react-router": "6.5.2", + "google-maps": "^4.3.3", + "google-maps-react": "^2.0.6", "history": "4.10.1", "jquery": "^3.5.1", "merge": "1.2.1", diff --git a/Birdmap.API/ClientApp/src/components/devices/DeviceService.js b/Birdmap.API/ClientApp/src/components/devices/DeviceService.js new file mode 100644 index 0000000..25fda0c --- /dev/null +++ b/Birdmap.API/ClientApp/src/components/devices/DeviceService.js @@ -0,0 +1,601 @@ +"use strict"; +/* tslint:disable */ +/* eslint-disable */ +//---------------------- +// +// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org) +// +//---------------------- +// ReSharper disable InconsistentNaming +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ApiException = exports.SensorStatus = exports.Coordinates = exports.DeviceStatus = exports.Sensor = exports.Device = exports.DeviceService = void 0; +var DeviceService = /** @class */ (function () { + function DeviceService(baseUrl, http) { + this.jsonParseReviver = undefined; + this.http = http ? http : window; + this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "api/devices"; + } + /** + * Get all device info + * @return Array of devices + */ + DeviceService.prototype.getall = function () { + var _this = this; + var url_ = this.baseUrl; + var options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processGetall(_response); + }); + }; + DeviceService.prototype.processGetall = function (response) { + var _this = this; + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + var result200 = null; + var resultData200 = _responseText === "" ? null : JSON.parse(_responseText, _this.jsonParseReviver); + if (Array.isArray(resultData200)) { + result200 = []; + for (var _i = 0, resultData200_1 = resultData200; _i < resultData200_1.length; _i++) { + var item = resultData200_1[_i]; + result200.push(Device.fromJS(item)); + } + } + return result200; + }); + } + else if (status === 404) { + return response.text().then(function (_responseText) { + return throwException("No device found", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Shut down all devices + * @return Message sent + */ + DeviceService.prototype.offlineall = function () { + var _this = this; + var url_ = this.baseUrl + "/offline"; + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "POST", + headers: {} + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processOfflineall(_response); + }); + }; + DeviceService.prototype.processOfflineall = function (response) { + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + return; + }); + } + else if (status === 500) { + return response.text().then(function (_responseText) { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Bring all devices online + * @return Message sent + */ + DeviceService.prototype.onlineall = function () { + var _this = this; + var url_ = this.baseUrl + "/online"; + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "POST", + headers: {} + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processOnlineall(_response); + }); + }; + DeviceService.prototype.processOnlineall = function (response) { + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + return; + }); + } + else if (status === 500) { + return response.text().then(function (_responseText) { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Get all device info + * @param deviceID ID of device to query + * @return Information about a particular device + */ + DeviceService.prototype.getdevice = function (deviceID) { + var _this = this; + var url_ = this.baseUrl + "/{deviceID}"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processGetdevice(_response); + }); + }; + DeviceService.prototype.processGetdevice = function (response) { + var _this = this; + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + var result200 = null; + var resultData200 = _responseText === "" ? null : JSON.parse(_responseText, _this.jsonParseReviver); + result200 = Device.fromJS(resultData200); + return result200; + }); + } + else if (status === 404) { + return response.text().then(function (_responseText) { + return throwException("Device not found", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Shut down device + * @param deviceID ID of device to shut down + * @return Message sent + */ + DeviceService.prototype.offlinedevice = function (deviceID) { + var _this = this; + var url_ = this.baseUrl + "/{deviceID}/offline"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "POST", + headers: {} + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processOfflinedevice(_response); + }); + }; + DeviceService.prototype.processOfflinedevice = function (response) { + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + return; + }); + } + else if (status === 500) { + return response.text().then(function (_responseText) { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Bring device online + * @param deviceID ID of device to bring online + * @return Message sent + */ + DeviceService.prototype.onlinedevice = function (deviceID) { + var _this = this; + var url_ = this.baseUrl + "/{deviceID}/online"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "POST", + headers: {} + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processOnlinedevice(_response); + }); + }; + DeviceService.prototype.processOnlinedevice = function (response) { + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + return; + }); + } + else if (status === 500) { + return response.text().then(function (_responseText) { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Get info about a particular device's sensor + * @param deviceID ID of device to query + * @param sensorID ID of sensor to query + * @return Information about a sensor + */ + DeviceService.prototype.getsensor = function (deviceID, sensorID) { + var _this = this; + var url_ = this.baseUrl + "/{deviceID}/{sensorID}"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + if (sensorID === undefined || sensorID === null) + throw new Error("The parameter 'sensorID' must be defined."); + url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID)); + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processGetsensor(_response); + }); + }; + DeviceService.prototype.processGetsensor = function (response) { + var _this = this; + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + var result200 = null; + var resultData200 = _responseText === "" ? null : JSON.parse(_responseText, _this.jsonParseReviver); + result200 = Sensor.fromJS(resultData200); + return result200; + }); + } + else if (status === 404) { + return response.text().then(function (_responseText) { + return throwException("Device or sensor not found", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Shut down sensor + * @param deviceID ID of device to query + * @param sensorID ID of sensor to query + * @return Message sent + */ + DeviceService.prototype.offlinesensor = function (deviceID, sensorID) { + var _this = this; + var url_ = this.baseUrl + "/{deviceID}/{sensorID}/offline"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + if (sensorID === undefined || sensorID === null) + throw new Error("The parameter 'sensorID' must be defined."); + url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID)); + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "POST", + headers: {} + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processOfflinesensor(_response); + }); + }; + DeviceService.prototype.processOfflinesensor = function (response) { + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + return; + }); + } + else if (status === 500) { + return response.text().then(function (_responseText) { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + /** + * Bring sensor online + * @param deviceID ID of device to query + * @param sensorID ID of sensor to query + * @return Message sent + */ + DeviceService.prototype.onlinesensor = function (deviceID, sensorID) { + var _this = this; + var url_ = this.baseUrl + "/{deviceID}/{sensorID}/online"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + if (sensorID === undefined || sensorID === null) + throw new Error("The parameter 'sensorID' must be defined."); + url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID)); + url_ = url_.replace(/[?&]$/, ""); + var options_ = { + method: "POST", + headers: {} + }; + return this.http.fetch(url_, options_).then(function (_response) { + return _this.processOnlinesensor(_response); + }); + }; + DeviceService.prototype.processOnlinesensor = function (response) { + var status = response.status; + var _headers = {}; + if (response.headers && response.headers.forEach) { + response.headers.forEach(function (v, k) { return _headers[k] = v; }); + } + ; + if (status === 200) { + return response.text().then(function (_responseText) { + return; + }); + } + else if (status === 500) { + return response.text().then(function (_responseText) { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } + else if (status !== 200 && status !== 204) { + return response.text().then(function (_responseText) { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + }; + return DeviceService; +}()); +exports.DeviceService = DeviceService; +var Device = /** @class */ (function () { + function Device(data) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + this[property] = data[property]; + } + } + if (!data) { + this.coordinates = new Coordinates(); + this.sensors = []; + } + } + Device.prototype.init = function (_data) { + if (_data) { + this.id = _data["id"]; + this.status = _data["status"]; + this.url = _data["url"]; + this.coordinates = _data["coordinates"] ? Coordinates.fromJS(_data["coordinates"]) : new Coordinates(); + if (Array.isArray(_data["sensors"])) { + this.sensors = []; + for (var _i = 0, _a = _data["sensors"]; _i < _a.length; _i++) { + var item = _a[_i]; + this.sensors.push(Sensor.fromJS(item)); + } + } + } + }; + Device.fromJS = function (data) { + data = typeof data === 'object' ? data : {}; + var result = new Device(); + result.init(data); + return result; + }; + Device.prototype.toJSON = function (data) { + data = typeof data === 'object' ? data : {}; + data["id"] = this.id; + data["status"] = this.status; + data["url"] = this.url; + data["coordinates"] = this.coordinates ? this.coordinates.toJSON() : undefined; + if (Array.isArray(this.sensors)) { + data["sensors"] = []; + for (var _i = 0, _a = this.sensors; _i < _a.length; _i++) { + var item = _a[_i]; + data["sensors"].push(item.toJSON()); + } + } + return data; + }; + return Device; +}()); +exports.Device = Device; +var Sensor = /** @class */ (function () { + function Sensor(data) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + this[property] = data[property]; + } + } + } + Sensor.prototype.init = function (_data) { + if (_data) { + this.id = _data["id"]; + this.status = _data["status"]; + } + }; + Sensor.fromJS = function (data) { + data = typeof data === 'object' ? data : {}; + var result = new Sensor(); + result.init(data); + return result; + }; + Sensor.prototype.toJSON = function (data) { + data = typeof data === 'object' ? data : {}; + data["id"] = this.id; + data["status"] = this.status; + return data; + }; + return Sensor; +}()); +exports.Sensor = Sensor; +var DeviceStatus; +(function (DeviceStatus) { + DeviceStatus["Online"] = "online"; + DeviceStatus["Error"] = "error"; + DeviceStatus["Offline"] = "offline"; +})(DeviceStatus = exports.DeviceStatus || (exports.DeviceStatus = {})); +var Coordinates = /** @class */ (function () { + function Coordinates(data) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + this[property] = data[property]; + } + } + } + Coordinates.prototype.init = function (_data) { + if (_data) { + this.latitude = _data["latitude"]; + this.longitude = _data["longitude"]; + } + }; + Coordinates.fromJS = function (data) { + data = typeof data === 'object' ? data : {}; + var result = new Coordinates(); + result.init(data); + return result; + }; + Coordinates.prototype.toJSON = function (data) { + data = typeof data === 'object' ? data : {}; + data["latitude"] = this.latitude; + data["longitude"] = this.longitude; + return data; + }; + return Coordinates; +}()); +exports.Coordinates = Coordinates; +var SensorStatus; +(function (SensorStatus) { + SensorStatus["Online"] = "online"; + SensorStatus["Unknown"] = "unknown"; + SensorStatus["Offline"] = "offline"; +})(SensorStatus = exports.SensorStatus || (exports.SensorStatus = {})); +var ApiException = /** @class */ (function (_super) { + __extends(ApiException, _super); + function ApiException(message, status, response, headers, result) { + var _this = _super.call(this) || this; + _this.isApiException = true; + _this.message = message; + _this.status = status; + _this.response = response; + _this.headers = headers; + _this.result = result; + return _this; + } + ApiException.isApiException = function (obj) { + return obj.isApiException === true; + }; + return ApiException; +}(Error)); +exports.ApiException = ApiException; +function throwException(message, status, response, headers, result) { + if (result !== null && result !== undefined) + throw result; + else + throw new ApiException(message, status, response, headers, null); +} +//# sourceMappingURL=DeviceService.js.map \ No newline at end of file diff --git a/Birdmap.API/ClientApp/src/components/devices/DeviceService.js.map b/Birdmap.API/ClientApp/src/components/devices/DeviceService.js.map new file mode 100644 index 0000000..e562720 --- /dev/null +++ b/Birdmap.API/ClientApp/src/components/devices/DeviceService.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DeviceService.js","sourceRoot":"","sources":["DeviceService.ts"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,oBAAoB;AACpB,wBAAwB;AACxB,mBAAmB;AACnB,2HAA2H;AAC3H,oBAAoB;AACpB,wBAAwB;AACxB,uCAAuC;;;;;;;;;;;;;;;;AAEvC;IAKI,uBAAY,OAAgB,EAAE,IAAyE;QAF7F,qBAAgB,GAAmD,SAAS,CAAC;QAGnF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,MAAM,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;IACvF,CAAC;IAED;;;OAGG;IACH,8BAAM,GAAN;QAAA,iBAaC;QAZG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAExB,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACL,QAAQ,EAAE,kBAAkB;aAC/B;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACP,CAAC;IAES,qCAAa,GAAvB,UAAwB,QAAkB;QAA1C,iBAwBC;QAvBG,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,IAAI,SAAS,GAAQ,IAAI,CAAC;gBAC1B,IAAI,aAAa,GAAG,aAAa,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,KAAI,CAAC,gBAAgB,CAAC,CAAC;gBACnG,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;oBAC9B,SAAS,GAAG,EAAS,CAAC;oBACtB,KAAiB,UAAa,EAAb,+BAAa,EAAb,2BAAa,EAAb,IAAa;wBAAzB,IAAI,IAAI,sBAAA;wBACT,SAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;qBAAA;iBAC5C;gBACD,OAAO,SAAS,CAAC;YACrB,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC9E,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAgB,IAAI,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACH,kCAAU,GAAV;QAAA,iBAaC;QAZG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;QACrC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EACR;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACP,CAAC;IAES,yCAAiB,GAA3B,UAA4B,QAAkB;QAC1C,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO;YACX,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,8BAA8B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC3F,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAY,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACH,iCAAS,GAAT;QAAA,iBAaC;QAZG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACpC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EACR;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACP,CAAC;IAES,wCAAgB,GAA1B,UAA2B,QAAkB;QACzC,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO;YACX,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,8BAA8B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC3F,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAY,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACH,iCAAS,GAAT,UAAU,QAAgB;QAA1B,iBAiBC;QAhBG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACL,QAAQ,EAAE,kBAAkB;aAC/B;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACP,CAAC;IAES,wCAAgB,GAA1B,UAA2B,QAAkB;QAA7C,iBAoBC;QAnBG,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,IAAI,SAAS,GAAQ,IAAI,CAAC;gBAC1B,IAAI,aAAa,GAAG,aAAa,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,KAAI,CAAC,gBAAgB,CAAC,CAAC;gBACnG,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACzC,OAAO,SAAS,CAAC;YACrB,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,kBAAkB,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC/E,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAc,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACH,qCAAa,GAAb,UAAc,QAAgB;QAA9B,iBAgBC;QAfG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,qBAAqB,CAAC;QAChD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EACR;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACP,CAAC;IAES,4CAAoB,GAA9B,UAA+B,QAAkB;QAC7C,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO;YACX,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,8BAA8B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC3F,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAY,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACH,oCAAY,GAAZ,UAAa,QAAgB;QAA7B,iBAgBC;QAfG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,oBAAoB,CAAC;QAC/C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EACR;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACP,CAAC;IAES,2CAAmB,GAA7B,UAA8B,QAAkB;QAC5C,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO;YACX,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,8BAA8B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC3F,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAY,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,iCAAS,GAAT,UAAU,QAAgB,EAAE,QAAgB;QAA5C,iBAoBC;QAnBG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,wBAAwB,CAAC;QACnD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACL,QAAQ,EAAE,kBAAkB;aAC/B;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACP,CAAC;IAES,wCAAgB,GAA1B,UAA2B,QAAkB;QAA7C,iBAoBC;QAnBG,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,IAAI,SAAS,GAAQ,IAAI,CAAC;gBAC1B,IAAI,aAAa,GAAG,aAAa,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,KAAI,CAAC,gBAAgB,CAAC,CAAC;gBACnG,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACzC,OAAO,SAAS,CAAC;YACrB,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,4BAA4B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACzF,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAc,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACH,qCAAa,GAAb,UAAc,QAAgB,EAAE,QAAgB;QAAhD,iBAmBC;QAlBG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,gCAAgC,CAAC;QAC3D,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EACR;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACP,CAAC;IAES,4CAAoB,GAA9B,UAA+B,QAAkB;QAC7C,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO;YACX,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,8BAA8B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC3F,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAY,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,oCAAY,GAAZ,UAAa,QAAgB,EAAE,QAAgB;QAA/C,iBAmBC;QAlBG,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,+BAA+B,CAAC;QAC1D,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,QAAQ,GAAgB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EACR;SACJ,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,SAAmB;YAC5D,OAAO,KAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACP,CAAC;IAES,2CAAmB,GAA7B,UAA8B,QAAkB;QAC5C,IAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAC,CAAM,EAAE,CAAM,IAAK,OAAA,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAf,CAAe,CAAC,CAAC;SAAE;QAAA,CAAC;QAC7I,IAAI,MAAM,KAAK,GAAG,EAAE;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO;YACX,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE;YACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,8BAA8B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC3F,CAAC,CAAC,CAAC;SACN;aAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;YACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,aAAa;gBACtC,OAAO,cAAc,CAAC,sCAAsC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;SACN;QACD,OAAO,OAAO,CAAC,OAAO,CAAY,IAAI,CAAC,CAAC;IAC5C,CAAC;IACL,oBAAC;AAAD,CAAC,AAlZD,IAkZC;AAlZY,sCAAa;AAoZ1B;IAOI,gBAAY,IAAc;QACtB,IAAI,IAAI,EAAE;YACN,KAAK,IAAI,QAAQ,IAAI,IAAI,EAAE;gBACvB,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC;oBACvB,IAAK,CAAC,QAAQ,CAAC,GAAS,IAAK,CAAC,QAAQ,CAAC,CAAC;aACrD;SACJ;QACD,IAAI,CAAC,IAAI,EAAE;YACP,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;SACrB;IACL,CAAC;IAED,qBAAI,GAAJ,UAAK,KAAW;QACZ,IAAI,KAAK,EAAE;YACP,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC;YACvG,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE;gBACjC,IAAI,CAAC,OAAO,GAAG,EAAS,CAAC;gBACzB,KAAiB,UAAgB,EAAhB,KAAA,KAAK,CAAC,SAAS,CAAC,EAAhB,cAAgB,EAAhB,IAAgB;oBAA5B,IAAI,IAAI,SAAA;oBACT,IAAI,CAAC,OAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;iBAAA;aAC/C;SACJ;IACL,CAAC;IAEM,aAAM,GAAb,UAAc,IAAS;QACnB,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,uBAAM,GAAN,UAAO,IAAU;QACb,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAM,SAAS,CAAC;QACpF,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;YACrB,KAAiB,UAAY,EAAZ,KAAA,IAAI,CAAC,OAAO,EAAZ,cAAY,EAAZ,IAAY;gBAAxB,IAAI,IAAI,SAAA;gBACT,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;aAAA;SAC3C;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IACL,aAAC;AAAD,CAAC,AAtDD,IAsDC;AAtDY,wBAAM;AAgEnB;IAII,gBAAY,IAAc;QACtB,IAAI,IAAI,EAAE;YACN,KAAK,IAAI,QAAQ,IAAI,IAAI,EAAE;gBACvB,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC;oBACvB,IAAK,CAAC,QAAQ,CAAC,GAAS,IAAK,CAAC,QAAQ,CAAC,CAAC;aACrD;SACJ;IACL,CAAC;IAED,qBAAI,GAAJ,UAAK,KAAW;QACZ,IAAI,KAAK,EAAE;YACP,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;SACjC;IACL,CAAC;IAEM,aAAM,GAAb,UAAc,IAAS;QACnB,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,uBAAM,GAAN,UAAO,IAAU;QACb,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7B,OAAO,IAAI,CAAC;IAChB,CAAC;IACL,aAAC;AAAD,CAAC,AAjCD,IAiCC;AAjCY,wBAAM;AAwCnB,IAAY,YAIX;AAJD,WAAY,YAAY;IACpB,iCAAiB,CAAA;IACjB,+BAAe,CAAA;IACf,mCAAmB,CAAA;AACvB,CAAC,EAJW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAIvB;AAED;IAII,qBAAY,IAAmB;QAC3B,IAAI,IAAI,EAAE;YACN,KAAK,IAAI,QAAQ,IAAI,IAAI,EAAE;gBACvB,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC;oBACvB,IAAK,CAAC,QAAQ,CAAC,GAAS,IAAK,CAAC,QAAQ,CAAC,CAAC;aACrD;SACJ;IACL,CAAC;IAED,0BAAI,GAAJ,UAAK,KAAW;QACZ,IAAI,KAAK,EAAE;YACP,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;YAClC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;SACvC;IACL,CAAC;IAEM,kBAAM,GAAb,UAAc,IAAS;QACnB,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,4BAAM,GAAN,UAAO,IAAU;QACb,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;QACnC,OAAO,IAAI,CAAC;IAChB,CAAC;IACL,kBAAC;AAAD,CAAC,AAjCD,IAiCC;AAjCY,kCAAW;AAwCxB,IAAY,YAIX;AAJD,WAAY,YAAY;IACpB,iCAAiB,CAAA;IACjB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;AACvB,CAAC,EAJW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAIvB;AAED;IAAkC,gCAAK;IAOnC,sBAAY,OAAe,EAAE,MAAc,EAAE,QAAgB,EAAE,OAAgC,EAAE,MAAW;QAA5G,YACI,iBAAO,SAOV;QAES,oBAAc,GAAG,IAAI,CAAC;QAP5B,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,KAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAI,CAAC,MAAM,GAAG,MAAM,CAAC;;IACzB,CAAC;IAIM,2BAAc,GAArB,UAAsB,GAAQ;QAC1B,OAAO,GAAG,CAAC,cAAc,KAAK,IAAI,CAAC;IACvC,CAAC;IACL,mBAAC;AAAD,CAAC,AAtBD,CAAkC,KAAK,GAsBtC;AAtBY,oCAAY;AAwBzB,SAAS,cAAc,CAAC,OAAe,EAAE,MAAc,EAAE,QAAgB,EAAE,OAAgC,EAAE,MAAY;IACrH,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS;QACvC,MAAM,MAAM,CAAC;;QAEb,MAAM,IAAI,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACzE,CAAC"} \ No newline at end of file diff --git a/Birdmap.API/ClientApp/src/components/devices/DeviceService.ts b/Birdmap.API/ClientApp/src/components/devices/DeviceService.ts new file mode 100644 index 0000000..5230923 --- /dev/null +++ b/Birdmap.API/ClientApp/src/components/devices/DeviceService.ts @@ -0,0 +1,599 @@ +/* tslint:disable */ +/* eslint-disable */ +//---------------------- +// +// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org) +// +//---------------------- +// ReSharper disable InconsistentNaming + +export class DeviceService { + private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise }) { + this.http = http ? http : window; + this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "api/devices"; + } + + /** + * Get all device info + * @return Array of devices + */ + getall(): Promise { + let url_ = this.baseUrl; + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGetall(_response); + }); + } + + protected processGetall(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + if (Array.isArray(resultData200)) { + result200 = [] as any; + for (let item of resultData200) + result200!.push(Device.fromJS(item)); + } + return result200; + }); + } else if (status === 404) { + return response.text().then((_responseText) => { + return throwException("No device found", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Shut down all devices + * @return Message sent + */ + offlineall(): Promise { + let url_ = this.baseUrl + "/offline"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "POST", + headers: { + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processOfflineall(_response); + }); + } + + protected processOfflineall(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + return; + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Bring all devices online + * @return Message sent + */ + onlineall(): Promise { + let url_ = this.baseUrl + "/online"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "POST", + headers: { + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processOnlineall(_response); + }); + } + + protected processOnlineall(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + return; + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Get all device info + * @param deviceID ID of device to query + * @return Information about a particular device + */ + getdevice(deviceID: string): Promise { + let url_ = this.baseUrl + "/{deviceID}"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGetdevice(_response); + }); + } + + protected processGetdevice(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = Device.fromJS(resultData200); + return result200; + }); + } else if (status === 404) { + return response.text().then((_responseText) => { + return throwException("Device not found", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Shut down device + * @param deviceID ID of device to shut down + * @return Message sent + */ + offlinedevice(deviceID: string): Promise { + let url_ = this.baseUrl + "/{deviceID}/offline"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "POST", + headers: { + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processOfflinedevice(_response); + }); + } + + protected processOfflinedevice(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + return; + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Bring device online + * @param deviceID ID of device to bring online + * @return Message sent + */ + onlinedevice(deviceID: string): Promise { + let url_ = this.baseUrl + "/{deviceID}/online"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "POST", + headers: { + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processOnlinedevice(_response); + }); + } + + protected processOnlinedevice(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + return; + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Get info about a particular device's sensor + * @param deviceID ID of device to query + * @param sensorID ID of sensor to query + * @return Information about a sensor + */ + getsensor(deviceID: string, sensorID: string): Promise { + let url_ = this.baseUrl + "/{deviceID}/{sensorID}"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + if (sensorID === undefined || sensorID === null) + throw new Error("The parameter 'sensorID' must be defined."); + url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGetsensor(_response); + }); + } + + protected processGetsensor(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = Sensor.fromJS(resultData200); + return result200; + }); + } else if (status === 404) { + return response.text().then((_responseText) => { + return throwException("Device or sensor not found", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Shut down sensor + * @param deviceID ID of device to query + * @param sensorID ID of sensor to query + * @return Message sent + */ + offlinesensor(deviceID: string, sensorID: string): Promise { + let url_ = this.baseUrl + "/{deviceID}/{sensorID}/offline"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + if (sensorID === undefined || sensorID === null) + throw new Error("The parameter 'sensorID' must be defined."); + url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "POST", + headers: { + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processOfflinesensor(_response); + }); + } + + protected processOfflinesensor(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + return; + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + /** + * Bring sensor online + * @param deviceID ID of device to query + * @param sensorID ID of sensor to query + * @return Message sent + */ + onlinesensor(deviceID: string, sensorID: string): Promise { + let url_ = this.baseUrl + "/{deviceID}/{sensorID}/online"; + if (deviceID === undefined || deviceID === null) + throw new Error("The parameter 'deviceID' must be defined."); + url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID)); + if (sensorID === undefined || sensorID === null) + throw new Error("The parameter 'sensorID' must be defined."); + url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "POST", + headers: { + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processOnlinesensor(_response); + }); + } + + protected processOnlinesensor(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + return; + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("Message sending unsuccessful", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } +} + +export class Device implements IDevice { + id!: string; + status!: DeviceStatus; + url!: string; + coordinates!: Coordinates; + sensors!: Sensor[]; + + constructor(data?: IDevice) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + (this)[property] = (data)[property]; + } + } + if (!data) { + this.coordinates = new Coordinates(); + this.sensors = []; + } + } + + init(_data?: any) { + if (_data) { + this.id = _data["id"]; + this.status = _data["status"]; + this.url = _data["url"]; + this.coordinates = _data["coordinates"] ? Coordinates.fromJS(_data["coordinates"]) : new Coordinates(); + if (Array.isArray(_data["sensors"])) { + this.sensors = [] as any; + for (let item of _data["sensors"]) + this.sensors!.push(Sensor.fromJS(item)); + } + } + } + + static fromJS(data: any): Device { + data = typeof data === 'object' ? data : {}; + let result = new Device(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data["id"] = this.id; + data["status"] = this.status; + data["url"] = this.url; + data["coordinates"] = this.coordinates ? this.coordinates.toJSON() : undefined; + if (Array.isArray(this.sensors)) { + data["sensors"] = []; + for (let item of this.sensors) + data["sensors"].push(item.toJSON()); + } + return data; + } +} + +export interface IDevice { + id: string; + status: DeviceStatus; + url: string; + coordinates: Coordinates; + sensors: Sensor[]; +} + +export class Sensor implements ISensor { + id!: string; + status!: SensorStatus; + + constructor(data?: ISensor) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + (this)[property] = (data)[property]; + } + } + } + + init(_data?: any) { + if (_data) { + this.id = _data["id"]; + this.status = _data["status"]; + } + } + + static fromJS(data: any): Sensor { + data = typeof data === 'object' ? data : {}; + let result = new Sensor(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data["id"] = this.id; + data["status"] = this.status; + return data; + } +} + +export interface ISensor { + id: string; + status: SensorStatus; +} + +export enum DeviceStatus { + Online = "online", + Error = "error", + Offline = "offline", +} + +export class Coordinates implements ICoordinates { + latitude!: number; + longitude!: number; + + constructor(data?: ICoordinates) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + (this)[property] = (data)[property]; + } + } + } + + init(_data?: any) { + if (_data) { + this.latitude = _data["latitude"]; + this.longitude = _data["longitude"]; + } + } + + static fromJS(data: any): Coordinates { + data = typeof data === 'object' ? data : {}; + let result = new Coordinates(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data["latitude"] = this.latitude; + data["longitude"] = this.longitude; + return data; + } +} + +export interface ICoordinates { + latitude: number; + longitude: number; +} + +export enum SensorStatus { + Online = "online", + Unknown = "unknown", + Offline = "offline", +} + +export class ApiException extends Error { + message: string; + status: number; + response: string; + headers: { [key: string]: any; }; + result: any; + + constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) { + super(); + + this.message = message; + this.status = status; + this.response = response; + this.headers = headers; + this.result = result; + } + + protected isApiException = true; + + static isApiException(obj: any): obj is ApiException { + return obj.isApiException === true; + } +} + +function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any { + if (result !== null && result !== undefined) + throw result; + else + throw new ApiException(message, status, response, headers, null); +} \ No newline at end of file diff --git a/Birdmap.API/ClientApp/src/components/heatmap/heatmap.js b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.js new file mode 100644 index 0000000..0e3bc3e --- /dev/null +++ b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.js @@ -0,0 +1,555 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.initMap = void 0; +var google_maps_1 = require("google-maps"); +var map, heatmap; +function initMap() { + var options = { /* todo */}; + var loader = new google_maps_1.Loader('AIzaSyCZ51VFfxqZ2GkCmVrcNZdUKsM0fuBQUCY', options); + loader.load().then(function (google) { + map = new google.maps.Map(document.getElementById("map"), { + zoom: 13, + center: { lat: 37.775, lng: -122.434 }, + mapTypeId: "satellite", + }); + heatmap = new google.maps.visualization.HeatmapLayer({ + data: getPoints(), + map: map, + }); + }); +} +exports.initMap = initMap; +function toggleHeatmap() { + heatmap.setMap(heatmap.getMap() ? null : map); +} +function changeGradient() { + var gradient = [ + "rgba(0, 255, 255, 0)", + "rgba(0, 255, 255, 1)", + "rgba(0, 191, 255, 1)", + "rgba(0, 127, 255, 1)", + "rgba(0, 63, 255, 1)", + "rgba(0, 0, 255, 1)", + "rgba(0, 0, 223, 1)", + "rgba(0, 0, 191, 1)", + "rgba(0, 0, 159, 1)", + "rgba(0, 0, 127, 1)", + "rgba(63, 0, 91, 1)", + "rgba(127, 0, 63, 1)", + "rgba(191, 0, 31, 1)", + "rgba(255, 0, 0, 1)", + ]; + heatmap.set("gradient", heatmap.get("gradient") ? null : gradient); +} +function changeRadius() { + heatmap.set("radius", heatmap.get("radius") ? null : 20); +} +function changeOpacity() { + heatmap.set("opacity", heatmap.get("opacity") ? null : 0.2); +} +// Heatmap data: 500 Points +function getPoints() { + return [ + new google.maps.LatLng(37.782551, -122.445368), + new google.maps.LatLng(37.782745, -122.444586), + new google.maps.LatLng(37.782842, -122.443688), + new google.maps.LatLng(37.782919, -122.442815), + new google.maps.LatLng(37.782992, -122.442112), + new google.maps.LatLng(37.7831, -122.441461), + new google.maps.LatLng(37.783206, -122.440829), + new google.maps.LatLng(37.783273, -122.440324), + new google.maps.LatLng(37.783316, -122.440023), + new google.maps.LatLng(37.783357, -122.439794), + new google.maps.LatLng(37.783371, -122.439687), + new google.maps.LatLng(37.783368, -122.439666), + new google.maps.LatLng(37.783383, -122.439594), + new google.maps.LatLng(37.783508, -122.439525), + new google.maps.LatLng(37.783842, -122.439591), + new google.maps.LatLng(37.784147, -122.439668), + new google.maps.LatLng(37.784206, -122.439686), + new google.maps.LatLng(37.784386, -122.43979), + new google.maps.LatLng(37.784701, -122.439902), + new google.maps.LatLng(37.784965, -122.439938), + new google.maps.LatLng(37.78501, -122.439947), + new google.maps.LatLng(37.78536, -122.439952), + new google.maps.LatLng(37.785715, -122.44003), + new google.maps.LatLng(37.786117, -122.440119), + new google.maps.LatLng(37.786564, -122.440209), + new google.maps.LatLng(37.786905, -122.44027), + new google.maps.LatLng(37.786956, -122.440279), + new google.maps.LatLng(37.800224, -122.43352), + new google.maps.LatLng(37.800155, -122.434101), + new google.maps.LatLng(37.80016, -122.43443), + new google.maps.LatLng(37.800378, -122.434527), + new google.maps.LatLng(37.800738, -122.434598), + new google.maps.LatLng(37.800938, -122.43465), + new google.maps.LatLng(37.801024, -122.434889), + new google.maps.LatLng(37.800955, -122.435392), + new google.maps.LatLng(37.800886, -122.435959), + new google.maps.LatLng(37.800811, -122.436275), + new google.maps.LatLng(37.800788, -122.436299), + new google.maps.LatLng(37.800719, -122.436302), + new google.maps.LatLng(37.800702, -122.436298), + new google.maps.LatLng(37.800661, -122.436273), + new google.maps.LatLng(37.800395, -122.436172), + new google.maps.LatLng(37.800228, -122.436116), + new google.maps.LatLng(37.800169, -122.43613), + new google.maps.LatLng(37.800066, -122.436167), + new google.maps.LatLng(37.784345, -122.422922), + new google.maps.LatLng(37.784389, -122.422926), + new google.maps.LatLng(37.784437, -122.422924), + new google.maps.LatLng(37.784746, -122.422818), + new google.maps.LatLng(37.785436, -122.422959), + new google.maps.LatLng(37.78612, -122.423112), + new google.maps.LatLng(37.786433, -122.423029), + new google.maps.LatLng(37.786631, -122.421213), + new google.maps.LatLng(37.78666, -122.421033), + new google.maps.LatLng(37.786801, -122.420141), + new google.maps.LatLng(37.786823, -122.420034), + new google.maps.LatLng(37.786831, -122.419916), + new google.maps.LatLng(37.787034, -122.418208), + new google.maps.LatLng(37.787056, -122.418034), + new google.maps.LatLng(37.787169, -122.417145), + new google.maps.LatLng(37.787217, -122.416715), + new google.maps.LatLng(37.786144, -122.416403), + new google.maps.LatLng(37.785292, -122.416257), + new google.maps.LatLng(37.780666, -122.390374), + new google.maps.LatLng(37.780501, -122.391281), + new google.maps.LatLng(37.780148, -122.392052), + new google.maps.LatLng(37.780173, -122.391148), + new google.maps.LatLng(37.780693, -122.390592), + new google.maps.LatLng(37.781261, -122.391142), + new google.maps.LatLng(37.781808, -122.39173), + new google.maps.LatLng(37.78234, -122.392341), + new google.maps.LatLng(37.782812, -122.393022), + new google.maps.LatLng(37.7833, -122.393672), + new google.maps.LatLng(37.783809, -122.394275), + new google.maps.LatLng(37.784246, -122.394979), + new google.maps.LatLng(37.784791, -122.395958), + new google.maps.LatLng(37.785675, -122.396746), + new google.maps.LatLng(37.786262, -122.39578), + new google.maps.LatLng(37.786776, -122.395093), + new google.maps.LatLng(37.787282, -122.394426), + new google.maps.LatLng(37.787783, -122.393767), + new google.maps.LatLng(37.788343, -122.393184), + new google.maps.LatLng(37.788895, -122.392506), + new google.maps.LatLng(37.789371, -122.391701), + new google.maps.LatLng(37.789722, -122.390952), + new google.maps.LatLng(37.790315, -122.390305), + new google.maps.LatLng(37.790738, -122.389616), + new google.maps.LatLng(37.779448, -122.438702), + new google.maps.LatLng(37.779023, -122.438585), + new google.maps.LatLng(37.778542, -122.438492), + new google.maps.LatLng(37.7781, -122.438411), + new google.maps.LatLng(37.777986, -122.438376), + new google.maps.LatLng(37.77768, -122.438313), + new google.maps.LatLng(37.777316, -122.438273), + new google.maps.LatLng(37.777135, -122.438254), + new google.maps.LatLng(37.776987, -122.438303), + new google.maps.LatLng(37.776946, -122.438404), + new google.maps.LatLng(37.776944, -122.438467), + new google.maps.LatLng(37.776892, -122.438459), + new google.maps.LatLng(37.776842, -122.438442), + new google.maps.LatLng(37.776822, -122.438391), + new google.maps.LatLng(37.776814, -122.438412), + new google.maps.LatLng(37.776787, -122.438628), + new google.maps.LatLng(37.776729, -122.43865), + new google.maps.LatLng(37.776759, -122.438677), + new google.maps.LatLng(37.776772, -122.438498), + new google.maps.LatLng(37.776787, -122.438389), + new google.maps.LatLng(37.776848, -122.438283), + new google.maps.LatLng(37.77687, -122.438239), + new google.maps.LatLng(37.777015, -122.438198), + new google.maps.LatLng(37.777333, -122.438256), + new google.maps.LatLng(37.777595, -122.438308), + new google.maps.LatLng(37.777797, -122.438344), + new google.maps.LatLng(37.77816, -122.438442), + new google.maps.LatLng(37.778414, -122.438508), + new google.maps.LatLng(37.778445, -122.438516), + new google.maps.LatLng(37.778503, -122.438529), + new google.maps.LatLng(37.778607, -122.438549), + new google.maps.LatLng(37.77867, -122.438644), + new google.maps.LatLng(37.778847, -122.438706), + new google.maps.LatLng(37.77924, -122.438744), + new google.maps.LatLng(37.779738, -122.438822), + new google.maps.LatLng(37.780201, -122.438882), + new google.maps.LatLng(37.7804, -122.438905), + new google.maps.LatLng(37.780501, -122.438921), + new google.maps.LatLng(37.780892, -122.438986), + new google.maps.LatLng(37.781446, -122.439087), + new google.maps.LatLng(37.781985, -122.439199), + new google.maps.LatLng(37.782239, -122.439249), + new google.maps.LatLng(37.782286, -122.439266), + new google.maps.LatLng(37.797847, -122.429388), + new google.maps.LatLng(37.797874, -122.42918), + new google.maps.LatLng(37.797885, -122.429069), + new google.maps.LatLng(37.797887, -122.42905), + new google.maps.LatLng(37.797933, -122.428954), + new google.maps.LatLng(37.798242, -122.42899), + new google.maps.LatLng(37.798617, -122.429075), + new google.maps.LatLng(37.798719, -122.429092), + new google.maps.LatLng(37.798944, -122.429145), + new google.maps.LatLng(37.79932, -122.429251), + new google.maps.LatLng(37.79959, -122.429309), + new google.maps.LatLng(37.799677, -122.429324), + new google.maps.LatLng(37.799966, -122.42936), + new google.maps.LatLng(37.800288, -122.42943), + new google.maps.LatLng(37.800443, -122.429461), + new google.maps.LatLng(37.800465, -122.429474), + new google.maps.LatLng(37.800644, -122.42954), + new google.maps.LatLng(37.800948, -122.42962), + new google.maps.LatLng(37.801242, -122.429685), + new google.maps.LatLng(37.801375, -122.429702), + new google.maps.LatLng(37.8014, -122.429703), + new google.maps.LatLng(37.801453, -122.429707), + new google.maps.LatLng(37.801473, -122.429709), + new google.maps.LatLng(37.801532, -122.429707), + new google.maps.LatLng(37.801852, -122.429729), + new google.maps.LatLng(37.802173, -122.429789), + new google.maps.LatLng(37.802459, -122.429847), + new google.maps.LatLng(37.802554, -122.429825), + new google.maps.LatLng(37.802647, -122.429549), + new google.maps.LatLng(37.802693, -122.429179), + new google.maps.LatLng(37.802729, -122.428751), + new google.maps.LatLng(37.766104, -122.409291), + new google.maps.LatLng(37.766103, -122.409268), + new google.maps.LatLng(37.766138, -122.409229), + new google.maps.LatLng(37.766183, -122.409231), + new google.maps.LatLng(37.766153, -122.409276), + new google.maps.LatLng(37.766005, -122.409365), + new google.maps.LatLng(37.765897, -122.40957), + new google.maps.LatLng(37.765767, -122.409739), + new google.maps.LatLng(37.765693, -122.410389), + new google.maps.LatLng(37.765615, -122.411201), + new google.maps.LatLng(37.765533, -122.412121), + new google.maps.LatLng(37.765467, -122.412939), + new google.maps.LatLng(37.765444, -122.414821), + new google.maps.LatLng(37.765444, -122.414964), + new google.maps.LatLng(37.765318, -122.415424), + new google.maps.LatLng(37.763961, -122.415296), + new google.maps.LatLng(37.763115, -122.415196), + new google.maps.LatLng(37.762967, -122.415183), + new google.maps.LatLng(37.762278, -122.415127), + new google.maps.LatLng(37.761675, -122.415055), + new google.maps.LatLng(37.760932, -122.414988), + new google.maps.LatLng(37.759337, -122.414862), + new google.maps.LatLng(37.773187, -122.421922), + new google.maps.LatLng(37.773043, -122.422118), + new google.maps.LatLng(37.773007, -122.422165), + new google.maps.LatLng(37.772979, -122.422219), + new google.maps.LatLng(37.772865, -122.422394), + new google.maps.LatLng(37.772779, -122.422503), + new google.maps.LatLng(37.772676, -122.422701), + new google.maps.LatLng(37.772606, -122.422806), + new google.maps.LatLng(37.772566, -122.42284), + new google.maps.LatLng(37.772508, -122.422852), + new google.maps.LatLng(37.772387, -122.423011), + new google.maps.LatLng(37.772099, -122.423328), + new google.maps.LatLng(37.771704, -122.423783), + new google.maps.LatLng(37.771481, -122.424081), + new google.maps.LatLng(37.7714, -122.424179), + new google.maps.LatLng(37.771352, -122.42422), + new google.maps.LatLng(37.771248, -122.424327), + new google.maps.LatLng(37.770904, -122.424781), + new google.maps.LatLng(37.77052, -122.425283), + new google.maps.LatLng(37.770337, -122.425553), + new google.maps.LatLng(37.770128, -122.425832), + new google.maps.LatLng(37.769756, -122.426331), + new google.maps.LatLng(37.7693, -122.426902), + new google.maps.LatLng(37.769132, -122.427065), + new google.maps.LatLng(37.769092, -122.427103), + new google.maps.LatLng(37.768979, -122.427172), + new google.maps.LatLng(37.768595, -122.427634), + new google.maps.LatLng(37.768372, -122.427913), + new google.maps.LatLng(37.768337, -122.427961), + new google.maps.LatLng(37.768244, -122.428138), + new google.maps.LatLng(37.767942, -122.428581), + new google.maps.LatLng(37.767482, -122.429094), + new google.maps.LatLng(37.767031, -122.429606), + new google.maps.LatLng(37.766732, -122.429986), + new google.maps.LatLng(37.76668, -122.430058), + new google.maps.LatLng(37.766633, -122.430109), + new google.maps.LatLng(37.76658, -122.430211), + new google.maps.LatLng(37.766367, -122.430594), + new google.maps.LatLng(37.76591, -122.431137), + new google.maps.LatLng(37.765353, -122.431806), + new google.maps.LatLng(37.764962, -122.432298), + new google.maps.LatLng(37.764868, -122.432486), + new google.maps.LatLng(37.764518, -122.432913), + new google.maps.LatLng(37.763435, -122.434173), + new google.maps.LatLng(37.762847, -122.434953), + new google.maps.LatLng(37.762291, -122.435935), + new google.maps.LatLng(37.762224, -122.436074), + new google.maps.LatLng(37.761957, -122.436892), + new google.maps.LatLng(37.761652, -122.438886), + new google.maps.LatLng(37.761284, -122.439955), + new google.maps.LatLng(37.76121, -122.440068), + new google.maps.LatLng(37.761064, -122.44072), + new google.maps.LatLng(37.76104, -122.441411), + new google.maps.LatLng(37.761048, -122.442324), + new google.maps.LatLng(37.760851, -122.443118), + new google.maps.LatLng(37.759977, -122.444591), + new google.maps.LatLng(37.759913, -122.444698), + new google.maps.LatLng(37.759623, -122.445065), + new google.maps.LatLng(37.758902, -122.445158), + new google.maps.LatLng(37.758428, -122.44457), + new google.maps.LatLng(37.757687, -122.44334), + new google.maps.LatLng(37.757583, -122.44324), + new google.maps.LatLng(37.757019, -122.442787), + new google.maps.LatLng(37.756603, -122.442322), + new google.maps.LatLng(37.75638, -122.441602), + new google.maps.LatLng(37.75579, -122.441382), + new google.maps.LatLng(37.754493, -122.442133), + new google.maps.LatLng(37.754361, -122.442206), + new google.maps.LatLng(37.753719, -122.44265), + new google.maps.LatLng(37.753096, -122.442915), + new google.maps.LatLng(37.751617, -122.443211), + new google.maps.LatLng(37.751496, -122.443246), + new google.maps.LatLng(37.750733, -122.443428), + new google.maps.LatLng(37.750126, -122.443536), + new google.maps.LatLng(37.750103, -122.443784), + new google.maps.LatLng(37.75039, -122.44401), + new google.maps.LatLng(37.750448, -122.444013), + new google.maps.LatLng(37.750536, -122.44404), + new google.maps.LatLng(37.750493, -122.444141), + new google.maps.LatLng(37.790859, -122.402808), + new google.maps.LatLng(37.790864, -122.402768), + new google.maps.LatLng(37.790995, -122.402539), + new google.maps.LatLng(37.791148, -122.402172), + new google.maps.LatLng(37.791385, -122.401312), + new google.maps.LatLng(37.791405, -122.400776), + new google.maps.LatLng(37.791288, -122.400528), + new google.maps.LatLng(37.791113, -122.400441), + new google.maps.LatLng(37.791027, -122.400395), + new google.maps.LatLng(37.791094, -122.400311), + new google.maps.LatLng(37.791211, -122.400183), + new google.maps.LatLng(37.79106, -122.399334), + new google.maps.LatLng(37.790538, -122.398718), + new google.maps.LatLng(37.790095, -122.398086), + new google.maps.LatLng(37.789644, -122.39736), + new google.maps.LatLng(37.789254, -122.396844), + new google.maps.LatLng(37.788855, -122.396397), + new google.maps.LatLng(37.788483, -122.395963), + new google.maps.LatLng(37.788015, -122.395365), + new google.maps.LatLng(37.787558, -122.394735), + new google.maps.LatLng(37.787472, -122.394323), + new google.maps.LatLng(37.78763, -122.394025), + new google.maps.LatLng(37.787767, -122.393987), + new google.maps.LatLng(37.787486, -122.394452), + new google.maps.LatLng(37.786977, -122.395043), + new google.maps.LatLng(37.786583, -122.395552), + new google.maps.LatLng(37.78654, -122.39561), + new google.maps.LatLng(37.786516, -122.395659), + new google.maps.LatLng(37.786378, -122.395707), + new google.maps.LatLng(37.786044, -122.395362), + new google.maps.LatLng(37.785598, -122.394715), + new google.maps.LatLng(37.785321, -122.394361), + new google.maps.LatLng(37.785207, -122.394236), + new google.maps.LatLng(37.785751, -122.394062), + new google.maps.LatLng(37.785996, -122.393881), + new google.maps.LatLng(37.786092, -122.39383), + new google.maps.LatLng(37.785998, -122.393899), + new google.maps.LatLng(37.785114, -122.394365), + new google.maps.LatLng(37.785022, -122.394441), + new google.maps.LatLng(37.784823, -122.394635), + new google.maps.LatLng(37.784719, -122.394629), + new google.maps.LatLng(37.785069, -122.394176), + new google.maps.LatLng(37.7855, -122.39365), + new google.maps.LatLng(37.78577, -122.393291), + new google.maps.LatLng(37.785839, -122.393159), + new google.maps.LatLng(37.782651, -122.400628), + new google.maps.LatLng(37.782616, -122.400599), + new google.maps.LatLng(37.782702, -122.40047), + new google.maps.LatLng(37.782915, -122.400192), + new google.maps.LatLng(37.783137, -122.399887), + new google.maps.LatLng(37.783414, -122.399519), + new google.maps.LatLng(37.783629, -122.399237), + new google.maps.LatLng(37.783688, -122.399157), + new google.maps.LatLng(37.783716, -122.399106), + new google.maps.LatLng(37.783798, -122.399072), + new google.maps.LatLng(37.783997, -122.399186), + new google.maps.LatLng(37.784271, -122.399538), + new google.maps.LatLng(37.784577, -122.399948), + new google.maps.LatLng(37.784828, -122.40026), + new google.maps.LatLng(37.784999, -122.400477), + new google.maps.LatLng(37.785113, -122.400651), + new google.maps.LatLng(37.785155, -122.400703), + new google.maps.LatLng(37.785192, -122.400749), + new google.maps.LatLng(37.785278, -122.400839), + new google.maps.LatLng(37.785387, -122.400857), + new google.maps.LatLng(37.785478, -122.40089), + new google.maps.LatLng(37.785526, -122.401022), + new google.maps.LatLng(37.785598, -122.401148), + new google.maps.LatLng(37.785631, -122.401202), + new google.maps.LatLng(37.78566, -122.401267), + new google.maps.LatLng(37.803986, -122.426035), + new google.maps.LatLng(37.804102, -122.425089), + new google.maps.LatLng(37.804211, -122.424156), + new google.maps.LatLng(37.803861, -122.423385), + new google.maps.LatLng(37.803151, -122.423214), + new google.maps.LatLng(37.802439, -122.423077), + new google.maps.LatLng(37.80174, -122.422905), + new google.maps.LatLng(37.801069, -122.422785), + new google.maps.LatLng(37.800345, -122.422649), + new google.maps.LatLng(37.799633, -122.422603), + new google.maps.LatLng(37.79975, -122.4217), + new google.maps.LatLng(37.799885, -122.420854), + new google.maps.LatLng(37.799209, -122.420607), + new google.maps.LatLng(37.795656, -122.400395), + new google.maps.LatLng(37.795203, -122.400304), + new google.maps.LatLng(37.778738, -122.415584), + new google.maps.LatLng(37.778812, -122.415189), + new google.maps.LatLng(37.778824, -122.415092), + new google.maps.LatLng(37.778833, -122.414932), + new google.maps.LatLng(37.778834, -122.414898), + new google.maps.LatLng(37.77874, -122.414757), + new google.maps.LatLng(37.778501, -122.414433), + new google.maps.LatLng(37.778182, -122.414026), + new google.maps.LatLng(37.777851, -122.413623), + new google.maps.LatLng(37.777486, -122.413166), + new google.maps.LatLng(37.777109, -122.412674), + new google.maps.LatLng(37.776743, -122.412186), + new google.maps.LatLng(37.77644, -122.4118), + new google.maps.LatLng(37.776295, -122.411614), + new google.maps.LatLng(37.776158, -122.41144), + new google.maps.LatLng(37.775806, -122.410997), + new google.maps.LatLng(37.775422, -122.410484), + new google.maps.LatLng(37.775126, -122.410087), + new google.maps.LatLng(37.775012, -122.409854), + new google.maps.LatLng(37.775164, -122.409573), + new google.maps.LatLng(37.775498, -122.40918), + new google.maps.LatLng(37.775868, -122.40873), + new google.maps.LatLng(37.776256, -122.40824), + new google.maps.LatLng(37.776519, -122.407928), + new google.maps.LatLng(37.776539, -122.407904), + new google.maps.LatLng(37.776595, -122.407854), + new google.maps.LatLng(37.776853, -122.407547), + new google.maps.LatLng(37.777234, -122.407087), + new google.maps.LatLng(37.777644, -122.406558), + new google.maps.LatLng(37.778066, -122.406017), + new google.maps.LatLng(37.778468, -122.405499), + new google.maps.LatLng(37.778866, -122.404995), + new google.maps.LatLng(37.779295, -122.404455), + new google.maps.LatLng(37.779695, -122.40395), + new google.maps.LatLng(37.779982, -122.403584), + new google.maps.LatLng(37.780295, -122.403223), + new google.maps.LatLng(37.780664, -122.402766), + new google.maps.LatLng(37.781043, -122.402288), + new google.maps.LatLng(37.781399, -122.401823), + new google.maps.LatLng(37.781727, -122.401407), + new google.maps.LatLng(37.781853, -122.401247), + new google.maps.LatLng(37.781894, -122.401195), + new google.maps.LatLng(37.782076, -122.400977), + new google.maps.LatLng(37.782338, -122.400603), + new google.maps.LatLng(37.782666, -122.400133), + new google.maps.LatLng(37.783048, -122.399634), + new google.maps.LatLng(37.78345, -122.399198), + new google.maps.LatLng(37.783791, -122.398998), + new google.maps.LatLng(37.784177, -122.398959), + new google.maps.LatLng(37.784388, -122.398971), + new google.maps.LatLng(37.784404, -122.399128), + new google.maps.LatLng(37.784586, -122.399524), + new google.maps.LatLng(37.784835, -122.399927), + new google.maps.LatLng(37.785116, -122.400307), + new google.maps.LatLng(37.785282, -122.400539), + new google.maps.LatLng(37.785346, -122.400692), + new google.maps.LatLng(37.765769, -122.407201), + new google.maps.LatLng(37.76579, -122.407414), + new google.maps.LatLng(37.765802, -122.407755), + new google.maps.LatLng(37.765791, -122.408219), + new google.maps.LatLng(37.765763, -122.408759), + new google.maps.LatLng(37.765726, -122.409348), + new google.maps.LatLng(37.765716, -122.409882), + new google.maps.LatLng(37.765708, -122.410202), + new google.maps.LatLng(37.765705, -122.410253), + new google.maps.LatLng(37.765707, -122.410369), + new google.maps.LatLng(37.765692, -122.41072), + new google.maps.LatLng(37.765699, -122.411215), + new google.maps.LatLng(37.765687, -122.411789), + new google.maps.LatLng(37.765666, -122.412373), + new google.maps.LatLng(37.765598, -122.412883), + new google.maps.LatLng(37.765543, -122.413039), + new google.maps.LatLng(37.765532, -122.413125), + new google.maps.LatLng(37.7655, -122.413553), + new google.maps.LatLng(37.765448, -122.414053), + new google.maps.LatLng(37.765388, -122.414645), + new google.maps.LatLng(37.765323, -122.41525), + new google.maps.LatLng(37.765303, -122.415847), + new google.maps.LatLng(37.765251, -122.416439), + new google.maps.LatLng(37.765204, -122.41702), + new google.maps.LatLng(37.765172, -122.417556), + new google.maps.LatLng(37.765164, -122.418075), + new google.maps.LatLng(37.765153, -122.418618), + new google.maps.LatLng(37.765136, -122.419112), + new google.maps.LatLng(37.765129, -122.419378), + new google.maps.LatLng(37.765119, -122.419481), + new google.maps.LatLng(37.7651, -122.419852), + new google.maps.LatLng(37.765083, -122.420349), + new google.maps.LatLng(37.765045, -122.42093), + new google.maps.LatLng(37.764992, -122.421481), + new google.maps.LatLng(37.76498, -122.421695), + new google.maps.LatLng(37.764993, -122.421843), + new google.maps.LatLng(37.764986, -122.422255), + new google.maps.LatLng(37.764975, -122.422823), + new google.maps.LatLng(37.764939, -122.423411), + new google.maps.LatLng(37.764902, -122.424014), + new google.maps.LatLng(37.764853, -122.424576), + new google.maps.LatLng(37.764826, -122.424922), + new google.maps.LatLng(37.764796, -122.425375), + new google.maps.LatLng(37.764782, -122.425869), + new google.maps.LatLng(37.764768, -122.426089), + new google.maps.LatLng(37.764766, -122.426117), + new google.maps.LatLng(37.764723, -122.426276), + new google.maps.LatLng(37.764681, -122.426649), + new google.maps.LatLng(37.782012, -122.4042), + new google.maps.LatLng(37.781574, -122.404911), + new google.maps.LatLng(37.781055, -122.405597), + new google.maps.LatLng(37.780479, -122.406341), + new google.maps.LatLng(37.779996, -122.406939), + new google.maps.LatLng(37.779459, -122.407613), + new google.maps.LatLng(37.778953, -122.408228), + new google.maps.LatLng(37.778409, -122.408839), + new google.maps.LatLng(37.777842, -122.409501), + new google.maps.LatLng(37.777334, -122.410181), + new google.maps.LatLng(37.776809, -122.410836), + new google.maps.LatLng(37.77624, -122.411514), + new google.maps.LatLng(37.775725, -122.412145), + new google.maps.LatLng(37.77519, -122.412805), + new google.maps.LatLng(37.774672, -122.413464), + new google.maps.LatLng(37.774084, -122.414186), + new google.maps.LatLng(37.773533, -122.413636), + new google.maps.LatLng(37.773021, -122.413009), + new google.maps.LatLng(37.772501, -122.412371), + new google.maps.LatLng(37.771964, -122.411681), + new google.maps.LatLng(37.771479, -122.411078), + new google.maps.LatLng(37.770992, -122.410477), + new google.maps.LatLng(37.770467, -122.409801), + new google.maps.LatLng(37.77009, -122.408904), + new google.maps.LatLng(37.769657, -122.408103), + new google.maps.LatLng(37.769132, -122.407276), + new google.maps.LatLng(37.768564, -122.406469), + new google.maps.LatLng(37.76798, -122.405745), + new google.maps.LatLng(37.76738, -122.405299), + new google.maps.LatLng(37.766604, -122.405297), + new google.maps.LatLng(37.765838, -122.4052), + new google.maps.LatLng(37.765139, -122.405139), + new google.maps.LatLng(37.764457, -122.405094), + new google.maps.LatLng(37.763716, -122.405142), + new google.maps.LatLng(37.762932, -122.405398), + new google.maps.LatLng(37.762126, -122.405813), + new google.maps.LatLng(37.761344, -122.406215), + new google.maps.LatLng(37.760556, -122.406495), + new google.maps.LatLng(37.759732, -122.406484), + new google.maps.LatLng(37.75891, -122.406228), + new google.maps.LatLng(37.758182, -122.405695), + new google.maps.LatLng(37.757676, -122.405118), + new google.maps.LatLng(37.757039, -122.404346), + new google.maps.LatLng(37.756335, -122.403719), + new google.maps.LatLng(37.755503, -122.403406), + new google.maps.LatLng(37.754665, -122.403242), + new google.maps.LatLng(37.753837, -122.403172), + new google.maps.LatLng(37.752986, -122.403112), + new google.maps.LatLng(37.751266, -122.403355), + ]; +} +//# sourceMappingURL=heatmap.js.map \ No newline at end of file diff --git a/Birdmap.API/ClientApp/src/components/heatmap/heatmap.js.map b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.js.map new file mode 100644 index 0000000..6a72953 --- /dev/null +++ b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"heatmap.js","sourceRoot":"","sources":["heatmap.ts"],"names":[],"mappings":"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CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE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,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC;QAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC;QAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC;QAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC;QAC9C,IAAI,MAA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"} \ No newline at end of file diff --git a/Birdmap.API/ClientApp/src/components/heatmap/heatmap.ts b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.ts new file mode 100644 index 0000000..183f6da --- /dev/null +++ b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.ts @@ -0,0 +1,561 @@ +import { Loader, LoaderOptions } from 'google-maps'; + +let map: google.maps.Map, heatmap: google.maps.visualization.HeatmapLayer; + +function initMap(): void { + const options: LoaderOptions = {/* todo */ }; + const loader = new Loader('AIzaSyCZ51VFfxqZ2GkCmVrcNZdUKsM0fuBQUCY', options); + + loader.load().then(function (google) { + map = new google.maps.Map(document.getElementById("map") as HTMLElement, { + zoom: 13, + center: { lat: 37.775, lng: -122.434 }, + mapTypeId: "satellite", + }); + + heatmap = new google.maps.visualization.HeatmapLayer({ + data: getPoints(), + map: map, + }); + }); +} + +function toggleHeatmap() { + heatmap.setMap(heatmap.getMap() ? null : map); +} + +function changeGradient() { + const gradient = [ + "rgba(0, 255, 255, 0)", + "rgba(0, 255, 255, 1)", + "rgba(0, 191, 255, 1)", + "rgba(0, 127, 255, 1)", + "rgba(0, 63, 255, 1)", + "rgba(0, 0, 255, 1)", + "rgba(0, 0, 223, 1)", + "rgba(0, 0, 191, 1)", + "rgba(0, 0, 159, 1)", + "rgba(0, 0, 127, 1)", + "rgba(63, 0, 91, 1)", + "rgba(127, 0, 63, 1)", + "rgba(191, 0, 31, 1)", + "rgba(255, 0, 0, 1)", + ]; + heatmap.set("gradient", heatmap.get("gradient") ? null : gradient); +} + +function changeRadius() { + heatmap.set("radius", heatmap.get("radius") ? null : 20); +} + +function changeOpacity() { + heatmap.set("opacity", heatmap.get("opacity") ? null : 0.2); +} + +// Heatmap data: 500 Points +function getPoints() { + return [ + new google.maps.LatLng(37.782551, -122.445368), + new google.maps.LatLng(37.782745, -122.444586), + new google.maps.LatLng(37.782842, -122.443688), + new google.maps.LatLng(37.782919, -122.442815), + new google.maps.LatLng(37.782992, -122.442112), + new google.maps.LatLng(37.7831, -122.441461), + new google.maps.LatLng(37.783206, -122.440829), + new google.maps.LatLng(37.783273, -122.440324), + new google.maps.LatLng(37.783316, -122.440023), + new google.maps.LatLng(37.783357, -122.439794), + new google.maps.LatLng(37.783371, -122.439687), + new google.maps.LatLng(37.783368, -122.439666), + new google.maps.LatLng(37.783383, -122.439594), + new google.maps.LatLng(37.783508, -122.439525), + new google.maps.LatLng(37.783842, -122.439591), + new google.maps.LatLng(37.784147, -122.439668), + new google.maps.LatLng(37.784206, -122.439686), + new google.maps.LatLng(37.784386, -122.43979), + new google.maps.LatLng(37.784701, -122.439902), + new google.maps.LatLng(37.784965, -122.439938), + new google.maps.LatLng(37.78501, -122.439947), + new google.maps.LatLng(37.78536, -122.439952), + new google.maps.LatLng(37.785715, -122.44003), + new google.maps.LatLng(37.786117, -122.440119), + new google.maps.LatLng(37.786564, -122.440209), + new google.maps.LatLng(37.786905, -122.44027), + new google.maps.LatLng(37.786956, -122.440279), + new google.maps.LatLng(37.800224, -122.43352), + new google.maps.LatLng(37.800155, -122.434101), + new google.maps.LatLng(37.80016, -122.43443), + new google.maps.LatLng(37.800378, -122.434527), + new google.maps.LatLng(37.800738, -122.434598), + new google.maps.LatLng(37.800938, -122.43465), + new google.maps.LatLng(37.801024, -122.434889), + new google.maps.LatLng(37.800955, -122.435392), + new google.maps.LatLng(37.800886, -122.435959), + new google.maps.LatLng(37.800811, -122.436275), + new google.maps.LatLng(37.800788, -122.436299), + new google.maps.LatLng(37.800719, -122.436302), + new google.maps.LatLng(37.800702, -122.436298), + new google.maps.LatLng(37.800661, -122.436273), + new google.maps.LatLng(37.800395, -122.436172), + new google.maps.LatLng(37.800228, -122.436116), + new google.maps.LatLng(37.800169, -122.43613), + new google.maps.LatLng(37.800066, -122.436167), + new google.maps.LatLng(37.784345, -122.422922), + new google.maps.LatLng(37.784389, -122.422926), + new google.maps.LatLng(37.784437, -122.422924), + new google.maps.LatLng(37.784746, -122.422818), + new google.maps.LatLng(37.785436, -122.422959), + new google.maps.LatLng(37.78612, -122.423112), + new google.maps.LatLng(37.786433, -122.423029), + new google.maps.LatLng(37.786631, -122.421213), + new google.maps.LatLng(37.78666, -122.421033), + new google.maps.LatLng(37.786801, -122.420141), + new google.maps.LatLng(37.786823, -122.420034), + new google.maps.LatLng(37.786831, -122.419916), + new google.maps.LatLng(37.787034, -122.418208), + new google.maps.LatLng(37.787056, -122.418034), + new google.maps.LatLng(37.787169, -122.417145), + new google.maps.LatLng(37.787217, -122.416715), + new google.maps.LatLng(37.786144, -122.416403), + new google.maps.LatLng(37.785292, -122.416257), + new google.maps.LatLng(37.780666, -122.390374), + new google.maps.LatLng(37.780501, -122.391281), + new google.maps.LatLng(37.780148, -122.392052), + new google.maps.LatLng(37.780173, -122.391148), + new google.maps.LatLng(37.780693, -122.390592), + new google.maps.LatLng(37.781261, -122.391142), + new google.maps.LatLng(37.781808, -122.39173), + new google.maps.LatLng(37.78234, -122.392341), + new google.maps.LatLng(37.782812, -122.393022), + new google.maps.LatLng(37.7833, -122.393672), + new google.maps.LatLng(37.783809, -122.394275), + new google.maps.LatLng(37.784246, -122.394979), + new google.maps.LatLng(37.784791, -122.395958), + new google.maps.LatLng(37.785675, -122.396746), + new google.maps.LatLng(37.786262, -122.39578), + new google.maps.LatLng(37.786776, -122.395093), + new google.maps.LatLng(37.787282, -122.394426), + new google.maps.LatLng(37.787783, -122.393767), + new google.maps.LatLng(37.788343, -122.393184), + new google.maps.LatLng(37.788895, -122.392506), + new google.maps.LatLng(37.789371, -122.391701), + new google.maps.LatLng(37.789722, -122.390952), + new google.maps.LatLng(37.790315, -122.390305), + new google.maps.LatLng(37.790738, -122.389616), + new google.maps.LatLng(37.779448, -122.438702), + new google.maps.LatLng(37.779023, -122.438585), + new google.maps.LatLng(37.778542, -122.438492), + new google.maps.LatLng(37.7781, -122.438411), + new google.maps.LatLng(37.777986, -122.438376), + new google.maps.LatLng(37.77768, -122.438313), + new google.maps.LatLng(37.777316, -122.438273), + new google.maps.LatLng(37.777135, -122.438254), + new google.maps.LatLng(37.776987, -122.438303), + new google.maps.LatLng(37.776946, -122.438404), + new google.maps.LatLng(37.776944, -122.438467), + new google.maps.LatLng(37.776892, -122.438459), + new google.maps.LatLng(37.776842, -122.438442), + new google.maps.LatLng(37.776822, -122.438391), + new google.maps.LatLng(37.776814, -122.438412), + new google.maps.LatLng(37.776787, -122.438628), + new google.maps.LatLng(37.776729, -122.43865), + new google.maps.LatLng(37.776759, -122.438677), + new google.maps.LatLng(37.776772, -122.438498), + new google.maps.LatLng(37.776787, -122.438389), + new google.maps.LatLng(37.776848, -122.438283), + new google.maps.LatLng(37.77687, -122.438239), + new google.maps.LatLng(37.777015, -122.438198), + new google.maps.LatLng(37.777333, -122.438256), + new google.maps.LatLng(37.777595, -122.438308), + new google.maps.LatLng(37.777797, -122.438344), + new google.maps.LatLng(37.77816, -122.438442), + new google.maps.LatLng(37.778414, -122.438508), + new google.maps.LatLng(37.778445, -122.438516), + new google.maps.LatLng(37.778503, -122.438529), + new google.maps.LatLng(37.778607, -122.438549), + new google.maps.LatLng(37.77867, -122.438644), + new google.maps.LatLng(37.778847, -122.438706), + new google.maps.LatLng(37.77924, -122.438744), + new google.maps.LatLng(37.779738, -122.438822), + new google.maps.LatLng(37.780201, -122.438882), + new google.maps.LatLng(37.7804, -122.438905), + new google.maps.LatLng(37.780501, -122.438921), + new google.maps.LatLng(37.780892, -122.438986), + new google.maps.LatLng(37.781446, -122.439087), + new google.maps.LatLng(37.781985, -122.439199), + new google.maps.LatLng(37.782239, -122.439249), + new google.maps.LatLng(37.782286, -122.439266), + new google.maps.LatLng(37.797847, -122.429388), + new google.maps.LatLng(37.797874, -122.42918), + new google.maps.LatLng(37.797885, -122.429069), + new google.maps.LatLng(37.797887, -122.42905), + new google.maps.LatLng(37.797933, -122.428954), + new google.maps.LatLng(37.798242, -122.42899), + new google.maps.LatLng(37.798617, -122.429075), + new google.maps.LatLng(37.798719, -122.429092), + new google.maps.LatLng(37.798944, -122.429145), + new google.maps.LatLng(37.79932, -122.429251), + new google.maps.LatLng(37.79959, -122.429309), + new google.maps.LatLng(37.799677, -122.429324), + new google.maps.LatLng(37.799966, -122.42936), + new google.maps.LatLng(37.800288, -122.42943), + new google.maps.LatLng(37.800443, -122.429461), + new google.maps.LatLng(37.800465, -122.429474), + new google.maps.LatLng(37.800644, -122.42954), + new google.maps.LatLng(37.800948, -122.42962), + new google.maps.LatLng(37.801242, -122.429685), + new google.maps.LatLng(37.801375, -122.429702), + new google.maps.LatLng(37.8014, -122.429703), + new google.maps.LatLng(37.801453, -122.429707), + new google.maps.LatLng(37.801473, -122.429709), + new google.maps.LatLng(37.801532, -122.429707), + new google.maps.LatLng(37.801852, -122.429729), + new google.maps.LatLng(37.802173, -122.429789), + new google.maps.LatLng(37.802459, -122.429847), + new google.maps.LatLng(37.802554, -122.429825), + new google.maps.LatLng(37.802647, -122.429549), + new google.maps.LatLng(37.802693, -122.429179), + new google.maps.LatLng(37.802729, -122.428751), + new google.maps.LatLng(37.766104, -122.409291), + new google.maps.LatLng(37.766103, -122.409268), + new google.maps.LatLng(37.766138, -122.409229), + new google.maps.LatLng(37.766183, -122.409231), + new google.maps.LatLng(37.766153, -122.409276), + new google.maps.LatLng(37.766005, -122.409365), + new google.maps.LatLng(37.765897, -122.40957), + new google.maps.LatLng(37.765767, -122.409739), + new google.maps.LatLng(37.765693, -122.410389), + new google.maps.LatLng(37.765615, -122.411201), + new google.maps.LatLng(37.765533, -122.412121), + new google.maps.LatLng(37.765467, -122.412939), + new google.maps.LatLng(37.765444, -122.414821), + new google.maps.LatLng(37.765444, -122.414964), + new google.maps.LatLng(37.765318, -122.415424), + new google.maps.LatLng(37.763961, -122.415296), + new google.maps.LatLng(37.763115, -122.415196), + new google.maps.LatLng(37.762967, -122.415183), + new google.maps.LatLng(37.762278, -122.415127), + new google.maps.LatLng(37.761675, -122.415055), + new google.maps.LatLng(37.760932, -122.414988), + new google.maps.LatLng(37.759337, -122.414862), + new google.maps.LatLng(37.773187, -122.421922), + new google.maps.LatLng(37.773043, -122.422118), + new google.maps.LatLng(37.773007, -122.422165), + new google.maps.LatLng(37.772979, -122.422219), + new google.maps.LatLng(37.772865, -122.422394), + new google.maps.LatLng(37.772779, -122.422503), + new google.maps.LatLng(37.772676, -122.422701), + new google.maps.LatLng(37.772606, -122.422806), + new google.maps.LatLng(37.772566, -122.42284), + new google.maps.LatLng(37.772508, -122.422852), + new google.maps.LatLng(37.772387, -122.423011), + new google.maps.LatLng(37.772099, -122.423328), + new google.maps.LatLng(37.771704, -122.423783), + new google.maps.LatLng(37.771481, -122.424081), + new google.maps.LatLng(37.7714, -122.424179), + new google.maps.LatLng(37.771352, -122.42422), + new google.maps.LatLng(37.771248, -122.424327), + new google.maps.LatLng(37.770904, -122.424781), + new google.maps.LatLng(37.77052, -122.425283), + new google.maps.LatLng(37.770337, -122.425553), + new google.maps.LatLng(37.770128, -122.425832), + new google.maps.LatLng(37.769756, -122.426331), + new google.maps.LatLng(37.7693, -122.426902), + new google.maps.LatLng(37.769132, -122.427065), + new google.maps.LatLng(37.769092, -122.427103), + new google.maps.LatLng(37.768979, -122.427172), + new google.maps.LatLng(37.768595, -122.427634), + new google.maps.LatLng(37.768372, -122.427913), + new google.maps.LatLng(37.768337, -122.427961), + new google.maps.LatLng(37.768244, -122.428138), + new google.maps.LatLng(37.767942, -122.428581), + new google.maps.LatLng(37.767482, -122.429094), + new google.maps.LatLng(37.767031, -122.429606), + new google.maps.LatLng(37.766732, -122.429986), + new google.maps.LatLng(37.76668, -122.430058), + new google.maps.LatLng(37.766633, -122.430109), + new google.maps.LatLng(37.76658, -122.430211), + new google.maps.LatLng(37.766367, -122.430594), + new google.maps.LatLng(37.76591, -122.431137), + new google.maps.LatLng(37.765353, -122.431806), + new google.maps.LatLng(37.764962, -122.432298), + new google.maps.LatLng(37.764868, -122.432486), + new google.maps.LatLng(37.764518, -122.432913), + new google.maps.LatLng(37.763435, -122.434173), + new google.maps.LatLng(37.762847, -122.434953), + new google.maps.LatLng(37.762291, -122.435935), + new google.maps.LatLng(37.762224, -122.436074), + new google.maps.LatLng(37.761957, -122.436892), + new google.maps.LatLng(37.761652, -122.438886), + new google.maps.LatLng(37.761284, -122.439955), + new google.maps.LatLng(37.76121, -122.440068), + new google.maps.LatLng(37.761064, -122.44072), + new google.maps.LatLng(37.76104, -122.441411), + new google.maps.LatLng(37.761048, -122.442324), + new google.maps.LatLng(37.760851, -122.443118), + new google.maps.LatLng(37.759977, -122.444591), + new google.maps.LatLng(37.759913, -122.444698), + new google.maps.LatLng(37.759623, -122.445065), + new google.maps.LatLng(37.758902, -122.445158), + new google.maps.LatLng(37.758428, -122.44457), + new google.maps.LatLng(37.757687, -122.44334), + new google.maps.LatLng(37.757583, -122.44324), + new google.maps.LatLng(37.757019, -122.442787), + new google.maps.LatLng(37.756603, -122.442322), + new google.maps.LatLng(37.75638, -122.441602), + new google.maps.LatLng(37.75579, -122.441382), + new google.maps.LatLng(37.754493, -122.442133), + new google.maps.LatLng(37.754361, -122.442206), + new google.maps.LatLng(37.753719, -122.44265), + new google.maps.LatLng(37.753096, -122.442915), + new google.maps.LatLng(37.751617, -122.443211), + new google.maps.LatLng(37.751496, -122.443246), + new google.maps.LatLng(37.750733, -122.443428), + new google.maps.LatLng(37.750126, -122.443536), + new google.maps.LatLng(37.750103, -122.443784), + new google.maps.LatLng(37.75039, -122.44401), + new google.maps.LatLng(37.750448, -122.444013), + new google.maps.LatLng(37.750536, -122.44404), + new google.maps.LatLng(37.750493, -122.444141), + new google.maps.LatLng(37.790859, -122.402808), + new google.maps.LatLng(37.790864, -122.402768), + new google.maps.LatLng(37.790995, -122.402539), + new google.maps.LatLng(37.791148, -122.402172), + new google.maps.LatLng(37.791385, -122.401312), + new google.maps.LatLng(37.791405, -122.400776), + new google.maps.LatLng(37.791288, -122.400528), + new google.maps.LatLng(37.791113, -122.400441), + new google.maps.LatLng(37.791027, -122.400395), + new google.maps.LatLng(37.791094, -122.400311), + new google.maps.LatLng(37.791211, -122.400183), + new google.maps.LatLng(37.79106, -122.399334), + new google.maps.LatLng(37.790538, -122.398718), + new google.maps.LatLng(37.790095, -122.398086), + new google.maps.LatLng(37.789644, -122.39736), + new google.maps.LatLng(37.789254, -122.396844), + new google.maps.LatLng(37.788855, -122.396397), + new google.maps.LatLng(37.788483, -122.395963), + new google.maps.LatLng(37.788015, -122.395365), + new google.maps.LatLng(37.787558, -122.394735), + new google.maps.LatLng(37.787472, -122.394323), + new google.maps.LatLng(37.78763, -122.394025), + new google.maps.LatLng(37.787767, -122.393987), + new google.maps.LatLng(37.787486, -122.394452), + new google.maps.LatLng(37.786977, -122.395043), + new google.maps.LatLng(37.786583, -122.395552), + new google.maps.LatLng(37.78654, -122.39561), + new google.maps.LatLng(37.786516, -122.395659), + new google.maps.LatLng(37.786378, -122.395707), + new google.maps.LatLng(37.786044, -122.395362), + new google.maps.LatLng(37.785598, -122.394715), + new google.maps.LatLng(37.785321, -122.394361), + new google.maps.LatLng(37.785207, -122.394236), + new google.maps.LatLng(37.785751, -122.394062), + new google.maps.LatLng(37.785996, -122.393881), + new google.maps.LatLng(37.786092, -122.39383), + new google.maps.LatLng(37.785998, -122.393899), + new google.maps.LatLng(37.785114, -122.394365), + new google.maps.LatLng(37.785022, -122.394441), + new google.maps.LatLng(37.784823, -122.394635), + new google.maps.LatLng(37.784719, -122.394629), + new google.maps.LatLng(37.785069, -122.394176), + new google.maps.LatLng(37.7855, -122.39365), + new google.maps.LatLng(37.78577, -122.393291), + new google.maps.LatLng(37.785839, -122.393159), + new google.maps.LatLng(37.782651, -122.400628), + new google.maps.LatLng(37.782616, -122.400599), + new google.maps.LatLng(37.782702, -122.40047), + new google.maps.LatLng(37.782915, -122.400192), + new google.maps.LatLng(37.783137, -122.399887), + new google.maps.LatLng(37.783414, -122.399519), + new google.maps.LatLng(37.783629, -122.399237), + new google.maps.LatLng(37.783688, -122.399157), + new google.maps.LatLng(37.783716, -122.399106), + new google.maps.LatLng(37.783798, -122.399072), + new google.maps.LatLng(37.783997, -122.399186), + new google.maps.LatLng(37.784271, -122.399538), + new google.maps.LatLng(37.784577, -122.399948), + new google.maps.LatLng(37.784828, -122.40026), + new google.maps.LatLng(37.784999, -122.400477), + new google.maps.LatLng(37.785113, -122.400651), + new google.maps.LatLng(37.785155, -122.400703), + new google.maps.LatLng(37.785192, -122.400749), + new google.maps.LatLng(37.785278, -122.400839), + new google.maps.LatLng(37.785387, -122.400857), + new google.maps.LatLng(37.785478, -122.40089), + new google.maps.LatLng(37.785526, -122.401022), + new google.maps.LatLng(37.785598, -122.401148), + new google.maps.LatLng(37.785631, -122.401202), + new google.maps.LatLng(37.78566, -122.401267), + new google.maps.LatLng(37.803986, -122.426035), + new google.maps.LatLng(37.804102, -122.425089), + new google.maps.LatLng(37.804211, -122.424156), + new google.maps.LatLng(37.803861, -122.423385), + new google.maps.LatLng(37.803151, -122.423214), + new google.maps.LatLng(37.802439, -122.423077), + new google.maps.LatLng(37.80174, -122.422905), + new google.maps.LatLng(37.801069, -122.422785), + new google.maps.LatLng(37.800345, -122.422649), + new google.maps.LatLng(37.799633, -122.422603), + new google.maps.LatLng(37.79975, -122.4217), + new google.maps.LatLng(37.799885, -122.420854), + new google.maps.LatLng(37.799209, -122.420607), + new google.maps.LatLng(37.795656, -122.400395), + new google.maps.LatLng(37.795203, -122.400304), + new google.maps.LatLng(37.778738, -122.415584), + new google.maps.LatLng(37.778812, -122.415189), + new google.maps.LatLng(37.778824, -122.415092), + new google.maps.LatLng(37.778833, -122.414932), + new google.maps.LatLng(37.778834, -122.414898), + new google.maps.LatLng(37.77874, -122.414757), + new google.maps.LatLng(37.778501, -122.414433), + new google.maps.LatLng(37.778182, -122.414026), + new google.maps.LatLng(37.777851, -122.413623), + new google.maps.LatLng(37.777486, -122.413166), + new google.maps.LatLng(37.777109, -122.412674), + new google.maps.LatLng(37.776743, -122.412186), + new google.maps.LatLng(37.77644, -122.4118), + new google.maps.LatLng(37.776295, -122.411614), + new google.maps.LatLng(37.776158, -122.41144), + new google.maps.LatLng(37.775806, -122.410997), + new google.maps.LatLng(37.775422, -122.410484), + new google.maps.LatLng(37.775126, -122.410087), + new google.maps.LatLng(37.775012, -122.409854), + new google.maps.LatLng(37.775164, -122.409573), + new google.maps.LatLng(37.775498, -122.40918), + new google.maps.LatLng(37.775868, -122.40873), + new google.maps.LatLng(37.776256, -122.40824), + new google.maps.LatLng(37.776519, -122.407928), + new google.maps.LatLng(37.776539, -122.407904), + new google.maps.LatLng(37.776595, -122.407854), + new google.maps.LatLng(37.776853, -122.407547), + new google.maps.LatLng(37.777234, -122.407087), + new google.maps.LatLng(37.777644, -122.406558), + new google.maps.LatLng(37.778066, -122.406017), + new google.maps.LatLng(37.778468, -122.405499), + new google.maps.LatLng(37.778866, -122.404995), + new google.maps.LatLng(37.779295, -122.404455), + new google.maps.LatLng(37.779695, -122.40395), + new google.maps.LatLng(37.779982, -122.403584), + new google.maps.LatLng(37.780295, -122.403223), + new google.maps.LatLng(37.780664, -122.402766), + new google.maps.LatLng(37.781043, -122.402288), + new google.maps.LatLng(37.781399, -122.401823), + new google.maps.LatLng(37.781727, -122.401407), + new google.maps.LatLng(37.781853, -122.401247), + new google.maps.LatLng(37.781894, -122.401195), + new google.maps.LatLng(37.782076, -122.400977), + new google.maps.LatLng(37.782338, -122.400603), + new google.maps.LatLng(37.782666, -122.400133), + new google.maps.LatLng(37.783048, -122.399634), + new google.maps.LatLng(37.78345, -122.399198), + new google.maps.LatLng(37.783791, -122.398998), + new google.maps.LatLng(37.784177, -122.398959), + new google.maps.LatLng(37.784388, -122.398971), + new google.maps.LatLng(37.784404, -122.399128), + new google.maps.LatLng(37.784586, -122.399524), + new google.maps.LatLng(37.784835, -122.399927), + new google.maps.LatLng(37.785116, -122.400307), + new google.maps.LatLng(37.785282, -122.400539), + new google.maps.LatLng(37.785346, -122.400692), + new google.maps.LatLng(37.765769, -122.407201), + new google.maps.LatLng(37.76579, -122.407414), + new google.maps.LatLng(37.765802, -122.407755), + new google.maps.LatLng(37.765791, -122.408219), + new google.maps.LatLng(37.765763, -122.408759), + new google.maps.LatLng(37.765726, -122.409348), + new google.maps.LatLng(37.765716, -122.409882), + new google.maps.LatLng(37.765708, -122.410202), + new google.maps.LatLng(37.765705, -122.410253), + new google.maps.LatLng(37.765707, -122.410369), + new google.maps.LatLng(37.765692, -122.41072), + new google.maps.LatLng(37.765699, -122.411215), + new google.maps.LatLng(37.765687, -122.411789), + new google.maps.LatLng(37.765666, -122.412373), + new google.maps.LatLng(37.765598, -122.412883), + new google.maps.LatLng(37.765543, -122.413039), + new google.maps.LatLng(37.765532, -122.413125), + new google.maps.LatLng(37.7655, -122.413553), + new google.maps.LatLng(37.765448, -122.414053), + new google.maps.LatLng(37.765388, -122.414645), + new google.maps.LatLng(37.765323, -122.41525), + new google.maps.LatLng(37.765303, -122.415847), + new google.maps.LatLng(37.765251, -122.416439), + new google.maps.LatLng(37.765204, -122.41702), + new google.maps.LatLng(37.765172, -122.417556), + new google.maps.LatLng(37.765164, -122.418075), + new google.maps.LatLng(37.765153, -122.418618), + new google.maps.LatLng(37.765136, -122.419112), + new google.maps.LatLng(37.765129, -122.419378), + new google.maps.LatLng(37.765119, -122.419481), + new google.maps.LatLng(37.7651, -122.419852), + new google.maps.LatLng(37.765083, -122.420349), + new google.maps.LatLng(37.765045, -122.42093), + new google.maps.LatLng(37.764992, -122.421481), + new google.maps.LatLng(37.76498, -122.421695), + new google.maps.LatLng(37.764993, -122.421843), + new google.maps.LatLng(37.764986, -122.422255), + new google.maps.LatLng(37.764975, -122.422823), + new google.maps.LatLng(37.764939, -122.423411), + new google.maps.LatLng(37.764902, -122.424014), + new google.maps.LatLng(37.764853, -122.424576), + new google.maps.LatLng(37.764826, -122.424922), + new google.maps.LatLng(37.764796, -122.425375), + new google.maps.LatLng(37.764782, -122.425869), + new google.maps.LatLng(37.764768, -122.426089), + new google.maps.LatLng(37.764766, -122.426117), + new google.maps.LatLng(37.764723, -122.426276), + new google.maps.LatLng(37.764681, -122.426649), + new google.maps.LatLng(37.782012, -122.4042), + new google.maps.LatLng(37.781574, -122.404911), + new google.maps.LatLng(37.781055, -122.405597), + new google.maps.LatLng(37.780479, -122.406341), + new google.maps.LatLng(37.779996, -122.406939), + new google.maps.LatLng(37.779459, -122.407613), + new google.maps.LatLng(37.778953, -122.408228), + new google.maps.LatLng(37.778409, -122.408839), + new google.maps.LatLng(37.777842, -122.409501), + new google.maps.LatLng(37.777334, -122.410181), + new google.maps.LatLng(37.776809, -122.410836), + new google.maps.LatLng(37.77624, -122.411514), + new google.maps.LatLng(37.775725, -122.412145), + new google.maps.LatLng(37.77519, -122.412805), + new google.maps.LatLng(37.774672, -122.413464), + new google.maps.LatLng(37.774084, -122.414186), + new google.maps.LatLng(37.773533, -122.413636), + new google.maps.LatLng(37.773021, -122.413009), + new google.maps.LatLng(37.772501, -122.412371), + new google.maps.LatLng(37.771964, -122.411681), + new google.maps.LatLng(37.771479, -122.411078), + new google.maps.LatLng(37.770992, -122.410477), + new google.maps.LatLng(37.770467, -122.409801), + new google.maps.LatLng(37.77009, -122.408904), + new google.maps.LatLng(37.769657, -122.408103), + new google.maps.LatLng(37.769132, -122.407276), + new google.maps.LatLng(37.768564, -122.406469), + new google.maps.LatLng(37.76798, -122.405745), + new google.maps.LatLng(37.76738, -122.405299), + new google.maps.LatLng(37.766604, -122.405297), + new google.maps.LatLng(37.765838, -122.4052), + new google.maps.LatLng(37.765139, -122.405139), + new google.maps.LatLng(37.764457, -122.405094), + new google.maps.LatLng(37.763716, -122.405142), + new google.maps.LatLng(37.762932, -122.405398), + new google.maps.LatLng(37.762126, -122.405813), + new google.maps.LatLng(37.761344, -122.406215), + new google.maps.LatLng(37.760556, -122.406495), + new google.maps.LatLng(37.759732, -122.406484), + new google.maps.LatLng(37.75891, -122.406228), + new google.maps.LatLng(37.758182, -122.405695), + new google.maps.LatLng(37.757676, -122.405118), + new google.maps.LatLng(37.757039, -122.404346), + new google.maps.LatLng(37.756335, -122.403719), + new google.maps.LatLng(37.755503, -122.403406), + new google.maps.LatLng(37.754665, -122.403242), + new google.maps.LatLng(37.753837, -122.403172), + new google.maps.LatLng(37.752986, -122.403112), + new google.maps.LatLng(37.751266, -122.403355), + ]; +} +// [END maps_layer_heatmap] +export { initMap }; diff --git a/Birdmap.API/ClientApp/src/components/heatmap/heatmap.tsx b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.tsx new file mode 100644 index 0000000..5d7a8b8 --- /dev/null +++ b/Birdmap.API/ClientApp/src/components/heatmap/heatmap.tsx @@ -0,0 +1,21 @@ +import { Map, GoogleApiWrapper } from 'google-maps-react'; + +export function Heatmap() { + const mapStyles = { + width: '100%', + height: '100%', + }; + + return ( + + ); +} + +export default GoogleApiWrapper({ + apiKey: 'AIzaSyCZ51VFfxqZ2GkCmVrcNZdUKsM0fuBQUCY' +}); \ No newline at end of file diff --git a/Birdmap.API/Controllers/AuthController.cs b/Birdmap.API/Controllers/AuthController.cs index 76d6872..4105a9e 100644 --- a/Birdmap.API/Controllers/AuthController.cs +++ b/Birdmap.API/Controllers/AuthController.cs @@ -35,8 +35,7 @@ namespace Birdmap.Controllers } [AllowAnonymous] - [HttpPost("authenticate")] - [ProducesResponseType(typeof(object), StatusCodes.Status200OK)] + [HttpPost("authenticate"), ProducesResponseType(typeof(object), StatusCodes.Status200OK)] public async Task AuthenticateAsync([FromBody] AuthenticateRequest model) { _logger.LogInformation($"Authenticating user [{model.Username}] with password [*******]..."); @@ -70,8 +69,7 @@ namespace Birdmap.Controllers } [AllowAnonymous] - [HttpPost("register")] - [ProducesResponseType(StatusCodes.Status204NoContent)] + [HttpPost("register"), ProducesResponseType(StatusCodes.Status204NoContent)] public async Task RegisterAsync([FromBody] RegisterRequest model) { _logger.LogInformation($"Registering user [{model.Username}]..."); diff --git a/Birdmap.API/Controllers/DevicesController.cs b/Birdmap.API/Controllers/DevicesController.cs new file mode 100644 index 0000000..2791598 --- /dev/null +++ b/Birdmap.API/Controllers/DevicesController.cs @@ -0,0 +1,144 @@ +using Birdmap.BLL.Interfaces; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using System.Linq; +using Microsoft.AspNetCore.Authorization; + +namespace Birdmap.API.Controllers +{ + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class DevicesController : ControllerBase + { + private readonly IDeviceService _service; + private readonly ILogger _logger; + + public DevicesController(IDeviceService service, ILogger logger) + { + _service = service; + _logger = logger; + } + + /// Get all device info + /// Array of devices + [HttpGet] + public async Task>> Getall() + { + _logger.LogInformation("Getting all devices..."); + + return (await _service.GetallAsync()).ToList(); + } + + /// Shut down all devices + /// Message sent + [HttpPost, Route("offline")] + public async Task Offlineall() + { + _logger.LogInformation("Turning off all devices and sensors..."); + + await _service.OfflineallAsync(); + + return Ok(); + } + + /// Bring all devices online + /// Message sent + [HttpPost, Route("online")] + public async Task Onlineall() + { + _logger.LogInformation("Turning on all devices and sensors..."); + + await _service.OnlineallAsync(); + + return Ok(); + } + + /// Get all device info + /// ID of device to query + /// Information about a particular device + [HttpGet, Route("{deviceID}")] + public async Task> Getdevice([BindRequired] Guid deviceID) + { + _logger.LogInformation($"Getting device [{deviceID}]..."); + + return await _service.GetdeviceAsync(deviceID); + } + + /// Shut down device + /// ID of device to shut down + /// Message sent + [HttpPost, Route("{deviceID}/offline")] + public async Task Offlinedevice([BindRequired] Guid deviceID) + { + _logger.LogInformation($"Turning off device [{deviceID}]..."); + + await _service.OfflinedeviceAsync(deviceID); + + return Ok(); + } + + /// Bring device online + /// ID of device to bring online + /// Message sent + [HttpPost, Route("{deviceID}/online")] + public async Task Onlinedevice([BindRequired] Guid deviceID) + { + _logger.LogInformation($"Turning on device [{deviceID}]..."); + + await _service.OnlinedeviceAsync(deviceID); + + return Ok(); + } + + /// Get info about a particular device's sensor + /// ID of device to query + /// ID of sensor to query + /// Information about a sensor + [HttpGet, Route("{deviceID}/{sensorID}")] + public async Task> Getsensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID) + { + _logger.LogInformation($"Getting sensor [{sensorID}] of device [{deviceID}]..."); + + return await _service.GetsensorAsync(deviceID, sensorID); + } + + /// Shut down sensor + /// ID of device to query + /// ID of sensor to query + /// Message sent + [HttpPost, Route("{deviceID}/{sensorID}/offline")] + public async Task Offlinesensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID) + { + _logger.LogInformation($"Turning off sensor [{sensorID}] of device [{deviceID}]..."); + + await _service.OfflinesensorAsync(deviceID, sensorID); + + return Ok(); + } + + /// Bring sensor online + /// ID of device to query + /// ID of sensor to query + /// Message sent + [HttpPost, Route("{deviceID}/{sensorID}/online")] + public async Task Onlinesensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID) + { + _logger.LogInformation($"Turning on sensor [{sensorID}] of device [{deviceID}]..."); + + await _service.OnlinesensorAsync(deviceID, sensorID); + + return Ok(); + } + } +} + +#pragma warning restore 1591 +#pragma warning restore 1573 +#pragma warning restore 472 +#pragma warning restore 114 +#pragma warning restore 108 \ No newline at end of file diff --git a/Birdmap.API/Controllers/ServicesController.cs b/Birdmap.API/Controllers/ServicesController.cs index d60e28c..6da1729 100644 --- a/Birdmap.API/Controllers/ServicesController.cs +++ b/Birdmap.API/Controllers/ServicesController.cs @@ -30,8 +30,7 @@ namespace Birdmap.API.Controllers _logger = logger; } - [HttpGet] - [ProducesResponseType(StatusCodes.Status200OK)] + [HttpGet, ProducesResponseType(StatusCodes.Status200OK)] public async Task>> GetAsync() { _logger.LogInformation($"Getting all services from db..."); @@ -59,8 +58,7 @@ namespace Birdmap.API.Controllers return serviceInfos.ToList(); } - [HttpPost] - [ProducesResponseType(StatusCodes.Status201Created)] + [HttpPost, ProducesResponseType(StatusCodes.Status201Created)] public async Task> PostAsync(ServiceRequest request) { _logger.LogInformation($"Creating service [{request.Name}]..."); @@ -74,8 +72,7 @@ namespace Birdmap.API.Controllers _mapper.Map(created)); } - [HttpPut] - [ProducesResponseType(StatusCodes.Status204NoContent)] + [HttpPut, ProducesResponseType(StatusCodes.Status204NoContent)] public async Task PutAsync(ServiceRequest request) { _logger.LogInformation($"Updating service [{request.Name}]..."); @@ -87,8 +84,7 @@ namespace Birdmap.API.Controllers return NoContent(); } - [HttpDelete("{id}")] - [ProducesResponseType(StatusCodes.Status204NoContent)] + [HttpDelete("{id}"), ProducesResponseType(StatusCodes.Status204NoContent)] public async Task DeleteAsync(int id) { _logger.LogInformation($"Deleting service [{id}]..."); diff --git a/Birdmap.API/appsettings.json b/Birdmap.API/appsettings.json index f774618..fe9b2e1 100644 --- a/Birdmap.API/appsettings.json +++ b/Birdmap.API/appsettings.json @@ -27,5 +27,6 @@ "Role": "User" } ] - } + }, + "UseDummyServices": true } diff --git a/Birdmap.BLL/Interfaces/IDeviceService.cs b/Birdmap.BLL/Interfaces/IDeviceService.cs new file mode 100644 index 0000000..047c619 --- /dev/null +++ b/Birdmap.BLL/Interfaces/IDeviceService.cs @@ -0,0 +1,279 @@ +namespace Birdmap.BLL.Interfaces +{ + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")] + public partial class ListOfDevices : System.Collections.ObjectModel.Collection + { + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")] + public partial class Device + { + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public System.Guid Id { get; set; } + + [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public DeviceStatus Status { get; set; } + + [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Url { get; set; } + + [Newtonsoft.Json.JsonProperty("coordinates", Required = Newtonsoft.Json.Required.AllowNull)] + [System.ComponentModel.DataAnnotations.Required] + public Coordinates Coordinates { get; set; } = new Coordinates(); + + [Newtonsoft.Json.JsonProperty("sensors", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public ArrayofSensors Sensors { get; set; } = new ArrayofSensors(); + + private System.Collections.Generic.IDictionary _additionalProperties = new System.Collections.Generic.Dictionary(); + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties; } + set { _additionalProperties = value; } + } + + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")] + public partial class ArrayofSensors : System.Collections.ObjectModel.Collection + { + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")] + public partial class Sensor + { + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public System.Guid Id { get; set; } + + [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public SensorStatus Status { get; set; } + + private System.Collections.Generic.IDictionary _additionalProperties = new System.Collections.Generic.Dictionary(); + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties; } + set { _additionalProperties = value; } + } + + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")] + public partial class Coordinates + { + [Newtonsoft.Json.JsonProperty("latitude", Required = Newtonsoft.Json.Required.Always)] + public double Latitude { get; set; } + + [Newtonsoft.Json.JsonProperty("longitude", Required = Newtonsoft.Json.Required.Always)] + public double Longitude { get; set; } + + private System.Collections.Generic.IDictionary _additionalProperties = new System.Collections.Generic.Dictionary(); + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties; } + set { _additionalProperties = value; } + } + + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")] + public enum DeviceStatus + { + [System.Runtime.Serialization.EnumMember(Value = @"online")] + Online = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"error")] + Error = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"offline")] + Offline = 2, + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")] + public enum SensorStatus + { + [System.Runtime.Serialization.EnumMember(Value = @"online")] + Online = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"unknown")] + Unknown = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"offline")] + Offline = 2, + + } + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")] + public partial class ApiException : System.Exception + { + public int StatusCode { get; private set; } + + public string Response { get; private set; } + + public System.Collections.Generic.IReadOnlyDictionary> Headers { get; private set; } + + public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Exception innerException) + : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException) + { + StatusCode = statusCode; + Response = response; + Headers = headers; + } + + public override string ToString() + { + return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString()); + } + } + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")] + public partial class ApiException : ApiException + { + public TResult Result { get; private set; } + + public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, TResult result, System.Exception innerException) + : base(message, statusCode, response, headers, innerException) + { + Result = result; + } + } + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")] + public partial interface IDeviceService + { + /// Get all device info + /// Array of devices + /// A server side error occurred. + System.Threading.Tasks.Task> GetallAsync(); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Get all device info + /// Array of devices + /// A server side error occurred. + System.Threading.Tasks.Task> GetallAsync(System.Threading.CancellationToken cancellationToken); + + /// Shut down all devices + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OfflineallAsync(); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Shut down all devices + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OfflineallAsync(System.Threading.CancellationToken cancellationToken); + + /// Bring all devices online + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OnlineallAsync(); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Bring all devices online + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OnlineallAsync(System.Threading.CancellationToken cancellationToken); + + /// Get all device info + /// ID of device to query + /// Information about a particular device + /// A server side error occurred. + System.Threading.Tasks.Task GetdeviceAsync(System.Guid deviceID); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Get all device info + /// ID of device to query + /// Information about a particular device + /// A server side error occurred. + System.Threading.Tasks.Task GetdeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken); + + /// Shut down device + /// ID of device to shut down + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Shut down device + /// ID of device to shut down + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken); + + /// Bring device online + /// ID of device to bring online + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Bring device online + /// ID of device to bring online + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken); + + /// Get info about a particular device's sensor + /// ID of device to query + /// ID of sensor to query + /// Information about a sensor + /// A server side error occurred. + System.Threading.Tasks.Task GetsensorAsync(System.Guid deviceID, System.Guid sensorID); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Get info about a particular device's sensor + /// ID of device to query + /// ID of sensor to query + /// Information about a sensor + /// A server side error occurred. + System.Threading.Tasks.Task GetsensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken); + + /// Shut down sensor + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Shut down sensor + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken); + + /// Bring sensor online + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Bring sensor online + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken); + } +} \ No newline at end of file diff --git a/Birdmap.BLL/Services/DeviceServiceBase.cs b/Birdmap.BLL/Services/DeviceServiceBase.cs new file mode 100644 index 0000000..aeab79d --- /dev/null +++ b/Birdmap.BLL/Services/DeviceServiceBase.cs @@ -0,0 +1,39 @@ +using Birdmap.BLL.Interfaces; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Birdmap.BLL.Services +{ + public abstract class DeviceServiceBase : IDeviceService + { + public virtual Task> GetallAsync() + => GetallAsync(CancellationToken.None); + public abstract Task> GetallAsync(CancellationToken cancellationToken); + public virtual Task GetdeviceAsync(Guid deviceID) + => GetdeviceAsync(deviceID, CancellationToken.None); + public abstract Task GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken); + public virtual Task GetsensorAsync(Guid deviceID, Guid sensorID) + => GetsensorAsync(deviceID, sensorID, CancellationToken.None); + public abstract Task GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken); + public virtual Task OfflineallAsync() + => OfflineallAsync(CancellationToken.None); + public abstract Task OfflineallAsync(CancellationToken cancellationToken); + public virtual Task OfflinedeviceAsync(Guid deviceID) + => OfflinedeviceAsync(deviceID, CancellationToken.None); + public abstract Task OfflinedeviceAsync(Guid deviceID, CancellationToken cancellationToken); + public virtual Task OfflinesensorAsync(Guid deviceID, Guid sensorID) + => OfflinesensorAsync(deviceID, sensorID, CancellationToken.None); + public abstract Task OfflinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken); + public virtual Task OnlineallAsync() + => OnlineallAsync(CancellationToken.None); + public abstract Task OnlineallAsync(CancellationToken cancellationToken); + public virtual Task OnlinedeviceAsync(Guid deviceID) + => OnlinedeviceAsync(deviceID, CancellationToken.None); + public abstract Task OnlinedeviceAsync(Guid deviceID, CancellationToken cancellationToken); + public virtual Task OnlinesensorAsync(Guid deviceID, Guid sensorID) + => OnlinesensorAsync(deviceID, sensorID, CancellationToken.None); + public abstract Task OnlinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken); + } +} diff --git a/Birdmap.BLL/Services/DummyDeviceService.cs b/Birdmap.BLL/Services/DummyDeviceService.cs new file mode 100644 index 0000000..617a83a --- /dev/null +++ b/Birdmap.BLL/Services/DummyDeviceService.cs @@ -0,0 +1,139 @@ +using Birdmap.BLL.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Birdmap.BLL.Services +{ + public class DummyDeviceService : DeviceServiceBase + { + private const double centerLong = 21.469640; + private const double centerLat = 48.275939; + private const double radius = 0.000200; + + private readonly Lazy> _devices = new Lazy>(GenerateDevices); + private static ListOfDevices GenerateDevices() + { + var devices = new ListOfDevices(); + var rand = new Random(); + + T GetRandomEnum() + { + var values = Enum.GetValues(typeof(T)); + return (T)values.GetValue(rand.Next(values.Length)); + } + + double GetPlusMinus(double center, double radius) + { + return center - radius + rand.NextDouble() * radius * 2; + } + + for (int d = 0; d < 15; d++) + { + var sensors = new ArrayofSensors(); + for (int s = 0; s < rand.Next(1, 5); s++) + { + sensors.Add(new Sensor + { + Id = Guid.NewGuid(), + Status = GetRandomEnum(), + }); + } + + devices.Add(new Device + { + Id = Guid.NewGuid(), + Sensors = sensors, + Status = GetRandomEnum(), + Url = "dummyservice.device.url", + Coordinates = new Coordinates + { + Latitude = GetPlusMinus(centerLat, radius), + Longitude = GetPlusMinus(centerLong, radius), + } + }); + } + + return devices; + } + + public override Task> GetallAsync(CancellationToken cancellationToken) + { + return Task.FromResult(_devices.Value); + } + + public override Task GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken) + { + return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID)); + } + + public override Task GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken) + { + return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID)?.Sensors.SingleOrDefault(s => s.Id == sensorID)); + } + + public override Task OfflineallAsync(CancellationToken cancellationToken) + { + SetStatus(DeviceStatus.Offline, SensorStatus.Offline); + + return Task.CompletedTask; + } + + public override Task OfflinedeviceAsync(Guid deviceID, CancellationToken cancellationToken) + { + SetDeviceStatus(deviceID, DeviceStatus.Offline); + return Task.CompletedTask; + } + + public override Task OfflinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken) + { + SetSensorStatus(deviceID, sensorID, SensorStatus.Offline); + return Task.CompletedTask; + } + + public override Task OnlineallAsync(CancellationToken cancellationToken) + { + SetStatus(DeviceStatus.Online, SensorStatus.Online); + + return Task.CompletedTask; + } + + public override Task OnlinedeviceAsync(Guid deviceID, CancellationToken cancellationToken) + { + SetDeviceStatus(deviceID, DeviceStatus.Online); + return Task.CompletedTask; + } + + public override Task OnlinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken) + { + SetSensorStatus(deviceID, sensorID, SensorStatus.Online); + return Task.CompletedTask; + } + + private void SetStatus(DeviceStatus deviceStatus, SensorStatus sensorStatus) + { + foreach (var device in _devices.Value) + { + device.Status = deviceStatus; + foreach (var sensor in device.Sensors) + { + sensor.Status = sensorStatus; + } + } + } + + private void SetDeviceStatus(Guid deviceID, DeviceStatus status) + { + var device = GetdeviceAsync(deviceID).Result; + device.Status = status; + } + + private void SetSensorStatus(Guid deviceId, Guid sensorID, SensorStatus status) + { + var sensor = GetsensorAsync(deviceId, sensorID).Result; + sensor.Status = status; + } + } +} diff --git a/Birdmap.BLL/Services/LiveDeviceService.cs b/Birdmap.BLL/Services/LiveDeviceService.cs new file mode 100644 index 0000000..eb423c3 --- /dev/null +++ b/Birdmap.BLL/Services/LiveDeviceService.cs @@ -0,0 +1,902 @@ +//---------------------- +// +// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org) +// +//---------------------- + +#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended." +#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword." +#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?' +#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ... +#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..." + +namespace Birdmap.BLL.Services +{ + using Birdmap.BLL.Interfaces; + using System = global::System; + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")] + public partial class LiveDummyService : IDeviceService + { + private string _baseUrl = "https://birb.k8s.kmlabz.com"; + private System.Net.Http.HttpClient _httpClient; + private System.Lazy _settings; + + public LiveDummyService(System.Net.Http.HttpClient httpClient) + { + _httpClient = httpClient; + _settings = new System.Lazy(CreateSerializerSettings); + } + + private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + public string BaseUrl + { + get { return _baseUrl; } + set { _baseUrl = value; } + } + + protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } } + + partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings); + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url); + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); + partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); + + /// Get all device info + /// Array of devices + /// A server side error occurred. + public System.Threading.Tasks.Task> GetallAsync() + { + return GetallAsync(System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Get all device info + /// Array of devices + /// A server side error occurred. + public async System.Threading.Tasks.Task> GetallAsync(System.Threading.CancellationToken cancellationToken) + { + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("No device found", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Shut down all devices + /// Message sent + /// A server side error occurred. + public System.Threading.Tasks.Task OfflineallAsync() + { + return OfflineallAsync(System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Shut down all devices + /// Message sent + /// A server side error occurred. + public async System.Threading.Tasks.Task OfflineallAsync(System.Threading.CancellationToken cancellationToken) + { + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/offline"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + if (status_ == 500) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Bring all devices online + /// Message sent + /// A server side error occurred. + public System.Threading.Tasks.Task OnlineallAsync() + { + return OnlineallAsync(System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Bring all devices online + /// Message sent + /// A server side error occurred. + public async System.Threading.Tasks.Task OnlineallAsync(System.Threading.CancellationToken cancellationToken) + { + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/online"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + if (status_ == 500) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Get all device info + /// ID of device to query + /// Information about a particular device + /// A server side error occurred. + public System.Threading.Tasks.Task GetdeviceAsync(System.Guid deviceID) + { + return GetdeviceAsync(deviceID, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Get all device info + /// ID of device to query + /// Information about a particular device + /// A server side error occurred. + public async System.Threading.Tasks.Task GetdeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken) + { + if (deviceID == null) + throw new System.ArgumentNullException("deviceID"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}"); + urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture))); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Device not found", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Shut down device + /// ID of device to shut down + /// Message sent + /// A server side error occurred. + public System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID) + { + return OfflinedeviceAsync(deviceID, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Shut down device + /// ID of device to shut down + /// Message sent + /// A server side error occurred. + public async System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken) + { + if (deviceID == null) + throw new System.ArgumentNullException("deviceID"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/offline"); + urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture))); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + if (status_ == 500) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Bring device online + /// ID of device to bring online + /// Message sent + /// A server side error occurred. + public System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID) + { + return OnlinedeviceAsync(deviceID, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Bring device online + /// ID of device to bring online + /// Message sent + /// A server side error occurred. + public async System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken) + { + if (deviceID == null) + throw new System.ArgumentNullException("deviceID"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/online"); + urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture))); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + if (status_ == 500) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Get info about a particular device's sensor + /// ID of device to query + /// ID of sensor to query + /// Information about a sensor + /// A server side error occurred. + public System.Threading.Tasks.Task GetsensorAsync(System.Guid deviceID, System.Guid sensorID) + { + return GetsensorAsync(deviceID, sensorID, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Get info about a particular device's sensor + /// ID of device to query + /// ID of sensor to query + /// Information about a sensor + /// A server side error occurred. + public async System.Threading.Tasks.Task GetsensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken) + { + if (deviceID == null) + throw new System.ArgumentNullException("deviceID"); + + if (sensorID == null) + throw new System.ArgumentNullException("sensorID"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/{sensorID}"); + urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Replace("{sensorID}", System.Uri.EscapeDataString(ConvertToString(sensorID, System.Globalization.CultureInfo.InvariantCulture))); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Device or sensor not found", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Shut down sensor + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + public System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID) + { + return OfflinesensorAsync(deviceID, sensorID, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Shut down sensor + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + public async System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken) + { + if (deviceID == null) + throw new System.ArgumentNullException("deviceID"); + + if (sensorID == null) + throw new System.ArgumentNullException("sensorID"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/{sensorID}/offline"); + urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Replace("{sensorID}", System.Uri.EscapeDataString(ConvertToString(sensorID, System.Globalization.CultureInfo.InvariantCulture))); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + if (status_ == 500) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// Bring sensor online + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + public System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID) + { + return OnlinesensorAsync(deviceID, sensorID, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// Bring sensor online + /// ID of device to query + /// ID of sensor to query + /// Message sent + /// A server side error occurred. + public async System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken) + { + if (deviceID == null) + throw new System.ArgumentNullException("deviceID"); + + if (sensorID == null) + throw new System.ArgumentNullException("sensorID"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/{sensorID}/online"); + urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Replace("{sensorID}", System.Uri.EscapeDataString(ConvertToString(sensorID, System.Globalization.CultureInfo.InvariantCulture))); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + + PrepareRequest(client_, request_, urlBuilder_); + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + if (status_ == 500) + { + string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + protected struct ObjectResponseResult + { + public ObjectResponseResult(T responseObject, string responseText) + { + this.Object = responseObject; + this.Text = responseText; + } + + public T Object { get; } + + public string Text { get; } + } + + public bool ReadResponseAsString { get; set; } + + protected virtual async System.Threading.Tasks.Task> ReadObjectResponseAsync(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary> headers) + { + if (response == null || response.Content == null) + { + return new ObjectResponseResult(default(T), string.Empty); + } + + if (ReadResponseAsString) + { + var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, JsonSerializerSettings); + return new ObjectResponseResult(typedBody, responseText); + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body string as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception); + } + } + else + { + try + { + using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) + using (var streamReader = new System.IO.StreamReader(responseStream)) + using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader)) + { + var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings); + var typedBody = serializer.Deserialize(jsonTextReader); + return new ObjectResponseResult(typedBody, string.Empty); + } + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body stream as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception); + } + } + } + + private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo) + { + if (value == null) + { + return null; + } + + if (value is System.Enum) + { + var name = System.Enum.GetName(value.GetType(), value); + if (name != null) + { + var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name); + if (field != null) + { + var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) + as System.Runtime.Serialization.EnumMemberAttribute; + if (attribute != null) + { + return attribute.Value != null ? attribute.Value : name; + } + } + + return System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo)); + } + } + else if (value is bool) + { + return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant(); + } + else if (value is byte[]) + { + return System.Convert.ToBase64String((byte[])value); + } + else if (value.GetType().IsArray) + { + var array = System.Linq.Enumerable.OfType((System.Array)value); + return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo))); + } + + var result = System.Convert.ToString(value, cultureInfo); + return (result is null) ? string.Empty : result; + } + } +} + +#pragma warning restore 1591 +#pragma warning restore 1573 +#pragma warning restore 472 +#pragma warning restore 114 +#pragma warning restore 108 \ No newline at end of file diff --git a/Birdmap.BLL/Startup.cs b/Birdmap.BLL/Startup.cs index a3b9480..698db11 100644 --- a/Birdmap.BLL/Startup.cs +++ b/Birdmap.BLL/Startup.cs @@ -13,6 +13,11 @@ namespace Birdmap.BLL services.AddTransient(); services.AddTransient(); + if (configuration.GetValue("UseDummyServices")) + services.AddTransient(); + else + services.AddTransient(); + return services; } } diff --git a/c-n-c-nswag.nswag b/c-n-c-nswag.nswag new file mode 100644 index 0000000..87f9a5c --- /dev/null +++ b/c-n-c-nswag.nswag @@ -0,0 +1,221 @@ +{ + "runtime": "NetCore31", + "defaultVariables": null, + "documentGenerator": { + "fromDocument": { + "json": "openapi: 3.0.3\ninfo:\n title: Command and Control Service\n description: This service s responsible for controlling and handling information\n about IoT devices in the Birbnetes system.\n contact:\n email: tormakristof@tormakristof.eu\n license:\n name: Apache 2.0\n url: http://www.apache.org/licenses/LICENSE-2.0.html\n version: 1.0.0\nservers:\n- url: https://birb.k8s.kmlabz.com\ntags:\n- name: cnc\n description: Command and Control Service interaction\npaths:\n /devices:\n get:\n tags:\n - cnc\n summary: Get all device info\n operationId: getall\n responses:\n 200:\n description: Array of devices\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ListOfDevices'\n 404:\n description: No device found\n content: {}\n /devices/offline:\n post:\n tags:\n - cnc\n summary: Shut down all devices\n operationId: offlineall\n responses:\n 200:\n description: Message sent\n content: {}\n 500:\n description: Message sending unsuccessful\n content: {}\n /devices/online:\n post:\n tags:\n - cnc\n summary: Bring all devices online\n operationId: onlineall\n responses:\n 200:\n description: Message sent\n content: {}\n 500:\n description: Message sending unsuccessful\n content: {}\n /devices/{deviceID}:\n get:\n tags:\n - cnc\n summary: Get all device info\n operationId: getdevice\n parameters:\n - name: deviceID\n in: path\n description: ID of device to query\n required: true\n schema:\n type: string\n format: uuid\n responses:\n 200:\n description: Information about a particular device\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Device'\n 404:\n description: Device not found\n content: {}\n /devices/{deviceID}/offline:\n post:\n tags:\n - cnc\n summary: Shut down device\n operationId: offlinedevice\n parameters:\n - name: deviceID\n in: path\n description: ID of device to shut down\n required: true\n schema:\n type: string\n format: uuid\n responses:\n 200:\n description: Message sent\n content: {}\n 500:\n description: Message sending unsuccessful\n content: {}\n /devices/{deviceID}/online:\n post:\n tags:\n - cnc\n summary: Bring device online\n operationId: onlinedevice\n parameters:\n - name: deviceID\n in: path\n description: ID of device to bring online\n required: true\n schema:\n type: string\n format: uuid\n responses:\n 200:\n description: Message sent\n content: {}\n 500:\n description: Message sending unsuccessful\n content: {}\n /devices/{deviceID}/{sensorID}:\n get:\n tags:\n - cnc\n summary: Get info about a particular device's sensor\n operationId: getsensor\n parameters:\n - name: deviceID\n in: path\n description: ID of device to query\n required: true\n schema:\n type: string\n format: uuid\n - name: sensorID\n in: path\n description: ID of sensor to query\n required: true\n schema:\n type: string\n format: uuid\n responses:\n 200:\n description: Information about a sensor\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Sensor'\n 404:\n description: Device or sensor not found\n content: {}\n /devices/{deviceID}/{sensorID}/offline:\n post:\n tags:\n - cnc\n summary: Shut down sensor\n operationId: offlinesensor\n parameters:\n - name: deviceID\n in: path\n description: ID of device to query\n required: true\n schema:\n type: string\n format: uuid\n - name: sensorID\n in: path\n description: ID of sensor to query\n required: true\n schema:\n type: string\n format: uuid\n responses:\n 200:\n description: Message sent\n content: {}\n 500:\n description: Message sending unsuccessful\n content: {}\n /devices/{deviceID}/{sensorID}/online:\n post:\n tags:\n - cnc\n summary: Bring sensor online\n operationId: onlinesensor\n parameters:\n - name: deviceID\n in: path\n description: ID of device to query\n required: true\n schema:\n type: string\n format: uuid\n - name: sensorID\n in: path\n description: ID of sensor to query\n required: true\n schema:\n type: string\n format: uuid\n responses:\n 200:\n description: Message sent\n content: {}\n 500:\n description: Message sending unsuccessful\n content: {}\ncomponents:\n schemas:\n ListOfDevices:\n type: array\n items:\n $ref: '#/components/schemas/Device'\n Device:\n required:\n - id\n - sensors\n - status\n - url\n - coordinates\n type: object\n properties:\n id:\n type: string\n format: uuid\n status:\n type: string\n enum:\n - online\n - error\n - offline\n url:\n type: string\n format: url\n coordinates:\n required:\n - latitude\n - longitude\n type: object\n properties:\n latitude:\n type: number\n format: double\n longitude:\n type: number\n format: double\n sensors:\n $ref: '#/components/schemas/ArrayofSensors'\n ArrayofSensors:\n type: array\n items:\n $ref: '#/components/schemas/Sensor'\n Sensor:\n required:\n - id\n - status\n type: object\n properties:\n id:\n type: string\n format: uuid\n status:\n type: string\n enum:\n - online\n - unknown\n - offline", + "url": "https://git.kmlabz.com/birbnetes/swagger-docs/raw/branch/master/command-and-control.yml", + "output": null, + "newLineBehavior": "Auto" + } + }, + "codeGenerators": { + "openApiToTypeScriptClient": { + "className": "DeviceService", + "moduleName": "", + "namespace": "", + "typeScriptVersion": 2.7, + "template": "Fetch", + "promiseType": "Promise", + "httpClass": "HttpClient", + "withCredentials": false, + "useSingletonProvider": false, + "injectionTokenType": "OpaqueToken", + "rxJsVersion": 6.0, + "dateTimeType": "Date", + "nullValue": "Undefined", + "generateClientClasses": true, + "generateClientInterfaces": false, + "generateOptionalParameters": false, + "exportTypes": true, + "wrapDtoExceptions": false, + "exceptionClass": "ApiException", + "clientBaseClass": null, + "wrapResponses": false, + "wrapResponseMethods": [], + "generateResponseClasses": true, + "responseClass": "SwaggerResponse", + "protectedMethods": [], + "configurationClass": null, + "useTransformOptionsMethod": false, + "useTransformResultMethod": false, + "generateDtoTypes": true, + "operationGenerationMode": "MultipleClientsFromOperationId", + "markOptionalProperties": true, + "generateCloneMethod": false, + "typeStyle": "Class", + "enumStyle": "Enum", + "useLeafType": false, + "classTypes": [], + "extendedClasses": [], + "extensionCode": null, + "generateDefaultValues": true, + "excludedTypeNames": [], + "excludedParameterNames": [], + "handleReferences": false, + "generateConstructorInterface": true, + "convertConstructorInterfaceData": false, + "importRequiredTypes": true, + "useGetBaseUrlMethod": false, + "baseUrlTokenName": "API_BASE_URL", + "queryNullValue": "", + "inlineNamedDictionaries": false, + "inlineNamedAny": false, + "templateDirectory": null, + "typeNameGeneratorType": null, + "propertyNameGeneratorType": null, + "enumNameGeneratorType": null, + "serviceHost": null, + "serviceSchemes": null, + "output": null, + "newLineBehavior": "Auto" + }, + "openApiToCSharpClient": { + "clientBaseClass": null, + "configurationClass": null, + "generateClientClasses": true, + "generateClientInterfaces": true, + "clientBaseInterface": null, + "injectHttpClient": true, + "disposeHttpClient": true, + "protectedMethods": [], + "generateExceptionClasses": true, + "exceptionClass": "ApiException", + "wrapDtoExceptions": true, + "useHttpClientCreationMethod": false, + "httpClientType": "System.Net.Http.HttpClient", + "useHttpRequestMessageCreationMethod": false, + "useBaseUrl": true, + "generateBaseUrlProperty": true, + "generateSyncMethods": false, + "exposeJsonSerializerSettings": false, + "clientClassAccessModifier": "public", + "typeAccessModifier": "public", + "generateContractsOutput": false, + "contractsNamespace": null, + "contractsOutputFilePath": null, + "parameterDateTimeFormat": "s", + "parameterDateFormat": "yyyy-MM-dd", + "generateUpdateJsonSerializerSettingsMethod": true, + "useRequestAndResponseSerializationSettings": false, + "serializeTypeInformation": false, + "queryNullValue": "", + "className": "LiveDeviceService", + "operationGenerationMode": "MultipleClientsFromOperationId", + "additionalNamespaceUsages": [], + "additionalContractNamespaceUsages": [], + "generateOptionalParameters": false, + "generateJsonMethods": false, + "enforceFlagEnums": false, + "parameterArrayType": "System.Collections.Generic.IEnumerable", + "parameterDictionaryType": "System.Collections.Generic.IDictionary", + "responseArrayType": "System.Collections.Generic.ICollection", + "responseDictionaryType": "System.Collections.Generic.IDictionary", + "wrapResponses": false, + "wrapResponseMethods": [], + "generateResponseClasses": true, + "responseClass": "SwaggerResponse", + "namespace": "Birdmap.BLL.Services", + "requiredPropertiesMustBeDefined": true, + "dateType": "System.DateTimeOffset", + "jsonConverters": null, + "anyType": "object", + "dateTimeType": "System.DateTimeOffset", + "timeType": "System.TimeSpan", + "timeSpanType": "System.TimeSpan", + "arrayType": "System.Collections.Generic.ICollection", + "arrayInstanceType": "System.Collections.ObjectModel.Collection", + "dictionaryType": "System.Collections.Generic.IDictionary", + "dictionaryInstanceType": "System.Collections.Generic.Dictionary", + "arrayBaseType": "System.Collections.ObjectModel.Collection", + "dictionaryBaseType": "System.Collections.Generic.Dictionary", + "classStyle": "Poco", + "generateDefaultValues": true, + "generateDataAnnotations": true, + "excludedTypeNames": [], + "excludedParameterNames": [], + "handleReferences": false, + "generateImmutableArrayProperties": false, + "generateImmutableDictionaryProperties": false, + "jsonSerializerSettingsTransformationMethod": null, + "inlineNamedArrays": false, + "inlineNamedDictionaries": false, + "inlineNamedTuples": true, + "inlineNamedAny": false, + "generateDtoTypes": true, + "generateOptionalPropertiesAsNullable": false, + "generateNullableReferenceTypes": false, + "templateDirectory": null, + "typeNameGeneratorType": null, + "propertyNameGeneratorType": null, + "enumNameGeneratorType": null, + "serviceHost": null, + "serviceSchemes": null, + "output": null, + "newLineBehavior": "Auto" + }, + "openApiToCSharpController": { + "controllerBaseClass": null, + "controllerStyle": "Partial", + "controllerTarget": "AspNetCore", + "useCancellationToken": false, + "useActionResultType": true, + "generateModelValidationAttributes": true, + "routeNamingStrategy": "None", + "basePath": null, + "className": "{controller}", + "operationGenerationMode": "MultipleClientsFromOperationId", + "additionalNamespaceUsages": [], + "additionalContractNamespaceUsages": [], + "generateOptionalParameters": false, + "generateJsonMethods": false, + "enforceFlagEnums": false, + "parameterArrayType": "System.Collections.Generic.IEnumerable", + "parameterDictionaryType": "System.Collections.Generic.IDictionary", + "responseArrayType": "System.Collections.Generic.ICollection", + "responseDictionaryType": "System.Collections.Generic.IDictionary", + "wrapResponses": false, + "wrapResponseMethods": [], + "generateResponseClasses": true, + "responseClass": "SwaggerResponse", + "namespace": "Birdmap.API.Controllers", + "requiredPropertiesMustBeDefined": true, + "dateType": "System.DateTimeOffset", + "jsonConverters": null, + "anyType": "object", + "dateTimeType": "System.DateTimeOffset", + "timeType": "System.TimeSpan", + "timeSpanType": "System.TimeSpan", + "arrayType": "System.Collections.Generic.List", + "arrayInstanceType": "System.Collections.Generic.List", + "dictionaryType": "System.Collections.Generic.IDictionary", + "dictionaryInstanceType": "System.Collections.Generic.Dictionary", + "arrayBaseType": "System.Collections.ObjectModel.Collection", + "dictionaryBaseType": "System.Collections.Generic.Dictionary", + "classStyle": "Poco", + "generateDefaultValues": true, + "generateDataAnnotations": true, + "excludedTypeNames": [], + "excludedParameterNames": [], + "handleReferences": false, + "generateImmutableArrayProperties": false, + "generateImmutableDictionaryProperties": false, + "jsonSerializerSettingsTransformationMethod": null, + "inlineNamedArrays": false, + "inlineNamedDictionaries": false, + "inlineNamedTuples": true, + "inlineNamedAny": false, + "generateDtoTypes": true, + "generateOptionalPropertiesAsNullable": false, + "generateNullableReferenceTypes": false, + "templateDirectory": null, + "typeNameGeneratorType": null, + "propertyNameGeneratorType": null, + "enumNameGeneratorType": null, + "serviceHost": null, + "serviceSchemes": null, + "output": null, + "newLineBehavior": "Auto" + } + } +} \ No newline at end of file diff --git a/c-n-c.yml b/c-n-c.yml new file mode 100644 index 0000000..75048aa --- /dev/null +++ b/c-n-c.yml @@ -0,0 +1,272 @@ +openapi: 3.0.3 +info: + title: Command and Control Service + description: This service s responsible for controlling and handling information + about IoT devices in the Birbnetes system. + contact: + email: tormakristof@tormakristof.eu + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.0 +servers: +- url: https://birb.k8s.kmlabz.com +tags: +- name: cnc + description: Command and Control Service interaction +paths: + /devices: + get: + tags: + - cnc + summary: Get all device info + operationId: getall + responses: + 200: + description: Array of devices + content: + application/json: + schema: + $ref: '#/components/schemas/ListOfDevices' + 404: + description: No device found + content: {} + /devices/offline: + post: + tags: + - cnc + summary: Shut down all devices + operationId: offlineall + responses: + 200: + description: Message sent + content: {} + 500: + description: Message sending unsuccessful + content: {} + /devices/online: + post: + tags: + - cnc + summary: Bring all devices online + operationId: onlineall + responses: + 200: + description: Message sent + content: {} + 500: + description: Message sending unsuccessful + content: {} + /devices/{deviceID}: + get: + tags: + - cnc + summary: Get all device info + operationId: getdevice + parameters: + - name: deviceID + in: path + description: ID of device to query + required: true + schema: + type: string + format: uuid + responses: + 200: + description: Information about a particular device + content: + application/json: + schema: + $ref: '#/components/schemas/Device' + 404: + description: Device not found + content: {} + /devices/{deviceID}/offline: + post: + tags: + - cnc + summary: Shut down device + operationId: offlinedevice + parameters: + - name: deviceID + in: path + description: ID of device to shut down + required: true + schema: + type: string + format: uuid + responses: + 200: + description: Message sent + content: {} + 500: + description: Message sending unsuccessful + content: {} + /devices/{deviceID}/online: + post: + tags: + - cnc + summary: Bring device online + operationId: onlinedevice + parameters: + - name: deviceID + in: path + description: ID of device to bring online + required: true + schema: + type: string + format: uuid + responses: + 200: + description: Message sent + content: {} + 500: + description: Message sending unsuccessful + content: {} + /devices/{deviceID}/{sensorID}: + get: + tags: + - cnc + summary: Get info about a particular device's sensor + operationId: getsensor + parameters: + - name: deviceID + in: path + description: ID of device to query + required: true + schema: + type: string + format: uuid + - name: sensorID + in: path + description: ID of sensor to query + required: true + schema: + type: string + format: uuid + responses: + 200: + description: Information about a sensor + content: + application/json: + schema: + $ref: '#/components/schemas/Sensor' + 404: + description: Device or sensor not found + content: {} + /devices/{deviceID}/{sensorID}/offline: + post: + tags: + - cnc + summary: Shut down sensor + operationId: offlinesensor + parameters: + - name: deviceID + in: path + description: ID of device to query + required: true + schema: + type: string + format: uuid + - name: sensorID + in: path + description: ID of sensor to query + required: true + schema: + type: string + format: uuid + responses: + 200: + description: Message sent + content: {} + 500: + description: Message sending unsuccessful + content: {} + /devices/{deviceID}/{sensorID}/online: + post: + tags: + - cnc + summary: Bring sensor online + operationId: onlinesensor + parameters: + - name: deviceID + in: path + description: ID of device to query + required: true + schema: + type: string + format: uuid + - name: sensorID + in: path + description: ID of sensor to query + required: true + schema: + type: string + format: uuid + responses: + 200: + description: Message sent + content: {} + 500: + description: Message sending unsuccessful + content: {} +components: + schemas: + ListOfDevices: + type: array + items: + $ref: '#/components/schemas/Device' + Device: + required: + - id + - sensors + - status + - url + - coordinates + type: object + properties: + id: + type: string + format: uuid + status: + type: string + enum: + - online + - error + - offline + url: + type: string + format: url + coordinates: + required: + - latitude + - longitude + type: object + properties: + latitude: + type: number + format: double + longitude: + type: number + format: double + sensors: + $ref: '#/components/schemas/ArrayofSensors' + ArrayofSensors: + type: array + items: + $ref: '#/components/schemas/Sensor' + Sensor: + required: + - id + - status + type: object + properties: + id: + type: string + format: uuid + status: + type: string + enum: + - online + - unknown + - offline \ No newline at end of file diff --git a/docs/Dashboard.jpg b/docs/Dashboard.jpg new file mode 100644 index 0000000..529fd7a Binary files /dev/null and b/docs/Dashboard.jpg differ diff --git a/docs/Login.jpg b/docs/Login.jpg new file mode 100644 index 0000000..d566fa2 Binary files /dev/null and b/docs/Login.jpg differ