diff --git a/BootstrapBlazor.Extensions.slnx b/BootstrapBlazor.Extensions.slnx index 35ea650eb..57c918ed3 100644 --- a/BootstrapBlazor.Extensions.slnx +++ b/BootstrapBlazor.Extensions.slnx @@ -27,7 +27,6 @@ - @@ -42,7 +41,6 @@ - @@ -53,7 +51,6 @@ - @@ -75,7 +72,6 @@ - @@ -84,8 +80,8 @@ - + diff --git a/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor b/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor deleted file mode 100644 index e99257f2b..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor +++ /dev/null @@ -1,6 +0,0 @@ -@namespace BootstrapBlazor.Components - -@if (Debug) -{ -

-}
diff --git a/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor.cs b/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor.cs
deleted file mode 100644
index e4232af0a..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// ********************************** 
-// Densen Informatica 中讯科技 
-// 作者:Alex Chow
-// e-mail:zhouchuanglin@gmail.com 
-// **********************************
-
-using Microsoft.AspNetCore.Components;
-using Microsoft.JSInterop;
-using System.Diagnostics.CodeAnalysis;
-
-namespace BootstrapBlazor.Components;
-
-/// 
-/// 蓝牙设备 BT BatteryLevel 组件
-/// 
-public partial class BatteryLevel : IAsyncDisposable
-{
-    [Inject]
-    [NotNull]
-    private IJSRuntime? JSRuntime { get; set; }
-
-    private IJSObjectReference? Module { get; set; }
-    private DotNetObjectReference? Instance { get; set; }
-
-    /// 
-    /// UI界面元素的引用对象
-    /// 
-    public ElementReference Element { get; set; }
-
-    /// 
-    /// 获得/设置 蓝牙设备
-    /// 
-    [Parameter]
-    public BluetoothDevice? Device { get; set; } = new BluetoothDevice();
-
-    /// 
-    /// 获得/设置 状态更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateStatus { get; set; }
-
-    /// 
-    /// 获得/设置 数值更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateValue { get; set; }
-
-    /// 
-    /// 获得/设置 错误更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateError { get; set; }
-
-    /// 
-    /// 获得/设置 显示log
-    /// 
-    [Parameter]
-    public bool Debug { get; set; }
-
-    protected override async Task OnAfterRenderAsync(bool firstRender)
-    {
-        try
-        {
-            if (firstRender)
-            {
-                Device ??= new BluetoothDevice();
-                Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.Bluetooth/BatteryLevel.razor.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
-                Instance = DotNetObjectReference.Create(this);
-                //await Module.InvokeVoidAsync("getBatteryLevel", InstanceBatteryLevel, BatteryLevelElement);
-            }
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    /// 
-    /// 查询电量
-    /// 
-    public virtual async Task GetBatteryLevel()
-    {
-        try
-        {
-            await Module!.InvokeVoidAsync("getBatteryLevel", Instance, Element);
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    async ValueTask IAsyncDisposable.DisposeAsync()
-    {
-        Instance?.Dispose();
-        if (Module is not null)
-        {
-            await Module.DisposeAsync();
-        }
-    }
-
-    /// 
-    /// 设备名称回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateDevicename(string devicename)
-    {
-        Device!.Name = devicename;
-        if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(Device);
-    }
-
-    /// 
-    /// 设备电量%回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateValue(decimal value)
-    {
-        Device!.Value = value;
-        if (OnUpdateValue != null) await OnUpdateValue.Invoke(value);
-    }
-
-    /// 
-    /// 状态更新回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateStatus(string status)
-    {
-        Device!.Status = status;
-        if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(Device);
-    }
-
-    /// 
-    /// 错误更新回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateError(string status)
-    {
-        if (OnUpdateError != null) await OnUpdateError.Invoke(status);
-    }
-
-}
diff --git a/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor.js b/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor.js
deleted file mode 100644
index 8f51cccab..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/BatteryLevel.razor.js
+++ /dev/null
@@ -1,48 +0,0 @@
-export function getBatteryLevel(wrapper, element) {
-    if (!element.id) element = document;
-    const log = element.querySelector("[data-action=log]"); 
-    getBatteryLevel();
-    async function getBatteryLevel() {
-        try {
-            logII('Requesting Bluetooth Device...');
-            const device = await navigator.bluetooth.requestDevice({
-                filters: [{ services: ['battery_service', 'heart_rate'] }]
-            });
-            wrapper.invokeMethodAsync('UpdateDevicename', device.name);
-
-            logII('Connecting to GATT Server...');
-            const server = await device.gatt.connect();
-
-            wrapper.invokeMethodAsync('UpdateStatus', 'Getting Battery Service...');
-            logII('Getting Battery Service...');
-            const service = await server.getPrimaryService('battery_service');
-
-            logII('Getting Battery Level Characteristic...');
-            const characteristic = await service.getCharacteristic('battery_level');
-
-            logII('Reading Battery Level...');
-            const value = await characteristic.readValue();
-
-            logII('> Battery Level is ' + value.getUint8(0) + '%');
-
-            wrapper.invokeMethodAsync('UpdateValue', value.getUint8(0));
-
-        } catch (error) {
-            logErr('Argh! ' + error);
-        }
-    }
-
-
-    function logII(info) {
-        if (log) log.textContent += info + '\n';
-        console.log(info);
-        wrapper.invokeMethodAsync('UpdateStatus', info);
-    }
-
-    function logErr(info) {
-        if (log) log.textContent += info + '\n';
-        console.log(info);
-        wrapper.invokeMethodAsync('UpdateError', info);
-    }
-
-}
\ No newline at end of file
diff --git a/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor b/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor
deleted file mode 100644
index e99257f2b..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor
+++ /dev/null
@@ -1,6 +0,0 @@
-@namespace BootstrapBlazor.Components
-
-@if (Debug)
-{
-    

-}
diff --git a/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor.cs b/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor.cs
deleted file mode 100644
index 756c4e139..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor.cs
+++ /dev/null
@@ -1,228 +0,0 @@
-// ********************************** 
-// Densen Informatica 中讯科技 
-// 作者:Alex Chow
-// e-mail:zhouchuanglin@gmail.com 
-// **********************************
-
-using Microsoft.AspNetCore.Components;
-using Microsoft.JSInterop;
-using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
-
-namespace BootstrapBlazor.Components;
-
-/// 
-/// 蓝牙通知 BleNotification 组件
-/// 
-public partial class BleNotification : IAsyncDisposable
-{
-    [Inject]
-    [NotNull]
-    private IJSRuntime? JSRuntime { get; set; }
-
-    private IJSObjectReference? Module { get; set; }
-    private DotNetObjectReference? Instance { get; set; }
-
-    /// 
-    /// UI界面元素的引用对象
-    /// 
-    public ElementReference Element { get; set; }
-
-    /// 
-    /// 获得/设置 蓝牙设备
-    /// 
-    [Parameter]
-    public BluetoothDevice? Device { get; set; } = new BluetoothDevice();
-
-    /// 
-    /// 获得/设置 状态更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateStatus { get; set; }
-
-    /// 
-    /// 获得/设置 数值更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateValue { get; set; }
-
-    /// 
-    /// 获得/设置 错误更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateError { get; set; }
-
-    /// 
-    /// 获得/设置 显示log
-    /// 
-    [Parameter]
-    public bool Debug { get; set; }
-
-    /// 
-    /// 自动连接设备
-    /// 
-    [Parameter]
-    [DisplayName("自动连接设备")]
-    public bool AutoConnect { get; set; }
-
-    /// 
-    /// 自动补全, 否则为转数字格式
-    /// 
-    [Parameter]
-    [DisplayName("自动补全, 否则为转数字格式")]
-    public bool AutomaticComplement { get; set; }
-
-    /// 
-    /// 显示扫描结果
-    /// 
-    [Parameter]
-    [DisplayName("显示扫描结果")]
-    public bool AdvertisementReceived { get; set; }
-
-    /// 
-    /// 服务UUID / Service UUID
-    /// 
-    [Parameter]
-    [DisplayName("服务UUID / Service UUID")]
-    public object? ServiceUuid { get; set; } = "heart_rate";
-
-    /// 
-    /// 特征UUID / Characteristic UUID
-    /// 
-    /// 
-    [Parameter]
-    [DisplayName("特征UUID / Characteristic UUID")]
-    public object? CharacteristicUuid { get; set; } = "heart_rate_measurement";
-
-    protected override async Task OnAfterRenderAsync(bool firstRender)
-    {
-        try
-        {
-            if (firstRender)
-            {
-                Device ??= new BluetoothDevice();
-                Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.Bluetooth/BleNotification.razor.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
-                Instance = DotNetObjectReference.Create(this);
-            }
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    /// 
-    /// 获取蓝牙低功耗设备BLE的特征通知
-    /// 
-    public virtual async Task GetNotification(object? serviceUuid, object? characteristicUuid, bool autoConnect, bool automaticComplement, bool advertisementReceived)
-    {
-        ServiceUuid = serviceUuid;
-        CharacteristicUuid = characteristicUuid;
-        AutoConnect = autoConnect;
-        AutomaticComplement = automaticComplement;
-        AdvertisementReceived = advertisementReceived;
-        await GetNotification();
-    }
-
-    /// 
-    /// 获取蓝牙低功耗设备BLE的特征通知
-    /// 
-    public virtual async Task GetNotification()
-    {
-        try
-        {
-            await Module!.InvokeVoidAsync("notification", Instance, Element, "getNotification", ServiceUuid, CharacteristicUuid, AutoConnect, AutomaticComplement, AdvertisementReceived);
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    /// 
-    /// 停止监听BLE的特征通知
-    /// 
-    public virtual async Task StopNotification()
-    {
-        try
-        {
-            await Module!.InvokeVoidAsync("notification", Instance, Element, "stopNotification");
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    /// 
-    /// 停止监听BLE的特征通知
-    /// 
-    public virtual async Task Scan()
-    {
-        try
-        {
-            await Module!.InvokeVoidAsync("scan", Instance);
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    async ValueTask IAsyncDisposable.DisposeAsync()
-    {
-        Instance?.Dispose();
-        if (Module is not null)
-        {
-            await Module.DisposeAsync();
-        }
-    }
-
-    /// 
-    /// 设备名称回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateDevicename(string devicename)
-    {
-        Device!.Name = devicename;
-        if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(Device);
-    }
-
-    /// 
-    /// 设备特征通知回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateValue(string value)
-    {
-        Device!.ValueRAW = value;
-        if (OnUpdateValue != null) await OnUpdateValue.Invoke(value);
-    }
-
-    /// 
-    /// 状态更新回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateStatus(string status)
-    {
-        Device!.Status = status;
-        if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(Device);
-    }
-
-    /// 
-    /// 错误更新回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateError(string status)
-    {
-        if (OnUpdateError != null) await OnUpdateError.Invoke(status);
-    }
-
-}
diff --git a/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor.js b/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor.js
deleted file mode 100644
index 4db4bcf10..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/BleNotification.razor.js
+++ /dev/null
@@ -1,224 +0,0 @@
-let device, myCharacteristic;
-
-export function notification(wrapper, element, callfunction = null, serviceUuid = 'heart_rate', characteristicUuid = 'heart_rate_measurement', autoConnect = false, automaticComplement = false, advertisementReceived =false) {
-    if (!element.id) element = document;
-    const log = element.querySelector("[data-action=log]");
-    const notificationValue = document.querySelector("[data-action=notificationValue]");
-
-    if (callfunction && callfunction == "stopNotification") {
-        console.log('stopNotification');
-        stopNotification();
-        return;
-    }
-
-    getNotification();
-
-    async function getNotification() {
-        if (notificationValue) notificationValue.innerHTML = '--';
-        serviceUuid = checkUUID(serviceUuid, automaticComplement);
-        characteristicUuid = checkUUID(characteristicUuid, automaticComplement); 
-        try {
-            let devices = await navigator.bluetooth.getDevices();
-            if (devices.length > 0) {
-                if (autoConnect) {
-                    device = devices[0];
-                    console.log("自动连接设备", device);
-                    logII(`自动连接设备 ${device.name}`);
-                }
-                logII(`获取到授权设备: ${devices.length}`);
-            }
-        } catch (error) {
-            logErr('Argh! ' + error);
-        }
-
-        try {
-            if (!device) {
-                logII(`Requesting Bluetooth Device... ${serviceUuid}`);
-                try {
-
-                    device = await navigator.bluetooth.requestDevice({
-                        filters: [{ services: [serviceUuid] }]
-                    });
-                } catch (error) {
-                    device = null;
-                    logErr('Argh! ' + error);
-                    return;
-                }
-            }
-
-            if (advertisementReceived) {
-                const abortController = new AbortController();
-                device.addEventListener('advertisementreceived', (event) => {
-                    logII('Advertisement received.');
-                    // Stop watching advertisements to conserve battery life.
-                    abortController.abort();
-                    logII('  Device Name: ' + event.device.name);
-                    logII('  Device ID: ' + event.device.id);
-                    logII('  RSSI: ' + event.rssi);
-                    logII('  TX Power: ' + event.txPower);
-                    logII('  UUIDs: ' + event.uuids);
-                    event.manufacturerData.forEach((valueDataView, key) => {
-                        logDataView('Manufacturer', key, valueDataView);
-                    });
-                    event.serviceData.forEach((valueDataView, key) => {
-                        logDataView('Service', key, valueDataView);
-                    });
-                });
-
-                logII('Watching advertisements from "' + device.name + '"...');
-                await device.watchAdvertisements({ signal: abortController.signal }); 
-            }
-
-            wrapper.invokeMethodAsync('UpdateDevicename', device.name);
-
-            logII(`${device.name}`);
-            logII('Connecting to GATT Server...');
-            const server = await device.gatt.connect();
-
-            wrapper.invokeMethodAsync('UpdateStatus', 'Getting Service...');
-            logII('Getting Service...');
-            const service = await server.getPrimaryService(serviceUuid);
-
-            logII('Getting Characteristic...');
-            myCharacteristic = await service.getCharacteristic(characteristicUuid);
-
-            await myCharacteristic.startNotifications();
-
-            logII('> Notifications started');
-            myCharacteristic.addEventListener('characteristicvaluechanged',
-                handleNotifications);
-        } catch (error) {
-            logErr('Argh! ' + error);
-        }
-    }
-
-    function checkUUID(uuid, automaticComplement) {
-        if (uuid.startsWith('0x')) {
-            if (!automaticComplement) {
-                try {
-                    uuid = parseInt(uuid);
-                } catch (error) {
-                    uuid = uuid.replace('0x', '0000') + '-0000-1000-8000-00805f9b34fb';
-                }
-            } else {
-                uuid = uuid.replace('0x', '0000') + '-0000-1000-8000-00805f9b34fb';
-            }
-        }
-        return uuid;
-    }
-
-    async function stopNotification() {
-        device = null;
-        if (myCharacteristic) {
-            try {
-                await myCharacteristic.stopNotifications();
-                logII('> Notifications stopped');
-                myCharacteristic.removeEventListener('characteristicvaluechanged',
-                    handleNotifications);
-            } catch (error) {
-                logErr('Argh! ' + error);
-            }
-        }
-    }
-
-    function handleNotifications(event) {
-        let value = event.target.value;
-        let a = [];
-        // 将原始数据字节转换为十六进制值只是为了显示某些内容。
-        // 在“真实”世界中,您可以使用 data.get Uint8、data.get Uint16 甚至
-        // 文本解码器处理原始数据字节。
-        for (let i = 0; i < value.byteLength; i++) {
-            a.push('0x' + ('00' + value.getUint8(i).toString(16)).slice(-2));
-        }
-        let result = a.join(' ');
-        wrapper.invokeMethodAsync('UpdateValue', result);
-        logII('> ' + result);
-        if (result) notificationValue.innerHTML = result;
-    }
-
-    function logII(info) {
-        if (log) log.textContent += info + '\n';
-        console.log(info);
-        wrapper.invokeMethodAsync('UpdateStatus', info);
-    }
-
-    function logErr(info) {
-        if (log) log.textContent += info + '\n';
-        console.log(info);
-        wrapper.invokeMethodAsync('UpdateError', info);
-    }
-
-}
-
-/* Utils */
-
-const logDataView = (labelOfDataSource, key, valueDataView) => {
-    const hexString = [...new Uint8Array(valueDataView.buffer)].map(b => {
-        return b.toString(16).padStart(2, '0');
-    }).join(' ');
-    const textDecoder = new TextDecoder('ascii');
-    const asciiString = textDecoder.decode(valueDataView.buffer);
-    console.log(`  ${labelOfDataSource} Data: ` + key +
-        '\n    (Hex) ' + hexString +
-        '\n    (ASCII) ' + asciiString);
-};
-
-export async function scan(wrapper,allAdvertisements=true, filterName = null, filterNamePrefix=null,) {
-    let filters = [];
-
-    if (filterName) {
-        filters.push({ name: filterName });
-    }
-
-    if (filterNamePrefix) {
-        filters.push({ namePrefix: filterNamePrefix });
-    }
-
-    let options = {};
-    if (allAdvertisements) {
-        options.acceptAllAdvertisements = true;
-    } else {
-        options.filters = filters;
-    }
-
-    try {
-        logII('Requesting Bluetooth Scan with options: ' + JSON.stringify(options));
-        const scan = await navigator.bluetooth.requestLEScan(options);
-
-        logII('Scan started with:');
-        logII(' acceptAllAdvertisements: ' + scan.acceptAllAdvertisements);
-        logII(' active: ' + scan.active);
-        logII(' keepRepeatedDevices: ' + scan.keepRepeatedDevices);
-        logII(' filters: ' + JSON.stringify(scan.filters));
-
-        navigator.bluetooth.addEventListener('advertisementreceived', event => {
-            logII('Advertisement received.');
-            logII('  Device Name: ' + event.device.name);
-            logII('  Device ID: ' + event.device.id);
-            logII('  RSSI: ' + event.rssi);
-            logII('  TX Power: ' + event.txPower);
-            logII('  UUIDs: ' + event.uuids);
-            event.manufacturerData.forEach((valueDataView, key) => {
-                logDataView('Manufacturer', key, valueDataView);
-            });
-            event.serviceData.forEach((valueDataView, key) => {
-                logDataView('Service', key, valueDataView);
-            });
-        });
-
-        setTimeout(stopScan, 10000);
-        function stopScan() {
-            logII('Stopping scan...');
-            scan.stop();
-            logII('Stopped.  scan.active = ' + scan.active);
-        }
-    } catch (error) {
-        logII('Argh! ' + error);
-    }
-
-    function logII(info) {
-        console.log(info);
-        wrapper.invokeMethodAsync('UpdateStatus', info);
-    }
-
-}
\ No newline at end of file
diff --git a/src/components/BootstrapBlazor.Bluetooth/BluetoothDevice.cs b/src/components/BootstrapBlazor.Bluetooth/BluetoothDevice.cs
deleted file mode 100644
index 81ba74830..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/BluetoothDevice.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// ********************************** 
-// Densen Informatica 中讯科技 
-// 作者:Alex Chow
-// e-mail:zhouchuanglin@gmail.com 
-// **********************************
-
-namespace BootstrapBlazor.Components;
-
-/// 
-/// 蓝牙设备
-/// 
-public class BluetoothDevice
-{
-    /// 
-    /// 设备名称
-    /// 
-    public string? Name { get; set; }
-
-    /// 
-    /// 设备数值:例如心率/电量%
-    /// 
-    public decimal? Value { get; set; }
-
-    /// 
-    /// 设备原始数值
-    /// 
-    public string? ValueRAW { get; set; }
-
-    /// 
-    /// 状态
-    /// 
-    public string? Status { get; set; }
-
-    /// 
-    /// 错误
-    /// 
-    public string? Error { get; set; }
-
-}
diff --git a/src/components/BootstrapBlazor.Bluetooth/BootstrapBlazor.Bluetooth.csproj b/src/components/BootstrapBlazor.Bluetooth/BootstrapBlazor.Bluetooth.csproj
deleted file mode 100644
index b1a6cac49..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/BootstrapBlazor.Bluetooth.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-
- 
-
-  
-    Bootstrap Blazor Bluetooth /Printer Components 蓝牙和打印组件库
-    Bootstrap UI Bluetooth/Printer components experience
-  
-
-  
-    
-  
-
-  
-    
-  
-
-
diff --git a/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor b/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor
deleted file mode 100644
index e99257f2b..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor
+++ /dev/null
@@ -1,6 +0,0 @@
-@namespace BootstrapBlazor.Components
-
-@if (Debug)
-{
-    

-}
diff --git a/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor.cs b/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor.cs
deleted file mode 100644
index 8f36caa3d..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-// ********************************** 
-// Densen Informatica 中讯科技 
-// 作者:Alex Chow
-// e-mail:zhouchuanglin@gmail.com 
-// **********************************
-
-using Microsoft.AspNetCore.Components;
-using Microsoft.JSInterop;
-using System.Diagnostics.CodeAnalysis;
-
-namespace BootstrapBlazor.Components;
-
-/// 
-/// 蓝牙心率 Heartrate 组件
-/// 
-public partial class Heartrate : IAsyncDisposable
-{
-    [Inject]
-    [NotNull]
-    private IJSRuntime? JSRuntime { get; set; }
-
-    private IJSObjectReference? Module { get; set; }
-    private DotNetObjectReference? Instance { get; set; }
-
-    /// 
-    /// UI界面元素的引用对象
-    /// 
-    public ElementReference Element { get; set; }
-
-    /// 
-    /// 获得/设置 蓝牙设备
-    /// 
-    [Parameter]
-    public BluetoothDevice? Device { get; set; } = new BluetoothDevice();
-
-    /// 
-    /// 获得/设置 状态更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateStatus { get; set; }
-
-    /// 
-    /// 获得/设置 数值更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateValue { get; set; }
-
-    /// 
-    /// 获得/设置 错误更新回调方法
-    /// 
-    [Parameter]
-    public Func? OnUpdateError { get; set; }
-
-    /// 
-    /// 获得/设置 显示log
-    /// 
-    [Parameter]
-    public bool Debug { get; set; }
-
-    protected override async Task OnAfterRenderAsync(bool firstRender)
-    {
-        try
-        {
-            if (firstRender)
-            {
-                Device ??= new BluetoothDevice();
-                Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.Bluetooth/Heartrate.razor.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
-                Instance = DotNetObjectReference.Create(this);
-            }
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    /// 
-    /// 连接心率带
-    /// 
-    public virtual async Task GetHeartrate()
-    {
-        try
-        {
-            await Module!.InvokeVoidAsync("heartrate", Instance, Element, "getHeartrate");
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    /// 
-    /// 停止监听心率
-    /// 
-    public virtual async Task StopHeartrate()
-    {
-        try
-        {
-            await Module!.InvokeVoidAsync("heartrate", Instance, Element, "stopHeartrate");
-        }
-        catch (Exception e)
-        {
-            if (OnUpdateError != null) await OnUpdateError.Invoke(e.Message);
-        }
-    }
-
-    async ValueTask IAsyncDisposable.DisposeAsync()
-    {
-        Instance?.Dispose();
-        if (Module is not null)
-        {
-            await Module.DisposeAsync();
-        }
-    }
-
-    /// 
-    /// 设备名称回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateDevicename(string devicename)
-    {
-        Device!.Name = devicename;
-        if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(Device);
-    }
-
-    /// 
-    /// 设备心率回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateValue(int value)
-    {
-        Device!.Value = value;
-        if (OnUpdateValue != null) await OnUpdateValue.Invoke(value);
-    }
-
-    /// 
-    /// 状态更新回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateStatus(string status)
-    {
-        Device!.Status = status;
-        if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(Device);
-    }
-
-    /// 
-    /// 错误更新回调方法
-    /// 
-    /// 
-    /// 
-    [JSInvokable]
-    public async Task UpdateError(string status)
-    {
-        if (OnUpdateError != null) await OnUpdateError.Invoke(status);
-    }
-
-}
diff --git a/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor.js b/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor.js
deleted file mode 100644
index f0be5f6b1..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/Heartrate.razor.js
+++ /dev/null
@@ -1,129 +0,0 @@
-let heartrateIcon = '❤';
-let myCharacteristic;
-
-export function heartrate(wrapper, element, callfunction =null) {
-    if (!element.id) element = document;
-    const log = element.querySelector("[data-action=log]");
-    const heartrate = document.querySelector("[data-action=heartrate]");
-
-    if (callfunction && callfunction == "stopHeartrate") {
-        console.log('stopHeartrate');
-        stopHeartrate();
-        return;
-    }
-
-    getHeartrate();
-
-    async function getHeartrate() {
-        if (heartrate) heartrate.innerHTML = '--';
-        let serviceUuid = 'heart_rate';
-        let characteristicUuid = 'heart_rate_measurement';
-        if (characteristicUuid.startsWith('0x')) {
-            characteristicUuid = parseInt(characteristicUuid);
-        }
-
-        try {
-            logII('Requesting Bluetooth Device...', serviceUuid);
-            const device = await navigator.bluetooth.requestDevice({
-                filters: [{ services: [serviceUuid] }]
-            });
-            wrapper.invokeMethodAsync('UpdateDevicename', device.name);
-
-            logII('Connecting to GATT Server...');
-            const server = await device.gatt.connect();
-
-            wrapper.invokeMethodAsync('UpdateStatus', 'Getting Heartrate Service...');
-            logII('Getting Service...');
-            const service = await server.getPrimaryService(serviceUuid);
-
-            logII('Getting Characteristic...');
-            myCharacteristic = await service.getCharacteristic(characteristicUuid);
-
-            await myCharacteristic.startNotifications();
-
-            logII('> Notifications started');
-            myCharacteristic.addEventListener('characteristicvaluechanged',
-                handleNotifications);
-        } catch (error) {
-            logErr('Argh! ' + error);
-        }
-    }
-
-    async function stopHeartrate() {
-        if (myCharacteristic) {
-            try {
-                await myCharacteristic.stopNotifications();
-                logII('> Notifications stopped');
-                myCharacteristic.removeEventListener('characteristicvaluechanged',
-                    handleNotifications);
-            } catch (error) {
-                logErr('Argh! ' + error);
-            }
-        }
-    }
-
-    function handleNotifications(event) {
-        let value = event.target.value;
-        let heartRates = parseHeartRate(value).heartRate;
-        wrapper.invokeMethodAsync('UpdateValue', heartRates);
-        logII('> ' + heartRates);
-        if (heartRates == -1) {
-            heartrate.innerHTML = "error";
-        } else {
-            heartrateIcon = (heartrateIcon == '❤' ? '♥' : '❤');
-            if (heartrate) heartrate.innerHTML = heartrateIcon + heartRates;
-        }
-    }
-
-    function parseHeartRate(data) {
-        const result = {};
-
-        if (data.byteLength == 0) {
-            result.heartRate = -1;
-            return result;
-        }
-
-        const flags = data.getUint8(0);
-        const rate16Bits = flags & 0x1;
-        let index = 1;
-        if (rate16Bits) {
-            result.heartRate = data.getUint16(index, /*littleEndian=*/true);
-            index += 2;
-        } else {
-            result.heartRate = data.getUint8(index);
-            index += 1;
-        }
-        const contactDetected = flags & 0x2;
-        const contactSensorPresent = flags & 0x4;
-        if (contactSensorPresent) {
-            result.contactDetected = !!contactDetected;
-        }
-        const energyPresent = flags & 0x8;
-        if (energyPresent) {
-            result.energyExpended = data.getUint16(index, /*littleEndian=*/true);
-            index += 2;
-        }
-        const rrIntervalPresent = flags & 0x10;
-        if (rrIntervalPresent) {
-            const rrIntervals = [];
-            for (; index + 1 < data.byteLength; index += 2) {
-                rrIntervals.push(data.getUint16(index, /*littleEndian=*/true));
-            }
-            result.rrIntervals = rrIntervals;
-        }
-        return result;
-    } 
-
-    function logII(info) {
-        if (log) log.textContent += info + '\n';
-        console.log(info);
-        wrapper.invokeMethodAsync('UpdateStatus', info);
-    }
-
-    function logErr(info) {
-        if (log) log.textContent += info + '\n';
-        console.log(info);
-        wrapper.invokeMethodAsync('UpdateError', info);
-    }
-
-}
\ No newline at end of file
diff --git a/src/components/BootstrapBlazor.Bluetooth/Printer.razor b/src/components/BootstrapBlazor.Bluetooth/Printer.razor
deleted file mode 100644
index 2af41b618..000000000
--- a/src/components/BootstrapBlazor.Bluetooth/Printer.razor
+++ /dev/null
@@ -1,64 +0,0 @@
-@namespace BootstrapBlazor.Components
-
-@if (ShowUI)
-{
-    
- - -
- - - - - - -
- - -
-} -@if (Debug) -{ -

-}
-@if (ShowUI)
-{
-
-服务UUID/ServiceUUID, 默认0xff00
-
-常见打印机ServiceUUID:
-
-[通用型号/BMAU32/QR380A]
-0000ff00-0000-1000-8000-00805f9b34fb => 0xff00
-
-[InnerPrinter商米内置/BlueToothPrinter/FK-POSP58A+]
-e7810a71-73ae-499d-8c15-faa9aef0c3f2
-
-[HM-A300]
-0000fee7-0000-1000-8000-00805f9b34fb
-
-其他设备ServiceUUID:
-'heart_rate'
-0x1802
-0x1803
-
-} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.cs b/src/components/BootstrapBlazor.Bluetooth/Printer.razor.cs deleted file mode 100644 index 6fab67814..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.cs +++ /dev/null @@ -1,242 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -/// -/// 蓝牙打印机 BT Printer 组件 -/// -public partial class Printer : IAsyncDisposable -{ - [Inject] - [NotNull] - private IJSRuntime? JSRuntime { get; set; } - - private IJSObjectReference? Module { get; set; } - private DotNetObjectReference? Instance { get; set; } - - /// - /// UI界面元素的引用对象 - /// - public ElementReference Element { get; set; } - - /// - /// 获得/设置 打印按钮文字 默认为 打印 - /// - [Parameter] - [NotNull] - public string? PrintButtonText { get; set; } = "打印"; - - /// - /// 获得/设置 PrinterOption - /// - [Parameter] - public PrinterOption Opt { get; set; } = new PrinterOption(); - - /// - /// 打印指令 - /// - /// - [DisplayName("打印指令")] - public string? Commands { get; set; } = @"! 10 200 200 400 1 -BEEP 1 -PW 380 -SETMAG 1 1 -CENTER -TEXT 10 2 10 40 Micro Bar -TEXT 12 3 10 75 Blazor -TEXT 10 2 10 350 eMenu -B QR 30 150 M 2 U 7 -MA,https://google.com -ENDQR -FORM -PRINT -"; - - /// - /// 获得/设置 状态更新回调方法 - /// - [Parameter] - public Func? OnUpdateStatus { get; set; } - - /// - /// 获得/设置 错误更新回调方法 - /// - [Parameter] - public Func? OnUpdateError { get; set; } - - /// - /// 可用已配对设备列表 - /// - public List? Devices; - - /// - /// 获得/设置 显示内置UI - /// - [Parameter] - public bool ShowUI { get; set; } - - /// - /// 获得/设置 显示log - /// - [Parameter] - public bool Debug { get; set; } - - /// - /// 获得/设置 设备名称 - /// - [Parameter] - public string? Devicename { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - try - { - if (firstRender) - { - Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.Bluetooth/Printer.razor.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - await Module.InvokeVoidAsync("addScript", "./_content/BootstrapBlazor.Bluetooth/lib/gbk.min.js"); - Instance = DotNetObjectReference.Create(this); - //可选设置初始搜索设备名称前缀,默认null - //Opt.NamePrefix = "BMAU"; - //可选设置服务UUID/ServiceUUID,默认0xff00.[非空!] - //Opt.ServiceUuid = "e7810a71-73ae-499d-8c15-faa9aef0c3f2"; - //Opt.FiltersServices =new object[] { 0xff00, 0xfee7, "e7810a71-73ae-499d-8c15-faa9aef0c3f2" }; - Opt.ServiceUuid = Opt.ServiceUuid ?? 0xff00; - await Module.InvokeVoidAsync("printFunction", Instance, Element, Opt); - } - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 打印 - /// - public virtual async Task Print() - { - try - { - await Module!.InvokeVoidAsync("printFunction", Instance, Element, Opt, "write", Commands); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - async ValueTask IAsyncDisposable.DisposeAsync() - { - Instance?.Dispose(); - if (Module is not null) - { - await Module.DisposeAsync(); - } - } - - /// - /// 连接完成回调方法 - /// - /// - /// - /// - [JSInvokable] - public async Task GetResult(PrinterOption opt, string status) - { - try - { - Opt = opt; - if (OnResult != null) await OnResult.Invoke($"{opt.Devicename}{status}"); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 获得/设置 连接完成回调方法 - /// - [Parameter] - public Func? OnResult { get; set; } - - /// - /// 获取已配对设备回调方法 - /// - /// - /// - [JSInvokable] - public async Task GetDevices(List? devices) - { - try - { - Devices = devices; - if (OnGetDevices != null) await OnGetDevices.Invoke(devices); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 获得/设置 获取已配对设备回调方法 - /// - [Parameter] - public Func?, Task>? OnGetDevices { get; set; } - - /// - /// 连接指定已配对设备 - /// - public virtual async Task ConnectDevices(string? devicename = null) - { - try - { - if (devicename != null) Opt.Devicename = devicename; - await Module!.InvokeVoidAsync("connectdevice", Instance, Element, Opt, Commands); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 获得/设置 错误回调方法 - /// - [Parameter] - public Func? OnError { get; set; } - - /// - /// 状态更新回调方法 - /// - /// - /// - [JSInvokable] - public async Task UpdateStatus(string status) - { - if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(status); - } - - /// - /// 错误更新回调方法 - /// - /// - /// - [JSInvokable] - public async Task UpdateError(string status) - { - if (OnUpdateError != null) await OnUpdateError.Invoke(status); - } - -} diff --git a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.css b/src/components/BootstrapBlazor.Bluetooth/Printer.razor.css deleted file mode 100644 index c5237467f..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.css +++ /dev/null @@ -1,11 +0,0 @@ -.hidden { - display: none; -} - -.notSupported { - padding: 1em; - background-color: red; - color: white; - margin-top: 1em; - margin-bottom: 1em; -} diff --git a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.js b/src/components/BootstrapBlazor.Bluetooth/Printer.razor.js deleted file mode 100644 index 9bcd19e9d..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.js +++ /dev/null @@ -1,489 +0,0 @@ -export function addScript(url) { - let scriptsIncluded = false; - let scriptTags = document.querySelectorAll('head > script'); - scriptTags.forEach(scriptTag => { - if (scriptTag) { - let srcAttribute = scriptTag.getAttribute('src'); - if (srcAttribute && srcAttribute.startsWith(url)) { - scriptsIncluded = true; - return true; - } - } - }); - - if (scriptsIncluded) { - return true; - } - - let script = document.createElement('script'); - script.src = url; - document.head.appendChild(script); - return false; - -} - -let port; -let bluetoothDevice; -let serialWriter; -let myDescriptor; - -export function printFunction(wrapper, element, opt = null, callfunction = null, write = null) { - if (!element.id) element = document; - const log = element.querySelector("[data-action=log]"); - const btnConnect = element.querySelector("[data-action=btnConnect]"); - const btnwrite = element.querySelector("[data-action=btnwrite]"); - const btnwrite2 = element.querySelector("[data-action=btnwrite2]"); - const btnwriteR = element.querySelector("[data-action=btnwriteR]"); - const btnwriteQr = element.querySelector("[data-action=btnwriteQr]"); - const barcode = element.querySelector("[data-action=barcode]"); - const notSupportedSerial = element.querySelector("[data-action=notSupportedSerial]"); - const notSupportedBluetooth = element.querySelector("[data-action=notSupportedBluetooth]"); - const tools = element.querySelector("[data-action=tools]"); - const btnDisconnect = element.querySelector("[data-action=btnDisconnect]"); - const btnReconnect = element.querySelector("[data-action=btnReconnect]"); - const btnGetDevices = element.querySelector("[data-action=btnGetDevices]"); - const btnComConnect = element.querySelector("[data-action=btnComConnect]"); - const btnConnectdevice = element.querySelector("[data-action=btnConnectdevice]"); - const selectDevices = element.querySelector("[data-action=selectDevices]"); - const devicename = element.querySelector("[data-action=devicename]"); - const serviceUuid = element.querySelector("[data-action=serviceUuid]"); - - if (callfunction && callfunction == "write") { - console.log('start WriteChunk'); - WriteChunk(write); - return; - } else if (callfunction && callfunction == "connectdevice") { - console.log('start connect device:' + opt.devicename); - connectDevices(opt.devicename); - return; - } - - console.log('start printer'); - - - let cpcl = '! 10 200 200 400 1\r\n' + - 'BEEP 1\r\n' + - 'PW 380\r\n' + - 'SETMAG 1 1\r\n' + - 'CENTER\r\n' + - 'TEXT 10 2 10 40 Loranca Bar\r\n' + - 'TEXT 12 3 10 75 DaydayGO\r\n' + - 'TEXT 10 2 10 350 eMenu\r\n' + - 'B QR 30 150 M 2 U 7\r\n' + - 'MA,https://app1.es/1121\r\n' + - 'ENDQR\r\n' + - 'FORM\r\n' + - 'PRINT\r\n'; - - if (!opt) opt = { - "id": null, - "deviceID": null, - "devicename": null, - "serviceUuid": '0xff00', - "characteristicUuid": '0xff02', - "descriptorsUuid": null, - "maxChunk": 100, - "namePrefix": null - }; - - if (!callfunction) { - initBtprinter(); - if (btnGetDevices) - getDevices(); - } - function initBtprinter() { - console.log('start printer DOMContentLoaded'); - if (btnConnect) btnConnect.addEventListener("click", onConnect); - - if (btnGetDevices) btnGetDevices.addEventListener("pointerup", getDevices); - if (selectDevices) selectDevices.addEventListener("change", (event) => { - logII(event.target.value); - if (devicename) devicename.value = event.target.value; - opt.devicename = event.target.value; - //await connectDevices(opt.devicename) - }); - - if (btnwrite) btnwrite.addEventListener("click", () => { - let string = barcode.value.replace(/\n/g, '\r\n'); - WriteChunk(string); - }); - - if (btnwrite2) btnwrite2.addEventListener("click", () => { - let string = PrintLabelBMAU('Batata Nopa 商品', '12345', '1.23'); - barcode.value = string; - WriteChunk(string); - }); - - if (btnwriteR) btnwriteR.addEventListener("click", () => { - WriteChunk(cpcl); - }); - - if (btnwriteQr) btnwriteQr.addEventListener("click", () => { - WriteChunk(cpcl); - }); - - if (btnDisconnect) btnDisconnect.addEventListener('click', () => { - event.stopPropagation(); - event.preventDefault(); - onDisconnectButtonClick(); - }); - - if (btnReconnect) btnReconnect.addEventListener('click', () => { - event.stopPropagation(); - event.preventDefault(); - onReconnectButtonClick(); - }); - - if (btnComConnect) btnComConnect.addEventListener('click', async () => { - // 响应用户手势(例如触摸或鼠标单击)来提示用户选择单个串行端口 - const port = await navigator.serial.requestPort(); - getPorts(); - }); - - if (btnConnectdevice) btnConnectdevice.addEventListener("click", async () => connectDevices()); - - if (notSupportedBluetooth) notSupportedBluetooth.classList.toggle('hidden', 'bluetooth' in navigator); - if (notSupportedSerial) notSupportedSerial.classList.toggle('hidden', 'serial' in navigator); - if (tools) tools.classList.add('hidden'); - if (btnDisconnect) btnDisconnect.classList.add('hidden'); - if (btnReconnect) btnReconnect.classList.add('hidden'); - - //let string = PrintLabelBMAU('Batata Nopa 商品', '12345', '1.23'); - //barcode.value = string; - if (barcode) barcode.value = cpcl; - }; - - async function getPorts() { - //或者选择一个navigator.serial.getPorts()返回网站已被授予访问权限的串行端口列表的串行端口 - let ports = await navigator.serial.getPorts(); - if (ports.length > 0) { - port = ports[0]; - console.log('设备0', port); - await port.open({ baudRate: 9600 }); - logII('已连接'); - serialWriter = port.writable.getWriter(); - - await WriteChunk(cpcl); - - // Allow the serial port to be closed later. - serialWriter.releaseLock(); - await port.close(); - } - } - - - async function onConnect() { - bluetoothDevice = null; - - if (opt.serviceUuid && opt.serviceUuid.toString().startsWith('0x')) { - opt.serviceUuid = parseInt(opt.serviceUuid); - } - if (opt.characteristicUuid && opt.characteristicUuid.toString().startsWith('0x')) { - opt.characteristicUuid = parseInt(opt.characteristicUuid); - } - - try { - logII('Requesting any Bluetooth Device...'); - var option = { - //acceptAllDevices: true, - //"filters": [{ - // namePrefix: "BMAU" - // services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb'] - //}], - //optionalServices: [opt.serviceUuid] - } - if (serviceUuid && serviceUuid.value.length>0) - option.optionalServices = [serviceUuid.value]; - else if (opt.serviceUuid) - option.optionalServices = [opt.serviceUuid]; - - if (opt.namePrefix) - option.filters = [{namePrefix: opt.namePrefix }]; - else if (opt.filtersServices) - option.filters = [{ services: opt.filtersServices }]; - else - option.acceptAllDevices = true; - - bluetoothDevice = await navigator.bluetooth.requestDevice(option); - bluetoothDevice.addEventListener('gattserverdisconnected', onDisconnected); - await connect(); - } catch (error) { - logErr('Argh! ' + error); - } - } - - async function connect() { - exponentialBackoff(3 /* max retries */, 2 /* seconds delay */, - async function toTry() { - time('Connecting to Bluetooth Device... '); - logII('Connecting to GATT Server...'); - logII('> Name: ' + bluetoothDevice.name); - logII('> Id: ' + bluetoothDevice.id); - opt.devicename = bluetoothDevice.name; - opt.deviceID = bluetoothDevice.id; - wrapper.invokeMethodAsync('GetResult', opt, "连接中..."); - wrapper.invokeMethodAsync('UpdateError', ''); - - const server = await bluetoothDevice.gatt.connect(); - - logII('Getting Services...'); - const services = await server.getPrimaryServices(); - logII('Getting Characteristics...'); - for (const service of services) { - logII('> Service: ' + service.uuid); - const characteristics = await service.getCharacteristics(); - - characteristics.forEach(characteristic => { - if (getSupportedPropertiesWrite(characteristic)) { - logII('>> Characteristic: ' + characteristic.uuid); - opt.characteristicUuid = characteristic.uuid; - myDescriptor = characteristic; - return; - } - }); - if (opt.characteristicUuid) { - if (tools) tools.classList.remove('hidden'); - if (btnDisconnect) btnDisconnect.classList.remove('hidden'); - if (btnReconnect) btnReconnect.classList.remove('hidden'); - wrapper.invokeMethodAsync('GetResult', opt, "已连接"); - wrapper.invokeMethodAsync('UpdateError', ''); - - return; - } - } - }, - function success() { - logII(`> Bluetooth Device ${bluetoothDevice.name} connected. `); - }, - function fail() { - time('Failed to reconnect.'); - }); - } - - /* Utils */ - function onDisconnectButtonClick() { - if (!bluetoothDevice) { - return; - } - logII('Disconnecting from Bluetooth Device...'); - if (bluetoothDevice.gatt.connected) { - bluetoothDevice.gatt.disconnect(); - } else { - logII('> Bluetooth Device is already disconnected'); - } - } - - function onDisconnected(event) { - // Object event.target is Bluetooth Device getting disconnected. - const device = event.target; - if (tools) tools.classList.add('hidden'); - if (btnDisconnect) btnDisconnect.classList.add('hidden'); - if (btnReconnect) btnReconnect.classList.add('hidden'); - logII(`> Bluetooth Device ${device.name} disconnected`); - } - - function onReconnectButtonClick() { - if (!bluetoothDevice) { - return; - } - if (bluetoothDevice.gatt.connected) { - logII('> Bluetooth Device is already connected'); - return; - } - try { - connect(); - } catch (error) { - logErr('Argh! ' + error); - } - } - async function getDevices() { - try { - let getBluetoothDevices = await navigator.bluetooth.getDevices(); - let devices = []; - if (selectDevices) selectDevices.innerHTML = ""; - getBluetoothDevices.forEach(element => { - logII(element.name); - devices.push(element.name); - if (selectDevices) { - var opt = document.createElement('option'); - opt.value = element.name; - opt.innerHTML = element.name; - selectDevices.appendChild(opt); - } - }); - wrapper.invokeMethodAsync('GetDevices', devices); - // logII(getBluetoothDevices); - // bluetoothDevice = getBluetoothDevices[0]; - // await connect(); - } catch (error) { - logErr('Argh! ' + error); - } - } - - async function connectDevices(name = null) { - try { - if (!name && devicename) name = devicename.value; - else if (!name && opt.devicename) name = opt.devicename; - - let getBluetoothDevices = await navigator.bluetooth.getDevices(); - try { - getBluetoothDevices.forEach(device => { - if (name == device.name) { - bluetoothDevice = device; - throw 'BreakException'; - } - }); - } catch (error) { - if (error !== 'BreakException') { - throw error; - } else { - logII('连接' + bluetoothDevice); - await connect(); - } - } - } catch (error) { - if (e !== 'BreakException') { - logErr('Argh! ' + error); - } - } - } - - function getSupportedProperties(characteristic) { - let supportedProperties = []; - for (const p in characteristic.properties) { - if (characteristic.properties[p] === true) { - supportedProperties.push(p); - } - } - return '[' + supportedProperties.join(', ') + ']'; - } - - function getSupportedPropertiesWrite(characteristic) { - for (const p in characteristic.properties) { - if (characteristic.properties.write) { - return true; - } - } - return false; - } - - async function WriteChunk(string) { - if (!myDescriptor && !serialWriter) { - console.log(' > !myDescriptor serialWriter null!'); - return; - } - console.log('WriteChunk', string); - var buffer = GBK.encode(string); - var buffer1 = new Uint8Array(buffer).buffer; - - for (let i = 0, j = 0, length = buffer1.byteLength; i < length; i += opt.maxChunk, j++) { - let subPackage = buffer1.slice(i, i + opt.maxChunk <= length ? (i + opt.maxChunk) : length); - await _print(subPackage); - } - } - - async function _print(buffer) { - try { - logII('Setting Characteristic User Description...'); - console.log(buffer); - if (myDescriptor) - await myDescriptor.writeValue(buffer); - } catch (error) { - logErr('Argh! ' + error); - } - try { - if (serialWriter) { - await serialWriter.write(buffer); - } - } catch (error) { - logErr('Argh! ' + error); - } - } - - function PrintLabelBMAU(title, barcode, price) { - //店名 - var title0 = '店名 My Shop'; - var size1 = '1 1'; - var BMAUtitle0 = '1 0 0 250'; - - //名称 - var size2 = '2 2'; - var BMAUtitle = '1 0 10 10'; - - //条码 - var BMAUbarcode = '1 0 50 0 70'; - - //价格 - var BMAUprice = '2 0 0 170'; - var size3 = '3 3'; - - // 价格PVP和Euros - var size4 = '2 2'; - var pos4 = '1 0 10 200'; - var pos5 = '1 0 10 200'; - - // 标签 - var LABELsize = '0 200 200 290'; - var LABELWidth = '450'; - - return '! ' + LABELsize + ' 1\r\n' + - 'BEEP 1\r\n' + - 'PW ' + LABELWidth + '\r\n' + - 'CENTER\r\n' + - 'SETMAG ' + size1 + '\r\n' + - 'TEXT ' + BMAUtitle0 + ' ' + title0 + '\r\n' + - 'SETMAG ' + size2 + '\r\n' + - 'TEXT ' + BMAUtitle + ' ' + title + '\r\n' + - 'BARCODE-TEXT 7 0 5\r\n' + - 'BARCODE 128 ' + BMAUbarcode + ' ' + barcode + '\r\n' + - 'BARCODE-TEXT OFF\r\n' + - 'SETBOLD 1\r\n' + - 'SETMAG ' + size3 + '\r\n' + - 'TEXT ' + BMAUprice + ' ' + price + '\r\n' + - 'SETMAG ' + size4 + '\r\n' + - 'LEFT\r\n' + - 'TEXT ' + pos5 + ' PVP:\r\n' + - 'RIGHT\r\n' + - 'TEXT ' + pos4 + ' Euros\r\n' + - 'SETBOLD 0\r\n' + - 'FORM\r\n' + - 'PRINT\r\n'; - - - } - - function logII(info) { - if (log) log.textContent += info + '\n'; - console.log(info); - wrapper.invokeMethodAsync('UpdateStatus', info); - } - - function logErr(info) { - if (log) log.textContent += info + '\n'; - console.log(info); - wrapper.invokeMethodAsync('UpdateError', info); - } - - // This function keeps calling "toTry" until promise resolves or has - // retried "max" number of times. First retry has a delay of "delay" seconds. - // "success" is called upon success. - async function exponentialBackoff(max, delay, toTry, success, fail) { - try { - const result = await toTry(); - success(result); - } catch (error) { - logErr('Argh! ' + error); - if (max === 0) { - return fail(); - } - time('Retrying in ' + delay + 's... (' + max + ' tries left)'); - setTimeout(function () { - exponentialBackoff(--max, delay * 2, toTry, success, fail); - }, delay * 1000); - } - } - - function time(text) { - logII('[' + new Date().toJSON().substr(11, 8) + '] ' + text); - } -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Bluetooth/PrinterOption.cs b/src/components/BootstrapBlazor.Bluetooth/PrinterOption.cs deleted file mode 100644 index df018e6d7..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/PrinterOption.cs +++ /dev/null @@ -1,113 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using System.ComponentModel; - -namespace BootstrapBlazor.Components; - - -/// -/// 打印机类型 -/// -public enum PrinterType -{ - [Description("CPCL指令打印机")] - CPCL, - [Description("ESC指令打印机")] - ESC, - [Description("TSPL指令打印机")] - TSPL, -} - -public class PrinterOption -{ - /// - /// 打印机类型 - /// - /// - [DisplayName("打印机类型")] - public PrinterType? Type { get; set; } = PrinterType.CPCL; - - /// - /// 初始搜索设备名称前缀,默认null - /// - /// - [DisplayName("初始搜索设备名称前缀,默认null")] - public string? NamePrefix { get; set; } - - /// - /// 设备名称 - /// - /// - [DisplayName("设备名称")] - public string? Devicename { get; set; } - - /// - /// 设备ID - /// - /// - [DisplayName("设备ID")] - public string? DeviceID { get; set; } - - // 蓝牙设备/通用属性协议 BluetoothDevice - // 串行设备端口 Port - // 串行设备写入句柄 SerialWriter - // 蓝牙设备描述符 MyDescriptor myDescriptor.writeValue(buffer) - - //> Service: e7810a71-73ae-499d-8c15-faa9aef0c3f2 - //>> Characteristic: bef8d6c9-9c21-4c9e-b632-bd58c1009f9f - //>> Desc: 00002902-0000-1000-8000-00805f9b34fb - - /// - /// 服务UUID/ServiceUUID, 默认0xff00. [非空!] - /// 常见打印机ServiceUUID: - /// [通用型号/BMAU32/QR380A] - /// 0000ff00-0000-1000-8000-00805f9b34fb => 0xff00 - /// [InnerPrinter商米内置/BlueToothPrinter/FK-POSP58A+] - /// e7810a71-73ae-499d-8c15-faa9aef0c3f2 - /// [HM-A300] - /// 0000fee7-0000-1000-8000-00805f9b34fb - /// - /// 其他设备ServiceUUID: - /// heart_rate 0x180D - /// BATTERY_SERVICE 0x180F - /// ALERT_NOTIFICATION_SERVICE 0x1811 - /// BLOOD_PRESSURE_SERVICE 0x1810 - /// RUNNING_SPEED_AND_CADENCE 0x1814 - /// CYCLING_SPEED_AND_CADENCE 0x1816 - /// 0x1802 - /// 0x1803 - /// - /// https://www.bluetooth.com/specifications/gatt/services - /// - [DisplayName("服务UUID / Service UUID")] - public object? ServiceUuid { get; set; } = 0xff00; - - [DisplayName("服务筛选器")] - public object? FiltersServices { get; set; } = null; - - /// - /// 特征UUID / Characteristic UUID - /// heart_rate_measurement 0x2A37 - /// body_sensor_location 0x2A38 - /// heart_rate_control_point 0x2A39 - /// sensor_location 0x2A5D - /// - /// https://blog.naver.com/geniusus/221761337501 - /// - [DisplayName("特征UUID / Characteristic UUID")] - public object? CharacteristicUuid { get; set; } = 0xff02; - - // 描述UUID / Descriptor UUID - - /// - /// 数据切片大小,默认100 - /// - /// - [DisplayName("数据切片大小,默认100")] - public int MaxChunk { get; set; } = 100; -} - diff --git a/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/gbk.min.js b/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/gbk.min.js deleted file mode 100644 index ee437e6cf..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/gbk.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * gbk.js v0.2.4 - * Homepage https://github.com/cnwhy/GBK.js - * License MIT - */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.GBK=t()}(this,function(){"use strict";var e,n=function(c){return{decode:function(e){for(var t="",n=0,r=e.length;n>8,255&u)):t.push(n)}}return t}}},t=function(e){var t=n(e);return t.URI=function(X){var e="!'()*-._~";function t(t){t.split("").sort();var U=function(e){return~t.indexOf(e)||/[0-9a-zA-Z]/.test(e)};return{encode:function(e){return(e+"").replace(/./g,function(e){if(U(e))return e;for(var t=X.encode(e),n=0;nBDGHO%RTUW%\\_a%jl%rtw} (V!*+-0%27>C%EHJ%MP%R\\`cdfn%ptvz{} (W!()*,/3%579;=%CFGM%QWX\\^cdg%ilnprtvy%} (X!&')%.468CDHJLMOPSTWY%\\_b%dg%ilnprtuwxz%|~ (Y!'(*+-469%=?%GI%KO%RT%V[%_bdikmnptuy{}~ (Z!&')+%-/%;>@ACE%GKMNPR%TW[_%ikmo%rt%vy%{} ([!'(%+-%024%;=%BD%LO%QSTX%[]^`%ce%y{} (\\!()+%/1%7:%LN%SU%WY%cf%im%prt%xz%~ (]!&'%*-%/1%68%EG%cgloqs%uwx|%~ (^!')%-/02356;>FJKOPRSVWZ%]_`dfi%kmor%vyz (_!'+%-124%68;=@ACE%MOQRUVX%]_adegjqwx|~ (`!&)*-%/689;%=?%ADFIKLNOVX^%cehilmoq%uwyz|%~ (a!'),%/124%=?AD%HJ%PRSU%[]e%ho%qu%~ (b!()*,%.024%79;%=?A%FH%KM%WY%`c%ei%loq%tvy%| (c!'*+-.1346%8:%<>%GKLOQSUZ%\\_cghjltwy{| (d!(,/1%4679=>@D%JLMOQRTVWZ]`%ce%km%pr%tvy%} (e!+,-/0279%;>?DQW[%]_bdhqu%wy (f!&().47:;>ACEFHIKMP%SU^a%egikm%tx}~ (g!)*,.02%58<>BCGI%MPY[]`%bdeginpuv (h!(*-2%6=>A%CF%KMPRT%WZ\\%`deg%ln%qswxz{} (i!&+-%/1%469;>@AD%HJ%MP%TV%Y[\\abdh%mrsvx~ (j!&,%.0235%7:;>@%FH%PRTVXZ\\_%cf%hjkn%puw%{~ (k!').04578;=?%CFI%NQRTW%^`acdg%ilmo%ru%wz|~ (l!&(*%,.%9=%ACDHIK%OQS%U[%^`%ce%hk%ru%{~ (m!&')%79%CE%KM%PR%^`%hjkmnqxz%~ (n!&(*+./2%478<%>ACG%WYZ\\%^`%cgmnp%txy{} (o!&'%)+,.5%9;%BE%UWZ\\^%`b%il%ps%ux%~ (s!&)%:<%?A%CE%OQ%SU%bd%ilnpqstvwy%~ (t!&')+,.%246%9=>ACDF%ILNRVXY[\\ac%fiklprsvxy (u!&(%,.013%?BDG%IK%MRVXY[%^abeg%jl%ostyz}~ (v!'(%,.013%9;%=@%CIJMOR%VXZ[]%_a%lnp%rtv~ (w!&(%+-/%24%689<=?A%CE%KNPR%VX%Z\\%`bcf%oq%tv%|~ (x!&'(*+-%5:;=%@B%SU%[^%km%svxy{%~ (y!&(),%1346%:<>@B%DF%HKMNPQSU%Y[%qs%~ (z!()%ACEFH%OQ%_bfnpqwx{}~ ({!&)+-%023569=ADEG%IKMV^%`c%fhinq%swxz (|!&'%)+%-/2%:>@ADEG%KMO%U[\\^`acefi%lnpquwy|%~ (}!&(+-%02%578:%?AI%MP%TVZ%\\^`be%hjlnoq%vx%} )&!&'%+-%356:<>?ABD%MO%TWX[%`b%fhj%mopr%vx{}~ )'!&)%-/%69%@BCG%QSTVX%bdghj%mo%{}~ )(!&'%9;%=?%WY%eg%mo%{} ))!'(+,2458=>@%DGHLOQ%SUVZ[_f%mp%twxz%~ )*!()-%025%:<%BE%IKLNOR%`dfhmp%rtwx{%} )+!(.137%:>%BD%HJP%SU%^a%fjkm%pr%} ),!&(%02568%:B%DFI%KMOQSVWY%[^%aehikmo%uxz%|~ )-!&'%358=%@B%DGIKLORSVX%Z\\^a%cgjq%suwxz~ ).!&(%+-%2467:%?AC%FI%MRSUVY^%`e%gijmnpqstwz{}~ )/!&()+,.9%;=>BCEIJLPQT%V^%`b%fh%loprv%|~ )0!'(*,-/%1457%:>?GJKMNPWY%[^%acdg%jlnp%ruwz{}~ )1!')*.035%79:=%DG%IL%PR%TVWY[^a%ejqruwx{%~ )2!&)%,.1%37%;=%@B%EHILO%QS%eg%nprtvwy%{}~ )3!&'%*,%/1%47%=?%BDF%XZ[]%ac%jl%txy{%~ )4!&'%+-%24%68%<>A%EHJ%Z\\%ik%su%z|~ )5!/058%:@D%FH%KN%SW\\_%afijlmp%su%wy%{} )7!(*+-59;?GHJKNTUZ\\_b%ejm%pt%wyz|%~ )8!&(%*-78:=%?ABD%ILMO%RUXY[b%eg%nqu%wy{%} )9!'(*%-014%79;%>CEIK%MOQ%WY\\^cgijmnqsuw%{} ):!&')%+02%46%<>AC%GJKM%PRTVX%[]bce%ilmpqt%y|~ );!()%+-%/14%9;%?ABDFHIOQ%WY[%]_%ce%lnp%rt%} )!'(+%.2578;%?ABEFHIKM%ORSUWZ%\\_`b%eh%jlnpqs%~ )?!&'(*%,/%146%8:ABD%HJMNP%RTVY%[_%ac%egj%mor%uwy{| )A!'(%+-/024%:=>@AHIK%NPRSUWY%]a%cehik%mo%qsuvx%{}~ )B!&')%,/%35%=@%DF%JL%OQ%TV%oqu%|~ )C!&(%-/34689;?%EJLMO%QTV%XZ\\^%ceglnpqt%wyz|} )D!&)*,/0279:<%@BG%IKLPQSVY[]%`beghjkmoq%tv%y{~ )E!'+%-0258:=>@E%LNQ%Za%cgkmopr%tvwyz~ )F!()%/14%79@CEGHK%OQ%SU%[^%dg%imnrz~ )G!'),0%9DF%MOR%Z\\^a%hj%ln%pr%{}~ )H!&*%-/2357%@BD%IKMO%RTUWXZ\\%`bce%nps%uw%y|~ )I!&'(*%,.%2479;%FI%KM%TVWY%[]%`b%dfhik%{}~ )J!'(*+.01346%9;<>?A%EIJL%NPRTY%[]%befhil%uxy{}~ )K!&()+,.%02%68%?ACEG%IK%PR%TW%bd%gi%rtv%~ )L!&(%36%;=?%DFH%KMO%QS%Y\\%`bce%ln%twy%} )M!&'(*%46%<>?A%CE%GI%QSV%Z\\%ce%lnq%~ )N!&'%~ )O!&'%178:%CE%HJM%OQ%TVWZ\\]_%jl%sz{}~ )P!&'%136%9>AEG%JMNP%RU%Y[%bd%koq%wy|} )Q!&'%*,.018:<%@B%IL%NP%RTV%XZ%\\^%dh%lnrw|%~ )R!'*,2%48:=>@%CEFJ%LOR%VX%Z]_%aijl%nr%vxz|~ )S!&(%*-.2589;ABGINTUWXZ[]%_bd%fh%kmqrt%y{}~ )U!()+,02%46;<>@EHLQ%TWY[]^`acdg%il%oqru%wy%} )V!&')*-.02359%=?EHOPSTVWYZ\\%ad%fk%mp%su%xz}~ )W!&),-/1%479:<>%@BDG%NP%SUY\\]_bcefhilp%rtvxz{} )X!&'(*,%36%=@%CFHJKM%OQ%[]^`%nq%suxy{%~ )Y!&)%/1%35689;<>@AC%FHKMPQTV%X[%^`%bd%fhjnpqs%u{ )Z!&)%24%79%@B%DFGI%MO%QU%^`%bd%gkmoqstv%|~ )[!&'%+.%024%=?%ACE%GI%KM%RU%WY[%]_ac%ik%mpqu%~ )\\!&'(*%-/%35%?ABDEG%LNP%UW%]`%jlo%z}~ )]!&'%DF%MP%VX%hj%ln%~ )^!&()+%8:%EIL%ORT%VX\\%_a%cf%hj%lnrsuvy%~ )_!&'%,246%8<@AF%IKM%Y\\^%`b%eglpr%xz|%~ )`!'(%14%8:;=@D%NP%W[%^`%mo%rtvx%~ )a!&'%+-/%359%=?%AD%GIKLN%SU%Y[%^`%ce%gj%nq%wy%{}~ )b!&'%)+-%/1%9;%DF%JM%VX%[]_%df%oq%|~ )c!&'%:<%EGIK%MP%RXZ\\^%dg%il%oq%suvxz|~ )d!()*-/%25689;%=@%BGHJ%NQSUVX%ce%psv%xz )e!&'%,1%35%8;=?%BDFG 'W!,-. &(+&.'&-~&'u'W!/1 ')>.= '.u'/!K. '0`'/!94 '1t'0T'/!?Bu`\\Q1t '0!)* '/!xy2IH ';!*( &'}')!\\] '+{.;U&'q.>!&' ')Z&'t',5':!GF '9!eiha`;:ML ')e'-!XVWY 'W?'-!67%?#3$ '6!-.%@ '5!rs%~ '6!&'%, '5!^_%g## ']!67%?## '-!&'%1## .;!RST .>+.;!VW%~ .)'W!mn%~ 'X!&'%f#8$t%~ 'Y!&'%p#5$ &0!=>%MO%U#5$]%mo%u#4$ .9!89<=BC@AD%G##>?:;4#67#6$ &1!cd%hTi%~ &2!&'%)#12$*%/K0%I#10$ &.!()7 ')!=?O_ '+}',('-!\\]%_ '/!)37fz{ '0z'8!CD%ft%~ '9!&'%)-%/VW|%~ ':!&J '0P'W!>IJ#8$ &(!uU &+7&(T&).&(]&)6&(\\&)F&(a&+9&(`&)h&(g&+;&(f&*-&(n&+=&(m&+!?ACE &(!p^ &,a-Qc&)!_c -Qd&,q#1$'Z!&'%J#18$ 'W!MN%U '^`'a!@AN%PSv 'b!'*+. .93.>!(*# ',@']G#'):#0$'Yv'X!no 'Y!wx 'W2'X!pq .9!LM%UW%Z\\%ik%n -R!*+%6 'W3#10$'7!LM%~ '8!&'%>#12$ )e!HIKN%SVWabei%lnp%uw%y{%~ )f!'+%-23679%;@BCEFHIM%PS%_abdf%ik%rt%~ )g!(*%79%=?@BDFGIJL%OQ%TV%XZ[]%bdfgkn%prsv%y{}~ )h!&'(,-/3%9;%>@B%EGIK%MO%RT%cehil%or%z}~ )i!&'%)+,/13579:?%CE%HJ%\\^`eh%tvwy%} )j!'(%,.13%57%9;<>@%JLN%UY%hj%~ )k!&')%1357;=%CF%IKN%TV%Y[%bdfhj%mqstv%z|} )l!'+1369:<>%ACDFGJM%PR%UZ%ad%fh%npr%tw%{}~ )m!&()+%.0%2479@%CEFHIMOQ%TVX%Z\\%_aeg%ilnrswyz|} )o!()+%-/346%=@%EGI%MOQ%TV%\\^%`b%iklnq%suw{|~ )p!&()+-.013%<>%FHILN%WYZ\\ (iC*r5(pM)89(gy(h[(gk)p*)o>*A;)s|*9E)ui)cO*s5*ux)R/({@(Z*)7s)B.(~d*4~)F{*42)@K)pg(_l)>Q)a|*2'*Jb(\\0(u2)4?)\\@*9t)8])5n(eJ(f+)|s(^7)mH))<)7>*Yr*ua)6M*2O(o@*t|*0J)cV)oo)E[)op);L(XR*W~)7F)z6)?3)hN);2)66*8L*xa)Dd)cf)61)76(Wo)k9(cY(a_*.d*b,))v)G`)Jk*6R*.k)HS)vH*E'*oR([d*U/*:L*4b(bm*L>(a&)p!]`bdelnrsu%wy%} )q!&'%-035%7:;=?@BCEFJLN%X[%^ac%egj%lnp%ty{}~ )r!&)+%-/%69%@C *B**t=(Yf(qR*{F({T)6!th )BK*V+++A)b})DT)um)12(c!`& *^r*4P*Wv*mT(Z=)e4(t-)1k)`B*K0(tz*:])Cj)}<)&|*/8)l*)TJ*[[*`!0t +3')Q4*cF)}()-`)v**@.*A<)Q!596 ))I)*v)nD*q<)>X),G).P*_0(s@*7;*a^*rQ*v?*_J*/W*X,)5](YH(e5(cm*_!9:< *a,)F:)-N*6j*JF+,1)3Y(`E)nu)-P)?.)\\_)Z'({u);N(^!A| )EP(T_)yA*{Q)_5)r!DE%GKNPQT%_a%ch%jm%rvwz%~ )s!&'%,/12469;%=?@BD%HJLN%Z\\%df%hk%or )mi)*e)gu*=C)(dx*E0)PD)1!mh )^Z*:;*8Q(Vg)SU*Bu)Y)lB(i*(ZQ*Y,)6G*mQ)C[(ky)[T))*(f9)^m*^P)62)*Y(*JJ)<>)yh(pX)Lv)5,(fL(UE)z*)1i)[j*T>)6B*`V*~U)y\\(e`)n?)7k(c()Rg*_p),X*~:*2q+3k(Xj(}?*Xd*1T)?G)_?(]j(^~*D_)&Z({W)7'*d@)lq*ZZ)z?)2()~4(V[*/9)rl(TW*7f(`7(_m)M5(d^*[|*n^*sl)YY*rZ)J))u!`abdfgklnp%ruyz|~ )v!')+%28%;=%@BCE%GI%KO%RT%VY%[]%jl%np%tvxy{|~ )w!&'%*,%.0%6 )tu(\\&)se):o*N`(t*):B)(~){E)Ie(W[*8Y(j8(Tx)mR){])*!Qy *q>(`5(f=)^e)9.*n~(oe)@n)Ig*d[(hY)W=*.I*IY)5O*/1)mY*;=)vD*si*_/)2o)kM*T1)Ov(`T*XP)O3*3G*>{(n-(bn(Vb(Ta(_D*(G*d_*&i(YL*[t*&C){b);m)&g(\\**51)nL*(i)W6*1o)D6(zh(|V)vN)<[):r)9b)8<*ns);3*_O)}h)nt)5o(tM(fJ)P2([z)5P))n)P?(Vw*X7*Ji)-i*`f)w!78%<>%GI%MO%]_%cgil%oqt%|~ )x!&)*2457:%=?A%GJL%PSTW%Z\\%_a%c )/R*2s)7/(U&(cd*b~)9p*4J)@/)R5(X()1n)W+*TB),v*Ef)-7)82(^&*;v)G=(_s)8t*[=(ZB(~G)xH(|Z(`J)zZ)1<*a2)pp).B)-{)ov*[a)^J)om)}])s8(_f*ar(qU(X0)Z3*_{)>G)}/)e0)VG*1n(yJ)6x)++(nl*?3)}@))e),\\*`J*/U*y')9:)Y_)ut)_;(^D*uF(p5)l2(W~)l5)+-)1f(u-)Vc)Px)ue(eY*sr(_!>t )9A(eg*mF*Tg*Ys)cW)u{*G_*_~*Tq(e=)x!de%jl%wy%~ )y!&'%*,%047:<=?@BDF%HKLNOQ%VX%Z]`bdfi%oqrtvwy|} )z!&'%)+.%24578:; (TG)q/(eK*m<*xV+2S*o.({Q*S_(T!hb (^x*>m)47(ai)F>(Xy)0D(_.)Ts(^()6Y)?9*rW*UQ*`O)m|*c*)rJ)Q2)dO)eX*T_(qf)r`*XL)DA*oA*3w)+<)Wk(u_)|\\)s{*o<)Pn)?O*/O(q7(]v*qn(|W(s((f,*[g)>a*x_(my*mP)q>*`y)9?(gq(t!@` (o~*\\N)Cs*ZH*8U(`[)1p(qF*F@)&;+0<(YM*x}*Sv(w@)0O(d:)6?*a.*c/*{T)0B*2B(]d*2i(|r*{J)U-(Uy)z!<>@AC%QS%UWY]_%df%oq%uw%~ ){!&'%57%9;A%DHKMO%RT%VYZ_%adgh *X0(e.*0B)}c(WK(U<*qO)T*)h1*C6))N)lg*21)L')t3*mE*-4(_T)_h(e**_e*:q*X))dt*{B)T0(o-*9z)?[*4.)5[*r((uu(W:*S|*.T)>9*=U*uI(iZ*ye*4)(c9*Ta(e}*4>)+5)Sf*X9*9s*d.(f-)Q{(_y*.Q(oB)`C)S,*(9(tq(W8)/1)2K*(Z(Tv(|_)E7*FD)&C*ne*yU)mS)`&*`Z(^{*/^*Sz(to(_W(X=(f*(tQ)>r*4(({,)69)7,*^z)*4)R&)}:(WJ(Ya)CK){!ijmo%qt%xz%~ )|!&'%+-%79%BDEG%JNOQT%Y[]%ehikm%ortvy%{} )}!&'*%,.0135%7;=A )Uj)VM)x`*K6),T)l()6]*^o(Yx*eW)?I*5!Z| )+2*5{*Xt(a0*MY*XK(t3([\\(Vl*qk)cT*6K*Wx(|**S`*r:(uT*/[(g;(ld(kU*TI)>4)JQ*mL)po)Xz)*a)kn)D+)E])|l*3z*Xv)2F)y>)>]*Xc(^T(`4*mU*/y*3x*.L(~C)Wy)DE*&;)o}+&I*6a*0|*),):}*oQ)z^(fN(h7)O^):`)4}+04*4w)m=(a3*uT*>e)Fo*F&*qP*s1*nF(Tp(ea*.s)Fl*Z-*2K)C2)+0*1H)}!CDFH%KMOQS%XZ\\^abgikmprsuw%~ )~!&'(*+./13578:<%?A%GIJL%NQS%VY%[^%`i%kmnp%rt%{}~ *&&(pL*2u)Gq))-)>6(a`)0F+4-(X}*\\H(^8({b),P))1)Re)7[*Wz(^=*m\\(bf)SM*:M)eC(p,)Di*X-(tE*_-*=*(g@)~H(Wk)Sk(zt(vE+2X(eA*Ee*~r*UB*3~)>@*x^(n6*sd(`H)k2(`j(|?)7l*L.(UC)7:)/\\)H{(^?({O(^l*N<)~\\*{[*08)1o)^'*X/(]n)*n*`S)ix*N>(ni)tz)-6+42*qI*^R+'T*TE)oj)Fu)Eh*Z8*X5(`W*^t)Yr)HN*n_*bs(n9)E(*K~*_X(gs*&!'*%-/%246%:=>@%BD%FI%KM%OQRT%XZ%]_a%hj%lopr%wy%~ *'!&')%.124%@B%GK +&)(zy)Us)R-(V9({j*~Q*d7)3v*b5*v{(f/)VX(|0(_p(j**0=*2&)u*4e*G])e<*(z)XG*'!LM%UW%{~ *(!&'%*.%8:%@CDFI%KPQSV%Y[%]_`d%hjk ),d*DB(h~)6g(V&)SX)5S*9x(h)(c])fQ)Yi)l8(`,(b~*TA)KF)-n)/2)W8(o2)O4)gi)G-*_i*/T)8s)0|(hv)n5*Um)`>)VF({])*j*;g)2s+1b)v}*G@*'0)oy(_c)1v)`u)A3)*;)0&*Tr)^K)86*^s).H)0;*Eo(ms)Pz)0m)35(cX)1`)AV*X?)yu(WU)_k)RN*Sp*TV*.r*;y)@X(wu+'Z)UM)WA*UL)U7(WT)^F*@%EG%NPQS%`b%vxz%} **!&'(*%,.%4 *3i*{:*`1)\\M*Sb+/q(v`*/!*J (ef)Df)HY*^{*'V*sc(e')/W)mb)Ry(d)(y2*.A)85(_S*55))9*@7)6C(^L(zs(WI)x>(`\\)18)UJ({!{y *S!^m )@+).W*r;(u`*/(*.D(kP)EC(t_(XU({m(aa*;o*xj*X>)l/*mq(Zw)z[(W2)EB*~H(y*)P5)pj(o=(|t)}N*qC)`w(^H*4-*97(uE*/E*;<)HA)Ex)v4)uS)7M)8r)~;(Yv(a+(_B*;e)KQ*g=*ZC*X1*N;*o/)~h(W1**!56%km%tv%~ *+!&'%= ([<*8P(`k*{D)WZ)Xv)VJ),7(\\s(vP(|d)UB)Rf)m**?<)GB(t|*So(c/*dE*rC*AH)I:)w+)`O*4z(V8*bP)UC*~N(v{(mQ):d*nJ)sy(Y.*5E)eM*NL*{O*/u*.x(a@)>T*dI*^!im (eH){\\):L)9])ox)yp*J5*r,)5F(al*9I)G.)DU)9/)rR)|Z)TV*.m*N](vD)5.*Bo*9l)lI(ZO(V_)mI*TO(}O))F)}_)?F*eL(V^)Tz*M2*)~*o'(VY*U3*_l*u^)A;)xR*_b)_n)Ut*+!>?%JL%RT%~ *,!&'%F (}B(as*;[(^.*:|)rB)Af++l(V@)1J*(!nc *.i(V)*R|)A_*xh*uD(r[)>g*o])-h)mm*uA)|!LK (_3)_1){^):I){<*.:)gP*w&(U2)^S(UJ*d&(d_)>L)@0*7!u~ (g9(}6)m>*v2)7B)eE)ma(}J*~C*=-(}E(g+)sw(U+)S\\*37)7<)9&))0(^C*Z!+l *o0(Yz(eB)1g)_.(a()8a+0:(w:(ZV)qw(d-*.|)<2)>&)6L)9P(ZD)cS*NC(_&*S}*.w(o**=/*mZ(^g(ex)&N*,!GH%~ *-!&'%-/%35%9;%P (YS)|P)UV*bg*~Y(iy(gA(cp(gZ),=):H)JF(_b)36(_}(q[(b@(o1)tB)qK)+M)3E*)7)5w)6Z(V6)^p*29)7a)_f*uK(oZ*:I)E{)Hv)vX*xw)yI(sr(g^(eL)W~(]p(`U({Y*Tb*43(i<(p0)0L(o4(f1){@)0)(zd)9_)6c(e@)6&({~)E;(h?){e*:T*dK)+)*Ki(t^(p8)7x*Z6*4s(o:)~2(Y2).v({t)OP(c0)}d)e.)Fy)t4)qv)@@(_((U|)pm(~k){k*?&(tt+'Y([W*-!QR%tv%~ *.!&'%46%8HNUVp~ */!-:KQ_xz|%~ *0!&'%)+.%7:; *{])2N)Xt(oG)@O)8W(n,)7V)6,)+i*qc(of)73(j'*Fc*5u*_4(i_*)_[)V@(b:(U=*t;*on*A})vM**-(]F(ou)AC%FHK%OS%UWX[]%`b%eghj%qsuw%{}~ *1!&'(*+/12457%=@B%FIJMOQ%SU%XZ\\^%befh%mqr )n-)|8*(B)SS*sS(a\\)j2(h;(Yr*31*V*5c*nX)/})_>*.]*(^(_<)G[*(a*96(Tj*^p*eJ)An(VB*Ti)(er*n7(Y,)?g(}!jf */V*DE)R6)-o)gA)Y|*/@)&9)8,(zz)Y~(d+(U^)9X)lb)6d*^X(Wa(Ve)ST*.P*Sw*>'*HJ*0?*`s*n})~d*~k*K}*>G)Tp*~P*.v(uU+1Y)gU)t6*Dv*~!6L (kb(et(pU(U]+1D(ce*_Y*54)ry*{g*F0)Yy*@k)C:)30)Zj*3![^_begj%oqrtv{ *4!'*%,0479:<=?IK%OS%Y\\cdfgjry{} *5!&)%,.%02367@BDF%HJ%VXY[^%`bd%hj *U4*9Y*;@)q2)Qs).d**:s*nt)Q;)si*my(c~*:p(^^)*,*V>*X8(U5)ge)E&)G_*dJ*tM)a4)SO)qI(xT*oB)Q/*0v)@p(|.(v-(x\\*q!7F (W'*=o*?J)Mp)px*o1)f.)H'(zo)qo*dn*uL*)3*`/*U'),b*'|)yP*N?)Sz*F^({})*1)HJ)q`*/6(^a(]r(b1(wD*/F*uM*:E):.)rk*Bv)yJ)X+)+/(uf*@i)^H)Qq)7))pX)>J)1/*qL)@W*H/+/s*nG(ej(g(*U7);~*5!kl%prtx%z} *6!()*-%13%68:<%>ADEG%JSU%Y[]%`bd%iklp%tvwy{}~ *7!&'%+-%25%8=>@%BDF%L )<&*C^)L>*6n)vk);o+'l)6|)Ci*)YR*A*)72)*c)vA))UO(^h),A(uA(ak)/D(u@)B-*DD)mC)8;)4[*)F*T^(h8)O9+/u)Pm*B{(fY([M)SR(ic*Y[)cJ))])/G)i>)77)9J)cj)-|)X4)U:)=T)[>)pq)vS)q<)lQ(`>(e8(U@)+4)?c*2`*4Z)6^(g1(`B)_0*Jk*Yx)T6(f|*4^(q**Ky*XT*r`*cz(XK)SI(jW)p_)te)6k)_{)[t)-Q*@D)H[)uX*&Y*6z)CI+0F)8x)v3(oR)tG*t})6!DGHKPU%XZ%\\^`acdfhj%nxy{~ *;!'(+-.2%;>?CEGLPR (i]*5i)mV)pG(cH)n)(\\y(}F*S)*&)([&)ce*~a*y_)ZA)k8)x9)<4)s3)7f*xq*X+(gl*35(U?(oM*:g*=p)*b(_`)kL*T((}T(oD)TQ*xg(wa)ti+'\\*_|*(E(`p)5m*nT(VZ*k*=L*?c(p^)Cr(n?)A^)Ub*U<)Bt)]E)C])OL)FI)56(v/(TI(_7)ZE)E^)S=(^B)HL(tm)Oy)lc)&a*5;+3<)?y)w!rk *~[*Xw(~.(UK(W<(f3(tw)tA(lV)Qt*_U),@)S+)T8*Sh)9H*;!STVWYZ]_%chj%nrw *AE%GI%KN%P )0I)U9)d:)6)*m!Ax (cR*_R)~9(Vs*U1(Uk+1r*m!df (`g)[B*aB)UA*U?(qB)'F)O!2[ )E6(f_*6&*0t(rq*A6),w)6e)Ld*o:)>m)0])G?)s5(UA(Y1))/*v*)(VF)y^)i<(bL*:')=&)y5(|;)S/*u=*^e)R)(Zn(d5)WO)<{)Ad)R7)1E*xW*T[)*u)iD){=)yC(T^*b7)hd)RI(mo*cx)Ss*Y2(cI*Ea)C0*\\K(}M*~;)Wj*=!QRV%Z]%_a%cehj%msu%z|%~ *>!()%-3%:<%AC%EH%OQ%Z\\%`bg%jln%rtx%z|~ *?!(*,- (e3(wQ+3w*YJ(dq(nD*y.)D(*do)Sw(^4)mn)7])dq(`R(a^*/{)^o)o*(d*+0A)K-)uJ*s]*K^*13)`_)b:(^U)E_)k:(sc)=l(mL*Sf*{K)63*.o)1y)_o(sk(V!UN ).X*vy(W6*Sa(_v(uW*.E)5p(Va)@.)5**;M*?z*;x*Gv)ad)YN({p*.l(^c):()E`*3f*;N*IL(]7({1(uO*_B(U`)Rd(^1*LQ*^Y*q}*AI)if*nj*q?)VI*:S),n)2*6@++w(r6*X[(TO(dw*?!./%24%7;>@%GIKLN%QS%_abdf%hlmoqstv%y|} *@!&'*,-/%469:^)G+(js(Tm):s*~d)6.(y+)ig*99)VL)Ho(\\e*1)5g*{k({?(|])9@(i'(e4)nq(^I*A+)E.)H4)PC)6U*^}(e1*82)Vt)m3(US*XN({')ao*BU)B!(p *0Z*FB+1k+2e(}c)Cm*`()FD)DD)5))|C(r])+L)>k)Zp*B!(),.%46%@C%IK%MOQ%SW%\\^`%fh%np%twxz|%~ *C!&'(*%02%57%E )0.(`Q*2C);Z*JN)l&))M)FF)7^*t`(e))c[*Te)R;)rH)z-(f2)s:*xZ*8<*TX)u1)CR)_C)?Q))MD)n;)[S*U8*Tl(oI)QO*Jp)v6)9Z(eV)_/)Rk(r0);0(q3)Ha*6m(hb*)-(ZH*\\V)Vo*YF)_m)9G)V>)Yl*/'*=g)Fv*`;)V{*rl*Se(t})d>*C1*6P)m`*PR)H0(`n*Zp*nk):/*xx*[9(iu(X5)C=(l})1U)V8(`](}N(tO)WE(rC)l-)kr)0E*84*5q)7{)DF*_s)qz*ZA*X4*mt))^(d;(f0)_E*D!acdf%lw%} *E!)*%-/1%69%=@AFHIMNR%TV%Z\\%^`cghmnp%ruwx{%~ *F!'(%*,%.17%9<%?ACF%HMNP%SVX )RG),4([3(VA)+C)8K*8g*`R)G**dB)sA(ei*n6)-H)|R)GP)8V)}f*.y)n&([N)6X(tZ*`G(_k)y;){G(n:)-v*`L)U~(}e(n[(em(]y)X>(mw)9`*xs*6Q*FW*LV*`8(e{(}t*79)7@)5t*5\\+0,*r6*~!8F )IU(ur)7=(i7)8'(gr*Et)U8(vw)k<*Jz)O|(t<*UW),l)Xo)gc*x](T~)_y({C)us)8N)AJ)p/)1K({R(wd(TM*6')Rq)gE(V5)Dn*09)-d)@C)CY).c(uQ(vu*F![]_abfh%jl%oqrtuwxz%|~ *G!&)%/3468%;=%?AC%HJKO%VXZ%\\^`%ch%jmoprsuw%{}~ *H!&(%.0%4 )(n).9(d'*vx*_n)Fx(n0(i()1_(U')[3*/5*:5*=q(vH(W!Ze (}C*.F)Ch*@r(fw)lL*4G(i{+'g(X/)Ww*Tw(|g)3>(cz)nj)Ws*D~)?)*qJ*.S(f?)zR*)a*q=(k(*1P)kD)8.*FY)VD){c)5-)?C(cv):@)S1))3(f`*m[(U9)Rh*TP(}P)@)*9c)H((f!B8 )Q+)Ox(V()8S(cW*8>(WH(Y7(oA)5&*tB)AT)d.(bg(ab)0x*TS)@])ai)Du*MR)u.)t2)A`(l)(f<*n{)d?*H!5679:>@%BDF%IKLNOQ%UW%Y\\%`d%jl%oq%tv%y{%} *I!&'%/1%46%9;%@B%IKN%QS%WZ )yx)0H))T)0b*6o(t;)1\\)aT)_q)YB)RW)dE)MH*K2))u(UM(xu(j<*n=)Tl*)R*s6)5+*.`)ru*Dr(c2*tb*_')Aw)&4(Y))eY(TQ(d\\(t5(ep)98*o)(]m(Vm++P*.>(gc*W}*J2*8W*qA)V1),c(y5)A.*r_)gj)fA(du*6L*{Z*10({a*r!mF *.Y)q8(dX*ow*{n)~l*Lp)XI(UN*1c)x6*TJ)1s(gx(V?*xY))?)L~(\\M(en*Ul*>1)u9*tH(`d(h@(m8*nZ)V+({l)Vi)AC*I![\\%hj%oqrt%vx%z}~ *J!&'%),%13468%>DEHKMOQ%TV%Z^adeghjl%oq%su%y{%~ *K!&(*%/ (|m(zm)FT*3s(iq)|~)>C)I|(V/)OY*G7*uv(c^)80);@*b0)?>*4E*Tt(^e)H1(d.*I0)4=)Sr)TP*U-(}V*BP*9v*nf)O5*_,)?R)/-).N(Yj*I|)@h*67)f<)1z(^@(`+(on)-F*b(*J**df)*g)D4)/Y(vG(]i(_i*4|(bp)S'*sa)aZ(WL(Yw*1-)C{(je*nb)y8*Jt*.}(rw)5(*tD*DN(k_*x[)-t*Su*?u*d+(e6)@6)*~)lY)0=**l(xA*/!+. *^S(jG({Z)1,)?m)g>*K!13%57%;=%@B%EHILMO%RT%VX[\\_%cefkln%twz%| *L!&')+%-/%57%;=@%DH%LN%PR%UX%[]%_ac *`A)oU)qi*.t*u_*BA(zv){:*t.*Iw(b3)a_).5)@5*TF(|Y*~9))))PB)Rb*S!jl *`B*_V(dA)7&+/!v} (fD(Tq*:+)cw*E7)&i*J7)VR*sb(g|(V.*Ss)`2(gh*qX)_a)WC)pi(Tk)tI*FT(~U),3*Nz*x|*q])^i)Sm(tj)9a)q|*J+)ZS*9:(qa)bL(dB)tO*s^(hS)-J)`Y({k*T~*~V)P<(tT+0&)y_)DM)6/(XQ)mE*0r)T`*r))R.(W+)mv(^G)Fj)Z}*a_*6B(uc)i~*L!de%lnoq%~ *M!&'%03%8:%MO%QSUWXZ%t );M(},*aD){W*U.(vN(gW*7y*<+*MT*26)IX(l<*2l)cU*eI(_)(UL*xU)9N(T`(eS)C1*5v(tB)VU(TF(sx(cJ):5*nK(Y&(WE*JA*xp(t]*a6)ys(V~*4t)m5)S0({S(v\\)-A)I-*Du(ZJ)):(UF)sq(Vy*9A)6T)@\\*ap(}~(VS)-]*7?*`p*3a)mO(V:*KY)26)P~).Q(U6)pc)Y:*TG*Sk*T!n5 ),?*22*1[*.h*;J*<'(mu)Pp*w,*r*(vo(e|*nP)W5({|*{C(}>),R*s-*M!uv%~ *N!&'%:=GM%OQ%SUWY%\\^a%df%hj%ln%y{%~ *O!&')%> (d&*:_)LN(x6+0g)+**/i*!./ *;|*G0*__*Xb)pa)-U*xv)uH)@i(h1)7O(XE*7<)ml)+N*sj*ZX*F;(g:)TH)V/)R?)0X(b/)k~)*l(WS)0y).r(}))l.*b4*ms)d~)Sg)X)*cv)CG(e!(P (X3*eD*TU(d~)*k*_S)W.(U{)p[)JU*DR)2A*8&(X;(Yg*`v++0)20)W!g^ *r{(Uu(wL*t,(TT(~+)y1({>*TQ*1L)gC(pi*9R*bG(e^*a&(j[)&=).,)2/)OD)e]*46*PQ*O!?@%^`%hj%~ *P!&'%@B%H )Up(|1*KZ*xd*Uv*~7+0*)WT(^p(]h(p-*J_(dU):S*_&(n)(f\\(nB)fR)Y(*/Y*_m*:?)2f)/Z*rX)C.*.@*Y!1j *mX(~_*(T)CF)1&*qT*2N(U~*bm(bh*r^(]f*_a*As*d1)AE*w.(ze(c,)tm)D')Fp(gt)^Y({g*^g(^Y(nd(g\\)=f)Ar*X!^C *5:*>v*aL*)6(_r*CH)E/)@2)\\.*E?*[v(lX*`X)ot)^Q)b\\*W|)7S(`3)TR*X<)/@(rv)3\\)C<*X`)5j(jS)Wm)Ck*^Q*P!IJ%PS%Z\\%~ *Q!&'%R *n;*qG)qh)F8)Jw(g6(U:)_:*T,);^)?-({<){J(Zj(|F)sI)QA*PA*(H)Sl)ph)?K*_()''(}Z*D,)F;(co)54)|F)XL*/>)L<)|M)-T)Zr),])9D)VK)D;(TN))X*X&(Vk*4D)o&*s9)7E)@v)6A)Sj*Xu)a7*0Q(]k*3d(eI*aM)6[(hD*F2*_**2;*nq*@o*_j)UU)h.)?A)q_)kZ)t\\*7t*Ww*m;(Y/)Dz)m]*T.*tK)8@*oH*r+*?i)84)r()-e)e\\(Uv)/F)>o)7Y)Ou)>:*Q!ST%uw%~ *R!&'%;=%[ ))o)mk*bW*S~*9d)E))>*(f5*FZ)ss*4&*5-)RH(U8*.a*3))q4)I5)PO)6*(Zl(Xf(n|)7q)Ot*Ye(eG)@1*.R).b)8+)9o*7!lm *0V))d)&,(`P)Aj)ya)z9*X()^t)mx)Yv)Si){X(Ts)p^).k*mR*JU*.b)yE*4C*eH(W!-R *8?(fl))&)U.*T0*(U*^^*3u))b(g=)pJ({P)A,*~n)hA)F]*Ev)Co)f=*T!\\? *`H)|f)_])a>)7.)s7(kx(U(*>a)E}(aj*E[*X.*nR)}e*R!\\]%{}~ *S!&'(*%\\inx *T!+4Nm *U)(X1)T=)x.*~E)6V)cH)7g(TY)tK*^V)<]*XZ*&()GC)*s*KJ(uS)*0R(|h*aT)@q)).(X2)Ej([1(X>(o3)+=#2$*U!CD%KM%PSUVX%_a%df%kn%tw%} *V!&'%)-%3568%:=?%EG%IK%_ (Uz(TR(]e(TV),<(cT(T[(V,(Td+'J(z|(lW(Tn)y2(U,(b}(U4(tS)cY(c})Qp(mt*4h*{l)Q3)re+2\\(T|(V3+2U(U!IV (V'*9O(zk(ie(kV(VX(d!CSY[d *uP*X](c)(eR(c!5=M *X\\(c!ur (_!u{ (`!(GMYZfx{v *?`(a!>CBQT (^N*0<(V!OW]V|u (W&(Vr(W!V.] (XF(W!0`bDf (X!@I )>3(X!@A (cx(d0*q!lqp *r'*qy*r!328?JU]bhj~ *s!*4M *a!vz|x *b!2':9<@ *Y|*Z!&'*.%03%57;<>%@BDJL%RT%VY[\\^%ac%jnor%vy{~ *[!'()+%-01348:;A%EH%MO%Z\\]_`cf *b!>6UKDVJMYlhb]aqu *c!+1OKP^\\fps (`'(th(a!cmn (b&(hQ(b!8>X (e<)be)s[),1(_!ho +'G(dl),>)lW))7(o/(p!3+ (rV(s!;DP (n!ehfoujk (o?(n!w~ (o!LhNi_^KPYV (p!7. (oo(p! (ov(p!*_bdc\\B~y (q)(p!ng *[!hjl%prsuw%y{}~ *\\!&'%*-%/1%79;%FIJLMO%UW%ik%~ *]!&' (q!<>. (pw(q!1OJuQ (r!=DYarX *{}+2^)4t*9!@DFVQoKUX^`r *:!&, *9w*:!68Q *9!_~u *:!9:/ *9!p{hqf *:!2< *9k*:!OweR}uJb@FziA *;!&/ *:t*;!)* *:!NC *;!1fpq *:v*!&B *=!ti7Brf[\\M( *<|*>0*=!SD *>!f[dc} *?!89+:) *>!FPs *?!'=? *>!;w *?!r~ *@!(> *?n*@+*?!{pk *@8*?!RjeH *@!=;d )kc*A7*@H*A8*@w*A9*^!/0%OTjv| *_!.1%35%8;=%@C%FHIK%MPQTWZ%^`cghkqrtx} *`!')*,%.2%467?@DFKMP *A!U: *@!WT *A!XGgc]y )s0*A!Bqz *B!JN-5 *Ax*B!TB+_]Vyg *C!)LtRvc *D0),!;E (t!bg *2m(t{(u'(t~(bw(}!'*19 )5h)6!-b~ )7!4DAX )83)7`)8!J\\T )9e):U)9!)2Fl )8~)9!dB )8z)9!ft ):!QW?^ )9|):!=- );X)9!~v );!KG ):!jz );&):k);!,'d )<1);s))),H).])ko),N(cn(e!NZFEXosc (f!OV%XZG (e~(f![]'6 (g!-? (f!{uh (g!EF/ (f!zj (g!H{Xm_}RQ~ (h&(fv(gN(h'(g!fjw (h!+,. (g!TUO (h/(gz(h!0m9rOfEtuacy| (i`(j!/U (i!Bf:N8I5 *b!HILNOQ%SXZ%\\^%`d%fi%koprtv%y{%} *c!&'%),%.02%EG%JL%NQ%[]_%eg%oq (i!0On%p,)U (j!+r (i|(j!QY( (iz(j?(iw(j!v1 (it(k&(j!]^49 (k!1> (ji(kf(jq(k!23 (jt(k-(j!}d (k!6,9: (j!lm (k!/<+ *^~(k!eOSHkjEGnt (l!F'E (ks(l!;PGJ:BtR_Yijs (m!(Dilrv (n!1'5;@FEX ))!Wa\\Yy )*!*+ *c!rtu~ *d!'(%*,-/034:% *U~)(!Xf )-!W[fkmpy} ).!'38@G *J@)-E)d!ruy|} )e!/-:9>T[U^`cm_of *e!ab%~ *f!&'%g )eg)f!*&4 )ev)f!10(5L8?KDc`js )g!&)8 *8;(tK*yn(t!J( *{!8<%AILRUY\\_befh%j )*o)+')*z)+!,;6OKTI *XS)+!hgq~ ),'*73).!OTaZ )/5).y)/6).!lo )/!078 ).!ux )/!*KgXMA?[]%VX%p )0!CVos )1-)0!v\\ket )1!l;1]XFZ4 )2!GMB: )R!op{} )S!4W~ )T))S[)T!LMF, )S`)T!5+O@C )S_)T!(DS *g!qr%vx%~ *h!&'%79%y )U5)T!|a )U!?D )T!\\Ync )U!'I*1 )To)U!KNP/ )V4)Uk)V!AC )UZ)V!67 )U!X\\x_ )Wd)V!jh )W!(X )Vb)W!*[0' )V|)W`)VN)WV)VQ)Wu)X!_?\\ )YJ)X!PwDE )W!|o )X5)Y!wI0x )Zl)Y!z=?USOoLg'Z7 )[!H,- )Z!cT8nu )[!1Z )Z!iHh )[!osr^Xb` )\\^*h!z{%~ *i!&'%TV%~ *j!&') )\\!V4FCOn{km| )]!NWOmi )^!*9 ({!7;LJ\\o )l,*~h);:(|!BL *L\\(|N*[<*Qv*_!Gdfv *`&*_!uzw *`+*_y*`!=(u!xkq (v!F& (u|(v!K2yzQ|WLm (w'(v}(w!MO,>.[ (x)(w!epW} (x7*4p(x!l]9< (y!'T (xt(y!;= (xz(y!ILZ?OAEr (z!'&BGP (|!sz (z!ju ({*(z!acr *~!?ABDIGJKORTZ\\]`be%gijlmoq *.!9;=?BC *k!34%:<%~ *l!&'%: *.!GJXZ%\\cefjnquz{ */!),/023N7;] )FP)G!/@ )Ft)GA)F!sq}|\\ )H6)G!iNQmE )HC)J=)H})I!GH )Hz*o!(4>DILV[aouvx%~ *p!&(%s )IL)Hq)I!3) )J&)Hd)I8)J@)Ia)J/)Ij)J!,S:OgG )I\\)KB)J!VW )KD)J!X52Hjv )K1)J!z| )K!J'7@U )Jd)KV)J\\)Ku)LL)Kc)L!45 )M))Kh)L!a[ )Md)L!mxR )M!R= )L!ZEu )M!@UTm[o )f!Je )P!:;@=KLFSTZc *^!UW[%]_`bacdfhklnqu *p!tu%~ *q!&'%6;NVbgjmor%xz%|~ *r!&-%0479@DEG%IL%PR%TVY[\\ac%gin%z} *s!&' *^!wxy *_!)+ *\\j)5!'37;>=A@H *7`)k!EJUegi )>/)@!789Sb )DW)@!L^I )^`)C5)@!f}z )A&)@~*2<)A!OD1?FQGgt| )B!>4Urs} )C'*X!236;=@EFHIGMUY *N!AD%FH%K )d!3d )c{)d!+4CDIPRTW )7r)8C)9h*s!)+.%02378:%CE%LNOQRTUWX\\_`eghmnpqs%|~ *t!&'%+/%24%689<>%ACFGIN%PT%VXY[%_acd );E)=,*2:)Q!JS]UYegfmux%z )R!(0+19 )>!0Pf )c!kptN *DV(`0*3!|yp *4@)CH*4!A5/18;k%n_FH]Q[ )CN*4!aouxq *5!89 *4v*5')CS*5=*Ue*5!aIWC]sw~ *6!F+,C2;NO?9 (q~(xw*6!ZTc )Ym*6!u| *7E)Cd*7!C4 *t!ef%moprsuw%{~ *u!&'(*%@BCEG%wz *w!'(%+-0%G )/n)0!63@ )/s)0!2< )1+)2!-4 )3!+wk )4!@F{ *3!]\\ )SA)TK)WF)t!+-5>LMF )?M)t!bQRn%pTqZaX^ )u!*I23 )t[)u,)t|)u!(Fwovcx} )v!&5<(W\\Lou )w/)vw)w!=NH^ +4.+2!>@A )q!1DM9GHZbYmfux )r!78.*AO *w!HI%~ *x!&'%N )r!ILftdgsx )s!-.>CK )l!7=KHEXov )m'*0!@IG *Oi*0!P\\Yaif )p!f~ *Ii*m!89:>=?@BCGJHM%OVW^]`_bcegi%moprw{%~ *n!&'(*%,/%13258%:<>?ABD *x!OP%Tknruy *y!*/%TVW[]^b%dg%mp%~ *z!&'%5 *n!CEHIM%OQSVWY]\\`acdg%il%pruw%y| *o!+,*-2357%9=?@C6E%GJMOPS%UW%Z\\_`^bce%mpr%t; )s!uz *sf)y!Me[c~ )'A)y!{z )z!=3 *z!67%:<=?%[]%~ *{!&'(+%79;HMNPSWX^ )z!XVp +1m*{z){6)oz)p!',2= )k!46 )l)+/!prx%| +0!)(-/.01589;=%@BCEHLNQ%SUZ]%chdj )m!68:DAPGWX\\hUTgfzq )n!.31/62N?FLN[lfrnsy *J!BGP[]` *K!'KE.DQ_PiKULJdjO *F!+34/5 *Ek*FU*Ey*F6*E!zsl *F!EI:JLOKe}`gp\\ *G!'1 *F!vsky *G!(k *Fd*G!fgdIY5Wt%ACE%HJ%OQS%VX%[]_a%ikm%su%w *HV*G!qn *H!=' *Gl*H!;u-BE498GR2lnY )~0)}!`qt )~!)6 )}v)~!-,KabsgXc@eW]fo *&3)~|*&!.??A *(,)>D*(!AMLNRblmqw|}xu *)!.? *95)B?*1!N]dtpux} *2)*)O**u*+!KS *-:*.5+1!VR *Xs*Y!+;8X *X!gm *U!RT *c!w}{| *d8+(!;<%~ +)!&'%A *d!65D=CQRFHM`Ydaevw~ *e!()*0/5 *U`+0u*Y_*Z!9S *[!N^ *Y!\\fcak}~ *Z!(, *Y!uv *Z)*Ym*Z!:EF1GI2WKbkmz|q} *[!/5.*2&>67FG?ekqdiz *\\!+0,8: *V!*4<7JF )?=*N!PXTV +)!BC%~ +*!&'%H *N!_ei *O_*R<*u>*t!-73JELSRnqt *u)+3!loq%vx +2!CPR *s!VYZko )sM*s}*g!Ww *h8*iU*j(*k/*jM*l!Jw ++!369%< )zB++!?BD%FHINOR%WY%]_abd%kn%qx%{~ +,&+*!IJ%~ ++!&'%/12478=>@CGJ%MQ^`cmr%v|} +,!,-56;<'%+.%02%478:= *u!gp|} *v!&A=5DF *~!{z +&(+0O+&!'+-2163<=B +'!][_a`ei *yo*z!;\\ *{!*) +&!PRW`\\l^jy +'!'+7; +1![\\ *-.+0!y~ +1!&)0 *k;+1!;=y%{~} +2!'.,*/4gqt~| +3!)*0 +,!>?%~ +-!&'%~ +.!&'%~ +/!&'%ntw~ +0!'+237DGI%KMPTV%Y\\efik%twxz%} +1!'(*%/2%:<>%CE%QS%UWXZ]%ac%fh%jnpqs%uwx| +2!&()+-0%35%=?BD%OQTVWY%[]_%dfh%prsu%{} +3!&(+%/1%;>%jmny%~ +4!&'%+/%14%8 .*f.+!Zv .,!oy .-!;<%>@BCGN%PRSV%X -R!XY%~ -S!&'%N")),t(e)}); \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/printer/index.html b/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/printer/index.html deleted file mode 100644 index 25dcd8481..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/printer/index.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - Web蓝牙打印机 - - - - - - - - - -
-

Web蓝牙打印机

-
-
- - - - -
- - - - -
-
- - - - -
-
- -

-
-    
- - \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Geolocation/BootstrapBlazor.Geolocation.csproj b/src/components/BootstrapBlazor.Geolocation/BootstrapBlazor.Geolocation.csproj deleted file mode 100644 index affa0a4f4..000000000 --- a/src/components/BootstrapBlazor.Geolocation/BootstrapBlazor.Geolocation.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Bootstrap Blazor Geolocation 定位/持续定位 组件 - Bootstrap UI Geolocation components experience - 1591 - - - - - - - - - - - diff --git a/src/components/BootstrapBlazor.Geolocation/GeolocationItem.cs b/src/components/BootstrapBlazor.Geolocation/GeolocationItem.cs deleted file mode 100644 index 42653d52a..000000000 --- a/src/components/BootstrapBlazor.Geolocation/GeolocationItem.cs +++ /dev/null @@ -1,124 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - - -using System.ComponentModel; - -namespace BootstrapBlazor.Components; - -/// -/// 定位数据类 -/// -public class Geolocationitem -{ - /// - /// 状态 - /// - /// - [DisplayName("状态")] - public string? Status { get; set; } - - /// - /// 纬度 - /// - /// - [DisplayName("纬度")] - public decimal Latitude { get; set; } - - /// - /// 经度 - /// - /// - [DisplayName("经度")] - public decimal Longitude { get; set; } - - /// - /// 准确度(米) - /// 将以m指定维度和经度值与实际位置的差距,置信度为95%. - /// - [DisplayName("准确度(米)")] - public decimal Accuracy { get; set; } - - /// - /// 时间戳 - /// - [DisplayName("时间戳")] - public long Timestamp { get; set; } - - /// - /// 时间 - /// - [DisplayName("时间")] - public DateTime LastUpdateTime { get => UnixTimeStampToDateTime(Timestamp); } - - /// - /// 移动距离 - /// - [DisplayName("移动距离")] - public decimal CurrentDistance { get; set; } = 0.0M; - - /// - /// 总移动距离 - /// - [DisplayName("总移动距离")] - public decimal TotalDistance { get; set; } = 0.0M; - - /// - /// 最后一次获取到的纬度 - /// - [DisplayName("最后一次获取到的纬度")] - public decimal LastLat { get; set; } - - /// - /// 最后一次获取到的经度 - /// - [DisplayName("最后一次获取到的经度")] - public decimal LastLong { get; set; } - - - /// - /// - /// - /// - /// - public static DateTime UnixTimeStampToDateTime(long unixTimeStamp) - { - // Unix timestamp is seconds past epoch - System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); - dtDateTime = dtDateTime.AddMilliseconds(unixTimeStamp).ToLocalTime(); - return dtDateTime; - } - -} - - -/// -/// 定位参数 -/// -public class GeolocationOptions -{ - /// - /// 是否启用高精度定位 - /// - /// - [DisplayName("是否启用高精度定位")] - public bool EnableHighAccuracy { get; set; } = true; - /// - /// - /// 超时时间 - /// - /// - [DisplayName("超时时间")] - public int Timeout { get; set; } = 5000; - /// - /// - /// 最大等待时间 - /// - /// - [DisplayName("最大等待时间")] - public int MaximumAge { get; set; } = 0; - -} diff --git a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor b/src/components/BootstrapBlazor.Geolocation/Geolocations.razor deleted file mode 100644 index f2c96ce6b..000000000 --- a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor +++ /dev/null @@ -1,15 +0,0 @@ -@namespace BootstrapBlazor.Components - -
- @if (ShowButtons) - { - if (WatchID == null) - { - - - } - else - { - } - } -
diff --git a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.cs b/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.cs deleted file mode 100644 index f61d83a1d..000000000 --- a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.cs +++ /dev/null @@ -1,205 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -/// -/// Geolocation 组件基类 -/// -/// 扩展阅读:Chrome中模拟定位信息,清除定位信息 -/// https://blog.csdn.net/u010844189/article/details/81163438 -/// -public partial class Geolocations : IAsyncDisposable -{ - [Inject] - [NotNull] - private IJSRuntime? JSRuntime { get; set; } - - - /// - /// 获得/设置 定位 - /// - [Parameter] - [NotNull] - public string? GeolocationInfo { get; set; } - - /// - /// 获得/设置 获取位置按钮文字 默认为 获取位置 - /// - [Parameter] - [NotNull] - public string? GetLocationButtonText { get; set; } = "获取位置"; - - /// - /// 获得/设置 获取持续定位监听器ID - /// - [Parameter] - public long? WatchID { get; set; } - - /// - /// 获得/设置 获取移动距离追踪按钮文字 默认为 移动距离追踪 - /// - [Parameter] - [NotNull] - public string? WatchPositionButtonText { get; set; } = "移动距离追踪"; - - /// - /// 获得/设置 获取停止追踪按钮文字 默认为 停止追踪 - /// - [Parameter] - [NotNull] - public string? ClearWatchPositionButtonText { get; set; } = "停止追踪"; - - /// - /// 获得/设置 是否显示默认按钮界面 - /// - [Parameter] - public bool ShowButtons { get; set; } = true; - - /// - /// UI界面元素的引用对象 - /// - protected ElementReference Element { get; set; } - - /// - /// 获得/设置 定位结果回调方法 - /// - [Parameter] - public Func? OnResult { get; set; } - - /// - /// 获得/设置 状态更新回调方法 - /// - [Parameter] - public Func? OnUpdateStatus { get; set; } - - /// - /// 获得/设置 状态更新回调方法 - /// - [Parameter] - public GeolocationOptions Options { get; set; } = new(); - - private IJSObjectReference? Module { get; set; } - private DotNetObjectReference? Instance { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - try - { - if (firstRender) - { - Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.Geolocation/Geolocations.razor.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - Instance = DotNetObjectReference.Create(this); - } - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - async ValueTask IAsyncDisposable.DisposeAsync() - { - if (Module is not null) - { - //await Module.InvokeVoidAsync("destroy"); - Instance!.Dispose(); - await Module.DisposeAsync(); - } - } - - - /// - /// 获取定位 - /// - public virtual async Task GetLocation() - { - try - { - await Module!.InvokeVoidAsync("getLocation", Instance, true, Options); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 持续定位 - /// - public virtual async Task WatchPosition() - { - try - { - await Module!.InvokeVoidAsync("getLocation", Instance, false); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 持续定位 - /// - public virtual async Task ClearWatch() - { - await Module!.InvokeVoidAsync("clearWatchLocation", Instance, WatchID); - WatchID = null; - } - - /// - /// 定位完成回调方法 - /// - /// - /// - [JSInvokable] - public async Task GetResult(Geolocationitem geolocations) - { - try - { - if (OnResult != null) await OnResult.Invoke(geolocations); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 获得/设置 错误回调方法 - /// - [Parameter] - public Func? OnError { get; set; } - - /// - /// 状态更新回调方法 - /// - /// - /// - [JSInvokable] - public async Task UpdateStatus(string status) - { - if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(status); - } - - /// - /// 监听器ID回调方法 - /// - /// - /// - [JSInvokable] - public Task UpdateWatchID(long watchID) - { - WatchID = watchID; - return Task.CompletedTask; - } - -} diff --git a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.js b/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.js deleted file mode 100644 index 4d9f4d3d0..000000000 --- a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.js +++ /dev/null @@ -1,135 +0,0 @@ -export function getLocation(wrapper, getPosition = true, options = null) { - console.log('start ' + (getPosition ? 'getLocation' : 'watchPosition')); - var currentDistance = 0.0; - var totalDistance = 0.0; - var lastLat; - var lastLong; - var status; - - if (getPosition) - getCurrentPosition(); - else - watchPosition(); - - Number.prototype.toRadians = function () { - return this * Math.PI / 180; - } - - if (!options) { - options = { - enableHighAccuracy: true, - timeout: 5000, - maximumAge: 0, - } - }; - - function distance(latitude1, longitude1, latitude2, longitude2) { - // R is the radius of the earth in kilometers - var R = 6371; - - var deltaLatitude = (latitude2 - latitude1).toRadians(); - var deltaLongitude = (longitude2 - longitude1).toRadians(); - latitude1 = latitude1.toRadians(), latitude2 = latitude2.toRadians(); - - var a = Math.sin(deltaLatitude / 2) * - Math.sin(deltaLatitude / 2) + - Math.cos(latitude1) * - Math.cos(latitude2) * - Math.sin(deltaLongitude / 2) * - Math.sin(deltaLongitude / 2); - - var c = 2 * Math.atan2(Math.sqrt(a), - Math.sqrt(1 - a)); - var d = R * c; - return d; - } - - - function updateStatus(message) { - status = message; - wrapper.invokeMethodAsync('UpdateStatus', message); - } - - function watchPosition() { - if (navigator.geolocation) { - status = "HTML5 Geolocation is supported in your browser."; - updateStatus(status); - var id = navigator.geolocation.watchPosition(updateLocation, - handleLocationError,{ maximumAge: 20000 }); - wrapper.invokeMethodAsync('UpdateWatchID', id); - } - } - - function getCurrentPosition() { - if (navigator.geolocation) { - updateStatus("HTML5 Geolocation is supported in your browser."); - navigator.geolocation.getCurrentPosition(updateLocation, - handleLocationError, options); - } - } - - function updateLocation(position) { - var latitude = position.coords.latitude; - var longitude = position.coords.longitude; - var accuracy = position.coords.accuracy; - var timestamp = position.timestamp; - - // sanity test... don't calculate distance if accuracy - // value too large - if (accuracy >= 500) { - updateStatus("Need more accurate values to calculate distance."); - } - - // calculate distance - currentDistance = 0.0; - if ((lastLat != null) && (lastLong != null)) { - currentDistance = distance(latitude, longitude, lastLat, lastLong); - totalDistance += currentDistance; - } - - - lastLat = latitude; - lastLong = longitude; - - updateStatus("Location successfully updated."); - - console.log("updateLocation end"); - var geolocationitem = { - "Status": status, - "Latitude": latitude, - "Longitude": longitude, - "Accuracy": accuracy, - "Timestamp": timestamp, - "CurrentDistance": currentDistance, - "TotalDistance": totalDistance, - "LastLat": lastLat, - "LastLong": lastLong, - }; - wrapper.invokeMethodAsync('GetResult', geolocationitem); - } - - function handleLocationError(error) { - switch (error.code) { - case 0: - updateStatus("There was an error while retrieving your location: " + error.message); - break; - case 1: - updateStatus("The user prevented this page from retrieving a location."); - break; - case 2: - updateStatus("The browser was unable to determine your location: " + error.message); - break; - case 3: - updateStatus("The browser timed out before retrieving the location."); - break; - } - } - -} -export function clearWatchLocation(wrapper, id) { - //扩展阅读:移除的监听器 - //id = navigator.geolocation.watchPosition(success, error, options); - console.log('clearWatch ' + id); - navigator.geolocation.clearWatch(id); - wrapper.invokeMethodAsync('UpdateStatus', 'clearWatch ok'); -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Maps/BootstrapBlazor.Maps.csproj b/src/components/BootstrapBlazor.Maps/BootstrapBlazor.Maps.csproj deleted file mode 100644 index 1b81cc07f..000000000 --- a/src/components/BootstrapBlazor.Maps/BootstrapBlazor.Maps.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Bootstrap Blazor Maps 谷歌地图 组件 - Bootstrap UI Maps components experience - 1591 - - - - - - - - - - - - - - - diff --git a/src/components/BootstrapBlazor.Maps/Map.razor b/src/components/BootstrapBlazor.Maps/Map.razor deleted file mode 100644 index e77101f35..000000000 --- a/src/components/BootstrapBlazor.Maps/Map.razor +++ /dev/null @@ -1,5 +0,0 @@ -@namespace BootstrapBlazor.Components - -
-
- diff --git a/src/components/BootstrapBlazor.Maps/Map.razor.cs b/src/components/BootstrapBlazor.Maps/Map.razor.cs deleted file mode 100644 index f8ed73591..000000000 --- a/src/components/BootstrapBlazor.Maps/Map.razor.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Configuration; -using Microsoft.JSInterop; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; -/// -/// 谷歌地图 Maps 组件 -/// -public partial class Map : IAsyncDisposable -{ - [Inject] - [NotNull] - private IJSRuntime? JSRuntime { get; set; } - - [Inject] private IConfiguration? config { get; set; } - - /// - /// 获得/设置 错误回调方法 - /// - [Parameter] - public Func? OnError { get; set; } - - /// - /// 获得/设置 GoogleKey - /// 为空则在 IConfiguration 服务获取 "GoogleKey" , 默认在 appsettings.json 文件配置 - /// - [Parameter] - public string? GoogleKey { get; set; } - - /// - /// 获得/设置 style - /// - [Parameter] - public string Style { get; set; } = "height:700px;width:100%;"; - - /// - /// UI界面元素的引用对象 - /// - private ElementReference Element { get; set; } - - private IJSObjectReference? Module { get; set; } - private string key = String.Empty; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - key = GoogleKey ?? (config?["GoogleKey"]) ?? "abcd"; - Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.Maps/lib/google/map.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - while (!(await Init())) - { - await Task.Delay(500); - } - - //await Module.InvokeVoidAsync("initMaps" ); - } - } - - - public async Task Init() => await Module!.InvokeAsync("addScript", new object?[] { key, Element, null, null, null }); - - public async Task OnBtnClick() => await Module!.InvokeVoidAsync("addScript", new object?[] { key, Element, null, null, null }); - - async ValueTask IAsyncDisposable.DisposeAsync() - { - if (Module is not null) - { - //await Module.InvokeVoidAsync("destroy", Options); - await Module.DisposeAsync(); - } - } -} diff --git a/src/components/BootstrapBlazor.Maps/wwwroot/lib/google/map.js b/src/components/BootstrapBlazor.Maps/wwwroot/lib/google/map.js deleted file mode 100644 index 3ba726906..000000000 --- a/src/components/BootstrapBlazor.Maps/wwwroot/lib/google/map.js +++ /dev/null @@ -1,601 +0,0 @@ -export function addScript(key, elementId, dotnetRef, backgroundColor, controlSize) { - if (!key || !elementId) { - return; - } - - //storeElementIdWithDotnetRef(_mapsElementDict, elementId, dotnetRef, backgroundColor, controlSize); //Store map info - - let url = "https://maps.googleapis.com/maps/api/js?key="; - let scriptsIncluded = false; - - let scriptTags = document.querySelectorAll('head > script'); - scriptTags.forEach(scriptTag => { - if (scriptTag) { - let srcAttribute = scriptTag.getAttribute('src'); - if (srcAttribute && srcAttribute.startsWith(url)) { - scriptsIncluded = true; - return true; - } - } - }); - - if (scriptsIncluded) { //防止多次向页面添加 JS 脚本.Prevent adding JS scripts to page multiple times. - if (window.google) { - initMaps(elementId); //页面已导航.Page was navigated - } - return true; - } - - //Inject required Google JS scripts to HTML (only once!) - //let importedPoly = document.createElement('script'); - //importedPoly.src = "https://polyfill.io/v3/polyfill.min.js?features=default"; - //document.head.appendChild(importedPoly); - - url = url + key + "&callback=initGoogleMaps&libraries=&v=weekly"; - let script = document.createElement('script'); - script.src = url; - script.defer = true; - document.head.appendChild(script); - return false; -} - -export function initMaps(elementId) { - var latlng = new google.maps.LatLng(40.26982, -3.758269); - var options = { - zoom: 14, center: latlng, - mapTypeId: google.maps.MapTypeId.ROADMAP - }; - var map = new google.maps.Map(elementId, options); - console.log(map); - return map; -} - -//Global function for Google Js callback. It will be called when "https://maps.googleapis.com/maps/api/js" loaded. -//TODO: multiple instances of Js Maps if registered must be stored before callback happens. In the future it might causes timing issues... -window.initGoogleMaps = () => { - for (let i = 0; i < _mapsElementDict.length; i++) { - let elementId = _mapsElementDict[i].key; - let mapInfo = _mapsElementDict[i].value; - - if (_mapsElementDict[i].value.map) { //Map already created - continue; - } - - //Create Map - let map = new google.maps.Map(document.getElementById(elementId), { - backgroundColor: mapInfo.bgColor, - controlSize: mapInfo.ctrSize, - }); - map.elementId = elementId; - _mapsElementDict[i].value.map = map; - - function mouseEventHandlers(mapsMouseEvent, callbackFuncName) { - if (map && map.elementId && mapsMouseEvent) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - let coord = mapsMouseEvent.latLng.toJSON(); - let arg = { - Latitude: coord.lat, - Longitude: coord.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync(callbackFuncName, arg); - } - } - } - - //Add Event listeners - //Mouse - map.addListener("click", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapClicked"); - }); - map.addListener("dblclick", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapDoubleClicked"); - }); - map.addListener("contextmenu", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapContextMenu"); - }); - map.addListener("mouseup", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapMouseUp"); - }); - map.addListener("mousedown", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapMouseDown"); - }); - map.addListener("mousemove", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapMouseMove"); - }); - map.addListener("mouseover", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapMouseOver"); - } - } - }); - map.addListener("mouseout", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapMouseOut"); - } - } - }); - //Changes - map.addListener("center_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapCenterChanged", arg); - } - } - }); - map.addListener("zoom_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapZoomChanged", map.getZoom()); - } - } - }); - map.addListener("maptypeid_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapTypeIdChanged", map.getMapTypeId()); - } - } - }); - map.addListener("heading_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapHeadingChanged", map.getHeading()); - } - } - }); - map.addListener("tilt_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapTiltChanged", map.getTilt()); - } - } - }); - map.addListener("bounds_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapBoundsChanged"); - } - } - }); - map.addListener("projection_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapProjectionChanged"); - } - } - }); - map.addListener("draggable_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapDraggableChanged"); - } - } - }); - map.addListener("streetview_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapStreetviewChanged"); - } - } - }); - //Drag - map.addListener("drag", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapDrag", arg); - } - } - }); - map.addListener("dragend", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapDragEnd", arg); - } - } - }); - map.addListener("dragstart", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapDragStart", arg); - } - } - }); - //Other - map.addListener("resize", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - let arg = { - Width: map.getDiv().offsetWidth, - Height: map.getDiv().offsetHeight - }; - mapWithDotnetRef.ref.invokeMethodAsync("MapResized", arg); - } - } - }); - map.addListener("tilesloaded", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapTilesLoaded"); - } - } - }); - map.addListener("idle", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapIdle"); - } - } - }); - //Init - _mapsElementDict[i].value.ref.invokeMethodAsync("MapInitialized", elementId); - } -}; - -//Store elementId with .NET Ref -function storeElementIdWithDotnetRef(dict, elementId, dotnetRef, backgroundColor, controlSize) { - let elementFound = false; - for (let i = 0; i < dict.length; i++) { - if (dict[i].key === elementId) { - return; //Element has been stored already - } - } - - if (!elementFound) { - dict.push({ - key: elementId, - value: { ref: dotnetRef, map: null, bgColor: backgroundColor, ctrSize: controlSize } - }); - } -} -//Remove elementId with data -function removeElementIdWithDotnetRef(dict, elementId) { - for (let i = 0; i < dict.length; i++) { - if (dict[i].key === elementId) { - dict.splice(i, 1); - break; - } - } -} -//Return elementId with data -function getElementIdWithDotnetRef(dict, elementId) { - for (let i = 0; i < dict.length; i++) { - if (dict[i].key === elementId) { - return dict[i].value; - } - } -} - -let _mapsElementDict = []; -let _mapsMarkers = []; - -//Google JS Maps Features -export function setCenterCoords(elementId, latitude, longitude) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setCenter({ lat: latitude, lng: longitude }); - } - } -} -export function setCenterAddress(elementId, address) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - geocodeAddress(address, function (results) { - if (results) { - mapWithDotnetRef.map.setCenter(results[0].geometry.location); - } - }); - } - } -} -export function panToCoords(elementId, latitude, longitude) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.panTo({ lat: latitude, lng: longitude }); - } - } -} -export function panToAddress(elementId, address) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - geocodeAddress(address, function (results) { - if (results) { - mapWithDotnetRef.map.panTo(results[0].geometry.location); - } - }); - } - } -} -//set methods -export function setZoom(elementId, zoom) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setZoom(zoom); - } - } -} -export function setMapType(elementId, mapType) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setMapTypeId(mapType); - } - } -} -export function setHeading(elementId, heading) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setHeading(heading); - } - } -} -export function setTilt(elementId, tilt) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setTilt(tilt); - } - } -} -export function setClickableIcons(elementId, isClickable) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setClickableIcons(isClickable); - } - } -} -//generic set -export function setOptions(elementId, options) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setOptions(options); - } - } -} - -export function resizeMap(elementId) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - google.maps.event.trigger(mapWithDotnetRef.map, "resize"); - } - } -} - -//Custom controls -export function createCustomControls(elementId, customControls) { - if (elementId && customControls) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - - for (var i = 0; i < customControls.length; i++) { - let control = customControls[i]; - let controlDiv = document.createElement("div"); - controlDiv.innerHTML = control.content; - - mapWithDotnetRef.map.controls[control.controlPosition].push(controlDiv); - - let id = control.id; - let dotnetRef = mapWithDotnetRef.ref; - controlDiv.addEventListener("click", () => { - dotnetRef.invokeMethodAsync("CustomControlClicked", id); - }); - } - } - } -} - -//Markers -export function createMarkers(elementId, markers) { - if (elementId && markers && markers.length) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - - for (var i = 0; i < markers.length; i++) { - - let markerData = markers[i]; - let marker = new google.maps.Marker({ - id: markerData.id, //Custom id to track Markers - //some property does not work after set... - crossOnDrag: markerData.crossOnDrag, - optimized: markerData.optimized, - }); - - marker.setMap(mapWithDotnetRef.map); - setMarkerData(markerData, marker); - _mapsMarkers.push(marker); - - //Marker events - if (markerData.clickable) { - //Create infoWindow - let infoWindow = null; - if (markerData.infoWindow) { - infoWindow = new google.maps.InfoWindow({ - content: markerData.infoWindow.content, - maxWidth: markerData.infoWindow.maxWidth - }); - } - - marker.addListener("click", () => { - mapWithDotnetRef.ref.invokeMethodAsync("MarkerClicked", markerData.id); - - //If marker has info window - if (infoWindow) { - infoWindow.open(mapWithDotnetRef.map, marker); - } - }); - } - if (markerData.draggable) { - marker.addListener("drag", () => { - markerDragEvents("MarkerDrag", markerData.id, marker.getPosition().toJSON()); - }); - - marker.addListener("dragend", () => { - markerDragEvents("MarkerDragEnd", markerData.id, marker.getPosition().toJSON()); - }); - - marker.addListener("dragstart", () => { - markerDragEvents("MarkerDragStart", markerData.id, marker.getPosition().toJSON()); - }); - - function markerDragEvents(callBackName, id, pos) { - let arg = { - Latitude: pos.lat, - Longitude: pos.lng - }; - mapWithDotnetRef.ref.invokeMethodAsync(callBackName, id, arg); - } - } - } - } - } -} -//export function updateMarkers(elementId, markers) { -// if (elementId && markers && markers.length) { -// let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); -// if (mapWithDotnetRef && mapWithDotnetRef.map) { - -// for (var i = 0; i < markers.length; i++) { -// let markerData = markers[i]; - -// _mapsMarkers.forEach(element => { -// if (markerData.id == element.id) { -// setMarkerData(markerData, element); -// return; -// } -// }); -// } -// } -// } -//} -export function removeMarkers(elementId, markers) { - if (elementId && markers && markers.length) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - - for (var i = 0; i < markers.length; i++) { - let markerData = markers[i]; - - _mapsMarkers.forEach((element, index) => { - if (markerData.id == element.id) { - element.setMap(null); - _mapsMarkers.splice(index, 1); - return; - } - }); - } - } - } -} -function setMarkerData(markerData, marker) { - if (!marker || !markerData) { - return; - } - - //required - marker.setPosition({ lat: markerData.position.latitude, lng: markerData.position.longitude }); - //optional - //marker.setAnchorPoint(markerData.anchorPoint ? { x: markerData.anchorPoint.x, y: markerData.anchorPoint.y } : null); - marker.anchorPoint = markerData.anchorPoint ? { x: markerData.anchorPoint.x, y: markerData.anchorPoint.y } : null; - marker.setAnimation(markerData.animation); - marker.setClickable(markerData.clickable); - //marker.setCrossOnDrag(markerData.crossOnDrag); - marker.crossOnDrag = markerData.crossOnDrag; - marker.setCursor(markerData.cursor); - marker.setDraggable(markerData.draggable); - marker.setIcon(markerData.icon); - marker.setLabel(markerData.label); - marker.setOpacity(markerData.opacity); - //marker.setOptimized(markerData.optimized); - marker.optimized = markerData.optimized; - marker.setShape(markerData.shape); - marker.setTitle(markerData.title); - marker.setVisible(markerData.visible); - marker.setZIndex(markerData.zIndex); -} - -//Google GeoCoder -export function getAddressCoordinates(elementId, address) { - geocodeAddress(address, function (results) { - if (results) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - //TODO: map .NET object - mapWithDotnetRef.ref.invokeMethodAsync("AddressSearch", results); - } - } - }); -} -function geocodeAddress(address, successCallback) { - let geocoder = new google.maps.Geocoder(); - geocoder.geocode({ - 'address': address - }, function (results, status) { - if (status == google.maps.GeocoderStatus.OK) { - successCallback(results); - } - }); -} - -//Dispose -export function dispose(elementId) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - mapWithDotnetRef.map = null; - mapWithDotnetRef.ref = null; - - removeElementIdWithDotnetRef(_mapsElementDict, elementId); - } -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/BootstrapBlazor.OpenAI.csproj b/src/components/BootstrapBlazor.OpenAI.GPT3/BootstrapBlazor.OpenAI.csproj deleted file mode 100644 index e92220345..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/BootstrapBlazor.OpenAI.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - Bootstrap Blazor OpenAI 组件 - Bootstrap UI OpenAI components experience - 1591 - - - - - - - - - - - - - - - - - - diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/EnumOpenAiModel.cs b/src/components/BootstrapBlazor.OpenAI.GPT3/EnumOpenAiModel.cs deleted file mode 100644 index 2fdb9606b..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/EnumOpenAiModel.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using System.ComponentModel.DataAnnotations; - -namespace BootstrapBlazor.OpenAI.Services; - -/// -/// -/// -public enum EnumOpenAiModel -{ - /// - ///ChatGPT - /// - [Display(Name = "ChatGPT")] - ChatGpt, - - /// - ///Completions - /// - [Display(Name = "Completions")] - Completions, - - ///// - ///// Completions Stream - ///// - //[Display(Name = "Completions Stream")] - //CompletionsStream, - - /// - /// DALL-E - /// - [Display(Name = "DALL-E")] - DALLE, - - /// - ///ChatGPT AiHomeAssistant - /// - [Display(Name = "AiHomeAssistant")] - ChatGptAiHomeAssistant, - - [Display(Name = "聊天机器人")] - Chatbot, - - [Display(Name = "自然语言转SQL")] - NaturalLanguageToSQL, - - [Display(Name = "提取信息")] - ExtractingInformation, - - /// - ///ChatGPT4 - /// - [Display(Name = "ChatGPT4")] - ChatGpt4, - - /// - ///ChatGPT4-32k - /// - [Display(Name = "ChatGPT4 32k")] - ChatGpt4_32k, - -} diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor b/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor deleted file mode 100644 index 7062f28eb..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor +++ /dev/null @@ -1,204 +0,0 @@ -@namespace BootstrapBlazor.Components - -@{ - bool isSimpleText = (SelectedEnumItem == EnumOpenAiModel.ChatGpt || SelectedEnumItem == EnumOpenAiModel.ChatGpt4 || SelectedEnumItem == EnumOpenAiModel.Completions || SelectedEnumItem == EnumOpenAiModel.ChatGptAiHomeAssistant || SelectedEnumItem == EnumOpenAiModel.Chatbot || SelectedEnumItem == EnumOpenAiModel.DALLE); -} -
-
-