Merge pull request #45 from MycroftAI/test
Ability to show and apply Pantacor software updatespull/57/head
commit
3813c24529
|
@ -28,6 +28,7 @@ const routes: Routes = [
|
|||
{ path: 'dashboard', component: DashboardComponent, resolve: {account: AccountResolverService} },
|
||||
{ path: 'maintenance', component: MaintenancePageComponent},
|
||||
{ path: '', redirectTo: '/dashboard', pathMatch: 'full'},
|
||||
{ path: 'pair', redirectTo: '/devices/add', pathMatch: 'full'},
|
||||
{ path: '**', component: PageNotFoundComponent }
|
||||
];
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ const deviceUrl = '/api/devices';
|
|||
const geographyUrl = 'api/geographies';
|
||||
const pairingCodeUrl = '/api/pairing-code';
|
||||
const preferencesUrl = '/api/preferences';
|
||||
const softwareUpdateUrl = '/api/software-update';
|
||||
const voicesUrl = '/api/voices';
|
||||
const wakeWordUrl = '/api/wake-words';
|
||||
|
||||
|
@ -100,4 +101,8 @@ export class DeviceService {
|
|||
getWakeWords() {
|
||||
return this.http.get<DeviceAttribute[]>(wakeWordUrl);
|
||||
}
|
||||
|
||||
applySoftwareUpdate(pantacorUpdateId: string) {
|
||||
return this.http.patch<any>(softwareUpdateUrl, {deploymentId: pantacorUpdateId});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,18 @@
|
|||
[value]="getPlatform(device)"
|
||||
>
|
||||
</account-display-field>
|
||||
<account-display-field
|
||||
<account-display-field *ngIf="device.platform === 'mycroft_mark_1'"
|
||||
[label]="'Enclosure Version'"
|
||||
[value]="device.enclosureVersion"
|
||||
>
|
||||
</account-display-field>
|
||||
<account-display-field *ngIf="device.platform === 'mycroft_mark_2'"
|
||||
[label]="'Hardware Version'"
|
||||
[value]="device.enclosureVersion"
|
||||
>
|
||||
</account-display-field>
|
||||
<account-display-field
|
||||
[label]="'Core Version'"
|
||||
[label]="'Mycroft Version'"
|
||||
[value]="device.coreVersion"
|
||||
>
|
||||
</account-display-field>
|
||||
|
@ -26,6 +31,14 @@
|
|||
[value]="device.pantacorConfig.ipAddress"
|
||||
>
|
||||
</account-display-field>
|
||||
<button
|
||||
mat-flat-button
|
||||
*ngIf="device.pantacorConfig.autoUpdate === false" (click)="applySoftwareUpdate()"
|
||||
fxFlex
|
||||
[disabled]="softwareUpdateDisabled"
|
||||
>
|
||||
{{softwareUpdateText}}
|
||||
</button>
|
||||
</mat-card-content>
|
||||
</mat-tab>
|
||||
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
@import "~@angular/material/theming";
|
||||
@import 'mycroft-colors';
|
||||
@import 'components/buttons';
|
||||
|
||||
mat-tab-group {
|
||||
mat-card-content {
|
||||
margin-top: 32px;
|
||||
height: 180px;
|
||||
button {
|
||||
@include action-button-primary;
|
||||
background-color: mat-color($mycroft-accent, 'A100');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,10 +17,13 @@ and limitations under the License.
|
|||
***************************************************************************** */
|
||||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
|
||||
|
||||
import { faInfoCircle, faCog, faMapMarkerAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { Device } from '@account/models/device.model';
|
||||
import { DeviceService } from '@account/http/device.service';
|
||||
import { SnackbarComponent } from 'shared';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-info',
|
||||
|
@ -38,10 +41,22 @@ export class DeviceDisplayComponent implements OnInit {
|
|||
public infoIcon = faInfoCircle;
|
||||
public configIcon = faCog;
|
||||
public locationIcon = faMapMarkerAlt;
|
||||
public softwareUpdateText: string;
|
||||
public softwareUpdateDisabled: boolean;
|
||||
|
||||
constructor() { }
|
||||
constructor(
|
||||
private deviceService: DeviceService,
|
||||
private snackbar: MatSnackBar
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.device.pantacorUpdateId) {
|
||||
this.softwareUpdateText = 'NO UPDATES AVAILABLE';
|
||||
this.softwareUpdateDisabled = true;
|
||||
} else {
|
||||
this.softwareUpdateText = 'APPLY SOFTWARE UPDATE';
|
||||
this.softwareUpdateDisabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
getPlatform(device: Device) {
|
||||
|
@ -49,4 +64,29 @@ export class DeviceDisplayComponent implements OnInit {
|
|||
return knownPlatform ? knownPlatform.displayName : device.platform;
|
||||
}
|
||||
|
||||
openErrorSnackbar() {
|
||||
const config = new MatSnackBarConfig();
|
||||
config.data = {type: 'error', message: 'An error occurred, device will not be updated.'};
|
||||
this.snackbar.openFromComponent(SnackbarComponent, config);
|
||||
}
|
||||
|
||||
openSuccessSnackbar() {
|
||||
const config = new MatSnackBarConfig();
|
||||
config.duration = 3000;
|
||||
config.data = {type: 'success', message: 'The update will be applied to your device momentarily'};
|
||||
this.snackbar.openFromComponent(SnackbarComponent, config);
|
||||
}
|
||||
|
||||
applySoftwareUpdate() {
|
||||
this.deviceService.applySoftwareUpdate(this.device.pantacorUpdateId).subscribe(
|
||||
() => {
|
||||
this.openSuccessSnackbar();
|
||||
this.softwareUpdateText = 'NO UPDATES AVAILABLE';
|
||||
this.softwareUpdateDisabled = true;
|
||||
|
||||
},
|
||||
() => { this.openErrorSnackbar(); }
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,9 +37,17 @@
|
|||
<account-geography-card [geoForm]="deviceForm" [required]="true"></account-geography-card>
|
||||
<account-voice-card [voiceForm]="deviceForm"></account-voice-card>
|
||||
<account-wake-word-card [wakeWordForm]="deviceForm"></account-wake-word-card>
|
||||
<account-software-release-card [softwareReleaseForm]="deviceForm"></account-software-release-card>
|
||||
<account-software-update-card [softwareUpdateForm]="deviceForm"></account-software-update-card>
|
||||
<account-ssh-card [sshForm]="deviceForm"></account-ssh-card>
|
||||
<account-software-release-card
|
||||
*ngIf="pantacorId"
|
||||
[softwareReleaseForm]="deviceForm"
|
||||
>
|
||||
</account-software-release-card>
|
||||
<account-software-update-card
|
||||
*ngIf="pantacorId"
|
||||
[softwareUpdateForm]="deviceForm"
|
||||
>
|
||||
</account-software-update-card>
|
||||
<account-ssh-card *ngIf="pantacorId" [sshForm]="deviceForm"></account-ssh-card>
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions *ngIf=!addDevice align="right">
|
||||
|
|
|
@ -27,6 +27,7 @@ import { FormGroup } from '@angular/forms';
|
|||
export class DeviceEditCardComponent implements OnInit {
|
||||
@Input() deviceForm: FormGroup;
|
||||
@Input() addDevice = false;
|
||||
@Input() pantacorId: string;
|
||||
@Output() saveChanges = new EventEmitter<boolean>();
|
||||
|
||||
constructor() { }
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
*ngIf="device$ | async"
|
||||
[deviceForm]="deviceForm"
|
||||
[addDevice]="false"
|
||||
[pantacorId]="pantacorId"
|
||||
(saveChanges)="onExit($event)"
|
||||
>
|
||||
</account-device-edit-card>
|
||||
|
|
|
@ -38,6 +38,7 @@ export class DeviceEditComponent implements OnInit {
|
|||
public deviceForm: FormGroup;
|
||||
private deviceId: string;
|
||||
public device$ = new Observable<Device>();
|
||||
public pantacorId: string;
|
||||
private snackbarConfig = new MatSnackBarConfig();
|
||||
|
||||
constructor(
|
||||
|
@ -57,6 +58,7 @@ export class DeviceEditComponent implements OnInit {
|
|||
switchMap((params: ParamMap) => this.deviceService.getDevice(params.get('deviceId'))),
|
||||
tap((device) => {
|
||||
this.deviceId = device.id;
|
||||
this.pantacorId = device.pantacorConfig.pantacorId;
|
||||
this.buildDeviceForm(device);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
fxLayoutAlign="start center"
|
||||
routerLink="/devices/add"
|
||||
>
|
||||
<img src="../assets/generic-device-icon-blue.svg">
|
||||
<img src="../assets/generic-device-icon-white.svg">
|
||||
<span fxFlex class="mat-h2">ADD DEVICE</span>
|
||||
<fa-icon class="mat-h2" [icon]="addIcon"></fa-icon>
|
||||
</div>
|
||||
|
@ -49,9 +49,6 @@
|
|||
<button mat-flat-button color="warn" (click)="onRemove(device, i)">
|
||||
REMOVE
|
||||
</button>
|
||||
<button mat-flat-button color="accent" [disabled]="true" (click)="onRemove(device, i)">
|
||||
UPDATE
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
|
||||
img {
|
||||
height: 32px;
|
||||
height: 48px;
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,6 @@ export class DeviceListComponent implements OnInit {
|
|||
|
||||
getDeviceIcon(device: Device) {
|
||||
const knownPlatform = this.platforms[device.platform];
|
||||
return knownPlatform ? knownPlatform.icon : '../assets/generic-device-icon-white.svg';
|
||||
return knownPlatform ? knownPlatform.icon : '../assets/generic-device-icon-blue.svg';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,5 @@ export interface Device {
|
|||
voice: Voice;
|
||||
wakeWord: WakeWord;
|
||||
pantacorConfig: PantacorConfig;
|
||||
pantacorUpdateId: string;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ and limitations under the License.
|
|||
***************************************************************************** */
|
||||
|
||||
export interface PantacorConfig {
|
||||
autoUpdate: string;
|
||||
autoUpdate: boolean;
|
||||
ipAddress: string;
|
||||
pantacorId: string;
|
||||
sshPublicKey: string;
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="60" height="60" fill="#22A7F0"/>
|
||||
<rect x="19" y="11" width="22" height="38" rx="8" fill="white"/>
|
||||
<rect x="16.5" y="8.5" width="27" height="43" rx="9.5" stroke="white"/>
|
||||
<line x1="30" y1="38" x2="30" y2="22" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="33" y1="35" x2="33" y2="25" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="24" y1="32" x2="24" y2="28" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="27" y1="35" x2="27" y2="25" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="36" y1="32" x2="36" y2="28" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#5B6984;}
|
||||
.st1{fill:none;stroke:#5B6984;}
|
||||
.st2{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linecap:round;}
|
||||
</style>
|
||||
<path class="st0" d="M49,27v6c0,4.4-3.6,8-8,8H19c-4.4,0-8-3.6-8-8v-6c0-4.4,3.6-8,8-8h22C45.4,19,49,22.6,49,27z"/>
|
||||
<path class="st1" d="M51.5,26v8c0,5.2-4.3,9.5-9.5,9.5H18c-5.2,0-9.5-4.3-9.5-9.5v-8c0-5.2,4.3-9.5,9.5-9.5h24
|
||||
C47.2,16.5,51.5,20.8,51.5,26z"/>
|
||||
<line class="st2" x1="30" y1="38" x2="30" y2="22"/>
|
||||
<line class="st2" x1="33" y1="35" x2="33" y2="25"/>
|
||||
<line class="st2" x1="24" y1="32" x2="24" y2="28"/>
|
||||
<line class="st2" x1="27" y1="35" x2="27" y2="25"/>
|
||||
<line class="st2" x1="36" y1="32" x2="36" y2="28"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 771 B After Width: | Height: | Size: 1.0 KiB |
|
@ -1,10 +1,18 @@
|
|||
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="60" height="60" fill="white"/>
|
||||
<rect x="19" y="11" width="22" height="38" rx="8" fill="#5B6984"/>
|
||||
<rect x="16.5" y="8.5" width="27" height="43" rx="9.5" stroke="#5B6984"/>
|
||||
<line x1="30" y1="38" x2="30" y2="22" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="33" y1="35" x2="33" y2="25" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="24" y1="32" x2="24" y2="28" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="27" y1="35" x2="27" y2="25" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="36" y1="32" x2="36" y2="28" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:none;stroke:#FFFFFF;}
|
||||
.st2{fill:#FFFFFF;stroke:#5B6984;stroke-width:2;stroke-linecap:round;}
|
||||
</style>
|
||||
<path class="st0" d="M49,27v6c0,4.4-3.6,8-8,8H19c-4.4,0-8-3.6-8-8v-6c0-4.4,3.6-8,8-8h22C45.4,19,49,22.6,49,27z"/>
|
||||
<path class="st1" d="M51.5,26v8c0,5.2-4.3,9.5-9.5,9.5H18c-5.2,0-9.5-4.3-9.5-9.5v-8c0-5.2,4.3-9.5,9.5-9.5h24
|
||||
C47.2,16.5,51.5,20.8,51.5,26z"/>
|
||||
<line class="st2" x1="30" y1="38" x2="30" y2="22"/>
|
||||
<line class="st2" x1="33" y1="35" x2="33" y2="25"/>
|
||||
<line class="st2" x1="24" y1="32" x2="24" y2="28"/>
|
||||
<line class="st2" x1="27" y1="35" x2="27" y2="25"/>
|
||||
<line class="st2" x1="36" y1="32" x2="36" y2="28"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 1.0 KiB |
|
@ -1,6 +1,55 @@
|
|||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.52 29.8869C19.4771 30.5082 19.3766 31.1241 19.22 31.7269C19.2264 31.7532 19.2264 31.7806 19.22 31.8069C19.0677 32.3492 18.8874 32.8832 18.68 33.4069C18.57 33.6669 18.43 33.9369 18.29 34.1969C18.1326 34.4505 17.9554 34.6913 17.76 34.9169C17.5849 35.1432 17.3676 35.3334 17.12 35.4769C16.8678 35.6114 16.5858 35.6802 16.3 35.6769H3.53C3.24706 35.683 2.96756 35.614 2.72 35.4769C2.46971 35.3332 2.2491 35.1432 2.07 34.9169C1.88106 34.6909 1.71052 34.4501 1.56 34.1969C1.4 33.9369 1.28 33.6669 1.16 33.4069C1.02759 33.1247 0.914004 32.8341 0.820001 32.5369C0.820001 32.5369 0.700001 32.1169 0.650001 31.8969C0.650001 31.8369 0.43 30.7269 0.39 30.1369C0.0600003 25.3569 0 11.2269 0 11.2269C0 5.42689 3.17 0.00689305 9.88 0.00689305C11.2703 -0.0466351 12.655 0.212137 13.9321 0.764182C15.2092 1.31623 16.3464 2.14751 17.26 3.19689C18.9775 5.33145 19.8781 8.00826 19.8 10.7469C19.8 10.7469 19.89 25.1869 19.52 29.8869Z" transform="translate(10 2)" stroke="#6C7A89" stroke-width="0.75" stroke-linejoin="round"/>
|
||||
<path d="M13.8432 19.94C13.8432 19.53 13.8432 19.11 13.8432 18.69V9.77C13.8432 9.62333 13.8432 9.47667 13.8432 9.33C13.8432 4.4 12.9932 0 7.00319 0C0.81319 0 0.00318953 4.47 0.00318953 9.45V19.06C0.00318953 19.49 0.00318953 19.93 0.00318953 20.35C-0.0288053 22.0015 0.180056 23.6488 0.623189 25.24C1.34319 27.77 3.15319 29.53 6.84319 29.59C12.8432 29.69 13.7332 25.01 13.7832 19.96L13.8432 19.94Z" transform="translate(13.0469 5.1167)" fill="#6C7A89"/>
|
||||
<path d="M0.380812 1.96426C0.323184 1.96438 0.266283 1.9514 0.214414 1.92628C0.162545 1.90117 0.117067 1.86459 0.0814202 1.81931C0.0457737 1.77403 0.0208922 1.72123 0.00865958 1.66492C-0.00357306 1.6086 -0.00283688 1.55025 0.010812 1.49426C0.122676 1.06626 0.373284 0.687426 0.723414 0.417047C1.07354 0.146667 1.50344 0 1.94581 0C2.38819 0 2.81808 0.146667 3.16821 0.417047C3.51834 0.687426 3.76895 1.06626 3.88081 1.49426C3.89446 1.55025 3.8952 1.6086 3.88296 1.66492C3.87073 1.72123 3.84585 1.77403 3.8102 1.81931C3.77456 1.86459 3.72908 1.90117 3.67721 1.92628C3.62534 1.9514 3.56844 1.96438 3.51081 1.96426C3.42466 1.96216 3.34163 1.93158 3.27469 1.87731C3.20775 1.82303 3.16067 1.74812 3.14081 1.66426C3.072 1.40106 2.91787 1.1681 2.70255 1.00184C2.48722 0.835573 2.22286 0.745385 1.95081 0.745385C1.67877 0.745385 1.4144 0.835573 1.19908 1.00184C0.983753 1.1681 0.829625 1.40106 0.760812 1.66426C0.74095 1.74812 0.693873 1.82303 0.626934 1.87731C0.559995 1.93158 0.476964 1.96216 0.390812 1.96426H0.380812Z" transform="translate(14.4189 15.1528)" fill="white"/>
|
||||
<path d="M0.380812 1.96426C0.323184 1.96438 0.266282 1.9514 0.214413 1.92628C0.162544 1.90117 0.117066 1.86459 0.0814196 1.81931C0.0457732 1.77403 0.0208927 1.72123 0.00866002 1.66492C-0.00357263 1.6086 -0.0028374 1.55025 0.0108115 1.49426C0.122675 1.06626 0.373284 0.687426 0.723414 0.417047C1.07354 0.146667 1.50344 0 1.94581 0C2.38819 0 2.81808 0.146667 3.16821 0.417047C3.51834 0.687426 3.76895 1.06626 3.88081 1.49426C3.89446 1.55025 3.8952 1.6086 3.88296 1.66492C3.87073 1.72123 3.84585 1.77403 3.8102 1.81931C3.77456 1.86459 3.72908 1.90117 3.67721 1.92628C3.62534 1.9514 3.56844 1.96438 3.51081 1.96426C3.42466 1.96216 3.34163 1.93158 3.27469 1.87731C3.20775 1.82303 3.16067 1.74812 3.14081 1.66426C3.072 1.40106 2.91787 1.1681 2.70255 1.00184C2.48722 0.835573 2.22286 0.745385 1.95081 0.745385C1.67877 0.745385 1.4144 0.835573 1.19908 1.00184C0.983753 1.1681 0.829625 1.40106 0.760812 1.66426C0.74095 1.74812 0.693872 1.82303 0.626933 1.87731C0.559994 1.93158 0.476965 1.96216 0.390813 1.96426H0.380812Z" transform="translate(21.6191 15.1528)" fill="white"/>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 59.8 59.8" style="enable-background:new 0 0 59.8 59.8;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:none;stroke:#5B6984;stroke-width:1.2057;}
|
||||
.st1{fill:none;stroke:#5B6984;stroke-width:0.9546;}
|
||||
.st2{fill:#5B6984;}
|
||||
.st3{fill:none;stroke:#FFFFFF;stroke-width:2.2255;stroke-linecap:round;}
|
||||
</style>
|
||||
<path class="st0" d="M45.3,50.6H14.7c-2.9,0-5.2-2.3-5.2-5.2V14.8c0-2.9,2.3-5.2,5.2-5.2h30.6c2.9,0,5.2,2.3,5.2,5.2v30.6
|
||||
C50.5,48.3,48.2,50.6,45.3,50.6z"/>
|
||||
<path class="st1" d="M45.3,35.3H14.7c-2.9,0-5.2-2.3-5.2-5.2V14.8c0-2.9,2.3-5.2,5.2-5.2h30.6c2.9,0,5.2,2.3,5.2,5.2v15.3
|
||||
C50.5,33,48.2,35.3,45.3,35.3z"/>
|
||||
<path class="st2" d="M44,33.7H16c-2.3,0-4.1-1.8-4.1-4.1V15.9c0-2.3,1.8-4.1,4.1-4.1H44c2.3,0,4.1,1.8,4.1,4.1v13.7
|
||||
C48.1,31.9,46.2,33.7,44,33.7z"/>
|
||||
<g>
|
||||
<circle class="st2" cx="14" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="17.5" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="14" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="17.5" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="15.8" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="19.3" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="21.1" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="21.1" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="22.8" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="24.6" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="24.6" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="26.4" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="28.1" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="28.1" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="29.9" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="31.7" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="31.7" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="33.4" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="35.2" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="35.2" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="37" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="38.7" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="38.7" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="40.5" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="42.3" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="42.3" cy="45.2" r="0.9"/>
|
||||
<circle class="st2" cx="44" cy="42.2" r="0.9"/>
|
||||
<circle class="st2" cx="45.8" cy="39.1" r="0.9"/>
|
||||
<circle class="st2" cx="45.8" cy="45.2" r="0.9"/>
|
||||
</g>
|
||||
<g>
|
||||
<line class="st3" x1="30" y1="31.6" x2="30" y2="13.8"/>
|
||||
<line class="st3" x1="33.3" y1="28.3" x2="33.3" y2="17.2"/>
|
||||
<line class="st3" x1="23.3" y1="25" x2="23.3" y2="20.5"/>
|
||||
<line class="st3" x1="26.7" y1="28.3" x2="26.7" y2="17.2"/>
|
||||
<line class="st3" x1="36.7" y1="25" x2="36.7" y2="20.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.8 KiB |
Loading…
Reference in New Issue