diff --git a/arduino/eps8266RFID/eps8266RFID.ino b/arduino/esp8266RFID/esp8266RFID.ino similarity index 70% rename from arduino/eps8266RFID/eps8266RFID.ino rename to arduino/esp8266RFID/esp8266RFID.ino index 2f69b3e6..8546f34c 100644 --- a/arduino/eps8266RFID/eps8266RFID.ino +++ b/arduino/esp8266RFID/esp8266RFID.ino @@ -33,18 +33,17 @@ * SPI SCK SCK D5 13 / ICSP-3 52 D13 ICSP-3 15 */ +#include #include #include -#include +#define ESP8266 1 #include +#include // https://github.com/tzapu/WiFiManager -#ifndef STASSID -#define STASSID "HUAWEI-B535-07AA" -#define STAPSK "rozar97431" -#endif - -#define SERVER_IP "192.168.8.100:3000" +// #define SERVER_IP "192.168.8.100:3000" +// #define SERVER_IP "192.168.30.136:3000" +#define SERVER_IP "192.168.43.172:3000" // #define RST_PIN 9 // Configurable, see typical pin layout above // #define SS_PIN 10 // Configurable, see typical pin layout above @@ -58,49 +57,61 @@ MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance -const char *ssid = STASSID; -const char *password = STAPSK; +// const char *ssid = STASSID; +// const char *password = STAPSK; // byte newUid[4] = {0x71, 0x85, 0x13, 0x09}; +bool initialisation = true; + void setup() { Serial.begin(115200); // Initialize serial communications with the PC while (!Serial) ; // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4) - delay(5000); + delay(2000); Serial.println("Begin setup"); - // Serial.println("D3"); - // Serial.println(D3); - // Serial.println("D4"); - // Serial.println(D4); SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 delay(4); // Optional delay. Some board do need more time after init to be ready, see Readme mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks...")); - Serial.println(); - Serial.println(); - Serial.print("Connecting to "); - Serial.println(ssid); - /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default, would try to act as both a client and an access-point and could cause network-issues with your other WiFi-devices on your WiFi-network. */ WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) + // WiFiManager, Local intialization. Once its business is done, + // there is no need to keep it around + WiFiManager wm; + + // Configure a static IP address for the ESP card in Access Point mode + // wm.setAPStaticIPConfig(ip, gateway, subnet); + wm.setAPStaticIPConfig(IPAddress(192, 168, 5, 1), + IPAddress(192, 168, 5, 1), + IPAddress(255, 255, 255, 0)); + + //reset settings - wipe credentials for testing + wm.resetSettings(); + + // Automatically connect using saved credentials, + // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"), + // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect()) + // then goes into a blocking loop awaiting configuration and will return success result + + bool res = wm.autoConnect("AutoConnectAP"); // anonymous ap + + if (!res) { - delay(500); - Serial.print("."); + Serial.println("Failed to connect"); + // ESP.restart(); + } + else + { + //if you get here you have connected to the WiFi + Serial.println("connected...yeey :)"); } - - Serial.println(""); - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); Serial.println("End setup"); } @@ -109,20 +120,8 @@ String getUID(MFRC522::Uid *uid) { String res = ""; - // Serial.print(F("Card UID:")); for (byte i = 0; i < uid->size; i++) { - // if (uid->uidByte[i] < 0x10) - // { - // // Serial.print(F(" 0")); - // res += F(" 0"); - // } - // else - // { - // // Serial.print(F(" ")); - // res += F(" "); - // } - // Serial.print(uid->uidByte[i], HEX); res += String(uid->uidByte[i], HEX); } return res; @@ -130,6 +129,12 @@ String getUID(MFRC522::Uid *uid) void loop() { + if (initialisation) + { + Serial.println("IP address: " + WiFi.localIP().toString()); + initialisation = !initialisation; + } + // Serial.println("Begin loop"); // delay(1000); // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. @@ -145,7 +150,7 @@ void loop() } // wait for WiFi connection - if ((WiFi.status() == WL_CONNECTED)) + if (WiFi.status() == WL_CONNECTED) { WiFiClient client; @@ -153,12 +158,18 @@ void loop() Serial.print("[HTTP] begin...\n"); // configure traged server and url - http.begin(client, "http://" SERVER_IP "/postplain/"); //HTTP + String serverEndPoint = "http://" SERVER_IP "/postplain/"; + Serial.print("[HTTP] serverEndPoint: " + serverEndPoint + "\n"); + http.setReuse(true); + http.begin(client, serverEndPoint); http.addHeader("Content-Type", "application/json"); - Serial.print("[HTTP] BEFORE POST\n"); // start connection and send HTTP header and body - int httpCode = http.POST("{\"uid\":" + getUID(&(mfrc522.uid)) + "}"); + String message = "{\"uid\":" + getUID(&(mfrc522.uid)) + "}"; + Serial.print("[HTTP] message: " + message + "\n"); + int httpCode = http.POST(message); + String payload = http.getString(); + Serial.print("[HTTP] payload: " + payload + "\n"); // httpCode will be negative on error if (httpCode > 0) @@ -168,7 +179,8 @@ void loop() } else { - Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str()); + Serial.printf("[POST FAILED] httpCode: %d\n", httpCode); + Serial.printf("[POST FAILED] error: %s\n", http.errorToString(httpCode).c_str()); } http.end(); diff --git a/arduino/olimex_128x64_koch_snowflake/.gitignore b/arduino/olimex_128x64_koch_snowflake/.gitignore new file mode 100644 index 00000000..89cc49cb --- /dev/null +++ b/arduino/olimex_128x64_koch_snowflake/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/arduino/olimex_128x64_koch_snowflake/include/README b/arduino/olimex_128x64_koch_snowflake/include/README new file mode 100644 index 00000000..194dcd43 --- /dev/null +++ b/arduino/olimex_128x64_koch_snowflake/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/arduino/olimex_128x64_koch_snowflake/lib/README b/arduino/olimex_128x64_koch_snowflake/lib/README new file mode 100644 index 00000000..6debab1e --- /dev/null +++ b/arduino/olimex_128x64_koch_snowflake/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/arduino/olimex_128x64_koch_snowflake/platformio.ini b/arduino/olimex_128x64_koch_snowflake/platformio.ini new file mode 100644 index 00000000..be9a0bcf --- /dev/null +++ b/arduino/olimex_128x64_koch_snowflake/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 +framework = arduino +monitor_speed = 115200 +lib_deps = + adafruit/Adafruit SSD1306@^2.4.4 + tectiv3/Adafruit-SSD1331@0.0.0-alpha+sha.488737cb7a diff --git a/arduino/olimex_128x64_koch_snowflake/src/main.cpp b/arduino/olimex_128x64_koch_snowflake/src/main.cpp new file mode 100644 index 00000000..9027e346 --- /dev/null +++ b/arduino/olimex_128x64_koch_snowflake/src/main.cpp @@ -0,0 +1,251 @@ +/************************************************************************** + This is an example for our Monochrome OLEDs based on SSD1306 drivers + + Pick one up today in the adafruit shop! + ------> http://www.adafruit.com/category/63_98 + + This example is for a 128x64 pixel display using I2C to communicate + 3 pins are required to interface (two I2C and one reset). + + Adafruit invests time and resources providing this open + source code, please support Adafruit and open-source + hardware by purchasing products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries, + with contributions from the open source community. + BSD license, check license.txt for more information + All text above, and the splash screen below must be + included in any redistribution. + **************************************************************************/ + +#include +#include +#include +#include +#include + +#define SCREEN_WIDTH 128 // OLED display width, in pixels +#define SCREEN_HEIGHT 64 // OLED display height, in pixels + +// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) +// The pins for I2C are defined by the Wire-library. +// On an arduino UNO: A4(SDA), A5(SCL) +// On an arduino MEGA 2560: 20(SDA), 21(SCL) +// On an arduino LEONARDO: 2(SDA), 3(SCL), ... +#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 +#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) + +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); + +void rotVec2(float vec[2], float alpha, float *vecRot) +{ + float x = vec[0]; + float y = vec[1]; + float xRot = x * cos(alpha) - y * sin(alpha); + float yRot = x * sin(alpha) + y * cos(alpha); + vecRot[0] = xRot; + vecRot[1] = yRot; +} + +const int nbExtremyties = 5; +const int dim = 2; +const int16_t yMax = SCREEN_HEIGHT - 1; + +void nextKochSnoflake(float x0Screen, + float y0Screen, + float x1Screen, + float y1Screen, + float ptPath[nbExtremyties][dim]) +{ + float x0Cart = x0Screen; + float x1Cart = x1Screen; + float y0Cart = -y0Screen + yMax; + float y1Cart = -y1Screen + yMax; + + float vect[2] = {x1Cart - x0Cart, y1Cart - y0Cart}; + float alpha = atan2(vect[1], vect[0]); + float vectLen = sqrt(vect[0] * vect[0] + vect[1] * vect[1]); + float xLen = vectLen; + float xInc = xLen / 3; + float yMid = sqrt(3) / 2 * xInc; + + float v[4][2] = {{xInc, 0}, + {xInc / 2, yMid}, + {xInc / 2, -yMid}, + {xInc, 0}}; + + float vRot[4][2] = {{0, 0}, + {0, 0}, + {0, 0}, + {0, 0}}; + + for (int i = 0; i < 4; ++i) + { + rotVec2(v[i], alpha, vRot[i]); + } + + // Flip y to adapt screen coordinate system + for (int i = 0; i < 4; ++i) + { + vRot[i][1] = -vRot[i][1]; + } + + ptPath[0][0] = x0Screen; + ptPath[0][1] = y0Screen; + for (int i = 0; i < 4; ++i) + { + ptPath[i + 1][0] = ptPath[i][0] + vRot[i][0]; + ptPath[i + 1][1] = ptPath[i][1] + vRot[i][1]; + } +} + +int sumNbSegment(int order) +{ + if (order < 1) + { + return 1; + } + else + { + int sum = 0; + for (int i = 0; i < order; ++i) + { + sum += pow(4, i); + } + return sum; + } +} + +void kochSnowflake(int16_t x0Screen, + int16_t y0Screen, + int16_t x1Screen, + int16_t y1Screen, + int order) +{ + display.clearDisplay(); + + printf("order %d\n", order); + const int totalNbSegment = sumNbSegment(order); + // printf("totalNbSegment %d\n", totalNbSegment); + + int nbSegmentPerOrder[order]; + for (int i = 0; i < order; ++i) + { + nbSegmentPerOrder[i] = pow(4, i); + // printf("nbSegmentPerOrder[%d]: %d\n", i, nbSegmentPerOrder[i]); + } + + int parentMapping[totalNbSegment][2]; + for (int j = 1; j < totalNbSegment; ++j) + { + int toSub = 0; + int currentTotal = 0; + int iBreak = 0; + for (int i = 0; i < order; ++i) + { + currentTotal += nbSegmentPerOrder[i]; + if (j < currentTotal) + { + toSub = currentTotal - nbSegmentPerOrder[i]; + iBreak = std::max(i - 1, 0); + break; + } + } + int idxParentOffset = 0; + for (int i = 0; i < iBreak; ++i) + { + idxParentOffset += nbSegmentPerOrder[i]; + } + + int jNormalised = (j - toSub); + int quot = jNormalised / 4; + int parentIdx = quot + idxParentOffset; + int subIdx = jNormalised % 4; + parentMapping[j][0] = parentIdx; + parentMapping[j][1] = subIdx; + } + // printf("\n"); + + // Initialisation of path points + float ptPath[totalNbSegment][nbExtremyties][dim]; + nextKochSnoflake(x0Screen, + y0Screen, + x1Screen, + y1Screen, ptPath[0]); + + for (int j = 1; j < totalNbSegment; ++j) + { + + const int parentIdx = parentMapping[j][0]; + const int subIdx = parentMapping[j][1]; + nextKochSnoflake(ptPath[parentIdx][subIdx][0], + ptPath[parentIdx][subIdx][1], + ptPath[parentIdx][subIdx + 1][0], + ptPath[parentIdx][subIdx + 1][1], + ptPath[j]); + } + + int jStart = 0; + int jEnd = 0; + for (int i = 0; i < order; ++i) + { + if (i < (order - 1)) + { + jStart += nbSegmentPerOrder[i]; + } + jEnd += nbSegmentPerOrder[i]; + } + + for (int j = jStart; j < jEnd; ++j) + { + for (int i = 0; i < 4; ++i) + { + const int16_t i0 = i; + const int16_t i1 = i0 + 1; + display.drawLine(ptPath[j][i0][0], ptPath[j][i0][1], + ptPath[j][i1][0], ptPath[j][i1][1], SSD1306_WHITE); + display.display(); + delay(100); + } + } +} + +void setup() +{ + Serial.begin(115200); + + while (!Serial) + ; + + // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally + if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) + { + Serial.println(F("SSD1306 allocation failed")); + for (;;) + ; // Don't proceed, loop forever + } + + int16_t x0Screen; + int16_t x1Screen; + int16_t y0Screen; + int16_t y1Screen; + for (;;) + { + x0Screen = 1; + x1Screen = x0Screen + 42 * 3; + y0Screen = yMax - 14; + y1Screen = y0Screen - 0; + for (int i = 1; i < 4; ++i) + { + kochSnowflake(x0Screen, + y0Screen, + x1Screen, + y1Screen, i); + delay(1000); + } + } +} + +void loop() +{ +} diff --git a/arduino/olimex_128x64_koch_snowflake/test/README b/arduino/olimex_128x64_koch_snowflake/test/README new file mode 100644 index 00000000..b94d0890 --- /dev/null +++ b/arduino/olimex_128x64_koch_snowflake/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/arduino/readSensor/readSensor.ino b/arduino/readSensor/readSensor.ino new file mode 100644 index 00000000..1b4a5d78 --- /dev/null +++ b/arduino/readSensor/readSensor.ino @@ -0,0 +1,78 @@ +/* + Analog Input + + Demonstrates analog input by reading an analog sensor on analog pin 0 and + turning on and off a light emitting diode(LED) connected to digital pin 13. + The amount of time the LED will be on and off depends on the value obtained + by analogRead(). + + The circuit: + - potentiometer + center pin of the potentiometer to the analog input 0 + one side pin (either one) to ground + the other side pin to +5V + - LED + anode (long leg) attached to digital output 13 + cathode (short leg) attached to ground + + - Note: because most Arduinos have a built-in LED attached to pin 13 on the + board, the LED is optional. + + created by David Cuartielles + modified 30 Aug 2011 + By Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/AnalogInput +*/ + +int sensorPin = A0; // select the input pin for the potentiometer +int ledPin = 13; // select the pin for the LED +int sensorValue = 0; // variable to store the value coming from the sensor + +String commande; +char commandeRecu; + +void setup() { + Serial.begin(9600); + // declare the ledPin as an OUTPUT: + // pinMode(ledPin, OUTPUT); + Serial.println("Setup done"); + + // initialize digital pin LED_BUILTIN as an output. + pinMode(LED_BUILTIN, OUTPUT); +} + +void loop() { + // read the value from the sensor: + sensorValue = analogRead(sensorPin); + Serial.println(sensorValue); + + while (Serial.available() > 0){ + commande = Serial.readString(); + // Serial.println("WHILE : [" + commande + "]"); + delay(200); + } + + if(commande == "co") { + //digitalWrite(13, HIGH); + // Serial.println("allumer"); + + // turn the LED on (HIGH is the voltage level) + digitalWrite(LED_BUILTIN, HIGH); + delay(2000); + } + else { + // turn the LED off by making the voltage LOW + digitalWrite(LED_BUILTIN, LOW); + // Serial.println("éteind"); + + // turn LED off + //digitalWrite(13, LOW); + delay(500); + } + commande = ""; + + //delay(500); +} diff --git a/arduino/sendSerialPort/sendSerialPort.ino b/arduino/sendSerialPort/sendSerialPort.ino new file mode 100644 index 00000000..aa8933e0 --- /dev/null +++ b/arduino/sendSerialPort/sendSerialPort.ino @@ -0,0 +1,75 @@ +/* + Button + Turns on and off a light emitting diode(LED) + connected to digital pin 13, when pressing a + pushbutton attached to pin 2. + + The circuit: + * LED attached from pin 13 to ground + * pushbutton attached to pin 2 from +5V + * 10K resistor attached to pin 2 from ground + * Note: on most Arduinos there is already an LED + on the board attached to pin 13. + + created 2005 by DojoDave http://www.0j0.org/ + + modified 30 Aug 2011 by Tom Igoe + + This example code is in the public domain. + http://www.arduino.cc/en/Tutorial/Button +*/ + +int buttonState = 0; +String commande; +char commandeRecu; +void setup() +{ + Serial.begin(9600); + pinMode(2, INPUT); + pinMode(13, OUTPUT); +} + +void loop() +{ + // read the state of the pushbutton value + buttonState = digitalRead(2); + // check if pushbutton is pressed. if it is, the + // buttonState is HIGH + while (Serial.available() > 0){ + + commande = Serial.readString(); + Serial.println("WHILE : [" + commande + "]"); + + } + + if(commande == "coca") { + digitalWrite(13, HIGH); + Serial.println("allumer"); + + delay(1000); + + digitalWrite(13, LOW); + Serial.println("eteint"); + + delay(1000); + + digitalWrite(13, HIGH); + Serial.println("allumer"); + + delay(1000); + + digitalWrite(13, LOW); + Serial.println("eteint"); + + Serial.println("ENDIF : " + commande); + } + else { + // turn LED off + digitalWrite(13, LOW); + // commande=""; + //Serial.print("ici"); + // Serial.println("ELSE : " + commande); + } + commande = ""; + +} diff --git a/arduino/wifiManagerBasic/Basic.ino b/arduino/wifiManagerBasic/Basic.ino new file mode 100644 index 00000000..e372d8c3 --- /dev/null +++ b/arduino/wifiManagerBasic/Basic.ino @@ -0,0 +1,52 @@ +#include +// #include +#define ESP8266 1 +#include // https://github.com/tzapu/WiFiManager + +void setup() +{ + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP + + // put your setup code here, to run once: + Serial.begin(115200); + + // WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it. + + //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wm; + + // Configure a static IP address for the ESP card in Access Point mode + // wm.setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn); + wm.setAPStaticIPConfig(IPAddress(192, 168, 5, 1), IPAddress(192, 168, 5, 0), IPAddress(255, 255, 255, 0)); + + //reset settings - wipe credentials for testing + wm.resetSettings(); + + // Automatically connect using saved credentials, + // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"), + // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect()) + // then goes into a blocking loop awaiting configuration and will return success result + + bool res; + // res = wm.autoConnect(); // auto generated AP name from chipid + res = wm.autoConnect("AutoConnectAP"); // anonymous ap + // res = wm.autoConnect("AutoConnectAP", "password"); // password protected ap + + if (!res) + { + Serial.println("Failed to connect"); + // ESP.restart(); + } + else + { + //if you get here you have connected to the WiFi + Serial.println("connected...yeey :)"); + } +} + +void loop() +{ + // put your main code here, to run repeatedly: + Serial.println("loop"); + delay(10000); +} diff --git a/clojurescript/hello-shadow-cljs/package-lock.json b/clojurescript/hello-shadow-cljs/package-lock.json index 61ef9dd2..34041f9c 100644 --- a/clojurescript/hello-shadow-cljs/package-lock.json +++ b/clojurescript/hello-shadow-cljs/package-lock.json @@ -961,9 +961,9 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.21", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", - "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" + "version": "0.7.28", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", + "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==" }, "ultron": { "version": "1.1.1",