node-red-contrib-blynk-ws
Advanced tools
Comparing version 0.8.0 to 0.9.0
@@ -9,2 +9,20 @@ # Changelog | ||
## [0.9.0] - 2019-03-19 | ||
### Add | ||
- Node - *Image Gallery* - Implemented "url" and "urls" property [NOTE: url and urls property are supported only in beta app] | ||
- Node - *Set Property* - Implemented "url" and "urls" property [NOTE: url and urls property are supported only in beta app] | ||
### Changed | ||
- Node - *Configuration* - Using tabs for better UI | ||
- All nodes - Increased the limit of the pins to 255 and better validation checks | ||
- Improved heartbeat , send PING command only if necessary. | ||
- Control and blocking of sending too long messages (BLYNK_PROTOCOL_MAX_LENGTH) | ||
- Compatibility with Blynk C++ Library 0.6.1 | ||
- LOGIN command changed to int 29 (old int 2) | ||
- Remove unused command and code clean | ||
### Fixed | ||
- Fix TypeError on node-red restart | ||
- Crash on websocket "timeout" error | ||
## [0.8.0] - 2019-01-05 | ||
@@ -23,3 +41,3 @@ ### Added | ||
- Increase heartbeat timeout to 15 seconds - see Blynk Server [Issue #1294](https://github.com/blynkkk/blynk-server/issues/1294) | ||
- Compatibility with Blynk Library 0.5.4 | ||
- Compatibility with Blynk C++ Library 0.5.4 | ||
@@ -43,3 +61,3 @@ ### Fixed | ||
- Code refactor - Extract blynk method and variable to files in "libs" directory | ||
- Node - *Notify* - Rate limit increased to 5 msg/s (Blynk Library 0.5.3) | ||
- Node - *Notify* - Rate limit increased to 5 msg/s (Blynk C++ Library 0.5.3) | ||
@@ -67,3 +85,3 @@ ### Fixed | ||
### Added | ||
- Blynk protocol - Handle any number of Blynk commands (virtualWrite(), setProperty(), etc.) in a row see [Blynk Library 0.5.0](https://community.blynk.cc/t/beta-blynk-library-v0-5-0/19841) | ||
- Blynk protocol - Handle any number of Blynk commands (virtualWrite(), setProperty(), etc.) in a row see [Blynk C++ Library 0.5.0](https://community.blynk.cc/t/beta-blynk-library-v0-5-0/19841) | ||
- Control max lenght of message and max number of commands in a single message | ||
@@ -99,6 +117,6 @@ - Config node - Option to enable "Multiple blynk command in single message" (blynk cloud or local server >= v0.34.0) | ||
### Added | ||
- Handle CONNECT_REDIRECT command see [iusse #5](https://github.com/gablau/node-red-contrib-blynk-ws/issues/5) and [this](https://community.blynk.cc/t/correct-websocket-address-for-blynk-server/22496) | ||
- Handle REDIRECT command see [iusse #5](https://github.com/gablau/node-red-contrib-blynk-ws/issues/5) and [this](https://community.blynk.cc/t/correct-websocket-address-for-blynk-server/22496) | ||
### Changed | ||
- Server port configuration and help message see [Blynk Library 0.5.1](https://community.blynk.cc/t/new-blynk-library-v0-5-1-is-released-important-for-local-server-owners/22449) | ||
- Server port configuration and help message see [Blynk C++ Library 0.5.1](https://community.blynk.cc/t/new-blynk-library-v0-5-1-is-released-important-for-local-server-owners/22449) | ||
@@ -146,3 +164,4 @@ ### Fixed | ||
[Unreleased]: https://github.com/gablau/node-red-contrib-blynk-ws/compare/0.8.0...HEAD | ||
[Unreleased]: https://github.com/gablau/node-red-contrib-blynk-ws/compare/0.9.0...HEAD | ||
[0.9.0]: https://github.com/gablau/node-red-contrib-blynk-ws/compare/0.8.0...0.9.0 | ||
[0.8.0]: https://github.com/gablau/node-red-contrib-blynk-ws/compare/0.7.1...0.8.0 | ||
@@ -149,0 +168,0 @@ [0.7.1]: https://github.com/gablau/node-red-contrib-blynk-ws/compare/0.7.0...0.7.1 |
@@ -7,14 +7,5 @@ /* blynk enum */ | ||
//app commands | ||
REGISTER : 1, //"mail pass" | ||
LOGIN : 2, //"token" or "mail pass" | ||
SAVE_PROF : 3, | ||
LOAD_PROF : 4, | ||
GET_TOKEN : 5, | ||
LOGIN : 29, | ||
PING : 6, | ||
ACTIVATE : 7, //"DASH_ID" | ||
DEACTIVATE : 8, // | ||
REFRESH : 9, //"refreshToken DASH_ID" | ||
GET_GRAPH_DATA : 10, | ||
GET_GRAPH_DATA_RESPONSE : 11, | ||
//HARDWARE commands | ||
@@ -26,95 +17,11 @@ TWEET : 12, | ||
HW_SYNC : 16, | ||
INTERNAL : 17, //0x11 | ||
INTERNAL : 17, | ||
SMS : 18, | ||
PROPERTY : 19, | ||
HW : 20, //0x14 | ||
//app commands | ||
CREATE_DASH : 21, | ||
UPDATE_DASH : 22, | ||
DELETE_DASH : 23, | ||
LOAD_PROF_GZ : 24, | ||
APP_SYNC : 25, | ||
SHARING : 26, | ||
ADD_PUSH_TOKEN : 27, | ||
EXPORT_GRAPH_DATA : 28, | ||
HW_LOGIN : 29, | ||
//app sharing commands | ||
GET_SHARE_TOKEN : 30, | ||
REFRESH_SHARE_TOKEN : 31, | ||
SHARE_LOGIN : 32, | ||
//app commands | ||
CREATE_WIDGET : 33, | ||
UPDATE_WIDGET : 34, | ||
DELETE_WIDGET : 35, | ||
HW : 20, | ||
REDIRECT : 41, | ||
DEBUG_PRINT : 55, | ||
EVENT_LOG : 64, | ||
//energy commands | ||
GET_ENERGY : 36, | ||
ADD_ENERGY : 37, | ||
UPDATE_PROJECT_SETTINGS : 38, | ||
ASSIGN_TOKEN : 39, | ||
GET_SERVER : 40, | ||
CONNECT_REDIRECT : 41, | ||
CREATE_DEVICE : 42, | ||
UPDATE_DEVICE : 43, | ||
DELETE_DEVICE : 44, | ||
GET_DEVICES : 45, | ||
CREATE_TAG : 46, | ||
UPDATE_TAG : 47, | ||
DELETE_TAG : 48, | ||
GET_TAGS : 49, | ||
APP_CONNECTED : 50, | ||
UPDATE_FACE : 51, | ||
//web sockets | ||
WEB_SOCKETS : 52, | ||
EVENTOR : 53, | ||
WEB_HOOKS : 54, | ||
CREATE_APP : 55, | ||
UPDATE_APP : 56, | ||
DELETE_APP : 57, | ||
GET_PROJECT_BY_TOKEN : 58, | ||
EMAIL_QR : 59, | ||
GET_ENHANCED_GRAPH_DATA : 60, | ||
DELETE_ENHANCED_GRAPH_DATA : 61, | ||
GET_CLONE_CODE : 62, | ||
GET_PROJECT_BY_CLONE_CODE : 63, | ||
HARDWARE_LOG_EVENT : 64, | ||
HARDWARE_RESEND_FROM_BLUETOOTH : 65, | ||
LOGOUT : 66, | ||
CREATE_TILE_TEMPLATE : 67, | ||
UPDATE_TILE_TEMPLATE : 68, | ||
DELETE_TILE_TEMPLATE : 69, | ||
GET_WIDGET : 70, | ||
DEVICE_OFFLINE : 71, | ||
OUTDATED_APP_NOTIFICATION : 72, | ||
TRACK_DEVICE : 73, | ||
GET_PROVISION_TOKEN : 74, | ||
/* | ||
//http codes. Used only for stats | ||
HTTP_IS_HARDWARE_CONNECTED : 82, | ||
HTTP_IS_APP_CONNECTED : 83, | ||
HTTP_GET_PIN_DATA : 84, | ||
HTTP_UPDATE_PIN_DATA : 85, | ||
HTTP_NOTIFY : 86, | ||
HTTP_EMAIL : 87, | ||
HTTP_GET_PROJECT : 88, | ||
HTTP_QR : 89, | ||
HTTP_GET_HISTORY_DATA : 90, | ||
HTTP_START_OTA : 91, | ||
HTTP_STOP_OTA : 92, | ||
HTTP_CLONE : 93, | ||
HTTP_TOTAL : 94, | ||
*/ | ||
}; | ||
@@ -126,6 +33,6 @@ | ||
ILLEGAL_COMMAND : 2, | ||
NOT_REGISTERED : 3, | ||
ALREADY_REGISTERED : 4, | ||
NOT_AUTHENTICATED : 5, | ||
NOT_ALLOWED : 6, | ||
NOT_REGISTERED : 3, //user | ||
ALREADY_REGISTERED : 4, //user | ||
NOT_AUTHENTICATED : 5, //user | ||
NOT_ALLOWED : 6, //user | ||
DEVICE_NOT_IN_NETWORK : 7, | ||
@@ -135,3 +42,3 @@ NO_ACTIVE_DASHBOARD : 8, | ||
ILLEGAL_COMMAND_BODY : 11, | ||
GET_GRAPH_DATA_EXCEPTION : 12, | ||
//GET_GRAPH_DATA_EXCEPTION : 12, | ||
NOTIFICATION_INVALID_BODY : 13, | ||
@@ -141,3 +48,3 @@ NOTIFICATION_NOT_AUTHORIZED : 14, | ||
//reserved | ||
BLYNK_TIMEOUT : 16, | ||
//BLYNK_TIMEOUT : 16, | ||
NO_DATA_EXCEPTION : 17, | ||
@@ -144,0 +51,0 @@ //DEVICE_WENT_OFFLINE : 18, //removed |
//blynk enum | ||
var blynkEnum = require('./../libs/blynk-enum.js'); | ||
var blynkEnum = require('./blynk-enum.js'); | ||
var MsgStatus = blynkEnum.MsgStatus; | ||
@@ -7,3 +7,3 @@ var MsgType = blynkEnum.MsgType; | ||
//blynk util | ||
var blynkUtil = require('./../libs/blynk-util.js'); | ||
var blynkUtil = require('./blynk-util.js'); | ||
var messageToDebugString = blynkUtil.messageToDebugString; | ||
@@ -31,2 +31,4 @@ var commandToDebugString = blynkUtil.commandToDebugString; | ||
// 0.5.4 - 2018-09-05 | ||
// 0.6.0 - 2018-02-01 | ||
// 0.6.1 - 2018-02-19 | ||
@@ -42,3 +44,3 @@ //Server Version | ||
// Blynk library constant | ||
var BLYNK_VERSION = "0.5.4"; //blynk library version | ||
var BLYNK_VERSION = "0.6.1"; //blynk library version | ||
var BLYNK_HEARTBEAT = 15; //seconds | ||
@@ -90,2 +92,7 @@ var BLYNK_PROTOCOL_MAX_LENGTH = 32767; //java Short.MAX_VALUE | ||
} | ||
if(data.length > BLYNK_PROTOCOL_MAX_LENGTH){ | ||
this.log("ERROR sendMsg - Message too long: "+data.length+"bytes"); | ||
return; | ||
} | ||
if (this.dbg_low) { | ||
@@ -142,3 +149,3 @@ this.log("SEND -> " + messageToDebugString(data)); | ||
} | ||
if(cmd.type === MsgType.CONNECT_REDIRECT) { | ||
if(cmd.type === MsgType.REDIRECT) { | ||
//handle server redirect | ||
@@ -158,4 +165,9 @@ var schema = "ws://"; | ||
} | ||
} else { // | ||
this.last_activity_in = getTimestamp(); | ||
} else { //logged | ||
//update received activity not update heartbeat | ||
if(cmd.type !== MsgType.RSP) { | ||
this.last_activity_in = getTimestamp(); | ||
} | ||
switch (cmd.type) { | ||
@@ -215,3 +227,2 @@ case MsgType.RSP: | ||
break; | ||
case MsgType.INTERNAL: | ||
@@ -229,18 +240,5 @@ switch (cmd.body) { | ||
break; | ||
case MsgType.GET_TOKEN: | ||
this.sendRsp(MsgType.GET_TOKEN, this.msg_id, this.key.length, this.key); | ||
break; | ||
case MsgType.LOAD_PROF: | ||
//this.sendRsp(MsgType.LOAD_PROF, this.msg_id, profile.length, self.profile); | ||
break; | ||
case MsgType.DEBUG_PRINT: | ||
this.log("Server: " + cmd.body); | ||
break; | ||
case MsgType.REGISTER: | ||
case MsgType.SAVE_PROF: | ||
case MsgType.ACTIVATE: | ||
case MsgType.DEACTIVATE: | ||
case MsgType.REFRESH: | ||
// skip this message types | ||
break; | ||
default: | ||
@@ -279,3 +277,4 @@ this.warn(RED._("Invalid header type: " + commandToDebugString(cmd))); | ||
"con", "Blynk-ws", | ||
"build", this.LIBRARY_INFO, | ||
"fw", this.LIBRARY_VERSION, | ||
"build", this.LIBRARY_DATE, | ||
]; | ||
@@ -391,2 +390,3 @@ this.msg_id++; | ||
//constants | ||
exports.BLYNK_VERSION = BLYNK_VERSION; | ||
@@ -397,3 +397,3 @@ exports.BLYNK_HEARTBEAT = BLYNK_HEARTBEAT; | ||
//protocol | ||
//protocol functions | ||
exports.blynkCmd = blynkCmd; | ||
@@ -407,3 +407,3 @@ exports.sendRsp = sendRsp; | ||
//protocol command | ||
//protocol commands | ||
exports.login = login; | ||
@@ -410,0 +410,0 @@ exports.sendInfo = sendInfo; |
@@ -7,4 +7,7 @@ module.exports = function(RED) { | ||
var LIBRARY_INFO = "0.8.0 2019-01-05"; //node-red lib version | ||
var LIBRARY_VERSION = "0.9.0"; //node-red lib version | ||
var LIBRARY_DATE = "2019-03-19"; //node-red lib version | ||
var RECONNECT_TIMEOUT = 5; //number of seconds for reconnection when disconnected or socket error | ||
@@ -51,3 +54,3 @@ //blynk util | ||
tmp_pins[i] = +tmp_pins[i]; | ||
if(Number.isInteger(tmp_pins[i]) && Number.parseInt(tmp_pins[i])>=0 && Number.parseInt(tmp_pins[i])<=127) { | ||
if(Number.isInteger(tmp_pins[i]) && Number.parseInt(tmp_pins[i])>=0 && Number.parseInt(tmp_pins[i])<=255) { | ||
this.log_pins.push(tmp_pins[i].toString()); | ||
@@ -63,3 +66,5 @@ } | ||
this.LIBRARY_INFO = LIBRARY_INFO; | ||
this.LIBRARY_VERSION = LIBRARY_VERSION; | ||
this.LIBRARY_DATE = LIBRARY_DATE; | ||
this.RECONNECT_TIMEOUT = RECONNECT_TIMEOUT; | ||
this.RED = RED; | ||
@@ -72,4 +77,2 @@ | ||
this.setMaxListeners(100); | ||
@@ -80,15 +83,11 @@ | ||
if (node.logged) { | ||
//var t = getTimestamp(); | ||
//if( t - node.last_heart_beat > BLYNK_HEARTBEAT ) { | ||
node.ping(); | ||
// } | ||
// else{ | ||
// if (node.dbg_low) { | ||
// node.log("no " + t + " - "+node.last_heart_beat+" "+node.last_activity_in+" "+node.last_activity_out); | ||
// } | ||
// } | ||
var now = getTimestamp(); | ||
var diff= now - node.last_heart_beat; | ||
//node.log("PING " + now + " - " + diff + " - "+node.last_heart_beat+" "+node.last_activity_in+" "+node.last_activity_out); | ||
if (diff >= blynkLib.BLYNK_HEARTBEAT){ | ||
node.ping(); | ||
} | ||
} | ||
}, blynkLib.BLYNK_HEARTBEAT * 1000); | ||
}, 1000); | ||
this.closing = false; | ||
this.msgList = {}; | ||
@@ -155,3 +154,2 @@ var node = this; | ||
node.last_heart_beat = node.last_activity_in = node.last_activity_out = getTimestamp(); | ||
//node.log(node.last_heart_beat+" "+node.last_activity_in+" "+node.last_activity_out); | ||
@@ -170,3 +168,3 @@ websocket.on("open", function() { | ||
startconn(); | ||
}, 5000); // try to reconnect every 5 secs... bit fast ? | ||
}, node.RECONNECT_TIMEOUT * 1000); // try to reconnect | ||
} | ||
@@ -203,3 +201,3 @@ }); | ||
websocket.on("error", function(err) { | ||
node.error("Websocket error: " + err); | ||
node.error("Websocket " + err); | ||
node.emit("error"); | ||
@@ -211,3 +209,3 @@ node.logged = false; | ||
startconn(); | ||
}, 5000); // try to reconnect every 5 secs... bit fast ? | ||
}, node.RECONNECT_TIMEOUT * 1000); // try to reconnect | ||
} | ||
@@ -223,3 +221,5 @@ }); | ||
node.logged = false; | ||
node.websocket.close(); | ||
if(node.websocket) { | ||
node.websocket.close(); | ||
} | ||
if (node.tout) { | ||
@@ -230,2 +230,16 @@ clearTimeout(node.tout); | ||
node.on("error", function() { | ||
// Workaround https://github.com/einaros/ws/pull/253 | ||
// Remove listeners from RED.server | ||
node.log("Client Error") | ||
node.closing = true; | ||
node.logged = false; | ||
if(node.websocket) { | ||
node.websocket.close(); | ||
} | ||
if (node.tout) { | ||
clearTimeout(node.tout); | ||
} | ||
}); | ||
//test enabled check | ||
@@ -232,0 +246,0 @@ if(this.enabled) { |
@@ -70,7 +70,7 @@ module.exports = function(RED) { | ||
if (msg.hasOwnProperty("payload") && msg.hasOwnProperty("topic")) { | ||
if (msg.hasOwnProperty("payload") || msg.hasOwnProperty("topic")) { | ||
var topic = RED.util.ensureString(msg.topic); | ||
//virtualwrite to node | ||
if (topic != 'write-property' ) { | ||
if (topic != "write-property" ) { | ||
var payload = RED.util.ensureString(msg.payload); | ||
@@ -90,3 +90,3 @@ if(payload === "true") payload = "1"; | ||
var pin = node.pin; | ||
//multiple property by code | ||
@@ -119,4 +119,6 @@ var msgkey = undefined; | ||
} | ||
else if (msg.hasOwnProperty("urls") && Array.isArray(msg.urls)) { | ||
node.blynkClient.setProperty(pin, "urls", msg.urls, msgkey); | ||
} | ||
if(node.blynkClient.multi_cmd) { | ||
@@ -123,0 +125,0 @@ node.blynkClient.sendMsgMulti(msgkey); |
@@ -79,4 +79,4 @@ module.exports = function(RED) { | ||
} | ||
if(msg.pin<0 || msg.pin>127) { | ||
node.warn("Bridge node - The msg.pin must be between 0 and 127."); | ||
if(msg.pin<0 || msg.pin>255) { | ||
node.warn("Bridge node - The msg.pin must be between 0 and 255."); | ||
return; | ||
@@ -83,0 +83,0 @@ } |
@@ -63,3 +63,3 @@ module.exports = function(RED) { | ||
if(node.pin<0 || node.pin>127) { | ||
if(node.pin<0 || node.pin>255) { | ||
node.warn(RED._("blynk-ws-out-lcd.warn.pin-value")); | ||
@@ -66,0 +66,0 @@ return; |
@@ -75,3 +75,3 @@ module.exports = function(RED) { | ||
} | ||
if(msg.pin<0 || msg.pin>127) { | ||
if(msg.pin<0 || msg.pin>255) { | ||
node.warn(RED._("blynk-ws-out-set-property.warn.pin-value")); | ||
@@ -123,4 +123,4 @@ return; | ||
if ((msg.hasOwnProperty("onColor") || msg.hasOwnProperty("offColor") || | ||
msg.hasOwnProperty("onBackColor") || msg.hasOwnProperty("offBackColor")) | ||
) { | ||
msg.hasOwnProperty("onBackColor") || msg.hasOwnProperty("offBackColor")) | ||
) { | ||
if (msg.hasOwnProperty("onColor")) { | ||
@@ -182,2 +182,5 @@ node.blynkClient.setProperty(pin, "onColor", RED.util.ensureString(msg.onColor), msgkey); | ||
} | ||
else if (msg.hasOwnProperty("urls") && Array.isArray(msg.urls)) { | ||
node.blynkClient.setProperty(pin, "urls", msg.urls, msgkey); | ||
} | ||
@@ -184,0 +187,0 @@ |
@@ -64,3 +64,3 @@ module.exports = function(RED) { | ||
if(node.pin<0 || node.pin>127) { | ||
if(node.pin<0 || node.pin>255) { | ||
node.warn(RED._("blynk-ws-out-table.warn.pin-value")); | ||
@@ -67,0 +67,0 @@ return; |
@@ -72,4 +72,4 @@ module.exports = function(RED) { | ||
} | ||
if(msg.pin<0 || msg.pin>127) { | ||
node.warn("Write node - The msg.pin must be between 0 and 127."); | ||
if(msg.pin<0 || msg.pin>255) { | ||
node.warn("Write node - The msg.pin must be between 0 and 255."); | ||
return; | ||
@@ -76,0 +76,0 @@ } |
@@ -12,3 +12,3 @@ { | ||
"pin-dinamic":"Set Property node - Setting \"pin mode\" to \"dynamic\" but no msg.pin found.", | ||
"pin-value":"Set Property node - The msg.pin must be between 0 and 127.", | ||
"pin-value":"Set Property node - The msg.pin must be between 0 and 255.", | ||
"property":"Set Property node - Please select a property.", | ||
@@ -15,0 +15,0 @@ "zergba":"Warning - zeRGBa not configured in merge mode." |
@@ -13,3 +13,3 @@ { | ||
"pin-dinamic":"Bridge node - Setting \"pin mode\" to \"dynamic\" but no msg.pin found.", | ||
"pin-value":"Bridge node - The msg.pin must be between 0 and 127." | ||
"pin-value":"Bridge node - The msg.pin must be between 0 and 255." | ||
}, | ||
@@ -16,0 +16,0 @@ "errors": { |
@@ -12,3 +12,3 @@ { | ||
"payload":"## Blynk LCD node does not use the msg.payload property! ## You must use the property msg.text or msg.text1 to write to the first or second line.", | ||
"pin-value":"LCD node - The msg.pin must be between 0 and 127." | ||
"pin-value":"LCD node - The msg.pin must be between 0 and 255." | ||
}, | ||
@@ -15,0 +15,0 @@ "errors": { |
@@ -13,3 +13,3 @@ { | ||
"pin-dinamic":"Set Property node - Setting \"pin mode\" to \"dynamic\" but no msg.pin found.", | ||
"pin-value":"Set Property node - The msg.pin must be between 0 and 127.", | ||
"pin-value":"Set Property node - The msg.pin must be between 0 and 255.", | ||
"property":"Set Property node - Please select a property." | ||
@@ -16,0 +16,0 @@ }, |
@@ -13,3 +13,3 @@ { | ||
"pin-dinamic":"Sync node - Setting \"pin mode\" to \"dynamic\" but no msg.pin found.", | ||
"pin-value":"Sync node - The msg.pin must be between 0 and 127." | ||
"pin-value":"Sync node - The msg.pin must be between 0 and 255." | ||
}, | ||
@@ -16,0 +16,0 @@ "errors": { |
@@ -12,3 +12,3 @@ { | ||
"payload":"## Blynk Table node does not use the msg.payload property! ## See node help.", | ||
"pin-value":"Table node - The msg.pin must be between 0 and 127." | ||
"pin-value":"Table node - The msg.pin must be between 0 and 255." | ||
}, | ||
@@ -15,0 +15,0 @@ "errors": { |
@@ -13,3 +13,3 @@ { | ||
"pin-dinamic":"Write node - Setting \"pin mode\" to \"dynamic\" but no msg.pin found.", | ||
"pin-value":"Write node - The msg.pin must be between 0 and 127." | ||
"pin-value":"Write node - The msg.pin must be between 0 and 255." | ||
}, | ||
@@ -16,0 +16,0 @@ "errors": { |
{ | ||
"name": "node-red-contrib-blynk-ws", | ||
"version": "0.8.0", | ||
"version": "0.9.0", | ||
"description": "Node Red integration with Blynk App and Server through websockets", | ||
@@ -5,0 +5,0 @@ "scripts": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
177239
2602