From 32839bd0d12320701b722e82ac9c4ccba4c928ce Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Feb 2025 14:03:38 -0800 Subject: [PATCH 001/136] initial notification impl --- v3/examples/notifications/main.go | 131 ++++ .../desktop/@wailsio/runtime/package.json | 2 +- .../@wailsio/runtime/src/event_types.js | 1 + .../@wailsio/runtime/types/event_types.d.ts | 1 + v3/pkg/application/application_darwin.go | 35 + .../application/context_application_event.go | 6 +- v3/pkg/application/notifications_darwin.go | 177 +++++ v3/pkg/application/notifications_darwin.h | 31 + v3/pkg/application/notifications_darwin.m | 278 ++++++++ v3/pkg/events/events.go | 619 +++++++++--------- v3/pkg/events/events.txt | 1 + v3/pkg/events/events_darwin.h | 223 +++---- 12 files changed, 1084 insertions(+), 421 deletions(-) create mode 100644 v3/examples/notifications/main.go create mode 100644 v3/pkg/application/notifications_darwin.go create mode 100644 v3/pkg/application/notifications_darwin.h create mode 100644 v3/pkg/application/notifications_darwin.m diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go new file mode 100644 index 000000000..2bf9735fd --- /dev/null +++ b/v3/examples/notifications/main.go @@ -0,0 +1,131 @@ +package main + +import ( + _ "embed" + "fmt" + "log" + "time" + + "github.com/wailsapp/wails/v3/pkg/application" + "github.com/wailsapp/wails/v3/pkg/events" +) + +func main() { + app := application.New(application.Options{ + Name: "Notifications Demo", + Description: "A test of macOS notifications", + Assets: application.AlphaAssets, + }) + + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Width: 500, + Height: 800, + }) + + app.OnApplicationEvent(events.Mac.ApplicationDidFinishLaunching, func(event *application.ApplicationEvent) { + // Request pemission to send notifications + granted, err := application.RequestUserNotificationAuthorization() + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + + if granted { + // Send notification with no actions + err = application.SendNotification("some-uuid", "Title", "", "body!") + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + + err = application.RegisterNotificationCategory(application.NotificationCategory{ + ID: "MESSAGE_CATEGORY", + Actions: []application.NotificationAction{ + {ID: "VIEW_ACTION", Title: "View"}, + {ID: "MARK_READ_ACTION", Title: "Mark as Read"}, + {ID: "DELETE_ACTION", Title: "Delete", Destructive: true}, + }, + HasReplyField: true, + ReplyPlaceholder: "Type your reply...", + ReplyButtonTitle: "Reply", + }) + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + + err = application.SendNotificationWithActions(application.NotificationOptions{ + ID: "some-other-uuid", + Title: "New Message", + Subtitle: "From: Jane Doe", + Body: "Is it raining today where you are?", + CategoryID: "MESSAGE_CATEGORY", + Data: map[string]interface{}{ + "messageId": "msg-123", + "senderId": "user-123", + "timestamp": time.Now().Unix(), + }, + }) + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + } + }) + + app.OnApplicationEvent(events.Mac.DidReceiveNotificationResponse, func(event *application.ApplicationEvent) { + data := event.Context().GetData() + + // Parse data received + if data != nil { + if identifier, ok := data["identifier"].(string); ok { + fmt.Printf("Notification identifier: %s\n", identifier) + } + + if actionIdentifier, ok := data["actionIdentifier"].(string); ok { + fmt.Printf("Action Identifier: %s\n", actionIdentifier) + } + + if userText, ok := data["userText"].(string); ok { + fmt.Printf("User replied: %s\n", userText) + } + + if userInfo, ok := data["userInfo"].(map[string]interface{}); ok { + fmt.Printf("Custom data: %+v\n", userInfo) + } + + // Send notification to JS + app.EmitEvent("notification", data) + } + }) + + go func() { + time.Sleep(time.Second * 5) + // Sometime later check if you are still authorized + granted, err := application.CheckNotificationAuthorization() + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + println(granted) + + // Sometime later remove delivered notification by identifier + err = application.RemoveDeliveredNotification("some-uuid") + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + }() + + go func() { + time.Sleep(time.Second * 10) + // Sometime later remove all pending and delivered notifications + err := application.RemoveAllPendingNotifications() + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + err = application.RemoveAllDeliveredNotifications() + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + } + }() + + err := app.Run() + if err != nil { + log.Fatal(err) + } +} diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/package.json b/v3/internal/runtime/desktop/@wailsio/runtime/package.json index 4c3544130..7412db923 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/package.json +++ b/v3/internal/runtime/desktop/@wailsio/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@wailsio/runtime", "type": "module", - "version": "3.0.0-alpha.56", + "version": "3.0.0-alpha.57", "description": "Wails Runtime", "types": "types/index.d.ts", "exports": { diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js b/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js index 9c7feed7c..f56a77cb6 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js @@ -69,6 +69,7 @@ export const EventTypes = { ApplicationWillTerminate: "mac:ApplicationWillTerminate", ApplicationWillUnhide: "mac:ApplicationWillUnhide", ApplicationWillUpdate: "mac:ApplicationWillUpdate", + DidReceiveNotificationResponse: "mac:DidReceiveNotificationResponse", MenuDidAddItem: "mac:MenuDidAddItem", MenuDidBeginTracking: "mac:MenuDidBeginTracking", MenuDidClose: "mac:MenuDidClose", diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts b/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts index e8742de59..5c2d40009 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts +++ b/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts @@ -69,6 +69,7 @@ export declare const EventTypes: { ApplicationWillTerminate: string, ApplicationWillUnhide: string, ApplicationWillUpdate: string, + DidReceiveNotificationResponse: string, MenuDidAddItem: string, MenuDidBeginTracking: string, MenuDidClose: string, diff --git a/v3/pkg/application/application_darwin.go b/v3/pkg/application/application_darwin.go index 623e4a94c..ce205b029 100644 --- a/v3/pkg/application/application_darwin.go +++ b/v3/pkg/application/application_darwin.go @@ -228,6 +228,41 @@ func (m *macosApp) setApplicationMenu(menu *Menu) { C.setApplicationMenu(m.applicationMenu) } +// RequestNotificationPermission requests user permission for notifications +func (m *macosApp) RequestNotificationPermission() (bool, error) { + return RequestUserNotificationAuthorization() +} + +// CheckNotificationPermission checks current permission status +func (m *macosApp) CheckNotificationPermission() (bool, error) { + return CheckNotificationAuthorization() +} + +// SendNotification sends a simple notification +func (m *macosApp) SendNotification(identifier, title, subtitle, body string) error { + return SendNotification(identifier, title, subtitle, body) +} + +// SendNotificationWithActions sends a notification with custom actions +func (m *macosApp) SendNotificationWithActions(options NotificationOptions) error { + return SendNotificationWithActions(options) +} + +// RegisterNotificationCategory registers a notification category with actions +func (m *macosApp) RegisterNotificationCategory(category NotificationCategory) error { + return RegisterNotificationCategory(category) +} + +// RemoveAllPendingNotifications removes all pending notifications +func (m *macosApp) RemoveAllPendingNotifications() { + RemoveAllPendingNotifications() +} + +// RemovePendingNotification removes a specific pending notification +func (m *macosApp) RemovePendingNotification(identifier string) { + RemovePendingNotification(identifier) +} + func (m *macosApp) run() error { if m.parent.options.SingleInstance != nil { cUniqueID := C.CString(m.parent.options.SingleInstance.UniqueID) diff --git a/v3/pkg/application/context_application_event.go b/v3/pkg/application/context_application_event.go index 468634f22..50cf8b90d 100644 --- a/v3/pkg/application/context_application_event.go +++ b/v3/pkg/application/context_application_event.go @@ -52,7 +52,7 @@ func (c ApplicationEventContext) HasVisibleWindows() bool { return c.getBool("hasVisibleWindows") } -func (c ApplicationEventContext) setData(data map[string]any) { +func (c *ApplicationEventContext) setData(data map[string]any) { c.data = data } @@ -72,6 +72,10 @@ func (c ApplicationEventContext) Filename() string { return result } +func (c *ApplicationEventContext) GetData() map[string]any { + return c.data +} + func newApplicationEventContext() *ApplicationEventContext { return &ApplicationEventContext{ data: make(map[string]any), diff --git a/v3/pkg/application/notifications_darwin.go b/v3/pkg/application/notifications_darwin.go new file mode 100644 index 000000000..e04075238 --- /dev/null +++ b/v3/pkg/application/notifications_darwin.go @@ -0,0 +1,177 @@ +//go:build darwin + +package application + +/* +#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c +#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications +#import "notifications_darwin.h" +*/ +import "C" +import ( + "encoding/json" + "fmt" + "unsafe" +) + +// NotificationAction represents a button in a notification +type NotificationAction struct { + ID string `json:"id"` + Title string `json:"title"` + Destructive bool `json:"destructive,omitempty"` + AuthenticationRequired bool `json:"authenticationRequired,omitempty"` +} + +// NotificationCategory groups actions for notifications +type NotificationCategory struct { + ID string `json:"id"` + Actions []NotificationAction `json:"actions"` + HasReplyField bool `json:"hasReplyField,omitempty"` + ReplyPlaceholder string `json:"replyPlaceholder,omitempty"` + ReplyButtonTitle string `json:"replyButtonTitle,omitempty"` +} + +// NotificationOptions contains configuration for a notification +type NotificationOptions struct { + ID string `json:"id"` + Title string `json:"title"` + Subtitle string `json:"subtitle,omitempty"` + Body string `json:"body"` + CategoryID string `json:"categoryId,omitempty"` + Data map[string]interface{} `json:"data,omitempty"` +} + +// Check if the app has a valid bundle identifier +func CheckBundleIdentifier() bool { + return bool(C.checkBundleIdentifier()) +} + +// RequestUserNotificationAuthorization requests permission for notifications. +func RequestUserNotificationAuthorization() (bool, error) { + if !CheckBundleIdentifier() { + return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + result := C.requestUserNotificationAuthorization(nil) + return result == true, nil +} + +// CheckNotificationAuthorization checks current permission status +func CheckNotificationAuthorization() (bool, error) { + if !CheckBundleIdentifier() { + return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + return bool(C.checkNotificationAuthorization()), nil +} + +// SendNotification sends a notification with the given identifier, title, subtitle, and body. +func SendNotification(identifier, title, subtitle, body string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + cTitle := C.CString(title) + cSubtitle := C.CString(subtitle) + cBody := C.CString(body) + defer C.free(unsafe.Pointer(cIdentifier)) + defer C.free(unsafe.Pointer(cTitle)) + defer C.free(unsafe.Pointer(cSubtitle)) + defer C.free(unsafe.Pointer(cBody)) + + C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil) + return nil +} + +// SendNotificationWithActions sends a notification with the specified actions +func SendNotificationWithActions(options NotificationOptions) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(options.ID) + cTitle := C.CString(options.Title) + cSubtitle := C.CString(options.Subtitle) + cBody := C.CString(options.Body) + cCategoryID := C.CString(options.CategoryID) + defer C.free(unsafe.Pointer(cIdentifier)) + defer C.free(unsafe.Pointer(cTitle)) + defer C.free(unsafe.Pointer(cSubtitle)) + defer C.free(unsafe.Pointer(cBody)) + defer C.free(unsafe.Pointer(cCategoryID)) + + var cActionsJSON *C.char + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + cActionsJSON = C.CString(string(jsonData)) + defer C.free(unsafe.Pointer(cActionsJSON)) + } + } + + C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil) + return nil +} + +// RegisterNotificationCategory registers a category with actions and optional reply field +func RegisterNotificationCategory(category NotificationCategory) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cCategoryID := C.CString(category.ID) + defer C.free(unsafe.Pointer(cCategoryID)) + + actionsJSON, err := json.Marshal(category.Actions) + if err != nil { + return err + } + cActionsJSON := C.CString(string(actionsJSON)) + defer C.free(unsafe.Pointer(cActionsJSON)) + + var cReplyPlaceholder, cReplyButtonTitle *C.char + if category.HasReplyField { + cReplyPlaceholder = C.CString(category.ReplyPlaceholder) + cReplyButtonTitle = C.CString(category.ReplyButtonTitle) + defer C.free(unsafe.Pointer(cReplyPlaceholder)) + defer C.free(unsafe.Pointer(cReplyButtonTitle)) + } + + C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField), + cReplyPlaceholder, cReplyButtonTitle) + return nil +} + +// RemoveAllPendingNotifications removes all pending notifications +func RemoveAllPendingNotifications() error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + C.removeAllPendingNotifications() + return nil +} + +// RemovePendingNotification removes a specific pending notification +func RemovePendingNotification(identifier string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + defer C.free(unsafe.Pointer(cIdentifier)) + C.removePendingNotification(cIdentifier) + return nil +} + +func RemoveAllDeliveredNotifications() error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + C.removeAllDeliveredNotifications() + return nil +} + +func RemoveDeliveredNotification(identifier string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + defer C.free(unsafe.Pointer(cIdentifier)) + C.removeDeliveredNotification(cIdentifier) + return nil +} diff --git a/v3/pkg/application/notifications_darwin.h b/v3/pkg/application/notifications_darwin.h new file mode 100644 index 000000000..4014b9a1c --- /dev/null +++ b/v3/pkg/application/notifications_darwin.h @@ -0,0 +1,31 @@ +//go:build darwin + +#ifndef NOTIFICATIONS_DARWIN_H +#define NOTIFICATIONS_DARWIN_H + +#import + +#ifdef __cplusplus +extern "C" { +#endif + +bool checkBundleIdentifier(void); +bool requestUserNotificationAuthorization(void *completion); +bool checkNotificationAuthorization(void); +void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, void *completion); + +// New advanced notification functions +void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, + const char *body, const char *categoryId, const char *actions_json, void *completion); +void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, + const char *replyPlaceholder, const char *replyButtonTitle); +void removeAllPendingNotifications(void); +void removePendingNotification(const char *identifier); +void removeAllDeliveredNotifications(void); +void removeDeliveredNotification(const char *identifier); + +#ifdef __cplusplus +} +#endif + +#endif /* NOTIFICATIONS_DARWIN_H */ \ No newline at end of file diff --git a/v3/pkg/application/notifications_darwin.m b/v3/pkg/application/notifications_darwin.m new file mode 100644 index 000000000..31152e13e --- /dev/null +++ b/v3/pkg/application/notifications_darwin.m @@ -0,0 +1,278 @@ +#import "notifications_darwin.h" +#import +#import +#import "../events/events_darwin.h" + +extern bool hasListeners(unsigned int); +extern void processApplicationEvent(unsigned int, void* data); + +@interface NotificationsDelegate : NSObject +@end + +@implementation NotificationsDelegate + +- (void)userNotificationCenter:(UNUserNotificationCenter *)center + willPresentNotification:(UNNotification *)notification + withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { + UNNotificationPresentationOptions options = UNNotificationPresentationOptionList | + UNNotificationPresentationOptionBanner | + UNNotificationPresentationOptionSound; + completionHandler(options); +} + +- (void)userNotificationCenter:(UNUserNotificationCenter *)center +didReceiveNotificationResponse:(UNNotificationResponse *)response + withCompletionHandler:(void (^)(void))completionHandler { + + NSMutableDictionary *payload = [NSMutableDictionary dictionary]; + + [payload setObject:response.notification.request.identifier forKey:@"identifier"]; + [payload setObject:response.actionIdentifier forKey:@"actionIdentifier"]; + [payload setObject:response.notification.request.content.title ?: @"" forKey:@"title"]; + [payload setObject:response.notification.request.content.body ?: @"" forKey:@"body"]; + + if (response.notification.request.content.categoryIdentifier) { + [payload setObject:response.notification.request.content.categoryIdentifier forKey:@"categoryIdentifier"]; + } + + if (response.notification.request.content.userInfo) { + [payload setObject:response.notification.request.content.userInfo forKey:@"userInfo"]; + } + + if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) { + UNTextInputNotificationResponse *textResponse = (UNTextInputNotificationResponse *)response; + [payload setObject:textResponse.userText forKey:@"userText"]; + } + + // Check if there are listeners for our notification response event + if (hasListeners(EventDidReceiveNotificationResponse)) { + processApplicationEvent(EventDidReceiveNotificationResponse, (__bridge void*)payload); + } + + completionHandler(); +} + +@end + +static NotificationsDelegate *delegateInstance = nil; + +static void ensureDelegateInitialized(void) { + if (!delegateInstance) { + delegateInstance = [[NotificationsDelegate alloc] init]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + center.delegate = delegateInstance; + } +} + +bool checkBundleIdentifier(void) { + NSBundle *main = [NSBundle mainBundle]; + if (main.bundleIdentifier == nil) { + NSLog(@"Error: Cannot use notifications in development mode.\n" + " Notifications require the app to be properly bundled with a bundle identifier.\n" + " To test notifications:\n" + " 1. Build and package your app using 'wails package'\n" + " 2. Sign the packaged .app\n" + " 3. Run the signed .app bundle"); + return false; + } + return true; +} + +bool requestUserNotificationAuthorization(void *completion) { + if (!checkBundleIdentifier()) { + return false; + } + + ensureDelegateInitialized(); + + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; + + [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) { + if (completion != NULL) { + void (^callback)(NSError *, BOOL) = completion; + callback(error, granted); + } + }]; + return true; +} + +bool checkNotificationAuthorization(void) { + ensureDelegateInitialized(); + + __block BOOL isAuthorized = NO; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { + isAuthorized = (settings.authorizationStatus == UNAuthorizationStatusAuthorized); + dispatch_semaphore_signal(semaphore); + }]; + + // Wait for response with a timeout + dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC)); + return isAuthorized; +} + +void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, void *completion) { + ensureDelegateInitialized(); + + NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; + NSString *nsTitle = [NSString stringWithUTF8String:title]; + NSString *nsSubtitle = [NSString stringWithUTF8String:subtitle]; + NSString *nsBody = [NSString stringWithUTF8String:body]; + + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + + UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; + content.title = nsTitle; + content.subtitle = nsSubtitle; + content.body = nsBody; + content.sound = [UNNotificationSound defaultSound]; + + UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO]; + + UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; + + [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { + if (completion != NULL) { + void (^callback)(NSError *) = completion; + callback(error); + } + }]; +} + +void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, + const char *body, const char *categoryId, const char *actions_json, void *completion) { + ensureDelegateInitialized(); + + NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; + NSString *nsTitle = [NSString stringWithUTF8String:title]; + NSString *nsSubtitle = subtitle ? [NSString stringWithUTF8String:subtitle] : @""; + NSString *nsBody = [NSString stringWithUTF8String:body]; + NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; + + NSMutableDictionary *customData = [NSMutableDictionary dictionary]; + if (actions_json) { + NSString *actionsJsonStr = [NSString stringWithUTF8String:actions_json]; + NSData *jsonData = [actionsJsonStr dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error = nil; + NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; + if (!error && parsedData) { + [customData addEntriesFromDictionary:parsedData]; + } + } + + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + + UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; + content.title = nsTitle; + if (![nsSubtitle isEqualToString:@""]) { + content.subtitle = nsSubtitle; + } + content.body = nsBody; + content.sound = [UNNotificationSound defaultSound]; + content.categoryIdentifier = nsCategoryId; + + // Add custom data if available + if (customData.count > 0) { + content.userInfo = customData; + } + + UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO]; + + UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; + + [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { + if (completion != NULL) { + void (^callback)(NSError *) = completion; + callback(error); + } + }]; +} + +void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, + const char *replyPlaceholder, const char *replyButtonTitle) { + ensureDelegateInitialized(); + + NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; + NSString *actionsJsonStr = actions_json ? [NSString stringWithUTF8String:actions_json] : @"[]"; + + NSData *jsonData = [actionsJsonStr dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error = nil; + NSArray *actionsArray = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; + + if (error) { + NSLog(@"Error parsing notification actions JSON: %@", error); + return; + } + + NSMutableArray *actions = [NSMutableArray array]; + + for (NSDictionary *actionDict in actionsArray) { + NSString *actionId = actionDict[@"id"]; + NSString *actionTitle = actionDict[@"title"]; + BOOL destructive = [actionDict[@"destructive"] boolValue]; + BOOL authRequired = [actionDict[@"authenticationRequired"] boolValue]; + + if (actionId && actionTitle) { + UNNotificationActionOptions options = UNNotificationActionOptionNone; + if (destructive) options |= UNNotificationActionOptionDestructive; + if (authRequired) options |= UNNotificationActionOptionAuthenticationRequired; + + UNNotificationAction *action = [UNNotificationAction + actionWithIdentifier:actionId + title:actionTitle + options:options]; + [actions addObject:action]; + } + } + + if (hasReplyField && replyPlaceholder && replyButtonTitle) { + NSString *placeholder = [NSString stringWithUTF8String:replyPlaceholder]; + NSString *buttonTitle = [NSString stringWithUTF8String:replyButtonTitle]; + + UNTextInputNotificationAction *textAction = + [UNTextInputNotificationAction actionWithIdentifier:@"TEXT_REPLY" + title:buttonTitle + options:UNNotificationActionOptionNone + textInputButtonTitle:buttonTitle + textInputPlaceholder:placeholder]; + [actions addObject:textAction]; + } + + UNNotificationCategory *category = [UNNotificationCategory + categoryWithIdentifier:nsCategoryId + actions:actions + intentIdentifiers:@[] + options:UNNotificationCategoryOptionNone]; + + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getNotificationCategoriesWithCompletionHandler:^(NSSet *categories) { + NSMutableSet *updatedCategories = [NSMutableSet setWithSet:categories]; + [updatedCategories addObject:category]; + [center setNotificationCategories:updatedCategories]; + }]; +} + +void removeAllPendingNotifications(void) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllPendingNotificationRequests]; +} + +void removePendingNotification(const char *identifier) { + NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removePendingNotificationRequestsWithIdentifiers:@[nsIdentifier]]; +} + +void removeAllDeliveredNotifications(void) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllDeliveredNotifications]; +} + +void removeDeliveredNotification(const char *identifier) { + NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeDeliveredNotificationsWithIdentifiers:@[nsIdentifier]]; +} \ No newline at end of file diff --git a/v3/pkg/events/events.go b/v3/pkg/events/events.go index 0bb4c850c..84f214cac 100644 --- a/v3/pkg/events/events.go +++ b/v3/pkg/events/events.go @@ -112,6 +112,7 @@ type macEvents struct { ApplicationWillTerminate ApplicationEventType ApplicationWillUnhide ApplicationEventType ApplicationWillUpdate ApplicationEventType + DidReceiveNotificationResponse ApplicationEventType MenuDidAddItem ApplicationEventType MenuDidBeginTracking ApplicationEventType MenuDidClose ApplicationEventType @@ -248,116 +249,117 @@ func newMacEvents() macEvents { ApplicationWillTerminate: 1075, ApplicationWillUnhide: 1076, ApplicationWillUpdate: 1077, - MenuDidAddItem: 1078, - MenuDidBeginTracking: 1079, - MenuDidClose: 1080, - MenuDidDisplayItem: 1081, - MenuDidEndTracking: 1082, - MenuDidHighlightItem: 1083, - MenuDidOpen: 1084, - MenuDidPopUp: 1085, - MenuDidRemoveItem: 1086, - MenuDidSendAction: 1087, - MenuDidSendActionToItem: 1088, - MenuDidUpdate: 1089, - MenuWillAddItem: 1090, - MenuWillBeginTracking: 1091, - MenuWillDisplayItem: 1092, - MenuWillEndTracking: 1093, - MenuWillHighlightItem: 1094, - MenuWillOpen: 1095, - MenuWillPopUp: 1096, - MenuWillRemoveItem: 1097, - MenuWillSendAction: 1098, - MenuWillSendActionToItem: 1099, - MenuWillUpdate: 1100, - WebViewDidCommitNavigation: 1101, - WebViewDidFinishNavigation: 1102, - WebViewDidReceiveServerRedirectForProvisionalNavigation: 1103, - WebViewDidStartProvisionalNavigation: 1104, - WindowDidBecomeKey: 1105, - WindowDidBecomeMain: 1106, - WindowDidBeginSheet: 1107, - WindowDidChangeAlpha: 1108, - WindowDidChangeBackingLocation: 1109, - WindowDidChangeBackingProperties: 1110, - WindowDidChangeCollectionBehavior: 1111, - WindowDidChangeEffectiveAppearance: 1112, - WindowDidChangeOcclusionState: 1113, - WindowDidChangeOrderingMode: 1114, - WindowDidChangeScreen: 1115, - WindowDidChangeScreenParameters: 1116, - WindowDidChangeScreenProfile: 1117, - WindowDidChangeScreenSpace: 1118, - WindowDidChangeScreenSpaceProperties: 1119, - WindowDidChangeSharingType: 1120, - WindowDidChangeSpace: 1121, - WindowDidChangeSpaceOrderingMode: 1122, - WindowDidChangeTitle: 1123, - WindowDidChangeToolbar: 1124, - WindowDidDeminiaturize: 1125, - WindowDidEndSheet: 1126, - WindowDidEnterFullScreen: 1127, - WindowDidEnterVersionBrowser: 1128, - WindowDidExitFullScreen: 1129, - WindowDidExitVersionBrowser: 1130, - WindowDidExpose: 1131, - WindowDidFocus: 1132, - WindowDidMiniaturize: 1133, - WindowDidMove: 1134, - WindowDidOrderOffScreen: 1135, - WindowDidOrderOnScreen: 1136, - WindowDidResignKey: 1137, - WindowDidResignMain: 1138, - WindowDidResize: 1139, - WindowDidUpdate: 1140, - WindowDidUpdateAlpha: 1141, - WindowDidUpdateCollectionBehavior: 1142, - WindowDidUpdateCollectionProperties: 1143, - WindowDidUpdateShadow: 1144, - WindowDidUpdateTitle: 1145, - WindowDidUpdateToolbar: 1146, - WindowDidZoom: 1147, - WindowFileDraggingEntered: 1148, - WindowFileDraggingExited: 1149, - WindowFileDraggingPerformed: 1150, - WindowHide: 1151, - WindowMaximise: 1152, - WindowUnMaximise: 1153, - WindowMinimise: 1154, - WindowUnMinimise: 1155, - WindowShouldClose: 1156, - WindowShow: 1157, - WindowWillBecomeKey: 1158, - WindowWillBecomeMain: 1159, - WindowWillBeginSheet: 1160, - WindowWillChangeOrderingMode: 1161, - WindowWillClose: 1162, - WindowWillDeminiaturize: 1163, - WindowWillEnterFullScreen: 1164, - WindowWillEnterVersionBrowser: 1165, - WindowWillExitFullScreen: 1166, - WindowWillExitVersionBrowser: 1167, - WindowWillFocus: 1168, - WindowWillMiniaturize: 1169, - WindowWillMove: 1170, - WindowWillOrderOffScreen: 1171, - WindowWillOrderOnScreen: 1172, - WindowWillResignMain: 1173, - WindowWillResize: 1174, - WindowWillUnfocus: 1175, - WindowWillUpdate: 1176, - WindowWillUpdateAlpha: 1177, - WindowWillUpdateCollectionBehavior: 1178, - WindowWillUpdateCollectionProperties: 1179, - WindowWillUpdateShadow: 1180, - WindowWillUpdateTitle: 1181, - WindowWillUpdateToolbar: 1182, - WindowWillUpdateVisibility: 1183, - WindowWillUseStandardFrame: 1184, - WindowZoomIn: 1185, - WindowZoomOut: 1186, - WindowZoomReset: 1187, + DidReceiveNotificationResponse: 1078, + MenuDidAddItem: 1079, + MenuDidBeginTracking: 1080, + MenuDidClose: 1081, + MenuDidDisplayItem: 1082, + MenuDidEndTracking: 1083, + MenuDidHighlightItem: 1084, + MenuDidOpen: 1085, + MenuDidPopUp: 1086, + MenuDidRemoveItem: 1087, + MenuDidSendAction: 1088, + MenuDidSendActionToItem: 1089, + MenuDidUpdate: 1090, + MenuWillAddItem: 1091, + MenuWillBeginTracking: 1092, + MenuWillDisplayItem: 1093, + MenuWillEndTracking: 1094, + MenuWillHighlightItem: 1095, + MenuWillOpen: 1096, + MenuWillPopUp: 1097, + MenuWillRemoveItem: 1098, + MenuWillSendAction: 1099, + MenuWillSendActionToItem: 1100, + MenuWillUpdate: 1101, + WebViewDidCommitNavigation: 1102, + WebViewDidFinishNavigation: 1103, + WebViewDidReceiveServerRedirectForProvisionalNavigation: 1104, + WebViewDidStartProvisionalNavigation: 1105, + WindowDidBecomeKey: 1106, + WindowDidBecomeMain: 1107, + WindowDidBeginSheet: 1108, + WindowDidChangeAlpha: 1109, + WindowDidChangeBackingLocation: 1110, + WindowDidChangeBackingProperties: 1111, + WindowDidChangeCollectionBehavior: 1112, + WindowDidChangeEffectiveAppearance: 1113, + WindowDidChangeOcclusionState: 1114, + WindowDidChangeOrderingMode: 1115, + WindowDidChangeScreen: 1116, + WindowDidChangeScreenParameters: 1117, + WindowDidChangeScreenProfile: 1118, + WindowDidChangeScreenSpace: 1119, + WindowDidChangeScreenSpaceProperties: 1120, + WindowDidChangeSharingType: 1121, + WindowDidChangeSpace: 1122, + WindowDidChangeSpaceOrderingMode: 1123, + WindowDidChangeTitle: 1124, + WindowDidChangeToolbar: 1125, + WindowDidDeminiaturize: 1126, + WindowDidEndSheet: 1127, + WindowDidEnterFullScreen: 1128, + WindowDidEnterVersionBrowser: 1129, + WindowDidExitFullScreen: 1130, + WindowDidExitVersionBrowser: 1131, + WindowDidExpose: 1132, + WindowDidFocus: 1133, + WindowDidMiniaturize: 1134, + WindowDidMove: 1135, + WindowDidOrderOffScreen: 1136, + WindowDidOrderOnScreen: 1137, + WindowDidResignKey: 1138, + WindowDidResignMain: 1139, + WindowDidResize: 1140, + WindowDidUpdate: 1141, + WindowDidUpdateAlpha: 1142, + WindowDidUpdateCollectionBehavior: 1143, + WindowDidUpdateCollectionProperties: 1144, + WindowDidUpdateShadow: 1145, + WindowDidUpdateTitle: 1146, + WindowDidUpdateToolbar: 1147, + WindowDidZoom: 1148, + WindowFileDraggingEntered: 1149, + WindowFileDraggingExited: 1150, + WindowFileDraggingPerformed: 1151, + WindowHide: 1152, + WindowMaximise: 1153, + WindowUnMaximise: 1154, + WindowMinimise: 1155, + WindowUnMinimise: 1156, + WindowShouldClose: 1157, + WindowShow: 1158, + WindowWillBecomeKey: 1159, + WindowWillBecomeMain: 1160, + WindowWillBeginSheet: 1161, + WindowWillChangeOrderingMode: 1162, + WindowWillClose: 1163, + WindowWillDeminiaturize: 1164, + WindowWillEnterFullScreen: 1165, + WindowWillEnterVersionBrowser: 1166, + WindowWillExitFullScreen: 1167, + WindowWillExitVersionBrowser: 1168, + WindowWillFocus: 1169, + WindowWillMiniaturize: 1170, + WindowWillMove: 1171, + WindowWillOrderOffScreen: 1172, + WindowWillOrderOnScreen: 1173, + WindowWillResignMain: 1174, + WindowWillResize: 1175, + WindowWillUnfocus: 1176, + WindowWillUpdate: 1177, + WindowWillUpdateAlpha: 1178, + WindowWillUpdateCollectionBehavior: 1179, + WindowWillUpdateCollectionProperties: 1180, + WindowWillUpdateShadow: 1181, + WindowWillUpdateTitle: 1182, + WindowWillUpdateToolbar: 1183, + WindowWillUpdateVisibility: 1184, + WindowWillUseStandardFrame: 1185, + WindowZoomIn: 1186, + WindowZoomOut: 1187, + WindowZoomReset: 1188, } } @@ -412,50 +414,50 @@ type windowsEvents struct { func newWindowsEvents() windowsEvents { return windowsEvents{ - APMPowerSettingChange: 1188, - APMPowerStatusChange: 1189, - APMResumeAutomatic: 1190, - APMResumeSuspend: 1191, - APMSuspend: 1192, - ApplicationStarted: 1193, - SystemThemeChanged: 1194, - WebViewNavigationCompleted: 1195, - WindowActive: 1196, - WindowBackgroundErase: 1197, - WindowClickActive: 1198, - WindowClosing: 1199, - WindowDidMove: 1200, - WindowDidResize: 1201, - WindowDPIChanged: 1202, - WindowDragDrop: 1203, - WindowDragEnter: 1204, - WindowDragLeave: 1205, - WindowDragOver: 1206, - WindowEndMove: 1207, - WindowEndResize: 1208, - WindowFullscreen: 1209, - WindowHide: 1210, - WindowInactive: 1211, - WindowKeyDown: 1212, - WindowKeyUp: 1213, - WindowKillFocus: 1214, - WindowNonClientHit: 1215, - WindowNonClientMouseDown: 1216, - WindowNonClientMouseLeave: 1217, - WindowNonClientMouseMove: 1218, - WindowNonClientMouseUp: 1219, - WindowPaint: 1220, - WindowRestore: 1221, - WindowSetFocus: 1222, - WindowShow: 1223, - WindowStartMove: 1224, - WindowStartResize: 1225, - WindowUnFullscreen: 1226, - WindowZOrderChanged: 1227, - WindowMinimise: 1228, - WindowUnMinimise: 1229, - WindowMaximise: 1230, - WindowUnMaximise: 1231, + APMPowerSettingChange: 1189, + APMPowerStatusChange: 1190, + APMResumeAutomatic: 1191, + APMResumeSuspend: 1192, + APMSuspend: 1193, + ApplicationStarted: 1194, + SystemThemeChanged: 1195, + WebViewNavigationCompleted: 1196, + WindowActive: 1197, + WindowBackgroundErase: 1198, + WindowClickActive: 1199, + WindowClosing: 1200, + WindowDidMove: 1201, + WindowDidResize: 1202, + WindowDPIChanged: 1203, + WindowDragDrop: 1204, + WindowDragEnter: 1205, + WindowDragLeave: 1206, + WindowDragOver: 1207, + WindowEndMove: 1208, + WindowEndResize: 1209, + WindowFullscreen: 1210, + WindowHide: 1211, + WindowInactive: 1212, + WindowKeyDown: 1213, + WindowKeyUp: 1214, + WindowKillFocus: 1215, + WindowNonClientHit: 1216, + WindowNonClientMouseDown: 1217, + WindowNonClientMouseLeave: 1218, + WindowNonClientMouseMove: 1219, + WindowNonClientMouseUp: 1220, + WindowPaint: 1221, + WindowRestore: 1222, + WindowSetFocus: 1223, + WindowShow: 1224, + WindowStartMove: 1225, + WindowStartResize: 1226, + WindowUnFullscreen: 1227, + WindowZOrderChanged: 1228, + WindowMinimise: 1229, + WindowUnMinimise: 1230, + WindowMaximise: 1231, + WindowUnMaximise: 1232, } } @@ -518,159 +520,160 @@ var eventToJS = map[uint]string{ 1075: "mac:ApplicationWillTerminate", 1076: "mac:ApplicationWillUnhide", 1077: "mac:ApplicationWillUpdate", - 1078: "mac:MenuDidAddItem", - 1079: "mac:MenuDidBeginTracking", - 1080: "mac:MenuDidClose", - 1081: "mac:MenuDidDisplayItem", - 1082: "mac:MenuDidEndTracking", - 1083: "mac:MenuDidHighlightItem", - 1084: "mac:MenuDidOpen", - 1085: "mac:MenuDidPopUp", - 1086: "mac:MenuDidRemoveItem", - 1087: "mac:MenuDidSendAction", - 1088: "mac:MenuDidSendActionToItem", - 1089: "mac:MenuDidUpdate", - 1090: "mac:MenuWillAddItem", - 1091: "mac:MenuWillBeginTracking", - 1092: "mac:MenuWillDisplayItem", - 1093: "mac:MenuWillEndTracking", - 1094: "mac:MenuWillHighlightItem", - 1095: "mac:MenuWillOpen", - 1096: "mac:MenuWillPopUp", - 1097: "mac:MenuWillRemoveItem", - 1098: "mac:MenuWillSendAction", - 1099: "mac:MenuWillSendActionToItem", - 1100: "mac:MenuWillUpdate", - 1101: "mac:WebViewDidCommitNavigation", - 1102: "mac:WebViewDidFinishNavigation", - 1103: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation", - 1104: "mac:WebViewDidStartProvisionalNavigation", - 1105: "mac:WindowDidBecomeKey", - 1106: "mac:WindowDidBecomeMain", - 1107: "mac:WindowDidBeginSheet", - 1108: "mac:WindowDidChangeAlpha", - 1109: "mac:WindowDidChangeBackingLocation", - 1110: "mac:WindowDidChangeBackingProperties", - 1111: "mac:WindowDidChangeCollectionBehavior", - 1112: "mac:WindowDidChangeEffectiveAppearance", - 1113: "mac:WindowDidChangeOcclusionState", - 1114: "mac:WindowDidChangeOrderingMode", - 1115: "mac:WindowDidChangeScreen", - 1116: "mac:WindowDidChangeScreenParameters", - 1117: "mac:WindowDidChangeScreenProfile", - 1118: "mac:WindowDidChangeScreenSpace", - 1119: "mac:WindowDidChangeScreenSpaceProperties", - 1120: "mac:WindowDidChangeSharingType", - 1121: "mac:WindowDidChangeSpace", - 1122: "mac:WindowDidChangeSpaceOrderingMode", - 1123: "mac:WindowDidChangeTitle", - 1124: "mac:WindowDidChangeToolbar", - 1125: "mac:WindowDidDeminiaturize", - 1126: "mac:WindowDidEndSheet", - 1127: "mac:WindowDidEnterFullScreen", - 1128: "mac:WindowDidEnterVersionBrowser", - 1129: "mac:WindowDidExitFullScreen", - 1130: "mac:WindowDidExitVersionBrowser", - 1131: "mac:WindowDidExpose", - 1132: "mac:WindowDidFocus", - 1133: "mac:WindowDidMiniaturize", - 1134: "mac:WindowDidMove", - 1135: "mac:WindowDidOrderOffScreen", - 1136: "mac:WindowDidOrderOnScreen", - 1137: "mac:WindowDidResignKey", - 1138: "mac:WindowDidResignMain", - 1139: "mac:WindowDidResize", - 1140: "mac:WindowDidUpdate", - 1141: "mac:WindowDidUpdateAlpha", - 1142: "mac:WindowDidUpdateCollectionBehavior", - 1143: "mac:WindowDidUpdateCollectionProperties", - 1144: "mac:WindowDidUpdateShadow", - 1145: "mac:WindowDidUpdateTitle", - 1146: "mac:WindowDidUpdateToolbar", - 1147: "mac:WindowDidZoom", - 1148: "mac:WindowFileDraggingEntered", - 1149: "mac:WindowFileDraggingExited", - 1150: "mac:WindowFileDraggingPerformed", - 1151: "mac:WindowHide", - 1152: "mac:WindowMaximise", - 1153: "mac:WindowUnMaximise", - 1154: "mac:WindowMinimise", - 1155: "mac:WindowUnMinimise", - 1156: "mac:WindowShouldClose", - 1157: "mac:WindowShow", - 1158: "mac:WindowWillBecomeKey", - 1159: "mac:WindowWillBecomeMain", - 1160: "mac:WindowWillBeginSheet", - 1161: "mac:WindowWillChangeOrderingMode", - 1162: "mac:WindowWillClose", - 1163: "mac:WindowWillDeminiaturize", - 1164: "mac:WindowWillEnterFullScreen", - 1165: "mac:WindowWillEnterVersionBrowser", - 1166: "mac:WindowWillExitFullScreen", - 1167: "mac:WindowWillExitVersionBrowser", - 1168: "mac:WindowWillFocus", - 1169: "mac:WindowWillMiniaturize", - 1170: "mac:WindowWillMove", - 1171: "mac:WindowWillOrderOffScreen", - 1172: "mac:WindowWillOrderOnScreen", - 1173: "mac:WindowWillResignMain", - 1174: "mac:WindowWillResize", - 1175: "mac:WindowWillUnfocus", - 1176: "mac:WindowWillUpdate", - 1177: "mac:WindowWillUpdateAlpha", - 1178: "mac:WindowWillUpdateCollectionBehavior", - 1179: "mac:WindowWillUpdateCollectionProperties", - 1180: "mac:WindowWillUpdateShadow", - 1181: "mac:WindowWillUpdateTitle", - 1182: "mac:WindowWillUpdateToolbar", - 1183: "mac:WindowWillUpdateVisibility", - 1184: "mac:WindowWillUseStandardFrame", - 1185: "mac:WindowZoomIn", - 1186: "mac:WindowZoomOut", - 1187: "mac:WindowZoomReset", - 1188: "windows:APMPowerSettingChange", - 1189: "windows:APMPowerStatusChange", - 1190: "windows:APMResumeAutomatic", - 1191: "windows:APMResumeSuspend", - 1192: "windows:APMSuspend", - 1193: "windows:ApplicationStarted", - 1194: "windows:SystemThemeChanged", - 1195: "windows:WebViewNavigationCompleted", - 1196: "windows:WindowActive", - 1197: "windows:WindowBackgroundErase", - 1198: "windows:WindowClickActive", - 1199: "windows:WindowClosing", - 1200: "windows:WindowDidMove", - 1201: "windows:WindowDidResize", - 1202: "windows:WindowDPIChanged", - 1203: "windows:WindowDragDrop", - 1204: "windows:WindowDragEnter", - 1205: "windows:WindowDragLeave", - 1206: "windows:WindowDragOver", - 1207: "windows:WindowEndMove", - 1208: "windows:WindowEndResize", - 1209: "windows:WindowFullscreen", - 1210: "windows:WindowHide", - 1211: "windows:WindowInactive", - 1212: "windows:WindowKeyDown", - 1213: "windows:WindowKeyUp", - 1214: "windows:WindowKillFocus", - 1215: "windows:WindowNonClientHit", - 1216: "windows:WindowNonClientMouseDown", - 1217: "windows:WindowNonClientMouseLeave", - 1218: "windows:WindowNonClientMouseMove", - 1219: "windows:WindowNonClientMouseUp", - 1220: "windows:WindowPaint", - 1221: "windows:WindowRestore", - 1222: "windows:WindowSetFocus", - 1223: "windows:WindowShow", - 1224: "windows:WindowStartMove", - 1225: "windows:WindowStartResize", - 1226: "windows:WindowUnFullscreen", - 1227: "windows:WindowZOrderChanged", - 1228: "windows:WindowMinimise", - 1229: "windows:WindowUnMinimise", - 1230: "windows:WindowMaximise", - 1231: "windows:WindowUnMaximise", + 1078: "mac:DidReceiveNotificationResponse", + 1079: "mac:MenuDidAddItem", + 1080: "mac:MenuDidBeginTracking", + 1081: "mac:MenuDidClose", + 1082: "mac:MenuDidDisplayItem", + 1083: "mac:MenuDidEndTracking", + 1084: "mac:MenuDidHighlightItem", + 1085: "mac:MenuDidOpen", + 1086: "mac:MenuDidPopUp", + 1087: "mac:MenuDidRemoveItem", + 1088: "mac:MenuDidSendAction", + 1089: "mac:MenuDidSendActionToItem", + 1090: "mac:MenuDidUpdate", + 1091: "mac:MenuWillAddItem", + 1092: "mac:MenuWillBeginTracking", + 1093: "mac:MenuWillDisplayItem", + 1094: "mac:MenuWillEndTracking", + 1095: "mac:MenuWillHighlightItem", + 1096: "mac:MenuWillOpen", + 1097: "mac:MenuWillPopUp", + 1098: "mac:MenuWillRemoveItem", + 1099: "mac:MenuWillSendAction", + 1100: "mac:MenuWillSendActionToItem", + 1101: "mac:MenuWillUpdate", + 1102: "mac:WebViewDidCommitNavigation", + 1103: "mac:WebViewDidFinishNavigation", + 1104: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation", + 1105: "mac:WebViewDidStartProvisionalNavigation", + 1106: "mac:WindowDidBecomeKey", + 1107: "mac:WindowDidBecomeMain", + 1108: "mac:WindowDidBeginSheet", + 1109: "mac:WindowDidChangeAlpha", + 1110: "mac:WindowDidChangeBackingLocation", + 1111: "mac:WindowDidChangeBackingProperties", + 1112: "mac:WindowDidChangeCollectionBehavior", + 1113: "mac:WindowDidChangeEffectiveAppearance", + 1114: "mac:WindowDidChangeOcclusionState", + 1115: "mac:WindowDidChangeOrderingMode", + 1116: "mac:WindowDidChangeScreen", + 1117: "mac:WindowDidChangeScreenParameters", + 1118: "mac:WindowDidChangeScreenProfile", + 1119: "mac:WindowDidChangeScreenSpace", + 1120: "mac:WindowDidChangeScreenSpaceProperties", + 1121: "mac:WindowDidChangeSharingType", + 1122: "mac:WindowDidChangeSpace", + 1123: "mac:WindowDidChangeSpaceOrderingMode", + 1124: "mac:WindowDidChangeTitle", + 1125: "mac:WindowDidChangeToolbar", + 1126: "mac:WindowDidDeminiaturize", + 1127: "mac:WindowDidEndSheet", + 1128: "mac:WindowDidEnterFullScreen", + 1129: "mac:WindowDidEnterVersionBrowser", + 1130: "mac:WindowDidExitFullScreen", + 1131: "mac:WindowDidExitVersionBrowser", + 1132: "mac:WindowDidExpose", + 1133: "mac:WindowDidFocus", + 1134: "mac:WindowDidMiniaturize", + 1135: "mac:WindowDidMove", + 1136: "mac:WindowDidOrderOffScreen", + 1137: "mac:WindowDidOrderOnScreen", + 1138: "mac:WindowDidResignKey", + 1139: "mac:WindowDidResignMain", + 1140: "mac:WindowDidResize", + 1141: "mac:WindowDidUpdate", + 1142: "mac:WindowDidUpdateAlpha", + 1143: "mac:WindowDidUpdateCollectionBehavior", + 1144: "mac:WindowDidUpdateCollectionProperties", + 1145: "mac:WindowDidUpdateShadow", + 1146: "mac:WindowDidUpdateTitle", + 1147: "mac:WindowDidUpdateToolbar", + 1148: "mac:WindowDidZoom", + 1149: "mac:WindowFileDraggingEntered", + 1150: "mac:WindowFileDraggingExited", + 1151: "mac:WindowFileDraggingPerformed", + 1152: "mac:WindowHide", + 1153: "mac:WindowMaximise", + 1154: "mac:WindowUnMaximise", + 1155: "mac:WindowMinimise", + 1156: "mac:WindowUnMinimise", + 1157: "mac:WindowShouldClose", + 1158: "mac:WindowShow", + 1159: "mac:WindowWillBecomeKey", + 1160: "mac:WindowWillBecomeMain", + 1161: "mac:WindowWillBeginSheet", + 1162: "mac:WindowWillChangeOrderingMode", + 1163: "mac:WindowWillClose", + 1164: "mac:WindowWillDeminiaturize", + 1165: "mac:WindowWillEnterFullScreen", + 1166: "mac:WindowWillEnterVersionBrowser", + 1167: "mac:WindowWillExitFullScreen", + 1168: "mac:WindowWillExitVersionBrowser", + 1169: "mac:WindowWillFocus", + 1170: "mac:WindowWillMiniaturize", + 1171: "mac:WindowWillMove", + 1172: "mac:WindowWillOrderOffScreen", + 1173: "mac:WindowWillOrderOnScreen", + 1174: "mac:WindowWillResignMain", + 1175: "mac:WindowWillResize", + 1176: "mac:WindowWillUnfocus", + 1177: "mac:WindowWillUpdate", + 1178: "mac:WindowWillUpdateAlpha", + 1179: "mac:WindowWillUpdateCollectionBehavior", + 1180: "mac:WindowWillUpdateCollectionProperties", + 1181: "mac:WindowWillUpdateShadow", + 1182: "mac:WindowWillUpdateTitle", + 1183: "mac:WindowWillUpdateToolbar", + 1184: "mac:WindowWillUpdateVisibility", + 1185: "mac:WindowWillUseStandardFrame", + 1186: "mac:WindowZoomIn", + 1187: "mac:WindowZoomOut", + 1188: "mac:WindowZoomReset", + 1189: "windows:APMPowerSettingChange", + 1190: "windows:APMPowerStatusChange", + 1191: "windows:APMResumeAutomatic", + 1192: "windows:APMResumeSuspend", + 1193: "windows:APMSuspend", + 1194: "windows:ApplicationStarted", + 1195: "windows:SystemThemeChanged", + 1196: "windows:WebViewNavigationCompleted", + 1197: "windows:WindowActive", + 1198: "windows:WindowBackgroundErase", + 1199: "windows:WindowClickActive", + 1200: "windows:WindowClosing", + 1201: "windows:WindowDidMove", + 1202: "windows:WindowDidResize", + 1203: "windows:WindowDPIChanged", + 1204: "windows:WindowDragDrop", + 1205: "windows:WindowDragEnter", + 1206: "windows:WindowDragLeave", + 1207: "windows:WindowDragOver", + 1208: "windows:WindowEndMove", + 1209: "windows:WindowEndResize", + 1210: "windows:WindowFullscreen", + 1211: "windows:WindowHide", + 1212: "windows:WindowInactive", + 1213: "windows:WindowKeyDown", + 1214: "windows:WindowKeyUp", + 1215: "windows:WindowKillFocus", + 1216: "windows:WindowNonClientHit", + 1217: "windows:WindowNonClientMouseDown", + 1218: "windows:WindowNonClientMouseLeave", + 1219: "windows:WindowNonClientMouseMove", + 1220: "windows:WindowNonClientMouseUp", + 1221: "windows:WindowPaint", + 1222: "windows:WindowRestore", + 1223: "windows:WindowSetFocus", + 1224: "windows:WindowShow", + 1225: "windows:WindowStartMove", + 1226: "windows:WindowStartResize", + 1227: "windows:WindowUnFullscreen", + 1228: "windows:WindowZOrderChanged", + 1229: "windows:WindowMinimise", + 1230: "windows:WindowUnMinimise", + 1231: "windows:WindowMaximise", + 1232: "windows:WindowUnMaximise", } diff --git a/v3/pkg/events/events.txt b/v3/pkg/events/events.txt index 1d43adf5e..fa83f4655 100644 --- a/v3/pkg/events/events.txt +++ b/v3/pkg/events/events.txt @@ -52,6 +52,7 @@ mac:ApplicationWillResignActive mac:ApplicationWillTerminate mac:ApplicationWillUnhide mac:ApplicationWillUpdate +mac:DidReceiveNotificationResponse mac:MenuDidAddItem mac:MenuDidBeginTracking mac:MenuDidClose diff --git a/v3/pkg/events/events_darwin.h b/v3/pkg/events/events_darwin.h index bacaab781..5e6c1a39e 100644 --- a/v3/pkg/events/events_darwin.h +++ b/v3/pkg/events/events_darwin.h @@ -28,118 +28,119 @@ extern void processWindowEvent(unsigned int, unsigned int); #define EventApplicationWillTerminate 1075 #define EventApplicationWillUnhide 1076 #define EventApplicationWillUpdate 1077 -#define EventMenuDidAddItem 1078 -#define EventMenuDidBeginTracking 1079 -#define EventMenuDidClose 1080 -#define EventMenuDidDisplayItem 1081 -#define EventMenuDidEndTracking 1082 -#define EventMenuDidHighlightItem 1083 -#define EventMenuDidOpen 1084 -#define EventMenuDidPopUp 1085 -#define EventMenuDidRemoveItem 1086 -#define EventMenuDidSendAction 1087 -#define EventMenuDidSendActionToItem 1088 -#define EventMenuDidUpdate 1089 -#define EventMenuWillAddItem 1090 -#define EventMenuWillBeginTracking 1091 -#define EventMenuWillDisplayItem 1092 -#define EventMenuWillEndTracking 1093 -#define EventMenuWillHighlightItem 1094 -#define EventMenuWillOpen 1095 -#define EventMenuWillPopUp 1096 -#define EventMenuWillRemoveItem 1097 -#define EventMenuWillSendAction 1098 -#define EventMenuWillSendActionToItem 1099 -#define EventMenuWillUpdate 1100 -#define EventWebViewDidCommitNavigation 1101 -#define EventWebViewDidFinishNavigation 1102 -#define EventWebViewDidReceiveServerRedirectForProvisionalNavigation 1103 -#define EventWebViewDidStartProvisionalNavigation 1104 -#define EventWindowDidBecomeKey 1105 -#define EventWindowDidBecomeMain 1106 -#define EventWindowDidBeginSheet 1107 -#define EventWindowDidChangeAlpha 1108 -#define EventWindowDidChangeBackingLocation 1109 -#define EventWindowDidChangeBackingProperties 1110 -#define EventWindowDidChangeCollectionBehavior 1111 -#define EventWindowDidChangeEffectiveAppearance 1112 -#define EventWindowDidChangeOcclusionState 1113 -#define EventWindowDidChangeOrderingMode 1114 -#define EventWindowDidChangeScreen 1115 -#define EventWindowDidChangeScreenParameters 1116 -#define EventWindowDidChangeScreenProfile 1117 -#define EventWindowDidChangeScreenSpace 1118 -#define EventWindowDidChangeScreenSpaceProperties 1119 -#define EventWindowDidChangeSharingType 1120 -#define EventWindowDidChangeSpace 1121 -#define EventWindowDidChangeSpaceOrderingMode 1122 -#define EventWindowDidChangeTitle 1123 -#define EventWindowDidChangeToolbar 1124 -#define EventWindowDidDeminiaturize 1125 -#define EventWindowDidEndSheet 1126 -#define EventWindowDidEnterFullScreen 1127 -#define EventWindowDidEnterVersionBrowser 1128 -#define EventWindowDidExitFullScreen 1129 -#define EventWindowDidExitVersionBrowser 1130 -#define EventWindowDidExpose 1131 -#define EventWindowDidFocus 1132 -#define EventWindowDidMiniaturize 1133 -#define EventWindowDidMove 1134 -#define EventWindowDidOrderOffScreen 1135 -#define EventWindowDidOrderOnScreen 1136 -#define EventWindowDidResignKey 1137 -#define EventWindowDidResignMain 1138 -#define EventWindowDidResize 1139 -#define EventWindowDidUpdate 1140 -#define EventWindowDidUpdateAlpha 1141 -#define EventWindowDidUpdateCollectionBehavior 1142 -#define EventWindowDidUpdateCollectionProperties 1143 -#define EventWindowDidUpdateShadow 1144 -#define EventWindowDidUpdateTitle 1145 -#define EventWindowDidUpdateToolbar 1146 -#define EventWindowDidZoom 1147 -#define EventWindowFileDraggingEntered 1148 -#define EventWindowFileDraggingExited 1149 -#define EventWindowFileDraggingPerformed 1150 -#define EventWindowHide 1151 -#define EventWindowMaximise 1152 -#define EventWindowUnMaximise 1153 -#define EventWindowMinimise 1154 -#define EventWindowUnMinimise 1155 -#define EventWindowShouldClose 1156 -#define EventWindowShow 1157 -#define EventWindowWillBecomeKey 1158 -#define EventWindowWillBecomeMain 1159 -#define EventWindowWillBeginSheet 1160 -#define EventWindowWillChangeOrderingMode 1161 -#define EventWindowWillClose 1162 -#define EventWindowWillDeminiaturize 1163 -#define EventWindowWillEnterFullScreen 1164 -#define EventWindowWillEnterVersionBrowser 1165 -#define EventWindowWillExitFullScreen 1166 -#define EventWindowWillExitVersionBrowser 1167 -#define EventWindowWillFocus 1168 -#define EventWindowWillMiniaturize 1169 -#define EventWindowWillMove 1170 -#define EventWindowWillOrderOffScreen 1171 -#define EventWindowWillOrderOnScreen 1172 -#define EventWindowWillResignMain 1173 -#define EventWindowWillResize 1174 -#define EventWindowWillUnfocus 1175 -#define EventWindowWillUpdate 1176 -#define EventWindowWillUpdateAlpha 1177 -#define EventWindowWillUpdateCollectionBehavior 1178 -#define EventWindowWillUpdateCollectionProperties 1179 -#define EventWindowWillUpdateShadow 1180 -#define EventWindowWillUpdateTitle 1181 -#define EventWindowWillUpdateToolbar 1182 -#define EventWindowWillUpdateVisibility 1183 -#define EventWindowWillUseStandardFrame 1184 -#define EventWindowZoomIn 1185 -#define EventWindowZoomOut 1186 -#define EventWindowZoomReset 1187 +#define EventDidReceiveNotificationResponse 1078 +#define EventMenuDidAddItem 1079 +#define EventMenuDidBeginTracking 1080 +#define EventMenuDidClose 1081 +#define EventMenuDidDisplayItem 1082 +#define EventMenuDidEndTracking 1083 +#define EventMenuDidHighlightItem 1084 +#define EventMenuDidOpen 1085 +#define EventMenuDidPopUp 1086 +#define EventMenuDidRemoveItem 1087 +#define EventMenuDidSendAction 1088 +#define EventMenuDidSendActionToItem 1089 +#define EventMenuDidUpdate 1090 +#define EventMenuWillAddItem 1091 +#define EventMenuWillBeginTracking 1092 +#define EventMenuWillDisplayItem 1093 +#define EventMenuWillEndTracking 1094 +#define EventMenuWillHighlightItem 1095 +#define EventMenuWillOpen 1096 +#define EventMenuWillPopUp 1097 +#define EventMenuWillRemoveItem 1098 +#define EventMenuWillSendAction 1099 +#define EventMenuWillSendActionToItem 1100 +#define EventMenuWillUpdate 1101 +#define EventWebViewDidCommitNavigation 1102 +#define EventWebViewDidFinishNavigation 1103 +#define EventWebViewDidReceiveServerRedirectForProvisionalNavigation 1104 +#define EventWebViewDidStartProvisionalNavigation 1105 +#define EventWindowDidBecomeKey 1106 +#define EventWindowDidBecomeMain 1107 +#define EventWindowDidBeginSheet 1108 +#define EventWindowDidChangeAlpha 1109 +#define EventWindowDidChangeBackingLocation 1110 +#define EventWindowDidChangeBackingProperties 1111 +#define EventWindowDidChangeCollectionBehavior 1112 +#define EventWindowDidChangeEffectiveAppearance 1113 +#define EventWindowDidChangeOcclusionState 1114 +#define EventWindowDidChangeOrderingMode 1115 +#define EventWindowDidChangeScreen 1116 +#define EventWindowDidChangeScreenParameters 1117 +#define EventWindowDidChangeScreenProfile 1118 +#define EventWindowDidChangeScreenSpace 1119 +#define EventWindowDidChangeScreenSpaceProperties 1120 +#define EventWindowDidChangeSharingType 1121 +#define EventWindowDidChangeSpace 1122 +#define EventWindowDidChangeSpaceOrderingMode 1123 +#define EventWindowDidChangeTitle 1124 +#define EventWindowDidChangeToolbar 1125 +#define EventWindowDidDeminiaturize 1126 +#define EventWindowDidEndSheet 1127 +#define EventWindowDidEnterFullScreen 1128 +#define EventWindowDidEnterVersionBrowser 1129 +#define EventWindowDidExitFullScreen 1130 +#define EventWindowDidExitVersionBrowser 1131 +#define EventWindowDidExpose 1132 +#define EventWindowDidFocus 1133 +#define EventWindowDidMiniaturize 1134 +#define EventWindowDidMove 1135 +#define EventWindowDidOrderOffScreen 1136 +#define EventWindowDidOrderOnScreen 1137 +#define EventWindowDidResignKey 1138 +#define EventWindowDidResignMain 1139 +#define EventWindowDidResize 1140 +#define EventWindowDidUpdate 1141 +#define EventWindowDidUpdateAlpha 1142 +#define EventWindowDidUpdateCollectionBehavior 1143 +#define EventWindowDidUpdateCollectionProperties 1144 +#define EventWindowDidUpdateShadow 1145 +#define EventWindowDidUpdateTitle 1146 +#define EventWindowDidUpdateToolbar 1147 +#define EventWindowDidZoom 1148 +#define EventWindowFileDraggingEntered 1149 +#define EventWindowFileDraggingExited 1150 +#define EventWindowFileDraggingPerformed 1151 +#define EventWindowHide 1152 +#define EventWindowMaximise 1153 +#define EventWindowUnMaximise 1154 +#define EventWindowMinimise 1155 +#define EventWindowUnMinimise 1156 +#define EventWindowShouldClose 1157 +#define EventWindowShow 1158 +#define EventWindowWillBecomeKey 1159 +#define EventWindowWillBecomeMain 1160 +#define EventWindowWillBeginSheet 1161 +#define EventWindowWillChangeOrderingMode 1162 +#define EventWindowWillClose 1163 +#define EventWindowWillDeminiaturize 1164 +#define EventWindowWillEnterFullScreen 1165 +#define EventWindowWillEnterVersionBrowser 1166 +#define EventWindowWillExitFullScreen 1167 +#define EventWindowWillExitVersionBrowser 1168 +#define EventWindowWillFocus 1169 +#define EventWindowWillMiniaturize 1170 +#define EventWindowWillMove 1171 +#define EventWindowWillOrderOffScreen 1172 +#define EventWindowWillOrderOnScreen 1173 +#define EventWindowWillResignMain 1174 +#define EventWindowWillResize 1175 +#define EventWindowWillUnfocus 1176 +#define EventWindowWillUpdate 1177 +#define EventWindowWillUpdateAlpha 1178 +#define EventWindowWillUpdateCollectionBehavior 1179 +#define EventWindowWillUpdateCollectionProperties 1180 +#define EventWindowWillUpdateShadow 1181 +#define EventWindowWillUpdateTitle 1182 +#define EventWindowWillUpdateToolbar 1183 +#define EventWindowWillUpdateVisibility 1184 +#define EventWindowWillUseStandardFrame 1185 +#define EventWindowZoomIn 1186 +#define EventWindowZoomOut 1187 +#define EventWindowZoomReset 1188 -#define MAX_EVENTS 1188 +#define MAX_EVENTS 1189 #endif \ No newline at end of file From 274511c5cba8d5055dcf53ad894c7f24588acd1b Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Feb 2025 22:27:56 -0800 Subject: [PATCH 002/136] update log message --- v3/pkg/application/notifications_darwin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/pkg/application/notifications_darwin.m b/v3/pkg/application/notifications_darwin.m index 31152e13e..7c0a1cade 100644 --- a/v3/pkg/application/notifications_darwin.m +++ b/v3/pkg/application/notifications_darwin.m @@ -70,7 +70,7 @@ bool checkBundleIdentifier(void) { NSLog(@"Error: Cannot use notifications in development mode.\n" " Notifications require the app to be properly bundled with a bundle identifier.\n" " To test notifications:\n" - " 1. Build and package your app using 'wails package'\n" + " 1. Build and package your app using 'wails3 package'\n" " 2. Sign the packaged .app\n" " 3. Run the signed .app bundle"); return false; From f694ad223ee421c7ed1e2191e7d87835ec6775c4 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Fri, 21 Feb 2025 18:20:37 -0800 Subject: [PATCH 003/136] service and minor refactor --- v3/pkg/application/application_darwin.go | 35 ---- v3/pkg/services/notification/notification.go | 200 +++++++++++++++++++ 2 files changed, 200 insertions(+), 35 deletions(-) create mode 100644 v3/pkg/services/notification/notification.go diff --git a/v3/pkg/application/application_darwin.go b/v3/pkg/application/application_darwin.go index ce205b029..623e4a94c 100644 --- a/v3/pkg/application/application_darwin.go +++ b/v3/pkg/application/application_darwin.go @@ -228,41 +228,6 @@ func (m *macosApp) setApplicationMenu(menu *Menu) { C.setApplicationMenu(m.applicationMenu) } -// RequestNotificationPermission requests user permission for notifications -func (m *macosApp) RequestNotificationPermission() (bool, error) { - return RequestUserNotificationAuthorization() -} - -// CheckNotificationPermission checks current permission status -func (m *macosApp) CheckNotificationPermission() (bool, error) { - return CheckNotificationAuthorization() -} - -// SendNotification sends a simple notification -func (m *macosApp) SendNotification(identifier, title, subtitle, body string) error { - return SendNotification(identifier, title, subtitle, body) -} - -// SendNotificationWithActions sends a notification with custom actions -func (m *macosApp) SendNotificationWithActions(options NotificationOptions) error { - return SendNotificationWithActions(options) -} - -// RegisterNotificationCategory registers a notification category with actions -func (m *macosApp) RegisterNotificationCategory(category NotificationCategory) error { - return RegisterNotificationCategory(category) -} - -// RemoveAllPendingNotifications removes all pending notifications -func (m *macosApp) RemoveAllPendingNotifications() { - RemoveAllPendingNotifications() -} - -// RemovePendingNotification removes a specific pending notification -func (m *macosApp) RemovePendingNotification(identifier string) { - RemovePendingNotification(identifier) -} - func (m *macosApp) run() error { if m.parent.options.SingleInstance != nil { cUniqueID := C.CString(m.parent.options.SingleInstance.UniqueID) diff --git a/v3/pkg/services/notification/notification.go b/v3/pkg/services/notification/notification.go new file mode 100644 index 000000000..987e4d438 --- /dev/null +++ b/v3/pkg/services/notification/notification.go @@ -0,0 +1,200 @@ +//go:build darwin + +package notification + +/* +#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c +#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications +#import "../../application/notifications_darwin.h" +*/ +import "C" +import ( + "context" + "encoding/json" + "fmt" + "unsafe" + + "github.com/wailsapp/wails/v3/pkg/application" +) + +type NotificationService struct { +} + +// NotificationAction represents an action button for a notification +type NotificationAction struct { + ID string `json:"id"` + Title string `json:"title"` + Destructive bool `json:"destructive,omitempty"` + AuthenticationRequired bool `json:"authenticationRequired,omitempty"` +} + +// NotificationCategory groups actions for notifications +type NotificationCategory struct { + ID string `json:"id"` + Actions []NotificationAction `json:"actions"` + HasReplyField bool `json:"hasReplyField,omitempty"` + ReplyPlaceholder string `json:"replyPlaceholder,omitempty"` + ReplyButtonTitle string `json:"replyButtonTitle,omitempty"` +} + +// NotificationOptions contains configuration for a notification +type NotificationOptions struct { + ID string `json:"id"` + Title string `json:"title"` + Subtitle string `json:"subtitle,omitempty"` + Body string `json:"body"` + CategoryID string `json:"categoryId,omitempty"` + Data map[string]interface{} `json:"data,omitempty"` +} + +func CheckBundleIdentifier() bool { + return bool(C.checkBundleIdentifier()) +} + +// ServiceName returns the name of the service +func (ns *NotificationService) ServiceName() string { + return "github.com/wailsapp/wails/v3/services/notifications" +} + +// ServiceStartup is called when the service is loaded +func (ns *NotificationService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + return nil +} + +// ServiceShutdown is called when the service is unloaded +func (ns *NotificationService) ServiceShutdown() error { + return nil +} + +// RequestUserNotificationAuthorization requests permission for notifications. +func (ns *NotificationService) RequestUserNotificationAuthorization() (bool, error) { + if !CheckBundleIdentifier() { + return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + result := C.requestUserNotificationAuthorization(nil) + return result == true, nil +} + +// CheckNotificationAuthorization checks current permission status +func (ns *NotificationService) CheckNotificationAuthorization() (bool, error) { + if !CheckBundleIdentifier() { + return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + return bool(C.checkNotificationAuthorization()), nil +} + +// SendNotification sends a notification with the given identifier, title, subtitle, and body. +func (ns *NotificationService) SendNotification(identifier, title, subtitle, body string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + cTitle := C.CString(title) + cSubtitle := C.CString(subtitle) + cBody := C.CString(body) + defer C.free(unsafe.Pointer(cIdentifier)) + defer C.free(unsafe.Pointer(cTitle)) + defer C.free(unsafe.Pointer(cSubtitle)) + defer C.free(unsafe.Pointer(cBody)) + + C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil) + return nil +} + +// SendNotificationWithActions sends a notification with the specified actions +func (ns *NotificationService) SendNotificationWithActions(options NotificationOptions) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(options.ID) + cTitle := C.CString(options.Title) + cSubtitle := C.CString(options.Subtitle) + cBody := C.CString(options.Body) + cCategoryID := C.CString(options.CategoryID) + defer C.free(unsafe.Pointer(cIdentifier)) + defer C.free(unsafe.Pointer(cTitle)) + defer C.free(unsafe.Pointer(cSubtitle)) + defer C.free(unsafe.Pointer(cBody)) + defer C.free(unsafe.Pointer(cCategoryID)) + + var cActionsJSON *C.char + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + cActionsJSON = C.CString(string(jsonData)) + defer C.free(unsafe.Pointer(cActionsJSON)) + } + } + + C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil) + return nil +} + +// RegisterNotificationCategory registers a category with actions and optional reply field +func (ns *NotificationService) RegisterNotificationCategory(category NotificationCategory) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cCategoryID := C.CString(category.ID) + defer C.free(unsafe.Pointer(cCategoryID)) + + actionsJSON, err := json.Marshal(category.Actions) + if err != nil { + return err + } + cActionsJSON := C.CString(string(actionsJSON)) + defer C.free(unsafe.Pointer(cActionsJSON)) + + var cReplyPlaceholder, cReplyButtonTitle *C.char + if category.HasReplyField { + cReplyPlaceholder = C.CString(category.ReplyPlaceholder) + cReplyButtonTitle = C.CString(category.ReplyButtonTitle) + defer C.free(unsafe.Pointer(cReplyPlaceholder)) + defer C.free(unsafe.Pointer(cReplyButtonTitle)) + } + + C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField), + cReplyPlaceholder, cReplyButtonTitle) + return nil +} + +// RemoveAllPendingNotifications removes all pending notifications +func (ns *NotificationService) RemoveAllPendingNotifications() error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + C.removeAllPendingNotifications() + return nil +} + +// RemovePendingNotification removes a specific pending notification +func (ns *NotificationService) RemovePendingNotification(identifier string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + defer C.free(unsafe.Pointer(cIdentifier)) + C.removePendingNotification(cIdentifier) + return nil +} + +func (ns *NotificationService) RemoveAllDeliveredNotifications() error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + C.removeAllDeliveredNotifications() + return nil +} + +func (ns *NotificationService) RemoveDeliveredNotification(identifier string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + defer C.free(unsafe.Pointer(cIdentifier)) + C.removeDeliveredNotification(cIdentifier) + return nil +} From cc524d78e4bca1691f3c6bb0f86fc31550c3186e Mon Sep 17 00:00:00 2001 From: popaprozac Date: Fri, 21 Feb 2025 18:36:54 -0800 Subject: [PATCH 004/136] update example --- v3/examples/notifications/frontend/index.html | 31 ++++ v3/examples/notifications/frontend/main.js | 67 ++++++++ .../notifications/frontend/package.json | 16 ++ .../frontend/public/Inter-Medium.ttf | Bin 0 -> 315132 bytes .../frontend/public/javascript.svg | 1 + .../notifications/frontend/public/style.css | 160 ++++++++++++++++++ .../notifications/frontend/public/wails.png | Bin 0 -> 9057 bytes v3/examples/notifications/main.go | 4 + 8 files changed, 279 insertions(+) create mode 100644 v3/examples/notifications/frontend/index.html create mode 100644 v3/examples/notifications/frontend/main.js create mode 100644 v3/examples/notifications/frontend/package.json create mode 100644 v3/examples/notifications/frontend/public/Inter-Medium.ttf create mode 100644 v3/examples/notifications/frontend/public/javascript.svg create mode 100644 v3/examples/notifications/frontend/public/style.css create mode 100644 v3/examples/notifications/frontend/public/wails.png diff --git a/v3/examples/notifications/frontend/index.html b/v3/examples/notifications/frontend/index.html new file mode 100644 index 000000000..88daa5e2f --- /dev/null +++ b/v3/examples/notifications/frontend/index.html @@ -0,0 +1,31 @@ + + + + + + + + Wails App + + +
+ +

Wails + Javascript

+ +
+ + + diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js new file mode 100644 index 000000000..18dd0214c --- /dev/null +++ b/v3/examples/notifications/frontend/main.js @@ -0,0 +1,67 @@ +import { GreetService } from "./bindings/notifications"; +import { NotificationService } from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notification"; +import { Events } from "@wailsio/runtime"; + +const resultElement = document.getElementById('result'); +const timeElement = document.getElementById('time'); +const notificationsElement = document.getElementById('notifications'); + +const nofitications = new Map(); + +window.doGreet = () => { + let name = document.getElementById('name').value; + if (!name) { + name = 'anonymous'; + } + GreetService.Greet(name).then((result) => { + resultElement.innerText = result; + }).catch((err) => { + console.log(err); + }); +} + +window.sendNotification = async () => { + const granted = await NotificationService.CheckNotificationAuthorization(); + if (granted) { + await NotificationService.SendNotification("some-uuid-fronted", "Frontend Notificaiton", "", "Notificaiton sent through JS!"); + } +} + +window.sendComplexNotification = async () => { + const granted = await NotificationService.CheckNotificationAuthorization(); + if (granted) { + await NotificationService.RegisterNotificationCategory({ + id: "FRONTEND_NOTIF", + actions: [ + { id: "VIEW_ACTION", title: "View" }, + { id: "MARK_READ_ACTION", title: "Mark as Read" }, + { id: "DELETE_ACTION", title: "Delete", destructive: true }, + ], + hasReplyField: true, + replyButtonTitle: "Reply", + replyPlaceholder: "Reply to frontend...", + }); + + await NotificationService.SendNotificationWithActions({ + id: "some-uuid-complex", + title: "Complex Frontend Notification", + subtitle: "From: Jane Doe", + body: "Is it rainging today where you are?", + categoryId: "FRONTEND_NOTIF", + data: { + messageId: "msg-456", + senderId: "user-456", + timestamp: Date.now(), + } + }); + } +} + +Events.On('time', (time) => { + timeElement.innerText = time.data; +}); + +Events.On("notification", (data) => { + nofitications.set(data.identifier, data); + notificationsElement.innerText = Array.from(nofitications.values()).map(notification => JSON.stringify(notification)).join(", "); +}); \ No newline at end of file diff --git a/v3/examples/notifications/frontend/package.json b/v3/examples/notifications/frontend/package.json new file mode 100644 index 000000000..9ae87549e --- /dev/null +++ b/v3/examples/notifications/frontend/package.json @@ -0,0 +1,16 @@ +{ + "name": "frontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build:dev": "vite build --minify false --mode development", + "build": "vite build --mode production", + "preview": "vite preview" + }, + "devDependencies": { + "vite": "^5.0.0", + "@wailsio/runtime": "latest" + } +} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/Inter-Medium.ttf b/v3/examples/notifications/frontend/public/Inter-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a01f3777a6fc284b7a720c0f8248a27066389ef9 GIT binary patch literal 315132 zcmd>{3Ajzw|M0(S?X!n-?sds<&AMdHJY`De%rlit*Gxz*k|ZQaMWm8sCL|H5Orgje zLX;sYN}^G@hWmcjK4)L_tKaY+-sgFr_ul8T*4k_QuJ8KpwfA0opS?wiNG6<+$lZ18 z)h}DV>>3eWoroNFw`kt_=)7a6M2)O0s^ph46$l{1e>k6gWyQwEyWNY9Gz_3HOX&vyAf z)S{Q>5MAJ8?;gqBOFo}`FX>%Kuhg4}e4BH=#y0Xu!QTA`56g7y>@Ol2dy5p=(eJ@- z$>AZbE{NPwf$hEhlZOqA#4CsVv?oaelKb~){O#aW5vPqvIP<^B5&SN zzrXqG{ycsElt;op`!QDN*v#5b&hDJC`frju&adR?&uep=z_GS14*mY-l@WRR#%E^J z5gn_;)b6n*lGS$$ihj6P@4+ggNJ_r}gHSL1OfsF!hHQL}O9s)M+nsb6q^Qx|dn(6vPA zI=TUFBi#nKoleH>rm-LWq<#hWRsAaNOuY_wquz}Bk=}y4L+`}htv|#4+^Q|gs%JIC zZDKuyJJ=e6`-n9Tcf7Rn$I0&?vs26| zhFiiZfm_XC?3_kUBivR_Pu$*4Z`=o*2XF^C18^U9hKc1o;ygllxHE$A80QJxxz0jS zuIEyxThJ|tTgUBy+u7}m`?&iA?o;klxKF!J<38g~!kywy!JX<(#hvD&2lrK%QFa%* zi*es@m*OsSm*cK3;-OD(xHp{e)}Vk zj}jgoW^}?YgkQj&9-fZ-es~?J8^W6i?+WiGygz&h_el5{?w4U|4u2c|7WaG@4Tpb< z&3F~`P%|^Jmxw&?#K*!)a@fDd!depS)3LB6rR?`&;m{3vY^h|U1HT@J_`b2QD{bt= zSlAQKPKbrWk`y{03&#=O6AQ=R5YC{ItYxwI1gT)5Z@>Ob60rux!na7g)jbx@d_A7& zF41ZhjaN$YSmk12Emid&v9Kle_1m#?vid~S~a&&R@fB%ch5h4XS)iH$F^BublD{H+{eYRAG!9CZrB!ugRWM=V@`kdUjN zBuh7WfLsk_FyVgEhwba}^<)_FgGi|@50cvbPdWcF{jc){v8|mem2h13VpUJrSMT9Ty>3?!}(7+ojH-SDu#-J4JfsYA$L->-WxHJI`PNg0eR zrk)%OnM*bDYd9+u%CMXc}>W)X;S;MZTi-o7KTVyUt%M{ zpqpyy=F2mb5@zI$)P2a=gfb8NwcIE}lbcEgd7JyvnwADob^xWW$D|N5?1t^0zAS_O zQtAi&vUMquf)xFc*ywzS->W{9Gc5#~G(9rbkmBnx1>HsEAMVR+MkEQ{8BLp>rLbir zGrCS9&XgYD_t!`p9oeqL4kG72YyWz`jLr6f!IZesh8y~=80{Nt9gJqGN@@O6kj9Lc zv5gcd1xCxI{5E@$-W-c)!v1aS(MVgL6eDkvv?kP((8K7#*oWzf$r0U;dyvc6hZ(zQ zpG@0PYchFTv)7wZyDs_ln$4cljk3`iN|37^TSfn*nUt7Tjja8l6mAc+*oxXs%n;lp+B0Ju?NN%a&mjNx zQA%QOYv@ZAwTBy1qIx#6N9RXVm)WNV`Ln4R6=O?*1lLQJyvZW|tkd#HTL!IG;ff$? zK_%HvmWsrckxH~t1`Xbrs}-Zz6sjSqu?f?oo7-qboY_;%TtDcBTuC=cQU@IjWS%m1 z7|f>SXw48EVPi4Z+enfY7y8oNVG@2$=8*Bb|Yth z#wE~FX<80?P)sDQpt&yPN^GUn|6ii|e_rpkJ?_f1l28#`I0oDP{d)d+`M8MGzY({b zoVDP42V>h{^2j=f$(R9Lo&d7Uiy12EF<#m^3% zk;mAc3tNaQ3?C4lt$)Av9sZ_hKH0z`#ŹD@)<7ltOtn$SSm;LMTrPEA?sR43d= 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�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 literal 0 HcmV?d00001 diff --git a/v3/examples/notifications/frontend/public/javascript.svg b/v3/examples/notifications/frontend/public/javascript.svg new file mode 100644 index 000000000..f9abb2b72 --- /dev/null +++ b/v3/examples/notifications/frontend/public/javascript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/style.css b/v3/examples/notifications/frontend/public/style.css new file mode 100644 index 000000000..127799eda --- /dev/null +++ b/v3/examples/notifications/frontend/public/style.css @@ -0,0 +1,160 @@ +:root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: rgba(27, 38, 54, 1); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./Inter-Medium.ttf") format("truetype"); +} + +h3 { + font-size: 3em; + line-height: 1.1; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +button { + /* width: 60px; */ + height: 30px; + line-height: 30px; + border-radius: 3px; + border: none; + margin: 0 0 0 20px; + padding: 0 8px; + cursor: pointer; +} + +.result { + height: 20px; + line-height: 20px; +} + +body { + margin: 0; + display: flex; + place-items: center; + place-content: center; + min-width: 320px; + min-height: 100vh; +} + +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #e80000aa); +} + +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #f7df1eaa); +} + +.result { + height: 20px; + line-height: 20px; + margin: 1.5rem auto; + text-align: center; +} + +.footer { + margin-top: 1rem; + align-content: center; + text-align: center; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + + a:hover { + color: #747bff; + } + + button { + background-color: #f9f9f9; + } +} + + +.input-box .btn:hover { + background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); + color: #333333; +} + +.input-box .input { + border: none; + border-radius: 3px; + outline: none; + height: 30px; + line-height: 30px; + padding: 0 10px; + color: black; + background-color: rgba(240, 240, 240, 1); + -webkit-font-smoothing: antialiased; +} + +.input-box .input:hover { + border: none; + background-color: rgba(255, 255, 255, 1); +} + +.input-box .input:focus { + border: none; + background-color: rgba(255, 255, 255, 1); +} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/wails.png b/v3/examples/notifications/frontend/public/wails.png new file mode 100644 index 0000000000000000000000000000000000000000..8bdf424833bfb5b6b34a0807224e94533f738f2e GIT binary patch literal 9057 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 Date: Sat, 22 Feb 2025 00:34:29 -0800 Subject: [PATCH 005/136] refactor --- v3/examples/notifications/frontend/index.html | 31 --- v3/examples/notifications/frontend/main.js | 67 ------- .../notifications/frontend/package.json | 16 -- .../frontend/public/Inter-Medium.ttf | Bin 315132 -> 0 bytes .../frontend/public/javascript.svg | 1 - .../notifications/frontend/public/style.css | 160 ---------------- .../notifications/frontend/public/wails.png | Bin 9057 -> 0 bytes v3/examples/notifications/main.go | 135 ------------- .../v3/pkg/services/notifications/index.js | 25 +++ .../v3/pkg/services/notifications/models.js | 37 ++++ .../v3/pkg/services/notifications/service.js | 98 ++++++++++ v3/examples/services/assets/index.html | 7 + v3/examples/services/main.go | 11 +- v3/pkg/application/notifications_darwin.go | 177 ------------------ .../notifications.go} | 40 ++-- .../notifications}/notifications_darwin.h | 0 .../notifications}/notifications_darwin.m | 2 +- 17 files changed, 197 insertions(+), 610 deletions(-) delete mode 100644 v3/examples/notifications/frontend/index.html delete mode 100644 v3/examples/notifications/frontend/main.js delete mode 100644 v3/examples/notifications/frontend/package.json delete mode 100644 v3/examples/notifications/frontend/public/Inter-Medium.ttf delete mode 100644 v3/examples/notifications/frontend/public/javascript.svg delete mode 100644 v3/examples/notifications/frontend/public/style.css delete mode 100644 v3/examples/notifications/frontend/public/wails.png delete mode 100644 v3/examples/notifications/main.go create mode 100644 v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js create mode 100644 v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js create mode 100644 v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js delete mode 100644 v3/pkg/application/notifications_darwin.go rename v3/pkg/services/{notification/notification.go => notifications/notifications.go} (83%) rename v3/pkg/{application => services/notifications}/notifications_darwin.h (100%) rename v3/pkg/{application => services/notifications}/notifications_darwin.m (99%) diff --git a/v3/examples/notifications/frontend/index.html b/v3/examples/notifications/frontend/index.html deleted file mode 100644 index 88daa5e2f..000000000 --- a/v3/examples/notifications/frontend/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - Wails App - - - - - - diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js deleted file mode 100644 index 18dd0214c..000000000 --- a/v3/examples/notifications/frontend/main.js +++ /dev/null @@ -1,67 +0,0 @@ -import { GreetService } from "./bindings/notifications"; -import { NotificationService } from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notification"; -import { Events } from "@wailsio/runtime"; - -const resultElement = document.getElementById('result'); -const timeElement = document.getElementById('time'); -const notificationsElement = document.getElementById('notifications'); - -const nofitications = new Map(); - -window.doGreet = () => { - let name = document.getElementById('name').value; - if (!name) { - name = 'anonymous'; - } - GreetService.Greet(name).then((result) => { - resultElement.innerText = result; - }).catch((err) => { - console.log(err); - }); -} - -window.sendNotification = async () => { - const granted = await NotificationService.CheckNotificationAuthorization(); - if (granted) { - await NotificationService.SendNotification("some-uuid-fronted", "Frontend Notificaiton", "", "Notificaiton sent through JS!"); - } -} - -window.sendComplexNotification = async () => { - const granted = await NotificationService.CheckNotificationAuthorization(); - if (granted) { - await NotificationService.RegisterNotificationCategory({ - id: "FRONTEND_NOTIF", - actions: [ - { id: "VIEW_ACTION", title: "View" }, - { id: "MARK_READ_ACTION", title: "Mark as Read" }, - { id: "DELETE_ACTION", title: "Delete", destructive: true }, - ], - hasReplyField: true, - replyButtonTitle: "Reply", - replyPlaceholder: "Reply to frontend...", - }); - - await NotificationService.SendNotificationWithActions({ - id: "some-uuid-complex", - title: "Complex Frontend Notification", - subtitle: "From: Jane Doe", - body: "Is it rainging today where you are?", - categoryId: "FRONTEND_NOTIF", - data: { - messageId: "msg-456", - senderId: "user-456", - timestamp: Date.now(), - } - }); - } -} - -Events.On('time', (time) => { - timeElement.innerText = time.data; -}); - -Events.On("notification", (data) => { - nofitications.set(data.identifier, data); - notificationsElement.innerText = Array.from(nofitications.values()).map(notification => JSON.stringify(notification)).join(", "); -}); \ No newline at end of file diff --git a/v3/examples/notifications/frontend/package.json b/v3/examples/notifications/frontend/package.json deleted file mode 100644 index 9ae87549e..000000000 --- a/v3/examples/notifications/frontend/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "frontend", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build:dev": "vite build --minify false --mode development", - "build": "vite build --mode production", - "preview": "vite preview" - }, - "devDependencies": { - "vite": "^5.0.0", - "@wailsio/runtime": "latest" - } -} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/Inter-Medium.ttf b/v3/examples/notifications/frontend/public/Inter-Medium.ttf deleted file mode 100644 index a01f3777a6fc284b7a720c0f8248a27066389ef9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 315132 zcmd>{3Ajzw|M0(S?X!n-?sds<&AMdHJY`De%rlit*Gxz*k|ZQaMWm8sCL|H5Orgje zLX;sYN}^G@hWmcjK4)L_tKaY+-sgFr_ul8T*4k_QuJ8KpwfA0opS?wiNG6<+$lZ18 z)h}DV>>3eWoroNFw`kt_=)7a6M2)O0s^ph46$l{1e>k6gWyQwEyWNY9Gz_3HOX&vyAf z)S{Q>5MAJ8?;gqBOFo}`FX>%Kuhg4}e4BH=#y0Xu!QTA`56g7y>@Ol2dy5p=(eJ@- z$>AZbE{NPwf$hEhlZOqA#4CsVv?oaelKb~){O#aW5vPqvIP<^B5&SN zzrXqG{ycsElt;op`!QDN*v#5b&hDJC`frju&adR?&uep=z_GS14*mY-l@WRR#%E^J z5gn_;)b6n*lGS$$ihj6P@4+ggNJ_r}gHSL1OfsF!hHQL}O9s)M+nsb6q^Qx|dn(6vPA zI=TUFBi#nKoleH>rm-LWq<#hWRsAaNOuY_wquz}Bk=}y4L+`}htv|#4+^Q|gs%JIC zZDKuyJJ=e6`-n9Tcf7Rn$I0&?vs26| zhFiiZfm_XC?3_kUBivR_Pu$*4Z`=o*2XF^C18^U9hKc1o;ygllxHE$A80QJxxz0jS zuIEyxThJ|tTgUBy+u7}m`?&iA?o;klxKF!J<38g~!kywy!JX<(#hvD&2lrK%QFa%* zi*es@m*OsSm*cK3;-OD(xHp{e)}Vk zj}jgoW^}?YgkQj&9-fZ-es~?J8^W6i?+WiGygz&h_el5{?w4U|4u2c|7WaG@4Tpb< z&3F~`P%|^Jmxw&?#K*!)a@fDd!depS)3LB6rR?`&;m{3vY^h|U1HT@J_`b2QD{bt= zSlAQKPKbrWk`y{03&#=O6AQ=R5YC{ItYxwI1gT)5Z@>Ob60rux!na7g)jbx@d_A7& zF41ZhjaN$YSmk12Emid&v9Kle_1m#?vid~S~a&&R@fB%ch5h4XS)iH$F^BublD{H+{eYRAG!9CZrB!ugRWM=V@`kdUjN zBuh7WfLsk_FyVgEhwba}^<)_FgGi|@50cvbPdWcF{jc){v8|mem2h13VpUJrSMT9Ty>3?!}(7+ojH-SDu#-J4JfsYA$L->-WxHJI`PNg0eR zrk)%OnM*bDYd9+u%CMXc}>W)X;S;MZTi-o7KTVyUt%M{ zpqpyy=F2mb5@zI$)P2a=gfb8NwcIE}lbcEgd7JyvnwADob^xWW$D|N5?1t^0zAS_O zQtAi&vUMquf)xFc*ywzS->W{9Gc5#~G(9rbkmBnx1>HsEAMVR+MkEQ{8BLp>rLbir zGrCS9&XgYD_t!`p9oeqL4kG72YyWz`jLr6f!IZesh8y~=80{Nt9gJqGN@@O6kj9Lc zv5gcd1xCxI{5E@$-W-c)!v1aS(MVgL6eDkvv?kP((8K7#*oWzf$r0U;dyvc6hZ(zQ zpG@0PYchFTv)7wZyDs_ln$4cljk3`iN|37^TSfn*nUt7Tjja8l6mAc+*oxXs%n;lp+B0Ju?NN%a&mjNx zQA%QOYv@ZAwTBy1qIx#6N9RXVm)WNV`Ln4R6=O?*1lLQJyvZW|tkd#HTL!IG;ff$? zK_%HvmWsrckxH~t1`Xbrs}-Zz6sjSqu?f?oo7-qboY_;%TtDcBTuC=cQU@IjWS%m1 z7|f>SXw48EVPi4Z+enfY7y8oNVG@2$=8*Bb|Yth z#wE~FX<80?P)sDQpt&yPN^GUn|6ii|e_rpkJ?_f1l28#`I0oDP{d)d+`M8MGzY({b zoVDP42V>h{^2j=f$(R9Lo&d7Uiy12EF<#m^3% zk;mAc3tNaQ3?C4lt$)Av9sZ_hKH0z`#ŹD@)<7ltOtn$SSm;LMTrPEA?sR43d= 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�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 diff --git a/v3/examples/notifications/frontend/public/javascript.svg b/v3/examples/notifications/frontend/public/javascript.svg deleted file mode 100644 index f9abb2b72..000000000 --- a/v3/examples/notifications/frontend/public/javascript.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/style.css b/v3/examples/notifications/frontend/public/style.css deleted file mode 100644 index 127799eda..000000000 --- a/v3/examples/notifications/frontend/public/style.css +++ /dev/null @@ -1,160 +0,0 @@ -:root { - font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", - "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - font-size: 16px; - line-height: 24px; - font-weight: 400; - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: rgba(27, 38, 54, 1); - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -* { - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; -} - -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 400; - src: local(""), - url("./Inter-Medium.ttf") format("truetype"); -} - -h3 { - font-size: 3em; - line-height: 1.1; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} - -a:hover { - color: #535bf2; -} - -button { - /* width: 60px; */ - height: 30px; - line-height: 30px; - border-radius: 3px; - border: none; - margin: 0 0 0 20px; - padding: 0 8px; - cursor: pointer; -} - -.result { - height: 20px; - line-height: 20px; -} - -body { - margin: 0; - display: flex; - place-items: center; - place-content: center; - min-width: 320px; - min-height: 100vh; -} - -.container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -#app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; -} - -.logo:hover { - filter: drop-shadow(0 0 2em #e80000aa); -} - -.logo.vanilla:hover { - filter: drop-shadow(0 0 2em #f7df1eaa); -} - -.result { - height: 20px; - line-height: 20px; - margin: 1.5rem auto; - text-align: center; -} - -.footer { - margin-top: 1rem; - align-content: center; - text-align: center; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - - a:hover { - color: #747bff; - } - - button { - background-color: #f9f9f9; - } -} - - -.input-box .btn:hover { - background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); - color: #333333; -} - -.input-box .input { - border: none; - border-radius: 3px; - outline: none; - height: 30px; - line-height: 30px; - padding: 0 10px; - color: black; - background-color: rgba(240, 240, 240, 1); - -webkit-font-smoothing: antialiased; -} - -.input-box .input:hover { - border: none; - background-color: rgba(255, 255, 255, 1); -} - -.input-box .input:focus { - border: none; - background-color: rgba(255, 255, 255, 1); -} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/wails.png b/v3/examples/notifications/frontend/public/wails.png deleted file mode 100644 index 8bdf424833bfb5b6b34a0807224e94533f738f2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9057 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 & { cancel(): void }} + */ +export function CheckNotificationAuthorization() { + let $resultPromise = /** @type {any} */($Call.ByID(2789931702)); + return $resultPromise; +} + +/** + * RegisterNotificationCategory registers a category with actions and optional reply field + * @param {$models.NotificationCategory} category + * @returns {Promise & { cancel(): void }} + */ +export function RegisterNotificationCategory(category) { + let $resultPromise = /** @type {any} */($Call.ByID(2679064664, category)); + return $resultPromise; +} + +/** + * @returns {Promise & { cancel(): void }} + */ +export function RemoveAllDeliveredNotifications() { + let $resultPromise = /** @type {any} */($Call.ByID(384520397)); + return $resultPromise; +} + +/** + * RemoveAllPendingNotifications removes all pending notifications + * @returns {Promise & { cancel(): void }} + */ +export function RemoveAllPendingNotifications() { + let $resultPromise = /** @type {any} */($Call.ByID(1423986276)); + return $resultPromise; +} + +/** + * @param {string} identifier + * @returns {Promise & { cancel(): void }} + */ +export function RemoveDeliveredNotification(identifier) { + let $resultPromise = /** @type {any} */($Call.ByID(149440045, identifier)); + return $resultPromise; +} + +/** + * RemovePendingNotification removes a specific pending notification + * @param {string} identifier + * @returns {Promise & { cancel(): void }} + */ +export function RemovePendingNotification(identifier) { + let $resultPromise = /** @type {any} */($Call.ByID(3872412470, identifier)); + return $resultPromise; +} + +/** + * RequestUserNotificationAuthorization requests permission for notifications. + * @returns {Promise & { cancel(): void }} + */ +export function RequestUserNotificationAuthorization() { + let $resultPromise = /** @type {any} */($Call.ByID(3412125712)); + return $resultPromise; +} + +/** + * SendNotification sends a notification with the given identifier, title, subtitle, and body. + * @param {string} identifier + * @param {string} title + * @param {string} subtitle + * @param {string} body + * @returns {Promise & { cancel(): void }} + */ +export function SendNotification(identifier, title, subtitle, body) { + let $resultPromise = /** @type {any} */($Call.ByID(2246903123, identifier, title, subtitle, body)); + return $resultPromise; +} + +/** + * SendNotificationWithActions sends a notification with the specified actions + * @param {$models.NotificationOptions} options + * @returns {Promise & { cancel(): void }} + */ +export function SendNotificationWithActions(options) { + let $resultPromise = /** @type {any} */($Call.ByID(1615199806, options)); + return $resultPromise; +} diff --git a/v3/examples/services/assets/index.html b/v3/examples/services/assets/index.html index 67746fdec..24a372593 100644 --- a/v3/examples/services/assets/index.html +++ b/v3/examples/services/assets/index.html @@ -10,6 +10,13 @@ import * as kvstore from './bindings/github.com/wailsapp/wails/v3/pkg/services/kvstore/keyvaluestore.js'; import {Debug, Info, Warning, Error} from './bindings/github.com/wailsapp/wails/v3/pkg/services/log/loggerservice.js'; import * as hash from './bindings/github.com/wailsapp/wails/v3/examples/services/hashes/service.js'; + import * as notifications from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js" + + notifications.RequestUserNotificationAuthorization().then((granted) => { + if (granted) { + notifications.SendNotification("some-uuid-fronted", "Frontend Notificaiton", "", "Notificaiton sent through JS!"); + } + }); function runHash() { let hashstring = document.getElementById("hashstring").value; diff --git a/v3/examples/services/main.go b/v3/examples/services/main.go index a4ebb6bf4..6bc020c8a 100644 --- a/v3/examples/services/main.go +++ b/v3/examples/services/main.go @@ -2,16 +2,18 @@ package main import ( "embed" + "log/slog" + "os" + "path/filepath" + "runtime" + "github.com/wailsapp/wails/v3/examples/services/hashes" "github.com/wailsapp/wails/v3/pkg/application" "github.com/wailsapp/wails/v3/pkg/services/fileserver" "github.com/wailsapp/wails/v3/pkg/services/kvstore" "github.com/wailsapp/wails/v3/pkg/services/log" + "github.com/wailsapp/wails/v3/pkg/services/notifications" "github.com/wailsapp/wails/v3/pkg/services/sqlite" - "log/slog" - "os" - "path/filepath" - "runtime" ) //go:embed assets/* @@ -48,6 +50,7 @@ func main() { }), application.ServiceOptions{ Route: "/files", }), + application.NewService(notifications.New()), }, Assets: application.AssetOptions{ Handler: application.BundledAssetFileServer(assets), diff --git a/v3/pkg/application/notifications_darwin.go b/v3/pkg/application/notifications_darwin.go deleted file mode 100644 index e04075238..000000000 --- a/v3/pkg/application/notifications_darwin.go +++ /dev/null @@ -1,177 +0,0 @@ -//go:build darwin - -package application - -/* -#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c -#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications -#import "notifications_darwin.h" -*/ -import "C" -import ( - "encoding/json" - "fmt" - "unsafe" -) - -// NotificationAction represents a button in a notification -type NotificationAction struct { - ID string `json:"id"` - Title string `json:"title"` - Destructive bool `json:"destructive,omitempty"` - AuthenticationRequired bool `json:"authenticationRequired,omitempty"` -} - -// NotificationCategory groups actions for notifications -type NotificationCategory struct { - ID string `json:"id"` - Actions []NotificationAction `json:"actions"` - HasReplyField bool `json:"hasReplyField,omitempty"` - ReplyPlaceholder string `json:"replyPlaceholder,omitempty"` - ReplyButtonTitle string `json:"replyButtonTitle,omitempty"` -} - -// NotificationOptions contains configuration for a notification -type NotificationOptions struct { - ID string `json:"id"` - Title string `json:"title"` - Subtitle string `json:"subtitle,omitempty"` - Body string `json:"body"` - CategoryID string `json:"categoryId,omitempty"` - Data map[string]interface{} `json:"data,omitempty"` -} - -// Check if the app has a valid bundle identifier -func CheckBundleIdentifier() bool { - return bool(C.checkBundleIdentifier()) -} - -// RequestUserNotificationAuthorization requests permission for notifications. -func RequestUserNotificationAuthorization() (bool, error) { - if !CheckBundleIdentifier() { - return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - result := C.requestUserNotificationAuthorization(nil) - return result == true, nil -} - -// CheckNotificationAuthorization checks current permission status -func CheckNotificationAuthorization() (bool, error) { - if !CheckBundleIdentifier() { - return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - return bool(C.checkNotificationAuthorization()), nil -} - -// SendNotification sends a notification with the given identifier, title, subtitle, and body. -func SendNotification(identifier, title, subtitle, body string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(identifier) - cTitle := C.CString(title) - cSubtitle := C.CString(subtitle) - cBody := C.CString(body) - defer C.free(unsafe.Pointer(cIdentifier)) - defer C.free(unsafe.Pointer(cTitle)) - defer C.free(unsafe.Pointer(cSubtitle)) - defer C.free(unsafe.Pointer(cBody)) - - C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil) - return nil -} - -// SendNotificationWithActions sends a notification with the specified actions -func SendNotificationWithActions(options NotificationOptions) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(options.ID) - cTitle := C.CString(options.Title) - cSubtitle := C.CString(options.Subtitle) - cBody := C.CString(options.Body) - cCategoryID := C.CString(options.CategoryID) - defer C.free(unsafe.Pointer(cIdentifier)) - defer C.free(unsafe.Pointer(cTitle)) - defer C.free(unsafe.Pointer(cSubtitle)) - defer C.free(unsafe.Pointer(cBody)) - defer C.free(unsafe.Pointer(cCategoryID)) - - var cActionsJSON *C.char - if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err == nil { - cActionsJSON = C.CString(string(jsonData)) - defer C.free(unsafe.Pointer(cActionsJSON)) - } - } - - C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil) - return nil -} - -// RegisterNotificationCategory registers a category with actions and optional reply field -func RegisterNotificationCategory(category NotificationCategory) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cCategoryID := C.CString(category.ID) - defer C.free(unsafe.Pointer(cCategoryID)) - - actionsJSON, err := json.Marshal(category.Actions) - if err != nil { - return err - } - cActionsJSON := C.CString(string(actionsJSON)) - defer C.free(unsafe.Pointer(cActionsJSON)) - - var cReplyPlaceholder, cReplyButtonTitle *C.char - if category.HasReplyField { - cReplyPlaceholder = C.CString(category.ReplyPlaceholder) - cReplyButtonTitle = C.CString(category.ReplyButtonTitle) - defer C.free(unsafe.Pointer(cReplyPlaceholder)) - defer C.free(unsafe.Pointer(cReplyButtonTitle)) - } - - C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField), - cReplyPlaceholder, cReplyButtonTitle) - return nil -} - -// RemoveAllPendingNotifications removes all pending notifications -func RemoveAllPendingNotifications() error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - C.removeAllPendingNotifications() - return nil -} - -// RemovePendingNotification removes a specific pending notification -func RemovePendingNotification(identifier string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(identifier) - defer C.free(unsafe.Pointer(cIdentifier)) - C.removePendingNotification(cIdentifier) - return nil -} - -func RemoveAllDeliveredNotifications() error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - C.removeAllDeliveredNotifications() - return nil -} - -func RemoveDeliveredNotification(identifier string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(identifier) - defer C.free(unsafe.Pointer(cIdentifier)) - C.removeDeliveredNotification(cIdentifier) - return nil -} diff --git a/v3/pkg/services/notification/notification.go b/v3/pkg/services/notifications/notifications.go similarity index 83% rename from v3/pkg/services/notification/notification.go rename to v3/pkg/services/notifications/notifications.go index 987e4d438..8f700daf5 100644 --- a/v3/pkg/services/notification/notification.go +++ b/v3/pkg/services/notifications/notifications.go @@ -1,11 +1,11 @@ //go:build darwin -package notification +package notifications /* #cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c #cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications -#import "../../application/notifications_darwin.h" +#import "./notifications_darwin.h" */ import "C" import ( @@ -17,11 +17,11 @@ import ( "github.com/wailsapp/wails/v3/pkg/application" ) -type NotificationService struct { +type Service struct { } // NotificationAction represents an action button for a notification -type NotificationAction struct { +type NotificationAction = struct { ID string `json:"id"` Title string `json:"title"` Destructive bool `json:"destructive,omitempty"` @@ -29,7 +29,7 @@ type NotificationAction struct { } // NotificationCategory groups actions for notifications -type NotificationCategory struct { +type NotificationCategory = struct { ID string `json:"id"` Actions []NotificationAction `json:"actions"` HasReplyField bool `json:"hasReplyField,omitempty"` @@ -38,7 +38,7 @@ type NotificationCategory struct { } // NotificationOptions contains configuration for a notification -type NotificationOptions struct { +type NotificationOptions = struct { ID string `json:"id"` Title string `json:"title"` Subtitle string `json:"subtitle,omitempty"` @@ -47,17 +47,21 @@ type NotificationOptions struct { Data map[string]interface{} `json:"data,omitempty"` } +func New() *Service { + return &Service{} +} + func CheckBundleIdentifier() bool { return bool(C.checkBundleIdentifier()) } // ServiceName returns the name of the service -func (ns *NotificationService) ServiceName() string { +func (ns *Service) ServiceName() string { return "github.com/wailsapp/wails/v3/services/notifications" } // ServiceStartup is called when the service is loaded -func (ns *NotificationService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { +func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -65,12 +69,12 @@ func (ns *NotificationService) ServiceStartup(ctx context.Context, options appli } // ServiceShutdown is called when the service is unloaded -func (ns *NotificationService) ServiceShutdown() error { +func (ns *Service) ServiceShutdown() error { return nil } // RequestUserNotificationAuthorization requests permission for notifications. -func (ns *NotificationService) RequestUserNotificationAuthorization() (bool, error) { +func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { if !CheckBundleIdentifier() { return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -79,7 +83,7 @@ func (ns *NotificationService) RequestUserNotificationAuthorization() (bool, err } // CheckNotificationAuthorization checks current permission status -func (ns *NotificationService) CheckNotificationAuthorization() (bool, error) { +func (ns *Service) CheckNotificationAuthorization() (bool, error) { if !CheckBundleIdentifier() { return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -87,7 +91,7 @@ func (ns *NotificationService) CheckNotificationAuthorization() (bool, error) { } // SendNotification sends a notification with the given identifier, title, subtitle, and body. -func (ns *NotificationService) SendNotification(identifier, title, subtitle, body string) error { +func (ns *Service) SendNotification(identifier, title, subtitle, body string) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -105,7 +109,7 @@ func (ns *NotificationService) SendNotification(identifier, title, subtitle, bod } // SendNotificationWithActions sends a notification with the specified actions -func (ns *NotificationService) SendNotificationWithActions(options NotificationOptions) error { +func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -134,7 +138,7 @@ func (ns *NotificationService) SendNotificationWithActions(options NotificationO } // RegisterNotificationCategory registers a category with actions and optional reply field -func (ns *NotificationService) RegisterNotificationCategory(category NotificationCategory) error { +func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -162,7 +166,7 @@ func (ns *NotificationService) RegisterNotificationCategory(category Notificatio } // RemoveAllPendingNotifications removes all pending notifications -func (ns *NotificationService) RemoveAllPendingNotifications() error { +func (ns *Service) RemoveAllPendingNotifications() error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -171,7 +175,7 @@ func (ns *NotificationService) RemoveAllPendingNotifications() error { } // RemovePendingNotification removes a specific pending notification -func (ns *NotificationService) RemovePendingNotification(identifier string) error { +func (ns *Service) RemovePendingNotification(identifier string) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -181,7 +185,7 @@ func (ns *NotificationService) RemovePendingNotification(identifier string) erro return nil } -func (ns *NotificationService) RemoveAllDeliveredNotifications() error { +func (ns *Service) RemoveAllDeliveredNotifications() error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } @@ -189,7 +193,7 @@ func (ns *NotificationService) RemoveAllDeliveredNotifications() error { return nil } -func (ns *NotificationService) RemoveDeliveredNotification(identifier string) error { +func (ns *Service) RemoveDeliveredNotification(identifier string) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") } diff --git a/v3/pkg/application/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h similarity index 100% rename from v3/pkg/application/notifications_darwin.h rename to v3/pkg/services/notifications/notifications_darwin.h diff --git a/v3/pkg/application/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m similarity index 99% rename from v3/pkg/application/notifications_darwin.m rename to v3/pkg/services/notifications/notifications_darwin.m index 7c0a1cade..f4e9b1404 100644 --- a/v3/pkg/application/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -1,7 +1,7 @@ #import "notifications_darwin.h" #import #import -#import "../events/events_darwin.h" +#import "../../events/events_darwin.h" extern bool hasListeners(unsigned int); extern void processApplicationEvent(unsigned int, void* data); From 91f1704f6874afb00c75a2a0fc325e9d124e31cd Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Feb 2025 01:11:44 -0800 Subject: [PATCH 006/136] cleanup --- v3/pkg/services/notifications/notifications_darwin.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index 4014b9a1c..fb21d4cb0 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -5,16 +5,10 @@ #import -#ifdef __cplusplus -extern "C" { -#endif - bool checkBundleIdentifier(void); bool requestUserNotificationAuthorization(void *completion); bool checkNotificationAuthorization(void); void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, void *completion); - -// New advanced notification functions void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json, void *completion); void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, @@ -24,8 +18,4 @@ void removePendingNotification(const char *identifier); void removeAllDeliveredNotifications(void); void removeDeliveredNotification(const char *identifier); -#ifdef __cplusplus -} -#endif - #endif /* NOTIFICATIONS_DARWIN_H */ \ No newline at end of file From 01fa3071f1bab414de2fc43638114e2bc019bfd3 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sat, 22 Feb 2025 17:30:04 -0800 Subject: [PATCH 007/136] windows impl --- v3/go.mod | 1 + v3/go.sum | 2 + .../services/notifications/notifications.go | 181 ++---------------- .../notifications/notifications_darwin.go | 176 +++++++++++++++++ .../notifications/notifications_darwin.m | 4 + .../notifications/notifications_windows.go | 150 +++++++++++++++ 6 files changed, 345 insertions(+), 169 deletions(-) create mode 100644 v3/pkg/services/notifications/notifications_darwin.go create mode 100644 v3/pkg/services/notifications/notifications_windows.go diff --git a/v3/go.mod b/v3/go.mod index 3067f25ff..fd4383baa 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -3,6 +3,7 @@ module github.com/wailsapp/wails/v3 go 1.24.0 require ( + git.sr.ht/~jackmordaunt/go-toast v1.1.2 github.com/Masterminds/semver v1.5.0 github.com/adrg/xdg v0.5.3 github.com/atterpac/refresh v0.8.4 diff --git a/v3/go.sum b/v3/go.sum index 672302267..faf9d7aff 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -8,6 +8,8 @@ atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +git.sr.ht/~jackmordaunt/go-toast v1.1.2 h1:/yrfI55LRt1M7H1vkaw+NaH1+L1CDxrqDltwm5euVuE= +git.sr.ht/~jackmordaunt/go-toast v1.1.2/go.mod h1:jA4OqHKTQ4AFBdwrSnwnskUIIS3HYzlJSgdzCKqfavo= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 8f700daf5..5e0ea6910 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -1,22 +1,5 @@ -//go:build darwin - package notifications -/* -#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c -#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications -#import "./notifications_darwin.h" -*/ -import "C" -import ( - "context" - "encoding/json" - "fmt" - "unsafe" - - "github.com/wailsapp/wails/v3/pkg/application" -) - type Service struct { } @@ -47,158 +30,18 @@ type NotificationOptions = struct { Data map[string]interface{} `json:"data,omitempty"` } -func New() *Service { - return &Service{} +type NotificationResponseData = struct { + ID string `json:"id,omitempty"` + ActionIdentifier string `json:"actionIdentifier,omitempty"` + CategoryID string `json:"categoryIdentifier,omitempty"` + Title string `json:"title,omitempty"` + Subtitle string `json:"subtitle,omitempty"` + Body string `json:"body,omitempty"` + UserText string `json:"userText,omitempty"` + UserInfo map[string]interface{} `json:"userInfo,omitempty"` } -func CheckBundleIdentifier() bool { - return bool(C.checkBundleIdentifier()) -} - -// ServiceName returns the name of the service -func (ns *Service) ServiceName() string { - return "github.com/wailsapp/wails/v3/services/notifications" -} - -// ServiceStartup is called when the service is loaded -func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - return nil -} - -// ServiceShutdown is called when the service is unloaded -func (ns *Service) ServiceShutdown() error { - return nil -} - -// RequestUserNotificationAuthorization requests permission for notifications. -func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { - if !CheckBundleIdentifier() { - return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - result := C.requestUserNotificationAuthorization(nil) - return result == true, nil -} - -// CheckNotificationAuthorization checks current permission status -func (ns *Service) CheckNotificationAuthorization() (bool, error) { - if !CheckBundleIdentifier() { - return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - return bool(C.checkNotificationAuthorization()), nil -} - -// SendNotification sends a notification with the given identifier, title, subtitle, and body. -func (ns *Service) SendNotification(identifier, title, subtitle, body string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(identifier) - cTitle := C.CString(title) - cSubtitle := C.CString(subtitle) - cBody := C.CString(body) - defer C.free(unsafe.Pointer(cIdentifier)) - defer C.free(unsafe.Pointer(cTitle)) - defer C.free(unsafe.Pointer(cSubtitle)) - defer C.free(unsafe.Pointer(cBody)) - - C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil) - return nil -} - -// SendNotificationWithActions sends a notification with the specified actions -func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(options.ID) - cTitle := C.CString(options.Title) - cSubtitle := C.CString(options.Subtitle) - cBody := C.CString(options.Body) - cCategoryID := C.CString(options.CategoryID) - defer C.free(unsafe.Pointer(cIdentifier)) - defer C.free(unsafe.Pointer(cTitle)) - defer C.free(unsafe.Pointer(cSubtitle)) - defer C.free(unsafe.Pointer(cBody)) - defer C.free(unsafe.Pointer(cCategoryID)) - - var cActionsJSON *C.char - if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err == nil { - cActionsJSON = C.CString(string(jsonData)) - defer C.free(unsafe.Pointer(cActionsJSON)) - } - } - - C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil) - return nil -} - -// RegisterNotificationCategory registers a category with actions and optional reply field -func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cCategoryID := C.CString(category.ID) - defer C.free(unsafe.Pointer(cCategoryID)) - - actionsJSON, err := json.Marshal(category.Actions) - if err != nil { - return err - } - cActionsJSON := C.CString(string(actionsJSON)) - defer C.free(unsafe.Pointer(cActionsJSON)) - - var cReplyPlaceholder, cReplyButtonTitle *C.char - if category.HasReplyField { - cReplyPlaceholder = C.CString(category.ReplyPlaceholder) - cReplyButtonTitle = C.CString(category.ReplyButtonTitle) - defer C.free(unsafe.Pointer(cReplyPlaceholder)) - defer C.free(unsafe.Pointer(cReplyButtonTitle)) - } - - C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField), - cReplyPlaceholder, cReplyButtonTitle) - return nil -} - -// RemoveAllPendingNotifications removes all pending notifications -func (ns *Service) RemoveAllPendingNotifications() error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - C.removeAllPendingNotifications() - return nil -} - -// RemovePendingNotification removes a specific pending notification -func (ns *Service) RemovePendingNotification(identifier string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(identifier) - defer C.free(unsafe.Pointer(cIdentifier)) - C.removePendingNotification(cIdentifier) - return nil -} - -func (ns *Service) RemoveAllDeliveredNotifications() error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - C.removeAllDeliveredNotifications() - return nil -} - -func (ns *Service) RemoveDeliveredNotification(identifier string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") - } - cIdentifier := C.CString(identifier) - defer C.free(unsafe.Pointer(cIdentifier)) - C.removeDeliveredNotification(cIdentifier) - return nil +type NotificationResponse = struct { + Name string `json:"name"` + Data NotificationResponseData `json:"data"` } diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go new file mode 100644 index 000000000..5fc72b235 --- /dev/null +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -0,0 +1,176 @@ +//go:build darwin + +package notifications + +/* +#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c +#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications +#import "./notifications_darwin.h" +*/ +import "C" +import ( + "context" + "encoding/json" + "fmt" + "unsafe" + + "github.com/wailsapp/wails/v3/pkg/application" +) + +func New() *Service { + return &Service{} +} + +// ServiceName returns the name of the service +func (ns *Service) ServiceName() string { + return "github.com/wailsapp/wails/v3/services/notifications" +} + +// ServiceStartup is called when the service is loaded +func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + return nil +} + +// ServiceShutdown is called when the service is unloaded +func (ns *Service) ServiceShutdown() error { + return nil +} + +func CheckBundleIdentifier() bool { + return bool(C.checkBundleIdentifier()) +} + +// RequestUserNotificationAuthorization requests permission for notifications. +func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { + if !CheckBundleIdentifier() { + return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + result := C.requestUserNotificationAuthorization(nil) + return result == true, nil +} + +// CheckNotificationAuthorization checks current permission status +func (ns *Service) CheckNotificationAuthorization() (bool, error) { + if !CheckBundleIdentifier() { + return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + return bool(C.checkNotificationAuthorization()), nil +} + +// SendNotification sends a notification with the given identifier, title, subtitle, and body. +func (ns *Service) SendNotification(identifier, title, subtitle, body string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + cTitle := C.CString(title) + cSubtitle := C.CString(subtitle) + cBody := C.CString(body) + defer C.free(unsafe.Pointer(cIdentifier)) + defer C.free(unsafe.Pointer(cTitle)) + defer C.free(unsafe.Pointer(cSubtitle)) + defer C.free(unsafe.Pointer(cBody)) + + C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil) + return nil +} + +// SendNotificationWithActions sends a notification with the specified actions +func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(options.ID) + cTitle := C.CString(options.Title) + cSubtitle := C.CString(options.Subtitle) + cBody := C.CString(options.Body) + cCategoryID := C.CString(options.CategoryID) + defer C.free(unsafe.Pointer(cIdentifier)) + defer C.free(unsafe.Pointer(cTitle)) + defer C.free(unsafe.Pointer(cSubtitle)) + defer C.free(unsafe.Pointer(cBody)) + defer C.free(unsafe.Pointer(cCategoryID)) + + var cActionsJSON *C.char + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + cActionsJSON = C.CString(string(jsonData)) + defer C.free(unsafe.Pointer(cActionsJSON)) + } + } + + C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil) + return nil +} + +// RegisterNotificationCategory registers a category with actions and optional reply field +func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cCategoryID := C.CString(category.ID) + defer C.free(unsafe.Pointer(cCategoryID)) + + actionsJSON, err := json.Marshal(category.Actions) + if err != nil { + return err + } + cActionsJSON := C.CString(string(actionsJSON)) + defer C.free(unsafe.Pointer(cActionsJSON)) + + var cReplyPlaceholder, cReplyButtonTitle *C.char + if category.HasReplyField { + cReplyPlaceholder = C.CString(category.ReplyPlaceholder) + cReplyButtonTitle = C.CString(category.ReplyButtonTitle) + defer C.free(unsafe.Pointer(cReplyPlaceholder)) + defer C.free(unsafe.Pointer(cReplyButtonTitle)) + } + + C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField), + cReplyPlaceholder, cReplyButtonTitle) + return nil +} + +// RemoveAllPendingNotifications removes all pending notifications +func (ns *Service) RemoveAllPendingNotifications() error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + C.removeAllPendingNotifications() + return nil +} + +// RemovePendingNotification removes a specific pending notification +func (ns *Service) RemovePendingNotification(identifier string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + defer C.free(unsafe.Pointer(cIdentifier)) + C.removePendingNotification(cIdentifier) + return nil +} + +// RemoveAllDeliveredNotifications removes all delivered notifications +func (ns *Service) RemoveAllDeliveredNotifications() error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + C.removeAllDeliveredNotifications() + return nil +} + +// RemoveDeliveredNotification removes a specific delivered notification +func (ns *Service) RemoveDeliveredNotification(identifier string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cIdentifier := C.CString(identifier) + defer C.free(unsafe.Pointer(cIdentifier)) + C.removeDeliveredNotification(cIdentifier) + return nil +} diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index f4e9b1404..f3eaec1a1 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -34,6 +34,10 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response if (response.notification.request.content.categoryIdentifier) { [payload setObject:response.notification.request.content.categoryIdentifier forKey:@"categoryIdentifier"]; } + + if (response.notification.request.content.subtitle) { + [payload setObject:response.notification.request.content.subtitle forKey:@"subtitle"]; + } if (response.notification.request.content.userInfo) { [payload setObject:response.notification.request.content.userInfo forKey:@"userInfo"]; diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go new file mode 100644 index 000000000..e942568d6 --- /dev/null +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -0,0 +1,150 @@ +//go:build windows + +package notifications + +import ( + "context" + + "git.sr.ht/~jackmordaunt/go-toast" + "github.com/wailsapp/wails/v3/pkg/application" +) + +var NotificationCategories map[string]NotificationCategory = make(map[string]NotificationCategory) + +func New() *Service { + return &Service{} +} + +// ServiceName returns the name of the service +func (ns *Service) ServiceName() string { + return "github.com/wailsapp/wails/v3/services/notifications" +} + +// ServiceStartup is called when the service is loaded +func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + toast.SetActivationCallback(func(args string, data []toast.UserData) { + response := NotificationResponse{ + Name: "notification", + Data: NotificationResponseData{ + ActionIdentifier: args, + }, + } + + if userText, found := getUserText(data); found { + response.Data.UserText = userText + } + + application.Get().EmitEvent("notificationResponse", response) + }) + return nil +} + +// ServiceShutdown is called when the service is unloaded +func (ns *Service) ServiceShutdown() error { + return nil +} + +// On Windows this does not apply, return true +func CheckBundleIdentifier() bool { + return true +} + +// On Windows this does not apply, return true +func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { + return true, nil +} + +// On Windows this does not apply, return true +func (ns *Service) CheckNotificationAuthorization() bool { + return true +} + +func (ns *Service) SendNotification(identifier, title, _, body string) error { + n := toast.Notification{ + AppID: identifier, + Title: title, + Body: body, + } + + err := n.Push() + if err != nil { + return err + } + return nil +} + +func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + nCategory := NotificationCategories[options.CategoryID] + + n := toast.Notification{ + AppID: options.ID, + Title: options.Title, + Body: options.Body, + } + + for _, action := range nCategory.Actions { + n.Actions = append(n.Actions, toast.Action{ + Content: action.Title, + Arguments: action.ID, + }) + } + + if nCategory.HasReplyField { + n.Inputs = append(n.Inputs, toast.Input{ + ID: "userText", + Title: nCategory.ReplyButtonTitle, + Placeholder: nCategory.ReplyPlaceholder, + }) + + n.Actions = append(n.Actions, toast.Action{ + Content: nCategory.ReplyButtonTitle, + }) + } + + err := n.Push() + if err != nil { + return err + } + return nil +} + +func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { + NotificationCategories[category.ID] = NotificationCategory{ + ID: category.ID, + Actions: category.Actions, + HasReplyField: bool(category.HasReplyField), + ReplyPlaceholder: category.ReplyPlaceholder, + ReplyButtonTitle: category.ReplyButtonTitle, + } + + return nil +} + +// RemoveAllPendingNotifications removes all pending notifications +func (ns *Service) RemoveAllPendingNotifications() error { + return nil +} + +// RemovePendingNotification removes a specific pending notification +func (ns *Service) RemovePendingNotification(_ string) error { + return nil +} + +// RemoveAllDeliveredNotifications removes all delivered notifications +func (ns *Service) RemoveAllDeliveredNotifications() error { + return nil +} + +// RemoveDeliveredNotification removes a specific delivered notification +func (ns *Service) RemoveDeliveredNotification(_ string) error { + return nil +} + +func getUserText(data []toast.UserData) (string, bool) { + for _, d := range data { + if d.Key == "userText" { + return d.Value, true + } + } + return "", false +} From c7d54e2fa9e3f7a4243ed0b36ad64334e80a9533 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Feb 2025 18:58:16 -0800 Subject: [PATCH 008/136] remove app event --- .../desktop/@wailsio/runtime/package.json | 2 +- .../@wailsio/runtime/src/event_types.js | 1 - .../@wailsio/runtime/types/event_types.d.ts | 1 - v3/pkg/events/events.go | 619 +++++++++--------- v3/pkg/events/events.txt | 1 - v3/pkg/events/events_darwin.h | 223 ++++--- .../notifications/notifications_darwin.go | 15 + .../notifications/notifications_darwin.m | 12 +- 8 files changed, 441 insertions(+), 433 deletions(-) diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/package.json b/v3/internal/runtime/desktop/@wailsio/runtime/package.json index 7412db923..ae1fd6853 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/package.json +++ b/v3/internal/runtime/desktop/@wailsio/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@wailsio/runtime", "type": "module", - "version": "3.0.0-alpha.57", + "version": "3.0.0-alpha.58", "description": "Wails Runtime", "types": "types/index.d.ts", "exports": { diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js b/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js index f56a77cb6..9c7feed7c 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js @@ -69,7 +69,6 @@ export const EventTypes = { ApplicationWillTerminate: "mac:ApplicationWillTerminate", ApplicationWillUnhide: "mac:ApplicationWillUnhide", ApplicationWillUpdate: "mac:ApplicationWillUpdate", - DidReceiveNotificationResponse: "mac:DidReceiveNotificationResponse", MenuDidAddItem: "mac:MenuDidAddItem", MenuDidBeginTracking: "mac:MenuDidBeginTracking", MenuDidClose: "mac:MenuDidClose", diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts b/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts index 5c2d40009..e8742de59 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts +++ b/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts @@ -69,7 +69,6 @@ export declare const EventTypes: { ApplicationWillTerminate: string, ApplicationWillUnhide: string, ApplicationWillUpdate: string, - DidReceiveNotificationResponse: string, MenuDidAddItem: string, MenuDidBeginTracking: string, MenuDidClose: string, diff --git a/v3/pkg/events/events.go b/v3/pkg/events/events.go index 84f214cac..0bb4c850c 100644 --- a/v3/pkg/events/events.go +++ b/v3/pkg/events/events.go @@ -112,7 +112,6 @@ type macEvents struct { ApplicationWillTerminate ApplicationEventType ApplicationWillUnhide ApplicationEventType ApplicationWillUpdate ApplicationEventType - DidReceiveNotificationResponse ApplicationEventType MenuDidAddItem ApplicationEventType MenuDidBeginTracking ApplicationEventType MenuDidClose ApplicationEventType @@ -249,117 +248,116 @@ func newMacEvents() macEvents { ApplicationWillTerminate: 1075, ApplicationWillUnhide: 1076, ApplicationWillUpdate: 1077, - DidReceiveNotificationResponse: 1078, - MenuDidAddItem: 1079, - MenuDidBeginTracking: 1080, - MenuDidClose: 1081, - MenuDidDisplayItem: 1082, - MenuDidEndTracking: 1083, - MenuDidHighlightItem: 1084, - MenuDidOpen: 1085, - MenuDidPopUp: 1086, - MenuDidRemoveItem: 1087, - MenuDidSendAction: 1088, - MenuDidSendActionToItem: 1089, - MenuDidUpdate: 1090, - MenuWillAddItem: 1091, - MenuWillBeginTracking: 1092, - MenuWillDisplayItem: 1093, - MenuWillEndTracking: 1094, - MenuWillHighlightItem: 1095, - MenuWillOpen: 1096, - MenuWillPopUp: 1097, - MenuWillRemoveItem: 1098, - MenuWillSendAction: 1099, - MenuWillSendActionToItem: 1100, - MenuWillUpdate: 1101, - WebViewDidCommitNavigation: 1102, - WebViewDidFinishNavigation: 1103, - WebViewDidReceiveServerRedirectForProvisionalNavigation: 1104, - WebViewDidStartProvisionalNavigation: 1105, - WindowDidBecomeKey: 1106, - WindowDidBecomeMain: 1107, - WindowDidBeginSheet: 1108, - WindowDidChangeAlpha: 1109, - WindowDidChangeBackingLocation: 1110, - WindowDidChangeBackingProperties: 1111, - WindowDidChangeCollectionBehavior: 1112, - WindowDidChangeEffectiveAppearance: 1113, - WindowDidChangeOcclusionState: 1114, - WindowDidChangeOrderingMode: 1115, - WindowDidChangeScreen: 1116, - WindowDidChangeScreenParameters: 1117, - WindowDidChangeScreenProfile: 1118, - WindowDidChangeScreenSpace: 1119, - WindowDidChangeScreenSpaceProperties: 1120, - WindowDidChangeSharingType: 1121, - WindowDidChangeSpace: 1122, - WindowDidChangeSpaceOrderingMode: 1123, - WindowDidChangeTitle: 1124, - WindowDidChangeToolbar: 1125, - WindowDidDeminiaturize: 1126, - WindowDidEndSheet: 1127, - WindowDidEnterFullScreen: 1128, - WindowDidEnterVersionBrowser: 1129, - WindowDidExitFullScreen: 1130, - WindowDidExitVersionBrowser: 1131, - WindowDidExpose: 1132, - WindowDidFocus: 1133, - WindowDidMiniaturize: 1134, - WindowDidMove: 1135, - WindowDidOrderOffScreen: 1136, - WindowDidOrderOnScreen: 1137, - WindowDidResignKey: 1138, - WindowDidResignMain: 1139, - WindowDidResize: 1140, - WindowDidUpdate: 1141, - WindowDidUpdateAlpha: 1142, - WindowDidUpdateCollectionBehavior: 1143, - WindowDidUpdateCollectionProperties: 1144, - WindowDidUpdateShadow: 1145, - WindowDidUpdateTitle: 1146, - WindowDidUpdateToolbar: 1147, - WindowDidZoom: 1148, - WindowFileDraggingEntered: 1149, - WindowFileDraggingExited: 1150, - WindowFileDraggingPerformed: 1151, - WindowHide: 1152, - WindowMaximise: 1153, - WindowUnMaximise: 1154, - WindowMinimise: 1155, - WindowUnMinimise: 1156, - WindowShouldClose: 1157, - WindowShow: 1158, - WindowWillBecomeKey: 1159, - WindowWillBecomeMain: 1160, - WindowWillBeginSheet: 1161, - WindowWillChangeOrderingMode: 1162, - WindowWillClose: 1163, - WindowWillDeminiaturize: 1164, - WindowWillEnterFullScreen: 1165, - WindowWillEnterVersionBrowser: 1166, - WindowWillExitFullScreen: 1167, - WindowWillExitVersionBrowser: 1168, - WindowWillFocus: 1169, - WindowWillMiniaturize: 1170, - WindowWillMove: 1171, - WindowWillOrderOffScreen: 1172, - WindowWillOrderOnScreen: 1173, - WindowWillResignMain: 1174, - WindowWillResize: 1175, - WindowWillUnfocus: 1176, - WindowWillUpdate: 1177, - WindowWillUpdateAlpha: 1178, - WindowWillUpdateCollectionBehavior: 1179, - WindowWillUpdateCollectionProperties: 1180, - WindowWillUpdateShadow: 1181, - WindowWillUpdateTitle: 1182, - WindowWillUpdateToolbar: 1183, - WindowWillUpdateVisibility: 1184, - WindowWillUseStandardFrame: 1185, - WindowZoomIn: 1186, - WindowZoomOut: 1187, - WindowZoomReset: 1188, + MenuDidAddItem: 1078, + MenuDidBeginTracking: 1079, + MenuDidClose: 1080, + MenuDidDisplayItem: 1081, + MenuDidEndTracking: 1082, + MenuDidHighlightItem: 1083, + MenuDidOpen: 1084, + MenuDidPopUp: 1085, + MenuDidRemoveItem: 1086, + MenuDidSendAction: 1087, + MenuDidSendActionToItem: 1088, + MenuDidUpdate: 1089, + MenuWillAddItem: 1090, + MenuWillBeginTracking: 1091, + MenuWillDisplayItem: 1092, + MenuWillEndTracking: 1093, + MenuWillHighlightItem: 1094, + MenuWillOpen: 1095, + MenuWillPopUp: 1096, + MenuWillRemoveItem: 1097, + MenuWillSendAction: 1098, + MenuWillSendActionToItem: 1099, + MenuWillUpdate: 1100, + WebViewDidCommitNavigation: 1101, + WebViewDidFinishNavigation: 1102, + WebViewDidReceiveServerRedirectForProvisionalNavigation: 1103, + WebViewDidStartProvisionalNavigation: 1104, + WindowDidBecomeKey: 1105, + WindowDidBecomeMain: 1106, + WindowDidBeginSheet: 1107, + WindowDidChangeAlpha: 1108, + WindowDidChangeBackingLocation: 1109, + WindowDidChangeBackingProperties: 1110, + WindowDidChangeCollectionBehavior: 1111, + WindowDidChangeEffectiveAppearance: 1112, + WindowDidChangeOcclusionState: 1113, + WindowDidChangeOrderingMode: 1114, + WindowDidChangeScreen: 1115, + WindowDidChangeScreenParameters: 1116, + WindowDidChangeScreenProfile: 1117, + WindowDidChangeScreenSpace: 1118, + WindowDidChangeScreenSpaceProperties: 1119, + WindowDidChangeSharingType: 1120, + WindowDidChangeSpace: 1121, + WindowDidChangeSpaceOrderingMode: 1122, + WindowDidChangeTitle: 1123, + WindowDidChangeToolbar: 1124, + WindowDidDeminiaturize: 1125, + WindowDidEndSheet: 1126, + WindowDidEnterFullScreen: 1127, + WindowDidEnterVersionBrowser: 1128, + WindowDidExitFullScreen: 1129, + WindowDidExitVersionBrowser: 1130, + WindowDidExpose: 1131, + WindowDidFocus: 1132, + WindowDidMiniaturize: 1133, + WindowDidMove: 1134, + WindowDidOrderOffScreen: 1135, + WindowDidOrderOnScreen: 1136, + WindowDidResignKey: 1137, + WindowDidResignMain: 1138, + WindowDidResize: 1139, + WindowDidUpdate: 1140, + WindowDidUpdateAlpha: 1141, + WindowDidUpdateCollectionBehavior: 1142, + WindowDidUpdateCollectionProperties: 1143, + WindowDidUpdateShadow: 1144, + WindowDidUpdateTitle: 1145, + WindowDidUpdateToolbar: 1146, + WindowDidZoom: 1147, + WindowFileDraggingEntered: 1148, + WindowFileDraggingExited: 1149, + WindowFileDraggingPerformed: 1150, + WindowHide: 1151, + WindowMaximise: 1152, + WindowUnMaximise: 1153, + WindowMinimise: 1154, + WindowUnMinimise: 1155, + WindowShouldClose: 1156, + WindowShow: 1157, + WindowWillBecomeKey: 1158, + WindowWillBecomeMain: 1159, + WindowWillBeginSheet: 1160, + WindowWillChangeOrderingMode: 1161, + WindowWillClose: 1162, + WindowWillDeminiaturize: 1163, + WindowWillEnterFullScreen: 1164, + WindowWillEnterVersionBrowser: 1165, + WindowWillExitFullScreen: 1166, + WindowWillExitVersionBrowser: 1167, + WindowWillFocus: 1168, + WindowWillMiniaturize: 1169, + WindowWillMove: 1170, + WindowWillOrderOffScreen: 1171, + WindowWillOrderOnScreen: 1172, + WindowWillResignMain: 1173, + WindowWillResize: 1174, + WindowWillUnfocus: 1175, + WindowWillUpdate: 1176, + WindowWillUpdateAlpha: 1177, + WindowWillUpdateCollectionBehavior: 1178, + WindowWillUpdateCollectionProperties: 1179, + WindowWillUpdateShadow: 1180, + WindowWillUpdateTitle: 1181, + WindowWillUpdateToolbar: 1182, + WindowWillUpdateVisibility: 1183, + WindowWillUseStandardFrame: 1184, + WindowZoomIn: 1185, + WindowZoomOut: 1186, + WindowZoomReset: 1187, } } @@ -414,50 +412,50 @@ type windowsEvents struct { func newWindowsEvents() windowsEvents { return windowsEvents{ - APMPowerSettingChange: 1189, - APMPowerStatusChange: 1190, - APMResumeAutomatic: 1191, - APMResumeSuspend: 1192, - APMSuspend: 1193, - ApplicationStarted: 1194, - SystemThemeChanged: 1195, - WebViewNavigationCompleted: 1196, - WindowActive: 1197, - WindowBackgroundErase: 1198, - WindowClickActive: 1199, - WindowClosing: 1200, - WindowDidMove: 1201, - WindowDidResize: 1202, - WindowDPIChanged: 1203, - WindowDragDrop: 1204, - WindowDragEnter: 1205, - WindowDragLeave: 1206, - WindowDragOver: 1207, - WindowEndMove: 1208, - WindowEndResize: 1209, - WindowFullscreen: 1210, - WindowHide: 1211, - WindowInactive: 1212, - WindowKeyDown: 1213, - WindowKeyUp: 1214, - WindowKillFocus: 1215, - WindowNonClientHit: 1216, - WindowNonClientMouseDown: 1217, - WindowNonClientMouseLeave: 1218, - WindowNonClientMouseMove: 1219, - WindowNonClientMouseUp: 1220, - WindowPaint: 1221, - WindowRestore: 1222, - WindowSetFocus: 1223, - WindowShow: 1224, - WindowStartMove: 1225, - WindowStartResize: 1226, - WindowUnFullscreen: 1227, - WindowZOrderChanged: 1228, - WindowMinimise: 1229, - WindowUnMinimise: 1230, - WindowMaximise: 1231, - WindowUnMaximise: 1232, + APMPowerSettingChange: 1188, + APMPowerStatusChange: 1189, + APMResumeAutomatic: 1190, + APMResumeSuspend: 1191, + APMSuspend: 1192, + ApplicationStarted: 1193, + SystemThemeChanged: 1194, + WebViewNavigationCompleted: 1195, + WindowActive: 1196, + WindowBackgroundErase: 1197, + WindowClickActive: 1198, + WindowClosing: 1199, + WindowDidMove: 1200, + WindowDidResize: 1201, + WindowDPIChanged: 1202, + WindowDragDrop: 1203, + WindowDragEnter: 1204, + WindowDragLeave: 1205, + WindowDragOver: 1206, + WindowEndMove: 1207, + WindowEndResize: 1208, + WindowFullscreen: 1209, + WindowHide: 1210, + WindowInactive: 1211, + WindowKeyDown: 1212, + WindowKeyUp: 1213, + WindowKillFocus: 1214, + WindowNonClientHit: 1215, + WindowNonClientMouseDown: 1216, + WindowNonClientMouseLeave: 1217, + WindowNonClientMouseMove: 1218, + WindowNonClientMouseUp: 1219, + WindowPaint: 1220, + WindowRestore: 1221, + WindowSetFocus: 1222, + WindowShow: 1223, + WindowStartMove: 1224, + WindowStartResize: 1225, + WindowUnFullscreen: 1226, + WindowZOrderChanged: 1227, + WindowMinimise: 1228, + WindowUnMinimise: 1229, + WindowMaximise: 1230, + WindowUnMaximise: 1231, } } @@ -520,160 +518,159 @@ var eventToJS = map[uint]string{ 1075: "mac:ApplicationWillTerminate", 1076: "mac:ApplicationWillUnhide", 1077: "mac:ApplicationWillUpdate", - 1078: "mac:DidReceiveNotificationResponse", - 1079: "mac:MenuDidAddItem", - 1080: "mac:MenuDidBeginTracking", - 1081: "mac:MenuDidClose", - 1082: "mac:MenuDidDisplayItem", - 1083: "mac:MenuDidEndTracking", - 1084: "mac:MenuDidHighlightItem", - 1085: "mac:MenuDidOpen", - 1086: "mac:MenuDidPopUp", - 1087: "mac:MenuDidRemoveItem", - 1088: "mac:MenuDidSendAction", - 1089: "mac:MenuDidSendActionToItem", - 1090: "mac:MenuDidUpdate", - 1091: "mac:MenuWillAddItem", - 1092: "mac:MenuWillBeginTracking", - 1093: "mac:MenuWillDisplayItem", - 1094: "mac:MenuWillEndTracking", - 1095: "mac:MenuWillHighlightItem", - 1096: "mac:MenuWillOpen", - 1097: "mac:MenuWillPopUp", - 1098: "mac:MenuWillRemoveItem", - 1099: "mac:MenuWillSendAction", - 1100: "mac:MenuWillSendActionToItem", - 1101: "mac:MenuWillUpdate", - 1102: "mac:WebViewDidCommitNavigation", - 1103: "mac:WebViewDidFinishNavigation", - 1104: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation", - 1105: "mac:WebViewDidStartProvisionalNavigation", - 1106: "mac:WindowDidBecomeKey", - 1107: "mac:WindowDidBecomeMain", - 1108: "mac:WindowDidBeginSheet", - 1109: "mac:WindowDidChangeAlpha", - 1110: "mac:WindowDidChangeBackingLocation", - 1111: "mac:WindowDidChangeBackingProperties", - 1112: "mac:WindowDidChangeCollectionBehavior", - 1113: "mac:WindowDidChangeEffectiveAppearance", - 1114: "mac:WindowDidChangeOcclusionState", - 1115: "mac:WindowDidChangeOrderingMode", - 1116: "mac:WindowDidChangeScreen", - 1117: "mac:WindowDidChangeScreenParameters", - 1118: "mac:WindowDidChangeScreenProfile", - 1119: "mac:WindowDidChangeScreenSpace", - 1120: "mac:WindowDidChangeScreenSpaceProperties", - 1121: "mac:WindowDidChangeSharingType", - 1122: "mac:WindowDidChangeSpace", - 1123: "mac:WindowDidChangeSpaceOrderingMode", - 1124: "mac:WindowDidChangeTitle", - 1125: "mac:WindowDidChangeToolbar", - 1126: "mac:WindowDidDeminiaturize", - 1127: "mac:WindowDidEndSheet", - 1128: "mac:WindowDidEnterFullScreen", - 1129: "mac:WindowDidEnterVersionBrowser", - 1130: "mac:WindowDidExitFullScreen", - 1131: "mac:WindowDidExitVersionBrowser", - 1132: "mac:WindowDidExpose", - 1133: "mac:WindowDidFocus", - 1134: "mac:WindowDidMiniaturize", - 1135: "mac:WindowDidMove", - 1136: "mac:WindowDidOrderOffScreen", - 1137: "mac:WindowDidOrderOnScreen", - 1138: "mac:WindowDidResignKey", - 1139: "mac:WindowDidResignMain", - 1140: "mac:WindowDidResize", - 1141: "mac:WindowDidUpdate", - 1142: "mac:WindowDidUpdateAlpha", - 1143: "mac:WindowDidUpdateCollectionBehavior", - 1144: "mac:WindowDidUpdateCollectionProperties", - 1145: "mac:WindowDidUpdateShadow", - 1146: "mac:WindowDidUpdateTitle", - 1147: "mac:WindowDidUpdateToolbar", - 1148: "mac:WindowDidZoom", - 1149: "mac:WindowFileDraggingEntered", - 1150: "mac:WindowFileDraggingExited", - 1151: "mac:WindowFileDraggingPerformed", - 1152: "mac:WindowHide", - 1153: "mac:WindowMaximise", - 1154: "mac:WindowUnMaximise", - 1155: "mac:WindowMinimise", - 1156: "mac:WindowUnMinimise", - 1157: "mac:WindowShouldClose", - 1158: "mac:WindowShow", - 1159: "mac:WindowWillBecomeKey", - 1160: "mac:WindowWillBecomeMain", - 1161: "mac:WindowWillBeginSheet", - 1162: "mac:WindowWillChangeOrderingMode", - 1163: "mac:WindowWillClose", - 1164: "mac:WindowWillDeminiaturize", - 1165: "mac:WindowWillEnterFullScreen", - 1166: "mac:WindowWillEnterVersionBrowser", - 1167: "mac:WindowWillExitFullScreen", - 1168: "mac:WindowWillExitVersionBrowser", - 1169: "mac:WindowWillFocus", - 1170: "mac:WindowWillMiniaturize", - 1171: "mac:WindowWillMove", - 1172: "mac:WindowWillOrderOffScreen", - 1173: "mac:WindowWillOrderOnScreen", - 1174: "mac:WindowWillResignMain", - 1175: "mac:WindowWillResize", - 1176: "mac:WindowWillUnfocus", - 1177: "mac:WindowWillUpdate", - 1178: "mac:WindowWillUpdateAlpha", - 1179: "mac:WindowWillUpdateCollectionBehavior", - 1180: "mac:WindowWillUpdateCollectionProperties", - 1181: "mac:WindowWillUpdateShadow", - 1182: "mac:WindowWillUpdateTitle", - 1183: "mac:WindowWillUpdateToolbar", - 1184: "mac:WindowWillUpdateVisibility", - 1185: "mac:WindowWillUseStandardFrame", - 1186: "mac:WindowZoomIn", - 1187: "mac:WindowZoomOut", - 1188: "mac:WindowZoomReset", - 1189: "windows:APMPowerSettingChange", - 1190: "windows:APMPowerStatusChange", - 1191: "windows:APMResumeAutomatic", - 1192: "windows:APMResumeSuspend", - 1193: "windows:APMSuspend", - 1194: "windows:ApplicationStarted", - 1195: "windows:SystemThemeChanged", - 1196: "windows:WebViewNavigationCompleted", - 1197: "windows:WindowActive", - 1198: "windows:WindowBackgroundErase", - 1199: "windows:WindowClickActive", - 1200: "windows:WindowClosing", - 1201: "windows:WindowDidMove", - 1202: "windows:WindowDidResize", - 1203: "windows:WindowDPIChanged", - 1204: "windows:WindowDragDrop", - 1205: "windows:WindowDragEnter", - 1206: "windows:WindowDragLeave", - 1207: "windows:WindowDragOver", - 1208: "windows:WindowEndMove", - 1209: "windows:WindowEndResize", - 1210: "windows:WindowFullscreen", - 1211: "windows:WindowHide", - 1212: "windows:WindowInactive", - 1213: "windows:WindowKeyDown", - 1214: "windows:WindowKeyUp", - 1215: "windows:WindowKillFocus", - 1216: "windows:WindowNonClientHit", - 1217: "windows:WindowNonClientMouseDown", - 1218: "windows:WindowNonClientMouseLeave", - 1219: "windows:WindowNonClientMouseMove", - 1220: "windows:WindowNonClientMouseUp", - 1221: "windows:WindowPaint", - 1222: "windows:WindowRestore", - 1223: "windows:WindowSetFocus", - 1224: "windows:WindowShow", - 1225: "windows:WindowStartMove", - 1226: "windows:WindowStartResize", - 1227: "windows:WindowUnFullscreen", - 1228: "windows:WindowZOrderChanged", - 1229: "windows:WindowMinimise", - 1230: "windows:WindowUnMinimise", - 1231: "windows:WindowMaximise", - 1232: "windows:WindowUnMaximise", + 1078: "mac:MenuDidAddItem", + 1079: "mac:MenuDidBeginTracking", + 1080: "mac:MenuDidClose", + 1081: "mac:MenuDidDisplayItem", + 1082: "mac:MenuDidEndTracking", + 1083: "mac:MenuDidHighlightItem", + 1084: "mac:MenuDidOpen", + 1085: "mac:MenuDidPopUp", + 1086: "mac:MenuDidRemoveItem", + 1087: "mac:MenuDidSendAction", + 1088: "mac:MenuDidSendActionToItem", + 1089: "mac:MenuDidUpdate", + 1090: "mac:MenuWillAddItem", + 1091: "mac:MenuWillBeginTracking", + 1092: "mac:MenuWillDisplayItem", + 1093: "mac:MenuWillEndTracking", + 1094: "mac:MenuWillHighlightItem", + 1095: "mac:MenuWillOpen", + 1096: "mac:MenuWillPopUp", + 1097: "mac:MenuWillRemoveItem", + 1098: "mac:MenuWillSendAction", + 1099: "mac:MenuWillSendActionToItem", + 1100: "mac:MenuWillUpdate", + 1101: "mac:WebViewDidCommitNavigation", + 1102: "mac:WebViewDidFinishNavigation", + 1103: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation", + 1104: "mac:WebViewDidStartProvisionalNavigation", + 1105: "mac:WindowDidBecomeKey", + 1106: "mac:WindowDidBecomeMain", + 1107: "mac:WindowDidBeginSheet", + 1108: "mac:WindowDidChangeAlpha", + 1109: "mac:WindowDidChangeBackingLocation", + 1110: "mac:WindowDidChangeBackingProperties", + 1111: "mac:WindowDidChangeCollectionBehavior", + 1112: "mac:WindowDidChangeEffectiveAppearance", + 1113: "mac:WindowDidChangeOcclusionState", + 1114: "mac:WindowDidChangeOrderingMode", + 1115: "mac:WindowDidChangeScreen", + 1116: "mac:WindowDidChangeScreenParameters", + 1117: "mac:WindowDidChangeScreenProfile", + 1118: "mac:WindowDidChangeScreenSpace", + 1119: "mac:WindowDidChangeScreenSpaceProperties", + 1120: "mac:WindowDidChangeSharingType", + 1121: "mac:WindowDidChangeSpace", + 1122: "mac:WindowDidChangeSpaceOrderingMode", + 1123: "mac:WindowDidChangeTitle", + 1124: "mac:WindowDidChangeToolbar", + 1125: "mac:WindowDidDeminiaturize", + 1126: "mac:WindowDidEndSheet", + 1127: "mac:WindowDidEnterFullScreen", + 1128: "mac:WindowDidEnterVersionBrowser", + 1129: "mac:WindowDidExitFullScreen", + 1130: "mac:WindowDidExitVersionBrowser", + 1131: "mac:WindowDidExpose", + 1132: "mac:WindowDidFocus", + 1133: "mac:WindowDidMiniaturize", + 1134: "mac:WindowDidMove", + 1135: "mac:WindowDidOrderOffScreen", + 1136: "mac:WindowDidOrderOnScreen", + 1137: "mac:WindowDidResignKey", + 1138: "mac:WindowDidResignMain", + 1139: "mac:WindowDidResize", + 1140: "mac:WindowDidUpdate", + 1141: "mac:WindowDidUpdateAlpha", + 1142: "mac:WindowDidUpdateCollectionBehavior", + 1143: "mac:WindowDidUpdateCollectionProperties", + 1144: "mac:WindowDidUpdateShadow", + 1145: "mac:WindowDidUpdateTitle", + 1146: "mac:WindowDidUpdateToolbar", + 1147: "mac:WindowDidZoom", + 1148: "mac:WindowFileDraggingEntered", + 1149: "mac:WindowFileDraggingExited", + 1150: "mac:WindowFileDraggingPerformed", + 1151: "mac:WindowHide", + 1152: "mac:WindowMaximise", + 1153: "mac:WindowUnMaximise", + 1154: "mac:WindowMinimise", + 1155: "mac:WindowUnMinimise", + 1156: "mac:WindowShouldClose", + 1157: "mac:WindowShow", + 1158: "mac:WindowWillBecomeKey", + 1159: "mac:WindowWillBecomeMain", + 1160: "mac:WindowWillBeginSheet", + 1161: "mac:WindowWillChangeOrderingMode", + 1162: "mac:WindowWillClose", + 1163: "mac:WindowWillDeminiaturize", + 1164: "mac:WindowWillEnterFullScreen", + 1165: "mac:WindowWillEnterVersionBrowser", + 1166: "mac:WindowWillExitFullScreen", + 1167: "mac:WindowWillExitVersionBrowser", + 1168: "mac:WindowWillFocus", + 1169: "mac:WindowWillMiniaturize", + 1170: "mac:WindowWillMove", + 1171: "mac:WindowWillOrderOffScreen", + 1172: "mac:WindowWillOrderOnScreen", + 1173: "mac:WindowWillResignMain", + 1174: "mac:WindowWillResize", + 1175: "mac:WindowWillUnfocus", + 1176: "mac:WindowWillUpdate", + 1177: "mac:WindowWillUpdateAlpha", + 1178: "mac:WindowWillUpdateCollectionBehavior", + 1179: "mac:WindowWillUpdateCollectionProperties", + 1180: "mac:WindowWillUpdateShadow", + 1181: "mac:WindowWillUpdateTitle", + 1182: "mac:WindowWillUpdateToolbar", + 1183: "mac:WindowWillUpdateVisibility", + 1184: "mac:WindowWillUseStandardFrame", + 1185: "mac:WindowZoomIn", + 1186: "mac:WindowZoomOut", + 1187: "mac:WindowZoomReset", + 1188: "windows:APMPowerSettingChange", + 1189: "windows:APMPowerStatusChange", + 1190: "windows:APMResumeAutomatic", + 1191: "windows:APMResumeSuspend", + 1192: "windows:APMSuspend", + 1193: "windows:ApplicationStarted", + 1194: "windows:SystemThemeChanged", + 1195: "windows:WebViewNavigationCompleted", + 1196: "windows:WindowActive", + 1197: "windows:WindowBackgroundErase", + 1198: "windows:WindowClickActive", + 1199: "windows:WindowClosing", + 1200: "windows:WindowDidMove", + 1201: "windows:WindowDidResize", + 1202: "windows:WindowDPIChanged", + 1203: "windows:WindowDragDrop", + 1204: "windows:WindowDragEnter", + 1205: "windows:WindowDragLeave", + 1206: "windows:WindowDragOver", + 1207: "windows:WindowEndMove", + 1208: "windows:WindowEndResize", + 1209: "windows:WindowFullscreen", + 1210: "windows:WindowHide", + 1211: "windows:WindowInactive", + 1212: "windows:WindowKeyDown", + 1213: "windows:WindowKeyUp", + 1214: "windows:WindowKillFocus", + 1215: "windows:WindowNonClientHit", + 1216: "windows:WindowNonClientMouseDown", + 1217: "windows:WindowNonClientMouseLeave", + 1218: "windows:WindowNonClientMouseMove", + 1219: "windows:WindowNonClientMouseUp", + 1220: "windows:WindowPaint", + 1221: "windows:WindowRestore", + 1222: "windows:WindowSetFocus", + 1223: "windows:WindowShow", + 1224: "windows:WindowStartMove", + 1225: "windows:WindowStartResize", + 1226: "windows:WindowUnFullscreen", + 1227: "windows:WindowZOrderChanged", + 1228: "windows:WindowMinimise", + 1229: "windows:WindowUnMinimise", + 1230: "windows:WindowMaximise", + 1231: "windows:WindowUnMaximise", } diff --git a/v3/pkg/events/events.txt b/v3/pkg/events/events.txt index fa83f4655..1d43adf5e 100644 --- a/v3/pkg/events/events.txt +++ b/v3/pkg/events/events.txt @@ -52,7 +52,6 @@ mac:ApplicationWillResignActive mac:ApplicationWillTerminate mac:ApplicationWillUnhide mac:ApplicationWillUpdate -mac:DidReceiveNotificationResponse mac:MenuDidAddItem mac:MenuDidBeginTracking mac:MenuDidClose diff --git a/v3/pkg/events/events_darwin.h b/v3/pkg/events/events_darwin.h index 5e6c1a39e..bacaab781 100644 --- a/v3/pkg/events/events_darwin.h +++ b/v3/pkg/events/events_darwin.h @@ -28,119 +28,118 @@ extern void processWindowEvent(unsigned int, unsigned int); #define EventApplicationWillTerminate 1075 #define EventApplicationWillUnhide 1076 #define EventApplicationWillUpdate 1077 -#define EventDidReceiveNotificationResponse 1078 -#define EventMenuDidAddItem 1079 -#define EventMenuDidBeginTracking 1080 -#define EventMenuDidClose 1081 -#define EventMenuDidDisplayItem 1082 -#define EventMenuDidEndTracking 1083 -#define EventMenuDidHighlightItem 1084 -#define EventMenuDidOpen 1085 -#define EventMenuDidPopUp 1086 -#define EventMenuDidRemoveItem 1087 -#define EventMenuDidSendAction 1088 -#define EventMenuDidSendActionToItem 1089 -#define EventMenuDidUpdate 1090 -#define EventMenuWillAddItem 1091 -#define EventMenuWillBeginTracking 1092 -#define EventMenuWillDisplayItem 1093 -#define EventMenuWillEndTracking 1094 -#define EventMenuWillHighlightItem 1095 -#define EventMenuWillOpen 1096 -#define EventMenuWillPopUp 1097 -#define EventMenuWillRemoveItem 1098 -#define EventMenuWillSendAction 1099 -#define EventMenuWillSendActionToItem 1100 -#define EventMenuWillUpdate 1101 -#define EventWebViewDidCommitNavigation 1102 -#define EventWebViewDidFinishNavigation 1103 -#define EventWebViewDidReceiveServerRedirectForProvisionalNavigation 1104 -#define EventWebViewDidStartProvisionalNavigation 1105 -#define EventWindowDidBecomeKey 1106 -#define EventWindowDidBecomeMain 1107 -#define EventWindowDidBeginSheet 1108 -#define EventWindowDidChangeAlpha 1109 -#define EventWindowDidChangeBackingLocation 1110 -#define EventWindowDidChangeBackingProperties 1111 -#define EventWindowDidChangeCollectionBehavior 1112 -#define EventWindowDidChangeEffectiveAppearance 1113 -#define EventWindowDidChangeOcclusionState 1114 -#define EventWindowDidChangeOrderingMode 1115 -#define EventWindowDidChangeScreen 1116 -#define EventWindowDidChangeScreenParameters 1117 -#define EventWindowDidChangeScreenProfile 1118 -#define EventWindowDidChangeScreenSpace 1119 -#define EventWindowDidChangeScreenSpaceProperties 1120 -#define EventWindowDidChangeSharingType 1121 -#define EventWindowDidChangeSpace 1122 -#define EventWindowDidChangeSpaceOrderingMode 1123 -#define EventWindowDidChangeTitle 1124 -#define EventWindowDidChangeToolbar 1125 -#define EventWindowDidDeminiaturize 1126 -#define EventWindowDidEndSheet 1127 -#define EventWindowDidEnterFullScreen 1128 -#define EventWindowDidEnterVersionBrowser 1129 -#define EventWindowDidExitFullScreen 1130 -#define EventWindowDidExitVersionBrowser 1131 -#define EventWindowDidExpose 1132 -#define EventWindowDidFocus 1133 -#define EventWindowDidMiniaturize 1134 -#define EventWindowDidMove 1135 -#define EventWindowDidOrderOffScreen 1136 -#define EventWindowDidOrderOnScreen 1137 -#define EventWindowDidResignKey 1138 -#define EventWindowDidResignMain 1139 -#define EventWindowDidResize 1140 -#define EventWindowDidUpdate 1141 -#define EventWindowDidUpdateAlpha 1142 -#define EventWindowDidUpdateCollectionBehavior 1143 -#define EventWindowDidUpdateCollectionProperties 1144 -#define EventWindowDidUpdateShadow 1145 -#define EventWindowDidUpdateTitle 1146 -#define EventWindowDidUpdateToolbar 1147 -#define EventWindowDidZoom 1148 -#define EventWindowFileDraggingEntered 1149 -#define EventWindowFileDraggingExited 1150 -#define EventWindowFileDraggingPerformed 1151 -#define EventWindowHide 1152 -#define EventWindowMaximise 1153 -#define EventWindowUnMaximise 1154 -#define EventWindowMinimise 1155 -#define EventWindowUnMinimise 1156 -#define EventWindowShouldClose 1157 -#define EventWindowShow 1158 -#define EventWindowWillBecomeKey 1159 -#define EventWindowWillBecomeMain 1160 -#define EventWindowWillBeginSheet 1161 -#define EventWindowWillChangeOrderingMode 1162 -#define EventWindowWillClose 1163 -#define EventWindowWillDeminiaturize 1164 -#define EventWindowWillEnterFullScreen 1165 -#define EventWindowWillEnterVersionBrowser 1166 -#define EventWindowWillExitFullScreen 1167 -#define EventWindowWillExitVersionBrowser 1168 -#define EventWindowWillFocus 1169 -#define EventWindowWillMiniaturize 1170 -#define EventWindowWillMove 1171 -#define EventWindowWillOrderOffScreen 1172 -#define EventWindowWillOrderOnScreen 1173 -#define EventWindowWillResignMain 1174 -#define EventWindowWillResize 1175 -#define EventWindowWillUnfocus 1176 -#define EventWindowWillUpdate 1177 -#define EventWindowWillUpdateAlpha 1178 -#define EventWindowWillUpdateCollectionBehavior 1179 -#define EventWindowWillUpdateCollectionProperties 1180 -#define EventWindowWillUpdateShadow 1181 -#define EventWindowWillUpdateTitle 1182 -#define EventWindowWillUpdateToolbar 1183 -#define EventWindowWillUpdateVisibility 1184 -#define EventWindowWillUseStandardFrame 1185 -#define EventWindowZoomIn 1186 -#define EventWindowZoomOut 1187 -#define EventWindowZoomReset 1188 +#define EventMenuDidAddItem 1078 +#define EventMenuDidBeginTracking 1079 +#define EventMenuDidClose 1080 +#define EventMenuDidDisplayItem 1081 +#define EventMenuDidEndTracking 1082 +#define EventMenuDidHighlightItem 1083 +#define EventMenuDidOpen 1084 +#define EventMenuDidPopUp 1085 +#define EventMenuDidRemoveItem 1086 +#define EventMenuDidSendAction 1087 +#define EventMenuDidSendActionToItem 1088 +#define EventMenuDidUpdate 1089 +#define EventMenuWillAddItem 1090 +#define EventMenuWillBeginTracking 1091 +#define EventMenuWillDisplayItem 1092 +#define EventMenuWillEndTracking 1093 +#define EventMenuWillHighlightItem 1094 +#define EventMenuWillOpen 1095 +#define EventMenuWillPopUp 1096 +#define EventMenuWillRemoveItem 1097 +#define EventMenuWillSendAction 1098 +#define EventMenuWillSendActionToItem 1099 +#define EventMenuWillUpdate 1100 +#define EventWebViewDidCommitNavigation 1101 +#define EventWebViewDidFinishNavigation 1102 +#define EventWebViewDidReceiveServerRedirectForProvisionalNavigation 1103 +#define EventWebViewDidStartProvisionalNavigation 1104 +#define EventWindowDidBecomeKey 1105 +#define EventWindowDidBecomeMain 1106 +#define EventWindowDidBeginSheet 1107 +#define EventWindowDidChangeAlpha 1108 +#define EventWindowDidChangeBackingLocation 1109 +#define EventWindowDidChangeBackingProperties 1110 +#define EventWindowDidChangeCollectionBehavior 1111 +#define EventWindowDidChangeEffectiveAppearance 1112 +#define EventWindowDidChangeOcclusionState 1113 +#define EventWindowDidChangeOrderingMode 1114 +#define EventWindowDidChangeScreen 1115 +#define EventWindowDidChangeScreenParameters 1116 +#define EventWindowDidChangeScreenProfile 1117 +#define EventWindowDidChangeScreenSpace 1118 +#define EventWindowDidChangeScreenSpaceProperties 1119 +#define EventWindowDidChangeSharingType 1120 +#define EventWindowDidChangeSpace 1121 +#define EventWindowDidChangeSpaceOrderingMode 1122 +#define EventWindowDidChangeTitle 1123 +#define EventWindowDidChangeToolbar 1124 +#define EventWindowDidDeminiaturize 1125 +#define EventWindowDidEndSheet 1126 +#define EventWindowDidEnterFullScreen 1127 +#define EventWindowDidEnterVersionBrowser 1128 +#define EventWindowDidExitFullScreen 1129 +#define EventWindowDidExitVersionBrowser 1130 +#define EventWindowDidExpose 1131 +#define EventWindowDidFocus 1132 +#define EventWindowDidMiniaturize 1133 +#define EventWindowDidMove 1134 +#define EventWindowDidOrderOffScreen 1135 +#define EventWindowDidOrderOnScreen 1136 +#define EventWindowDidResignKey 1137 +#define EventWindowDidResignMain 1138 +#define EventWindowDidResize 1139 +#define EventWindowDidUpdate 1140 +#define EventWindowDidUpdateAlpha 1141 +#define EventWindowDidUpdateCollectionBehavior 1142 +#define EventWindowDidUpdateCollectionProperties 1143 +#define EventWindowDidUpdateShadow 1144 +#define EventWindowDidUpdateTitle 1145 +#define EventWindowDidUpdateToolbar 1146 +#define EventWindowDidZoom 1147 +#define EventWindowFileDraggingEntered 1148 +#define EventWindowFileDraggingExited 1149 +#define EventWindowFileDraggingPerformed 1150 +#define EventWindowHide 1151 +#define EventWindowMaximise 1152 +#define EventWindowUnMaximise 1153 +#define EventWindowMinimise 1154 +#define EventWindowUnMinimise 1155 +#define EventWindowShouldClose 1156 +#define EventWindowShow 1157 +#define EventWindowWillBecomeKey 1158 +#define EventWindowWillBecomeMain 1159 +#define EventWindowWillBeginSheet 1160 +#define EventWindowWillChangeOrderingMode 1161 +#define EventWindowWillClose 1162 +#define EventWindowWillDeminiaturize 1163 +#define EventWindowWillEnterFullScreen 1164 +#define EventWindowWillEnterVersionBrowser 1165 +#define EventWindowWillExitFullScreen 1166 +#define EventWindowWillExitVersionBrowser 1167 +#define EventWindowWillFocus 1168 +#define EventWindowWillMiniaturize 1169 +#define EventWindowWillMove 1170 +#define EventWindowWillOrderOffScreen 1171 +#define EventWindowWillOrderOnScreen 1172 +#define EventWindowWillResignMain 1173 +#define EventWindowWillResize 1174 +#define EventWindowWillUnfocus 1175 +#define EventWindowWillUpdate 1176 +#define EventWindowWillUpdateAlpha 1177 +#define EventWindowWillUpdateCollectionBehavior 1178 +#define EventWindowWillUpdateCollectionProperties 1179 +#define EventWindowWillUpdateShadow 1180 +#define EventWindowWillUpdateTitle 1181 +#define EventWindowWillUpdateToolbar 1182 +#define EventWindowWillUpdateVisibility 1183 +#define EventWindowWillUseStandardFrame 1184 +#define EventWindowZoomIn 1185 +#define EventWindowZoomOut 1186 +#define EventWindowZoomReset 1187 -#define MAX_EVENTS 1189 +#define MAX_EVENTS 1188 #endif \ No newline at end of file diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 5fc72b235..d9d378bcf 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -174,3 +174,18 @@ func (ns *Service) RemoveDeliveredNotification(identifier string) error { C.removeDeliveredNotification(cIdentifier) return nil } + +//export didReceiveNotificationResponse +func didReceiveNotificationResponse(jsonPayload *C.char) { + payload := C.GoString(jsonPayload) + + var response NotificationResponseData + if err := json.Unmarshal([]byte(payload), &response); err != nil { + return + } + + application.Get().EmitEvent("notificationResponse", NotificationResponse{ + Name: "notification", + Data: response, + }) +} diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index f3eaec1a1..b4be6835a 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -1,10 +1,8 @@ #import "notifications_darwin.h" #import #import -#import "../../events/events_darwin.h" -extern bool hasListeners(unsigned int); -extern void processApplicationEvent(unsigned int, void* data); +extern void didReceiveNotificationResponse(const char *jsonPayload); @interface NotificationsDelegate : NSObject @end @@ -48,9 +46,11 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response [payload setObject:textResponse.userText forKey:@"userText"]; } - // Check if there are listeners for our notification response event - if (hasListeners(EventDidReceiveNotificationResponse)) { - processApplicationEvent(EventDidReceiveNotificationResponse, (__bridge void*)payload); + NSError *error = nil; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload options:0 error:&error]; + if (!error) { + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + didReceiveNotificationResponse([jsonString UTF8String]); } completionHandler(); From 7757eae7452f232bbc81a790743d242c2884c16c Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Feb 2025 19:05:00 -0800 Subject: [PATCH 009/136] standalone example --- .../frontend/Inter Font License.txt | 93 ++++++++++ .../v3/pkg/services/notifications/index.js | 0 .../v3/pkg/services/notifications/models.js | 0 .../v3/pkg/services/notifications/service.js | 2 + .../frontend/dist/Inter-Medium.ttf | Bin 0 -> 315132 bytes .../frontend/dist/assets/index-CS0sRFez.js | 6 + .../notifications/frontend/dist/index.html | 29 ++++ .../frontend/dist/javascript.svg | 1 + .../notifications/frontend/dist/style.css | 160 ++++++++++++++++++ .../notifications/frontend/dist/wails.png | Bin 0 -> 9057 bytes v3/examples/notifications/frontend/index.html | 29 ++++ v3/examples/notifications/frontend/main.js | 50 ++++++ .../notifications/frontend/package.json | 16 ++ .../frontend/public/Inter-Medium.ttf | Bin 0 -> 315132 bytes .../frontend/public/javascript.svg | 1 + .../notifications/frontend/public/style.css | 160 ++++++++++++++++++ .../notifications/frontend/public/wails.png | Bin 0 -> 9057 bytes v3/examples/notifications/main.go | 135 +++++++++++++++ v3/examples/services/assets/index.html | 7 - v3/examples/services/main.go | 2 - 20 files changed, 682 insertions(+), 9 deletions(-) create mode 100644 v3/examples/notifications/frontend/Inter Font License.txt rename v3/examples/{services/assets => notifications/frontend}/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js (100%) rename v3/examples/{services/assets => notifications/frontend}/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js (100%) rename v3/examples/{services/assets => notifications/frontend}/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js (95%) create mode 100644 v3/examples/notifications/frontend/dist/Inter-Medium.ttf create mode 100644 v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js create mode 100644 v3/examples/notifications/frontend/dist/index.html create mode 100644 v3/examples/notifications/frontend/dist/javascript.svg create mode 100644 v3/examples/notifications/frontend/dist/style.css create mode 100644 v3/examples/notifications/frontend/dist/wails.png create mode 100644 v3/examples/notifications/frontend/index.html create mode 100644 v3/examples/notifications/frontend/main.js create mode 100644 v3/examples/notifications/frontend/package.json create mode 100644 v3/examples/notifications/frontend/public/Inter-Medium.ttf create mode 100644 v3/examples/notifications/frontend/public/javascript.svg create mode 100644 v3/examples/notifications/frontend/public/style.css create mode 100644 v3/examples/notifications/frontend/public/wails.png create mode 100644 v3/examples/notifications/main.go diff --git a/v3/examples/notifications/frontend/Inter Font License.txt b/v3/examples/notifications/frontend/Inter Font License.txt new file mode 100644 index 000000000..b525cbf3a --- /dev/null +++ b/v3/examples/notifications/frontend/Inter Font License.txt @@ -0,0 +1,93 @@ +Copyright 2020 The Inter Project Authors (https://github.com/rsms/inter) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js similarity index 100% rename from v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js rename to v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js diff --git a/v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js similarity index 100% rename from v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js rename to v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js diff --git a/v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js similarity index 95% rename from v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js rename to v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js index 5c91a1c77..8fb7eff96 100644 --- a/v3/examples/services/assets/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js @@ -30,6 +30,7 @@ export function RegisterNotificationCategory(category) { } /** + * RemoveAllDeliveredNotifications removes all delivered notifications * @returns {Promise & { cancel(): void }} */ export function RemoveAllDeliveredNotifications() { @@ -47,6 +48,7 @@ export function RemoveAllPendingNotifications() { } /** + * RemoveDeliveredNotification removes a specific delivered notification * @param {string} identifier * @returns {Promise & { cancel(): void }} */ diff --git a/v3/examples/notifications/frontend/dist/Inter-Medium.ttf b/v3/examples/notifications/frontend/dist/Inter-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a01f3777a6fc284b7a720c0f8248a27066389ef9 GIT binary patch literal 315132 zcmd>{3Ajzw|M0(S?X!n-?sds<&AMdHJY`De%rlit*Gxz*k|ZQaMWm8sCL|H5Orgje zLX;sYN}^G@hWmcjK4)L_tKaY+-sgFr_ul8T*4k_QuJ8KpwfA0opS?wiNG6<+$lZ18 z)h}DV>>3eWoroNFw`kt_=)7a6M2)O0s^ph46$l{1e>k6gWyQwEyWNY9Gz_3HOX&vyAf z)S{Q>5MAJ8?;gqBOFo}`FX>%Kuhg4}e4BH=#y0Xu!QTA`56g7y>@Ol2dy5p=(eJ@- z$>AZbE{NPwf$hEhlZOqA#4CsVv?oaelKb~){O#aW5vPqvIP<^B5&SN zzrXqG{ycsElt;op`!QDN*v#5b&hDJC`frju&adR?&uep=z_GS14*mY-l@WRR#%E^J z5gn_;)b6n*lGS$$ihj6P@4+ggNJ_r}gHSL1OfsF!hHQL}O9s)M+nsb6q^Qx|dn(6vPA zI=TUFBi#nKoleH>rm-LWq<#hWRsAaNOuY_wquz}Bk=}y4L+`}htv|#4+^Q|gs%JIC zZDKuyJJ=e6`-n9Tcf7Rn$I0&?vs26| zhFiiZfm_XC?3_kUBivR_Pu$*4Z`=o*2XF^C18^U9hKc1o;ygllxHE$A80QJxxz0jS zuIEyxThJ|tTgUBy+u7}m`?&iA?o;klxKF!J<38g~!kywy!JX<(#hvD&2lrK%QFa%* zi*es@m*OsSm*cK3;-OD(xHp{e)}Vk zj}jgoW^}?YgkQj&9-fZ-es~?J8^W6i?+WiGygz&h_el5{?w4U|4u2c|7WaG@4Tpb< z&3F~`P%|^Jmxw&?#K*!)a@fDd!depS)3LB6rR?`&;m{3vY^h|U1HT@J_`b2QD{bt= zSlAQKPKbrWk`y{03&#=O6AQ=R5YC{ItYxwI1gT)5Z@>Ob60rux!na7g)jbx@d_A7& zF41ZhjaN$YSmk12Emid&v9Kle_1m#?vid~S~a&&R@fB%ch5h4XS)iH$F^BublD{H+{eYRAG!9CZrB!ugRWM=V@`kdUjN zBuh7WfLsk_FyVgEhwba}^<)_FgGi|@50cvbPdWcF{jc){v8|mem2h13VpUJrSMT9Ty>3?!}(7+ojH-SDu#-J4JfsYA$L->-WxHJI`PNg0eR zrk)%OnM*bDYd9+u%CMXc}>W)X;S;MZTi-o7KTVyUt%M{ zpqpyy=F2mb5@zI$)P2a=gfb8NwcIE}lbcEgd7JyvnwADob^xWW$D|N5?1t^0zAS_O zQtAi&vUMquf)xFc*ywzS->W{9Gc5#~G(9rbkmBnx1>HsEAMVR+MkEQ{8BLp>rLbir zGrCS9&XgYD_t!`p9oeqL4kG72YyWz`jLr6f!IZesh8y~=80{Nt9gJqGN@@O6kj9Lc zv5gcd1xCxI{5E@$-W-c)!v1aS(MVgL6eDkvv?kP((8K7#*oWzf$r0U;dyvc6hZ(zQ zpG@0PYchFTv)7wZyDs_ln$4cljk3`iN|37^TSfn*nUt7Tjja8l6mAc+*oxXs%n;lp+B0Ju?NN%a&mjNx zQA%QOYv@ZAwTBy1qIx#6N9RXVm)WNV`Ln4R6=O?*1lLQJyvZW|tkd#HTL!IG;ff$? zK_%HvmWsrckxH~t1`Xbrs}-Zz6sjSqu?f?oo7-qboY_;%TtDcBTuC=cQU@IjWS%m1 z7|f>SXw48EVPi4Z+enfY7y8oNVG@2$=8*Bb|Yth z#wE~FX<80?P)sDQpt&yPN^GUn|6ii|e_rpkJ?_f1l28#`I0oDP{d)d+`M8MGzY({b zoVDP42V>h{^2j=f$(R9Lo&d7Uiy12EF<#m^3% zk;mAc3tNaQ3?C4lt$)Av9sZ_hKH0z`#ŹD@)<7ltOtn$SSm;LMTrPEA?sR43d= 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�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 literal 0 HcmV?d00001 diff --git a/v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js b/v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js new file mode 100644 index 000000000..297ce49b9 --- /dev/null +++ b/v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js @@ -0,0 +1,6 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const s of r)if(s.type==="childList")for(const l of s.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&o(l)}).observe(document,{childList:!0,subtree:!0});function n(r){const s={};return r.integrity&&(s.integrity=r.integrity),r.referrerPolicy&&(s.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?s.credentials="include":r.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function o(r){if(r.ep)return;r.ep=!0;const s=n(r);fetch(r.href,s)}})();let L="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",O=(t=21)=>{let e="",n=t|0;for(;n--;)e+=L[Math.random()*64|0];return e};const _=window.location.origin+"/wails/runtime",h={Call:0,Events:3,ContextMenu:4,Dialog:5,Window:6,Browser:9,CancelCall:10};let k=O();function w(t,e){return function(n,o=null){return W(t,n,e,o)}}async function W(t,e,n,o){let r=new URL(_);t!=null&&r.searchParams.append("object",t),e!=null&&r.searchParams.append("method",e);let s={headers:{}};n&&(s.headers["x-wails-window-name"]=n),o&&r.searchParams.append("args",JSON.stringify(o)),s.headers["x-wails-client-id"]=k;let l=await fetch(r,s);if(!l.ok)throw new Error(await l.text());return l.headers.get("Content-Type")&&l.headers.get("Content-Type").indexOf("application/json")!==-1?l.json():l.text()}const P=(()=>{var t,e,n;try{if((t=window==null?void 0:window.chrome)!=null&&t.webview)return o=>window.chrome.webview.postMessage(o);if((n=(e=window==null?void 0:window.webkit)==null?void 0:e.messageHandlers)!=null&&n.external)return o=>window.webkit.messageHandlers.external.postMessage(o)}catch{console.warn(` +%c⚠️ Browser Environment Detected %c + +%cOnly UI previews are available in the browser. For full functionality, please run the application in desktop mode. +More information at: https://v3.wails.io/learn/build/#using-a-browser-for-development +`,"background: #ffffff; color: #000000; font-weight: bold; padding: 4px 8px; border-radius: 4px; border: 2px solid #000000;","background: transparent;","color: #ffffff; font-style: italic; font-weight: bold;")}return null})();function E(t){if(P)return P(t)}function H(){return window._wails.environment.OS==="windows"}function B(){return window._wails.environment.Debug===!0}window.addEventListener("contextmenu",Y);const U=w(h.ContextMenu,""),$=0;function Z(t,e,n,o){U($,{id:t,x:e,y:n,data:o})}function Y(t){let e=t.target,n=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu");if(n=n?n.trim():"",n){t.preventDefault();let o=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu-data");Z(n,t.clientX,t.clientY,o);return}j(t)}function j(t){if(B())return;const e=t.target;switch(window.getComputedStyle(e).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":t.preventDefault();return;default:if(e.isContentEditable)return;const r=window.getSelection(),s=r.toString().length>0;if(s)for(let l=0;lt.target.clientWidth||t.offsetY>t.target.clientHeight)return;p=!0}else p=!1}function V(){p=!1}function u(t){document.documentElement.style.cursor=t||G,S=t}function q(t){if(p&&(p=!1,(t.buttons!==void 0?t.buttons:t.which)>0)){E("wails:drag");return}if(!z||!H())return;let e=x("system.resizeHandleHeight")||5,n=x("system.resizeHandleWidth")||5,o=x("resizeCornerExtra")||10,r=window.outerWidth-t.clientXoe(type,{"call-id":e});let o=!1,r=!1,s=new Promise((l,a)=>{t["call-id"]=e,y.set(e,{resolve:l,reject:a}),ne(te,t).then(c=>{if(r=!0,o)return n()}).catch(c=>{a(c),y.delete(e)})});return s.cancel=()=>{if(r)return n();o=!0},s}function R(t,...e){return ae({methodID:t,args:e})}window._wails=window._wails||{};window._wails.dialogErrorCallback=we;window._wails.dialogResultCallback=he;const ce=2,ue=3,de=w(h.Dialog,""),f=new Map;function fe(){let t;do t=O();while(f.has(t));return t}function I(t,e={}){const n=fe();return e["dialog-id"]=n,new Promise((o,r)=>{f.set(n,{resolve:o,reject:r}),de(t,e).catch(s=>{r(s),f.delete(n)})})}function he(t,e,n){let o=f.get(t);o&&(f.delete(t),n?o.resolve(JSON.parse(e)):o.resolve(e))}function we(t,e){let n=f.get(t);n&&(f.delete(t),n.reject(new me(e)))}const me=t=>I(ce,t),ge=t=>I(ue,t);window._wails=window._wails||{};window._wails.dispatchWailsEvent=Ce;const pe=w(h.Events,""),Me=0,d=new Map;class be{constructor(e,n,o){this.eventName=e,this.maxCallbacks=o||-1,this.Callback=r=>(n(r),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}}class ye{constructor(e,n=null){this.name=e,this.data=n}}function Ce(t){let e=d.get(t.name);if(e){let n=e.filter(o=>{if(o.Callback(t))return!0});n.length>0&&(e=e.filter(o=>!n.includes(o)),e.length===0?d.delete(t.name):d.set(t.name,e))}}function Ee(t,e,n){let o=d.get(t)||[];const r=new be(t,e,n);return o.push(r),d.set(t,o),()=>Se(r)}function N(t,e){return Ee(t,e,-1)}function Se(t){const e=t.eventName;let n=d.get(e).filter(o=>o!==t);n.length===0?d.delete(e):d.set(e,n)}function ve(t){return pe(Me,t)}const Re=0,xe=1,Oe=2,Te=3,Pe=4,ze=5,De=6,Ie=7,Ne=8,Ae=9,Fe=10,Le=11,_e=12,ke=13,We=14,He=15,Be=16,Ue=17,$e=18,Ze=19,Ye=20,je=21,Ge=22,Je=23,Xe=24,Ve=25,qe=26,Ke=27,Qe=28,et=29,tt=30,nt=31,ot=32,rt=33,it=34,st=35,lt=36,at=37,ct=38,ut=39,dt=40,ft=41,ht=42,wt=43,mt=44,gt=45,pt=46,Mt=47,i=Symbol();class v{constructor(e=""){this[i]=w(h.Window,e);for(const n of Object.getOwnPropertyNames(v.prototype))n!=="constructor"&&typeof this[n]=="function"&&(this[n]=this[n].bind(this))}Get(e){return new v(e)}Position(){return this[i](Re)}Center(){return this[i](xe)}Close(){return this[i](Oe)}DisableSizeConstraints(){return this[i](Te)}EnableSizeConstraints(){return this[i](Pe)}Focus(){return this[i](ze)}ForceReload(){return this[i](De)}Fullscreen(){return this[i](Ie)}GetScreen(){return this[i](Ne)}GetZoom(){return this[i](Ae)}Height(){return this[i](Fe)}Hide(){return this[i](Le)}IsFocused(){return this[i](_e)}IsFullscreen(){return this[i](ke)}IsMaximised(){return this[i](We)}IsMinimised(){return this[i](He)}Maximise(){return this[i](Be)}Minimise(){return this[i](Ue)}Name(){return this[i]($e)}OpenDevTools(){return this[i](Ze)}RelativePosition(){return this[i](Ye)}Reload(){return this[i](je)}Resizable(){return this[i](Ge)}Restore(){return this[i](Je)}SetPosition(e,n){return this[i](Xe,{x:e,y:n})}SetAlwaysOnTop(e){return this[i](Ve,{alwaysOnTop:e})}SetBackgroundColour(e,n,o,r){return this[i](qe,{r:e,g:n,b:o,a:r})}SetFrameless(e){return this[i](Ke,{frameless:e})}SetFullscreenButtonEnabled(e){return this[i](Qe,{enabled:e})}SetMaxSize(e,n){return this[i](et,{width:e,height:n})}SetMinSize(e,n){return this[i](tt,{width:e,height:n})}SetRelativePosition(e,n){return this[i](nt,{x:e,y:n})}SetResizable(e){return this[i](ot,{resizable:e})}SetSize(e,n){return this[i](rt,{width:e,height:n})}SetTitle(e){return this[i](it,{title:e})}SetZoom(e){return this[i](st,{zoom:e})}Show(){return this[i](lt)}Size(){return this[i](at)}ToggleFullscreen(){return this[i](ct)}ToggleMaximise(){return this[i](ut)}UnFullscreen(){return this[i](dt)}UnMaximise(){return this[i](ft)}UnMinimise(){return this[i](ht)}Width(){return this[i](wt)}Zoom(){return this[i](mt)}ZoomIn(){return this[i](gt)}ZoomOut(){return this[i](pt)}ZoomReset(){return this[i](Mt)}}const bt=new v("");function yt(){if(!EventTarget||!AbortSignal||!AbortController)return!1;let t=!0;const e=new EventTarget,n=new AbortController;return e.addEventListener("test",()=>{t=!1},{signal:n.signal}),n.abort(),e.dispatchEvent(new CustomEvent("test")),t}document.addEventListener("DOMContentLoaded",()=>!0);function Ct(t,e=null){ve(new ye(t,e))}function Et(t,e){const n=bt.Get(t),o=n[e];if(typeof o!="function"){console.error(`Window method '${e}' not found`);return}try{o.call(n)}catch(r){console.error(`Error calling window method '${e}': `,r)}}function St(t){const e=t.currentTarget;function n(r="Yes"){if(r!=="Yes")return;const s=e.getAttribute("data-wml-event"),l=e.getAttribute("data-wml-target-window")||"",a=e.getAttribute("data-wml-window"),c=e.getAttribute("data-wml-openURL");s!==null&&Ct(s),a!==null&&Et(l,a),c!==null&&ee(c)}const o=e.getAttribute("data-wml-confirm");o?ge({Title:"Confirm",Message:o,Detached:!1,Buttons:[{Label:"Yes"},{Label:"No",IsDefault:!0}]}).then(n):n()}const C=Symbol();class vt{constructor(){this[C]=new AbortController}set(e,n){return{signal:this[C].signal}}reset(){this[C].abort(),this[C]=new AbortController}}const b=Symbol(),g=Symbol();class Rt{constructor(){this[b]=new WeakMap,this[g]=0}set(e,n){return this[g]+=!this[b].has(e),this[b].set(e,n),{}}reset(){if(!(this[g]<=0)){for(const e of document.body.querySelectorAll("*")){if(this[g]<=0)break;const n=this[b].get(e);this[g]-=typeof n<"u";for(const o of n||[])e.removeEventListener(o,St)}this[b]=new WeakMap,this[g]=0}}}yt()?new vt:new Rt;window._wails=window._wails||{};let A=!1;function xt(){window._wails.invoke=E,E("wails:runtime:ready"),A=!0}window.addEventListener("load",()=>{A||xt()});function Ot(t){return R(2679064664,t)}function F(){return R(3412125712)}function Tt(t,e,n,o){return R(2246903123,t,e,n,o)}function Pt(t){return R(1615199806,t)}const zt=document.getElementById("time"),Dt=document.getElementById("notifications");window.sendNotification=async()=>{await F()&&await Tt("some-uuid-fronted","Frontend Notificaiton","","Notificaiton sent through JS!")};window.sendComplexNotification=async()=>{await F()&&(await Ot({id:"FRONTEND_NOTIF",actions:[{id:"VIEW_ACTION",title:"View"},{id:"MARK_READ_ACTION",title:"Mark as Read"},{id:"DELETE_ACTION",title:"Delete",destructive:!0}],hasReplyField:!0,replyButtonTitle:"Reply",replyPlaceholder:"Reply to frontend..."}),await Pt({id:"some-uuid-complex",title:"Complex Frontend Notification",subtitle:"From: Jane Doe",body:"Is it rainging today where you are?",categoryId:"FRONTEND_NOTIF",data:{messageId:"msg-456",senderId:"user-456",timestamp:Date.now()}}))};N("time",t=>{zt.innerText=t.data});N("notificationResponse",t=>{Dt.innerText+=JSON.stringify(t.data[0].data)}); diff --git a/v3/examples/notifications/frontend/dist/index.html b/v3/examples/notifications/frontend/dist/index.html new file mode 100644 index 000000000..39216bd8d --- /dev/null +++ b/v3/examples/notifications/frontend/dist/index.html @@ -0,0 +1,29 @@ + + + + + + + + Wails App + + + + + + diff --git a/v3/examples/notifications/frontend/dist/javascript.svg b/v3/examples/notifications/frontend/dist/javascript.svg new file mode 100644 index 000000000..f9abb2b72 --- /dev/null +++ b/v3/examples/notifications/frontend/dist/javascript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/examples/notifications/frontend/dist/style.css b/v3/examples/notifications/frontend/dist/style.css new file mode 100644 index 000000000..127799eda --- /dev/null +++ b/v3/examples/notifications/frontend/dist/style.css @@ -0,0 +1,160 @@ +:root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: rgba(27, 38, 54, 1); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./Inter-Medium.ttf") format("truetype"); +} + +h3 { + font-size: 3em; + line-height: 1.1; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +button { + /* width: 60px; */ + height: 30px; + line-height: 30px; + border-radius: 3px; + border: none; + margin: 0 0 0 20px; + padding: 0 8px; + cursor: pointer; +} + +.result { + height: 20px; + line-height: 20px; +} + +body { + margin: 0; + display: flex; + place-items: center; + place-content: center; + min-width: 320px; + min-height: 100vh; +} + +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #e80000aa); +} + +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #f7df1eaa); +} + +.result { + height: 20px; + line-height: 20px; + margin: 1.5rem auto; + text-align: center; +} + +.footer { + margin-top: 1rem; + align-content: center; + text-align: center; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + + a:hover { + color: #747bff; + } + + button { + background-color: #f9f9f9; + } +} + + +.input-box .btn:hover { + background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); + color: #333333; +} + +.input-box .input { + border: none; + border-radius: 3px; + outline: none; + height: 30px; + line-height: 30px; + padding: 0 10px; + color: black; + background-color: rgba(240, 240, 240, 1); + -webkit-font-smoothing: antialiased; +} + +.input-box .input:hover { + border: none; + background-color: rgba(255, 255, 255, 1); +} + +.input-box .input:focus { + border: none; + background-color: rgba(255, 255, 255, 1); +} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/dist/wails.png b/v3/examples/notifications/frontend/dist/wails.png new file mode 100644 index 0000000000000000000000000000000000000000..8bdf424833bfb5b6b34a0807224e94533f738f2e GIT binary patch literal 9057 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 + + + + + + + Wails App + + +
+ +

Wails + Javascript

+ +
+ + + diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js new file mode 100644 index 000000000..54c03e560 --- /dev/null +++ b/v3/examples/notifications/frontend/main.js @@ -0,0 +1,50 @@ +import * as Notifications from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service"; +import { Events } from "@wailsio/runtime"; + +const timeElement = document.getElementById('time'); +const notificationsElement = document.getElementById('notifications'); + +window.sendNotification = async () => { + const granted = await Notifications.RequestUserNotificationAuthorization(); + if (granted) { + await Notifications.SendNotification("some-uuid-fronted", "Frontend Notificaiton", "", "Notificaiton sent through JS!"); + } +} + +window.sendComplexNotification = async () => { + const granted = await Notifications.RequestUserNotificationAuthorization(); + if (granted) { + await Notifications.RegisterNotificationCategory({ + id: "FRONTEND_NOTIF", + actions: [ + { id: "VIEW_ACTION", title: "View" }, + { id: "MARK_READ_ACTION", title: "Mark as Read" }, + { id: "DELETE_ACTION", title: "Delete", destructive: true }, + ], + hasReplyField: true, + replyButtonTitle: "Reply", + replyPlaceholder: "Reply to frontend...", + }); + + await Notifications.SendNotificationWithActions({ + id: "some-uuid-complex", + title: "Complex Frontend Notification", + subtitle: "From: Jane Doe", + body: "Is it rainging today where you are?", + categoryId: "FRONTEND_NOTIF", + data: { + messageId: "msg-456", + senderId: "user-456", + timestamp: Date.now(), + } + }); + } +} + +Events.On('time', (time) => { + timeElement.innerText = time.data; +}); + +Events.On("notificationResponse", (response) => { + notificationsElement.innerText += JSON.stringify(response.data[0].data); +}); \ No newline at end of file diff --git a/v3/examples/notifications/frontend/package.json b/v3/examples/notifications/frontend/package.json new file mode 100644 index 000000000..9ae87549e --- /dev/null +++ b/v3/examples/notifications/frontend/package.json @@ -0,0 +1,16 @@ +{ + "name": "frontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build:dev": "vite build --minify false --mode development", + "build": "vite build --mode production", + "preview": "vite preview" + }, + "devDependencies": { + "vite": "^5.0.0", + "@wailsio/runtime": "latest" + } +} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/Inter-Medium.ttf b/v3/examples/notifications/frontend/public/Inter-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a01f3777a6fc284b7a720c0f8248a27066389ef9 GIT binary patch literal 315132 zcmd>{3Ajzw|M0(S?X!n-?sds<&AMdHJY`De%rlit*Gxz*k|ZQaMWm8sCL|H5Orgje zLX;sYN}^G@hWmcjK4)L_tKaY+-sgFr_ul8T*4k_QuJ8KpwfA0opS?wiNG6<+$lZ18 z)h}DV>>3eWoroNFw`kt_=)7a6M2)O0s^ph46$l{1e>k6gWyQwEyWNY9Gz_3HOX&vyAf z)S{Q>5MAJ8?;gqBOFo}`FX>%Kuhg4}e4BH=#y0Xu!QTA`56g7y>@Ol2dy5p=(eJ@- z$>AZbE{NPwf$hEhlZOqA#4CsVv?oaelKb~){O#aW5vPqvIP<^B5&SN zzrXqG{ycsElt;op`!QDN*v#5b&hDJC`frju&adR?&uep=z_GS14*mY-l@WRR#%E^J z5gn_;)b6n*lGS$$ihj6P@4+ggNJ_r}gHSL1OfsF!hHQL}O9s)M+nsb6q^Qx|dn(6vPA zI=TUFBi#nKoleH>rm-LWq<#hWRsAaNOuY_wquz}Bk=}y4L+`}htv|#4+^Q|gs%JIC zZDKuyJJ=e6`-n9Tcf7Rn$I0&?vs26| zhFiiZfm_XC?3_kUBivR_Pu$*4Z`=o*2XF^C18^U9hKc1o;ygllxHE$A80QJxxz0jS zuIEyxThJ|tTgUBy+u7}m`?&iA?o;klxKF!J<38g~!kywy!JX<(#hvD&2lrK%QFa%* zi*es@m*OsSm*cK3;-OD(xHp{e)}Vk zj}jgoW^}?YgkQj&9-fZ-es~?J8^W6i?+WiGygz&h_el5{?w4U|4u2c|7WaG@4Tpb< z&3F~`P%|^Jmxw&?#K*!)a@fDd!depS)3LB6rR?`&;m{3vY^h|U1HT@J_`b2QD{bt= zSlAQKPKbrWk`y{03&#=O6AQ=R5YC{ItYxwI1gT)5Z@>Ob60rux!na7g)jbx@d_A7& zF41ZhjaN$YSmk12Emid&v9Kle_1m#?vid~S~a&&R@fB%ch5h4XS)iH$F^BublD{H+{eYRAG!9CZrB!ugRWM=V@`kdUjN zBuh7WfLsk_FyVgEhwba}^<)_FgGi|@50cvbPdWcF{jc){v8|mem2h13VpUJrSMT9Ty>3?!}(7+ojH-SDu#-J4JfsYA$L->-WxHJI`PNg0eR zrk)%OnM*bDYd9+u%CMXc}>W)X;S;MZTi-o7KTVyUt%M{ zpqpyy=F2mb5@zI$)P2a=gfb8NwcIE}lbcEgd7JyvnwADob^xWW$D|N5?1t^0zAS_O zQtAi&vUMquf)xFc*ywzS->W{9Gc5#~G(9rbkmBnx1>HsEAMVR+MkEQ{8BLp>rLbir zGrCS9&XgYD_t!`p9oeqL4kG72YyWz`jLr6f!IZesh8y~=80{Nt9gJqGN@@O6kj9Lc zv5gcd1xCxI{5E@$-W-c)!v1aS(MVgL6eDkvv?kP((8K7#*oWzf$r0U;dyvc6hZ(zQ zpG@0PYchFTv)7wZyDs_ln$4cljk3`iN|37^TSfn*nUt7Tjja8l6mAc+*oxXs%n;lp+B0Ju?NN%a&mjNx zQA%QOYv@ZAwTBy1qIx#6N9RXVm)WNV`Ln4R6=O?*1lLQJyvZW|tkd#HTL!IG;ff$? zK_%HvmWsrckxH~t1`Xbrs}-Zz6sjSqu?f?oo7-qboY_;%TtDcBTuC=cQU@IjWS%m1 z7|f>SXw48EVPi4Z+enfY7y8oNVG@2$=8*Bb|Yth z#wE~FX<80?P)sDQpt&yPN^GUn|6ii|e_rpkJ?_f1l28#`I0oDP{d)d+`M8MGzY({b zoVDP42V>h{^2j=f$(R9Lo&d7Uiy12EF<#m^3% zk;mAc3tNaQ3?C4lt$)Av9sZ_hKH0z`#ŹD@)<7ltOtn$SSm;LMTrPEA?sR43d= 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�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 literal 0 HcmV?d00001 diff --git a/v3/examples/notifications/frontend/public/javascript.svg b/v3/examples/notifications/frontend/public/javascript.svg new file mode 100644 index 000000000..f9abb2b72 --- /dev/null +++ b/v3/examples/notifications/frontend/public/javascript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/style.css b/v3/examples/notifications/frontend/public/style.css new file mode 100644 index 000000000..127799eda --- /dev/null +++ b/v3/examples/notifications/frontend/public/style.css @@ -0,0 +1,160 @@ +:root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: rgba(27, 38, 54, 1); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./Inter-Medium.ttf") format("truetype"); +} + +h3 { + font-size: 3em; + line-height: 1.1; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +button { + /* width: 60px; */ + height: 30px; + line-height: 30px; + border-radius: 3px; + border: none; + margin: 0 0 0 20px; + padding: 0 8px; + cursor: pointer; +} + +.result { + height: 20px; + line-height: 20px; +} + +body { + margin: 0; + display: flex; + place-items: center; + place-content: center; + min-width: 320px; + min-height: 100vh; +} + +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #e80000aa); +} + +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #f7df1eaa); +} + +.result { + height: 20px; + line-height: 20px; + margin: 1.5rem auto; + text-align: center; +} + +.footer { + margin-top: 1rem; + align-content: center; + text-align: center; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + + a:hover { + color: #747bff; + } + + button { + background-color: #f9f9f9; + } +} + + +.input-box .btn:hover { + background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); + color: #333333; +} + +.input-box .input { + border: none; + border-radius: 3px; + outline: none; + height: 30px; + line-height: 30px; + padding: 0 10px; + color: black; + background-color: rgba(240, 240, 240, 1); + -webkit-font-smoothing: antialiased; +} + +.input-box .input:hover { + border: none; + background-color: rgba(255, 255, 255, 1); +} + +.input-box .input:focus { + border: none; + background-color: rgba(255, 255, 255, 1); +} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/wails.png b/v3/examples/notifications/frontend/public/wails.png new file mode 100644 index 0000000000000000000000000000000000000000..8bdf424833bfb5b6b34a0807224e94533f738f2e GIT binary patch literal 9057 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 { - if (granted) { - notifications.SendNotification("some-uuid-fronted", "Frontend Notificaiton", "", "Notificaiton sent through JS!"); - } - }); function runHash() { let hashstring = document.getElementById("hashstring").value; diff --git a/v3/examples/services/main.go b/v3/examples/services/main.go index 6bc020c8a..b85650784 100644 --- a/v3/examples/services/main.go +++ b/v3/examples/services/main.go @@ -12,7 +12,6 @@ import ( "github.com/wailsapp/wails/v3/pkg/services/fileserver" "github.com/wailsapp/wails/v3/pkg/services/kvstore" "github.com/wailsapp/wails/v3/pkg/services/log" - "github.com/wailsapp/wails/v3/pkg/services/notifications" "github.com/wailsapp/wails/v3/pkg/services/sqlite" ) @@ -50,7 +49,6 @@ func main() { }), application.ServiceOptions{ Route: "/files", }), - application.NewService(notifications.New()), }, Assets: application.AssetOptions{ Handler: application.BundledAssetFileServer(assets), From 9f3957722809c5c216139ac7d16c0935f97ef2e5 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sat, 22 Feb 2025 20:02:26 -0800 Subject: [PATCH 010/136] add comments --- .../services/notifications/notifications.go | 2 ++ .../notifications/notifications_darwin.go | 26 +++++++++------- .../notifications/notifications_windows.go | 31 ++++++++++++++----- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 5e0ea6910..461f0b395 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -30,6 +30,7 @@ type NotificationOptions = struct { Data map[string]interface{} `json:"data,omitempty"` } +// NotificationResponseData type NotificationResponseData = struct { ID string `json:"id,omitempty"` ActionIdentifier string `json:"actionIdentifier,omitempty"` @@ -41,6 +42,7 @@ type NotificationResponseData = struct { UserInfo map[string]interface{} `json:"userInfo,omitempty"` } +// NotificationResponse type NotificationResponse = struct { Name string `json:"name"` Data NotificationResponseData `json:"data"` diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index d9d378bcf..78454d898 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -17,16 +17,18 @@ import ( "github.com/wailsapp/wails/v3/pkg/application" ) +// Creates a new Notifications Service. +// Your app must be packaged and signed for this feature to work. func New() *Service { return &Service{} } -// ServiceName returns the name of the service +// ServiceName returns the name of the service. func (ns *Service) ServiceName() string { return "github.com/wailsapp/wails/v3/services/notifications" } -// ServiceStartup is called when the service is loaded +// ServiceStartup is called when the service is loaded. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -34,7 +36,7 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi return nil } -// ServiceShutdown is called when the service is unloaded +// ServiceShutdown is called when the service is unloaded. func (ns *Service) ServiceShutdown() error { return nil } @@ -52,7 +54,7 @@ func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { return result == true, nil } -// CheckNotificationAuthorization checks current permission status +// CheckNotificationAuthorization checks current notification permission status. func (ns *Service) CheckNotificationAuthorization() (bool, error) { if !CheckBundleIdentifier() { return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -60,7 +62,7 @@ func (ns *Service) CheckNotificationAuthorization() (bool, error) { return bool(C.checkNotificationAuthorization()), nil } -// SendNotification sends a notification with the given identifier, title, subtitle, and body. +// SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ns *Service) SendNotification(identifier, title, subtitle, body string) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -78,7 +80,9 @@ func (ns *Service) SendNotification(identifier, title, subtitle, body string) er return nil } -// SendNotificationWithActions sends a notification with the specified actions +// SendNotificationWithActions sends a notification with additional actions and inputs. +// A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. +// If a NotificationCategory is not registered a basic notification will be sent. func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -107,7 +111,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro return nil } -// RegisterNotificationCategory registers a category with actions and optional reply field +// RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -135,7 +139,7 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e return nil } -// RemoveAllPendingNotifications removes all pending notifications +// RemoveAllPendingNotifications removes all pending notifications. func (ns *Service) RemoveAllPendingNotifications() error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -144,7 +148,7 @@ func (ns *Service) RemoveAllPendingNotifications() error { return nil } -// RemovePendingNotification removes a specific pending notification +// RemovePendingNotification removes a pending notification matching the unique identifier. func (ns *Service) RemovePendingNotification(identifier string) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -155,7 +159,7 @@ func (ns *Service) RemovePendingNotification(identifier string) error { return nil } -// RemoveAllDeliveredNotifications removes all delivered notifications +// RemoveAllDeliveredNotifications removes all delivered notifications. func (ns *Service) RemoveAllDeliveredNotifications() error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -164,7 +168,7 @@ func (ns *Service) RemoveAllDeliveredNotifications() error { return nil } -// RemoveDeliveredNotification removes a specific delivered notification +// RemoveDeliveredNotification removes a delivered notification matching the unique identifier. func (ns *Service) RemoveDeliveredNotification(identifier string) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index e942568d6..ab025f95f 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -21,6 +21,7 @@ func (ns *Service) ServiceName() string { } // ServiceStartup is called when the service is loaded +// Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { toast.SetActivationCallback(func(args string, data []toast.UserData) { response := NotificationResponse{ @@ -44,21 +45,26 @@ func (ns *Service) ServiceShutdown() error { return nil } -// On Windows this does not apply, return true +// CheckBundleIdentifier is a Windows stub that always returns true. +// (bundle identifiers are macOS-specific) func CheckBundleIdentifier() bool { return true } -// On Windows this does not apply, return true +// RequestUserNotificationAuthorization is a Windows stub that always returns true, nil. +// (user authorization is macOS-specific) func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { return true, nil } -// On Windows this does not apply, return true +// CheckNotificationAuthorization is a Windows stub that always returns true. +// (user authorization is macOS-specific) func (ns *Service) CheckNotificationAuthorization() bool { return true } +// SendNotification sends a basic notification with a name, title, and body. +// (subtitle is only available on macOS) func (ns *Service) SendNotification(identifier, title, _, body string) error { n := toast.Notification{ AppID: identifier, @@ -73,6 +79,9 @@ func (ns *Service) SendNotification(identifier, title, _, body string) error { return nil } +// SendNotificationWithActions sends a notification with additional actions and inputs. +// A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. +// If a NotificationCategory is not registered a basic notification will be sent. func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { nCategory := NotificationCategories[options.CategoryID] @@ -97,7 +106,8 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro }) n.Actions = append(n.Actions, toast.Action{ - Content: nCategory.ReplyButtonTitle, + Content: nCategory.ReplyButtonTitle, + Arguments: "TEXT_REPLY", }) } @@ -108,6 +118,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro return nil } +// RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { NotificationCategories[category.ID] = NotificationCategory{ ID: category.ID, @@ -120,22 +131,26 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e return nil } -// RemoveAllPendingNotifications removes all pending notifications +// RemoveAllPendingNotifications is a Windows stub that always returns nil. +// (macOS-specific) func (ns *Service) RemoveAllPendingNotifications() error { return nil } -// RemovePendingNotification removes a specific pending notification +// RemovePendingNotification is a Windows stub that always returns nil. +// (macOS-specific) func (ns *Service) RemovePendingNotification(_ string) error { return nil } -// RemoveAllDeliveredNotifications removes all delivered notifications +// RemoveAllDeliveredNotifications is a Windows stub that always returns nil. +// (macOS-specific) func (ns *Service) RemoveAllDeliveredNotifications() error { return nil } -// RemoveDeliveredNotification removes a specific delivered notification +// RemoveDeliveredNotification is a Windows stub that always returns nil. +// (macOS-specific) func (ns *Service) RemoveDeliveredNotification(_ string) error { return nil } From 47a0977ac68dee475cd5a976682c000845c1eba8 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Feb 2025 20:25:03 -0800 Subject: [PATCH 011/136] add overwrite and remove notification category --- .../notifications/notifications_darwin.go | 13 ++++++ .../notifications/notifications_darwin.h | 7 ++-- .../notifications/notifications_darwin.m | 41 ++++++++++++++++++- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 78454d898..41a5a4c11 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -112,6 +112,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. +// Registering a category with the same name as a previously registered NotificationCategory will override it. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") @@ -139,6 +140,18 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e return nil } +// RemoveNotificationCategory remove a previously registered NotificationCategory. +func (ns *Service) RemoveNotificationCategory(categoryId string) error { + if !CheckBundleIdentifier() { + return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + } + cCategoryID := C.CString(categoryId) + defer C.free(unsafe.Pointer(cCategoryID)) + + C.removeNotificationCategory(cCategoryID) + return nil +} + // RemoveAllPendingNotifications removes all pending notifications. func (ns *Service) RemoveAllPendingNotifications() error { if !CheckBundleIdentifier() { diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index fb21d4cb0..74ac28553 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -9,10 +9,9 @@ bool checkBundleIdentifier(void); bool requestUserNotificationAuthorization(void *completion); bool checkNotificationAuthorization(void); void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, void *completion); -void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, - const char *body, const char *categoryId, const char *actions_json, void *completion); -void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, - const char *replyPlaceholder, const char *replyButtonTitle); +void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json, void *completion); +void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); +void removeNotificationCategory(const char *categoryId); void removeAllPendingNotifications(void); void removePendingNotification(const char *identifier); void removeAllDeliveredNotifications(void); diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index b4be6835a..0028211ec 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -245,7 +245,7 @@ void registerNotificationCategory(const char *categoryId, const char *actions_js [actions addObject:textAction]; } - UNNotificationCategory *category = [UNNotificationCategory + UNNotificationCategory *newCategory = [UNNotificationCategory categoryWithIdentifier:nsCategoryId actions:actions intentIdentifiers:@[] @@ -254,11 +254,48 @@ void registerNotificationCategory(const char *categoryId, const char *actions_js UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center getNotificationCategoriesWithCompletionHandler:^(NSSet *categories) { NSMutableSet *updatedCategories = [NSMutableSet setWithSet:categories]; - [updatedCategories addObject:category]; + + // Remove existing category with same ID if it exists + UNNotificationCategory *existingCategory = nil; + for (UNNotificationCategory *category in updatedCategories) { + if ([category.identifier isEqualToString:nsCategoryId]) { + existingCategory = category; + break; + } + } + if (existingCategory) { + [updatedCategories removeObject:existingCategory]; + } + + // Add the new category + [updatedCategories addObject:newCategory]; [center setNotificationCategories:updatedCategories]; }]; } +void removeNotificationCategory(const char *categoryId) { + NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + + [center getNotificationCategoriesWithCompletionHandler:^(NSSet *categories) { + NSMutableSet *updatedCategories = [NSMutableSet setWithSet:categories]; + + // Find and remove the category with matching identifier + UNNotificationCategory *categoryToRemove = nil; + for (UNNotificationCategory *category in updatedCategories) { + if ([category.identifier isEqualToString:nsCategoryId]) { + categoryToRemove = category; + break; + } + } + + if (categoryToRemove) { + [updatedCategories removeObject:categoryToRemove]; + [center setNotificationCategories:updatedCategories]; + } + }]; +} + void removeAllPendingNotifications(void) { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center removeAllPendingNotificationRequests]; From 6d44068ede1d67005a2ffc24907c774cc68e41df Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sat, 22 Feb 2025 20:52:23 -0800 Subject: [PATCH 012/136] save notification categories to registry --- .../notifications/notifications_darwin.go | 2 +- .../notifications/notifications_windows.go | 75 ++++++++++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 41a5a4c11..626f52524 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -140,7 +140,7 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e return nil } -// RemoveNotificationCategory remove a previously registered NotificationCategory. +// RemoveNotificationCategory removes a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { if !CheckBundleIdentifier() { return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index ab025f95f..9c9fad042 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -4,9 +4,15 @@ package notifications import ( "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" "git.sr.ht/~jackmordaunt/go-toast" "github.com/wailsapp/wails/v3/pkg/application" + "golang.org/x/sys/windows/registry" ) var NotificationCategories map[string]NotificationCategory = make(map[string]NotificationCategory) @@ -37,12 +43,12 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi application.Get().EmitEvent("notificationResponse", response) }) - return nil + return loadCategoriesFromRegistry() } // ServiceShutdown is called when the service is unloaded func (ns *Service) ServiceShutdown() error { - return nil + return saveCategoriesToRegistry() } // CheckBundleIdentifier is a Windows stub that always returns true. @@ -128,7 +134,13 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e ReplyButtonTitle: category.ReplyButtonTitle, } - return nil + return saveCategoriesToRegistry() +} + +// RemoveNotificationCategory removes a previously registered NotificationCategory. +func (ns *Service) RemoveNotificationCategory(categoryId string) error { + delete(NotificationCategories, categoryId) + return saveCategoriesToRegistry() } // RemoveAllPendingNotifications is a Windows stub that always returns nil. @@ -155,6 +167,63 @@ func (ns *Service) RemoveDeliveredNotification(_ string) error { return nil } +func getExeName() string { + executable, err := os.Executable() + if err != nil { + return "" + } + + return strings.TrimSuffix(filepath.Base(executable), filepath.Ext(executable)) +} + +func saveCategoriesToRegistry() error { + appName := getExeName() + registryPath := fmt.Sprintf(`SOFTWARE\%s\NotificationCategories`, appName) + + key, _, err := registry.CreateKey( + registry.CURRENT_USER, + registryPath, + registry.ALL_ACCESS, + ) + if err != nil { + return err + } + defer key.Close() + + data, err := json.Marshal(NotificationCategories) + if err != nil { + return err + } + + return key.SetStringValue("Categories", string(data)) +} + +func loadCategoriesFromRegistry() error { + appName := getExeName() + println(appName) + registryPath := fmt.Sprintf(`SOFTWARE\%s\NotificationCategories`, appName) + + key, err := registry.OpenKey( + registry.CURRENT_USER, + registryPath, + registry.QUERY_VALUE, + ) + if err != nil { + if err == registry.ErrNotExist { + return nil + } + return err + } + defer key.Close() + + data, _, err := key.GetStringValue("Categories") + if err != nil { + return err + } + + return json.Unmarshal([]byte(data), &NotificationCategories) +} + func getUserText(data []toast.UserData) (string, bool) { for _, d := range data { if d.Key == "userText" { From ab9c4600880ca104b4edc6e5a3950ed1acbe0001 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 11:40:39 -0800 Subject: [PATCH 013/136] quick fixes --- v3/examples/notifications/frontend/main.js | 8 +++++--- v3/pkg/application/context_application_event.go | 6 +----- v3/pkg/services/notifications/notifications_windows.go | 8 +++++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js index 54c03e560..f032ac16b 100644 --- a/v3/examples/notifications/frontend/main.js +++ b/v3/examples/notifications/frontend/main.js @@ -7,7 +7,8 @@ const notificationsElement = document.getElementById('notifications'); window.sendNotification = async () => { const granted = await Notifications.RequestUserNotificationAuthorization(); if (granted) { - await Notifications.SendNotification("some-uuid-fronted", "Frontend Notificaiton", "", "Notificaiton sent through JS!"); + const uuid = crypto.randomUUID(); + await Notifications.SendNotification(uuid, "Frontend Notification", "", "Notification sent through JS!"); } } @@ -26,11 +27,12 @@ window.sendComplexNotification = async () => { replyPlaceholder: "Reply to frontend...", }); + const uuid = crypto.randomUUID(); await Notifications.SendNotificationWithActions({ - id: "some-uuid-complex", + id: uuid, title: "Complex Frontend Notification", subtitle: "From: Jane Doe", - body: "Is it rainging today where you are?", + body: "Is it raining today where you are?", categoryId: "FRONTEND_NOTIF", data: { messageId: "msg-456", diff --git a/v3/pkg/application/context_application_event.go b/v3/pkg/application/context_application_event.go index 50cf8b90d..468634f22 100644 --- a/v3/pkg/application/context_application_event.go +++ b/v3/pkg/application/context_application_event.go @@ -52,7 +52,7 @@ func (c ApplicationEventContext) HasVisibleWindows() bool { return c.getBool("hasVisibleWindows") } -func (c *ApplicationEventContext) setData(data map[string]any) { +func (c ApplicationEventContext) setData(data map[string]any) { c.data = data } @@ -72,10 +72,6 @@ func (c ApplicationEventContext) Filename() string { return result } -func (c *ApplicationEventContext) GetData() map[string]any { - return c.data -} - func newApplicationEventContext() *ApplicationEventContext { return &ApplicationEventContext{ data: make(map[string]any), diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 9c9fad042..d88e06f9c 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -167,6 +167,7 @@ func (ns *Service) RemoveDeliveredNotification(_ string) error { return nil } +// Is there a better way for me to grab this from the Wails config? func getExeName() string { executable, err := os.Executable() if err != nil { @@ -178,6 +179,9 @@ func getExeName() string { func saveCategoriesToRegistry() error { appName := getExeName() + if appName == "" { + return fmt.Errorf("failed to save categories to registry: empty executable name") + } registryPath := fmt.Sprintf(`SOFTWARE\%s\NotificationCategories`, appName) key, _, err := registry.CreateKey( @@ -200,7 +204,9 @@ func saveCategoriesToRegistry() error { func loadCategoriesFromRegistry() error { appName := getExeName() - println(appName) + if appName == "" { + return fmt.Errorf("failed to save categories to registry: empty executable name") + } registryPath := fmt.Sprintf(`SOFTWARE\%s\NotificationCategories`, appName) key, err := registry.OpenKey( From 27e512d5f1bdb5c03fa1c2e46b9b57e0dad705a3 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sun, 23 Feb 2025 13:55:03 -0800 Subject: [PATCH 014/136] add data option to basic notification --- .../notifications/notifications_darwin.go | 45 +++++++++++-------- .../notifications/notifications_darwin.h | 2 +- .../notifications/notifications_darwin.m | 18 +++++++- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 626f52524..a84d6f024 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -31,7 +31,7 @@ func (ns *Service) ServiceName() string { // ServiceStartup is called when the service is loaded. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } return nil } @@ -48,7 +48,7 @@ func CheckBundleIdentifier() bool { // RequestUserNotificationAuthorization requests permission for notifications. func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { if !CheckBundleIdentifier() { - return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return false, fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } result := C.requestUserNotificationAuthorization(nil) return result == true, nil @@ -57,26 +57,35 @@ func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { // CheckNotificationAuthorization checks current notification permission status. func (ns *Service) CheckNotificationAuthorization() (bool, error) { if !CheckBundleIdentifier() { - return false, fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return false, fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } return bool(C.checkNotificationAuthorization()), nil } // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. -func (ns *Service) SendNotification(identifier, title, subtitle, body string) error { +func (ns *Service) SendNotification(options NotificationOptions) error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } - cIdentifier := C.CString(identifier) - cTitle := C.CString(title) - cSubtitle := C.CString(subtitle) - cBody := C.CString(body) + cIdentifier := C.CString(options.ID) + cTitle := C.CString(options.Title) + cSubtitle := C.CString(options.Subtitle) + cBody := C.CString(options.Body) defer C.free(unsafe.Pointer(cIdentifier)) defer C.free(unsafe.Pointer(cTitle)) defer C.free(unsafe.Pointer(cSubtitle)) defer C.free(unsafe.Pointer(cBody)) - C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, nil) + var cDataJSON *C.char + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + cDataJSON = C.CString(string(jsonData)) + defer C.free(unsafe.Pointer(cDataJSON)) + } + } + + C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, cDataJSON, nil) return nil } @@ -85,7 +94,7 @@ func (ns *Service) SendNotification(identifier, title, subtitle, body string) er // If a NotificationCategory is not registered a basic notification will be sent. func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) @@ -115,7 +124,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro // Registering a category with the same name as a previously registered NotificationCategory will override it. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } cCategoryID := C.CString(category.ID) defer C.free(unsafe.Pointer(cCategoryID)) @@ -140,10 +149,10 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e return nil } -// RemoveNotificationCategory removes a previously registered NotificationCategory. +// RemoveNotificationCategory remove a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } cCategoryID := C.CString(categoryId) defer C.free(unsafe.Pointer(cCategoryID)) @@ -155,7 +164,7 @@ func (ns *Service) RemoveNotificationCategory(categoryId string) error { // RemoveAllPendingNotifications removes all pending notifications. func (ns *Service) RemoveAllPendingNotifications() error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } C.removeAllPendingNotifications() return nil @@ -164,7 +173,7 @@ func (ns *Service) RemoveAllPendingNotifications() error { // RemovePendingNotification removes a pending notification matching the unique identifier. func (ns *Service) RemovePendingNotification(identifier string) error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } cIdentifier := C.CString(identifier) defer C.free(unsafe.Pointer(cIdentifier)) @@ -175,7 +184,7 @@ func (ns *Service) RemovePendingNotification(identifier string) error { // RemoveAllDeliveredNotifications removes all delivered notifications. func (ns *Service) RemoveAllDeliveredNotifications() error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } C.removeAllDeliveredNotifications() return nil @@ -184,7 +193,7 @@ func (ns *Service) RemoveAllDeliveredNotifications() error { // RemoveDeliveredNotification removes a delivered notification matching the unique identifier. func (ns *Service) RemoveDeliveredNotification(identifier string) error { if !CheckBundleIdentifier() { - return fmt.Errorf("Notifications require a bundled application with a unique bundle identifier") + return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") } cIdentifier := C.CString(identifier) defer C.free(unsafe.Pointer(cIdentifier)) diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index 74ac28553..21a210289 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -8,7 +8,7 @@ bool checkBundleIdentifier(void); bool requestUserNotificationAuthorization(void *completion); bool checkNotificationAuthorization(void); -void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, void *completion); +void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json, void *completion); void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json, void *completion); void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); void removeNotificationCategory(const char *categoryId); diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 0028211ec..3c3fe4978 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -118,7 +118,7 @@ bool checkNotificationAuthorization(void) { return isAuthorized; } -void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, void *completion) { +void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json, void *completion) { ensureDelegateInitialized(); NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; @@ -126,6 +126,17 @@ void sendNotification(const char *identifier, const char *title, const char *sub NSString *nsSubtitle = [NSString stringWithUTF8String:subtitle]; NSString *nsBody = [NSString stringWithUTF8String:body]; + NSMutableDictionary *customData = [NSMutableDictionary dictionary]; + if (data_json) { + NSString *dataJsonStr = [NSString stringWithUTF8String:data_json]; + NSData *jsonData = [dataJsonStr dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error = nil; + NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; + if (!error && parsedData) { + [customData addEntriesFromDictionary:parsedData]; + } + } + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; @@ -134,6 +145,11 @@ void sendNotification(const char *identifier, const char *title, const char *sub content.body = nsBody; content.sound = [UNNotificationSound defaultSound]; + // Add custom data if available + if (customData.count > 0) { + content.userInfo = customData; + } + UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; From f8647ff73c2aa0e2a56e735b696859b86ac9385d Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sun, 23 Feb 2025 14:11:32 -0800 Subject: [PATCH 015/136] update min macos version --- v3/pkg/services/notifications/notifications_darwin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index a84d6f024..b95d93078 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -3,8 +3,8 @@ package notifications /* -#cgo CFLAGS: -mmacosx-version-min=10.14 -x objective-c -#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=10.14 -framework UserNotifications +#cgo CFLAGS: -mmacosx-version-min=11.0 -x objective-c +#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=11 -framework UserNotifications #import "./notifications_darwin.h" */ import "C" From c1230d4b86d7d559e3789e1a48ad8cf01c35de24 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 14:37:03 -0800 Subject: [PATCH 016/136] update win impl to match --- v3/pkg/services/notifications/notifications.go | 14 +++++++------- .../notifications/notifications_windows.go | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 461f0b395..57715b11e 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -5,16 +5,16 @@ type Service struct { // NotificationAction represents an action button for a notification type NotificationAction = struct { - ID string `json:"id"` - Title string `json:"title"` + ID string `json:"id,omitempty"` + Title string `json:"title,omitempty"` Destructive bool `json:"destructive,omitempty"` AuthenticationRequired bool `json:"authenticationRequired,omitempty"` } // NotificationCategory groups actions for notifications type NotificationCategory = struct { - ID string `json:"id"` - Actions []NotificationAction `json:"actions"` + ID string `json:"id,omitempty"` + Actions []NotificationAction `json:"actions,omitempty"` HasReplyField bool `json:"hasReplyField,omitempty"` ReplyPlaceholder string `json:"replyPlaceholder,omitempty"` ReplyButtonTitle string `json:"replyButtonTitle,omitempty"` @@ -22,10 +22,10 @@ type NotificationCategory = struct { // NotificationOptions contains configuration for a notification type NotificationOptions = struct { - ID string `json:"id"` - Title string `json:"title"` + ID string `json:"id,omitempty"` + Title string `json:"title,omitempty"` Subtitle string `json:"subtitle,omitempty"` - Body string `json:"body"` + Body string `json:"body,omitempty"` CategoryID string `json:"categoryId,omitempty"` Data map[string]interface{} `json:"data,omitempty"` } diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index d88e06f9c..f279f67be 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -71,11 +71,11 @@ func (ns *Service) CheckNotificationAuthorization() bool { // SendNotification sends a basic notification with a name, title, and body. // (subtitle is only available on macOS) -func (ns *Service) SendNotification(identifier, title, _, body string) error { +func (ns *Service) SendNotification(options NotificationOptions) error { n := toast.Notification{ - AppID: identifier, - Title: title, - Body: body, + AppID: options.ID, + Title: options.Title, + Body: options.Body, } err := n.Push() From 9eab58f0d2c8070199d161616f0ee0470b5b2b62 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 14:40:40 -0800 Subject: [PATCH 017/136] update comments --- v3/pkg/services/notifications/notifications_windows.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index f279f67be..92ae45f96 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -69,8 +69,8 @@ func (ns *Service) CheckNotificationAuthorization() bool { return true } -// SendNotification sends a basic notification with a name, title, and body. -// (subtitle is only available on macOS) +// SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. +// (subtitle, category id, and data are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { n := toast.Notification{ AppID: options.ID, @@ -88,6 +88,7 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // SendNotificationWithActions sends a notification with additional actions and inputs. // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. +// (subtitle, category id, and data are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { nCategory := NotificationCategories[options.CategoryID] From cc760a173a29371088625060dc675db05567c029 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 15:41:56 -0800 Subject: [PATCH 018/136] test data with toast --- .../notifications/notifications_windows.go | 58 ++++++++++++++++--- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 92ae45f96..f1b0d3a1a 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -17,6 +17,11 @@ import ( var NotificationCategories map[string]NotificationCategory = make(map[string]NotificationCategory) +const ( + defaultAction = "defaultActionIdentifier" + dataSeparator = ":::" +) + func New() *Service { return &Service{} } @@ -30,13 +35,22 @@ func (ns *Service) ServiceName() string { // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { toast.SetActivationCallback(func(args string, data []toast.UserData) { + actionIdentifier, userInfo := parseNotificationResponse(args) response := NotificationResponse{ Name: "notification", Data: NotificationResponseData{ - ActionIdentifier: args, + ActionIdentifier: actionIdentifier, }, } + if userInfo != "" { + jsonStr := strings.ReplaceAll(userInfo, "'", "\"") + var userInfoMap map[string]interface{} + if err := json.Unmarshal([]byte(jsonStr), &userInfoMap); err == nil { + response.Data.UserInfo = userInfoMap + } + } + if userText, found := getUserText(data); found { response.Data.UserText = userText } @@ -73,9 +87,20 @@ func (ns *Service) CheckNotificationAuthorization() bool { // (subtitle, category id, and data are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { n := toast.Notification{ - AppID: options.ID, - Title: options.Title, - Body: options.Body, + AppID: options.ID, + Title: options.Title, + Body: options.Body, + ActivationArguments: defaultAction, + } + + options.Data["title"] = options.Title + options.Data["body"] = options.Body + + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + n.ActivationArguments = defaultAction + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") + } } err := n.Push() @@ -93,9 +118,10 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro nCategory := NotificationCategories[options.CategoryID] n := toast.Notification{ - AppID: options.ID, - Title: options.Title, - Body: options.Body, + AppID: options.ID, + Title: options.Title, + Body: options.Body, + ActivationArguments: defaultAction, } for _, action := range nCategory.Actions { @@ -118,6 +144,16 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro }) } + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + n.ActivationArguments = defaultAction + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") + for index := range n.Actions { + n.Actions[index].Arguments = n.Actions[index].Arguments + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") + } + } + } + err := n.Push() if err != nil { return err @@ -168,6 +204,14 @@ func (ns *Service) RemoveDeliveredNotification(_ string) error { return nil } +func parseNotificationResponse(response string) (action string, data string) { + parts := strings.Split(response, dataSeparator) + if len(parts) == 1 { + return parts[0], "" + } + return parts[0], parts[1] +} + // Is there a better way for me to grab this from the Wails config? func getExeName() string { executable, err := os.Executable() From 978a982ab752843c1ee7829573c9949466226992 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 15:45:42 -0800 Subject: [PATCH 019/136] don't add title or body quite yet --- v3/pkg/services/notifications/notifications_windows.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index f1b0d3a1a..078a3cb08 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -93,9 +93,6 @@ func (ns *Service) SendNotification(options NotificationOptions) error { ActivationArguments: defaultAction, } - options.Data["title"] = options.Title - options.Data["body"] = options.Body - if options.Data != nil { jsonData, err := json.Marshal(options.Data) if err == nil { From bf4222c9cce0d7488ea7d64646496674b011780b Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 16:00:04 -0800 Subject: [PATCH 020/136] update example --- .../v3/pkg/services/notifications/models.js | 14 +- .../v3/pkg/services/notifications/service.js | 59 ++++--- .../frontend/dist/Inter-Medium.ttf | Bin 315132 -> 0 bytes .../frontend/dist/assets/index-CS0sRFez.js | 6 - .../notifications/frontend/dist/index.html | 29 ---- .../frontend/dist/javascript.svg | 1 - .../notifications/frontend/dist/style.css | 160 ------------------ .../notifications/frontend/dist/wails.png | Bin 9057 -> 0 bytes v3/examples/notifications/frontend/main.js | 23 ++- v3/examples/notifications/main.go | 141 +++++++-------- 10 files changed, 123 insertions(+), 310 deletions(-) delete mode 100644 v3/examples/notifications/frontend/dist/Inter-Medium.ttf delete mode 100644 v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js delete mode 100644 v3/examples/notifications/frontend/dist/index.html delete mode 100644 v3/examples/notifications/frontend/dist/javascript.svg delete mode 100644 v3/examples/notifications/frontend/dist/style.css delete mode 100644 v3/examples/notifications/frontend/dist/wails.png diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js index 2525e0f38..958e7d79c 100644 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js @@ -9,8 +9,8 @@ import {Create as $Create} from "@wailsio/runtime"; /** * NotificationAction represents an action button for a notification * @typedef {Object} NotificationAction - * @property {string} id - * @property {string} title + * @property {string} [id] + * @property {string} [title] * @property {boolean} [destructive] * @property {boolean} [authenticationRequired] */ @@ -18,8 +18,8 @@ import {Create as $Create} from "@wailsio/runtime"; /** * NotificationCategory groups actions for notifications * @typedef {Object} NotificationCategory - * @property {string} id - * @property {NotificationAction[]} actions + * @property {string} [id] + * @property {NotificationAction[]} [actions] * @property {boolean} [hasReplyField] * @property {string} [replyPlaceholder] * @property {string} [replyButtonTitle] @@ -28,10 +28,10 @@ import {Create as $Create} from "@wailsio/runtime"; /** * NotificationOptions contains configuration for a notification * @typedef {Object} NotificationOptions - * @property {string} id - * @property {string} title + * @property {string} [id] + * @property {string} [title] * @property {string} [subtitle] - * @property {string} body + * @property {string} [body] * @property {string} [categoryId] * @property {{ [_: string]: any }} [data] */ diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js index 8fb7eff96..85da85975 100644 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js @@ -11,7 +11,8 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime"; import * as $models from "./models.js"; /** - * CheckNotificationAuthorization checks current permission status + * CheckNotificationAuthorization is a Windows stub that always returns true. + * (user authorization is macOS-specific) * @returns {Promise & { cancel(): void }} */ export function CheckNotificationAuthorization() { @@ -20,7 +21,7 @@ export function CheckNotificationAuthorization() { } /** - * RegisterNotificationCategory registers a category with actions and optional reply field + * RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. * @param {$models.NotificationCategory} category * @returns {Promise & { cancel(): void }} */ @@ -30,7 +31,8 @@ export function RegisterNotificationCategory(category) { } /** - * RemoveAllDeliveredNotifications removes all delivered notifications + * RemoveAllDeliveredNotifications is a Windows stub that always returns nil. + * (macOS-specific) * @returns {Promise & { cancel(): void }} */ export function RemoveAllDeliveredNotifications() { @@ -39,7 +41,8 @@ export function RemoveAllDeliveredNotifications() { } /** - * RemoveAllPendingNotifications removes all pending notifications + * RemoveAllPendingNotifications is a Windows stub that always returns nil. + * (macOS-specific) * @returns {Promise & { cancel(): void }} */ export function RemoveAllPendingNotifications() { @@ -48,27 +51,40 @@ export function RemoveAllPendingNotifications() { } /** - * RemoveDeliveredNotification removes a specific delivered notification - * @param {string} identifier + * RemoveDeliveredNotification is a Windows stub that always returns nil. + * (macOS-specific) + * @param {string} $0 * @returns {Promise & { cancel(): void }} */ -export function RemoveDeliveredNotification(identifier) { - let $resultPromise = /** @type {any} */($Call.ByID(149440045, identifier)); +export function RemoveDeliveredNotification($0) { + let $resultPromise = /** @type {any} */($Call.ByID(149440045, $0)); return $resultPromise; } /** - * RemovePendingNotification removes a specific pending notification - * @param {string} identifier + * RemoveNotificationCategory removes a previously registered NotificationCategory. + * @param {string} categoryId * @returns {Promise & { cancel(): void }} */ -export function RemovePendingNotification(identifier) { - let $resultPromise = /** @type {any} */($Call.ByID(3872412470, identifier)); +export function RemoveNotificationCategory(categoryId) { + let $resultPromise = /** @type {any} */($Call.ByID(229511469, categoryId)); return $resultPromise; } /** - * RequestUserNotificationAuthorization requests permission for notifications. + * RemovePendingNotification is a Windows stub that always returns nil. + * (macOS-specific) + * @param {string} $0 + * @returns {Promise & { cancel(): void }} + */ +export function RemovePendingNotification($0) { + let $resultPromise = /** @type {any} */($Call.ByID(3872412470, $0)); + return $resultPromise; +} + +/** + * RequestUserNotificationAuthorization is a Windows stub that always returns true, nil. + * (user authorization is macOS-specific) * @returns {Promise & { cancel(): void }} */ export function RequestUserNotificationAuthorization() { @@ -77,20 +93,21 @@ export function RequestUserNotificationAuthorization() { } /** - * SendNotification sends a notification with the given identifier, title, subtitle, and body. - * @param {string} identifier - * @param {string} title - * @param {string} subtitle - * @param {string} body + * SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. + * (subtitle, category id, and data are only available on macOS) + * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ -export function SendNotification(identifier, title, subtitle, body) { - let $resultPromise = /** @type {any} */($Call.ByID(2246903123, identifier, title, subtitle, body)); +export function SendNotification(options) { + let $resultPromise = /** @type {any} */($Call.ByID(2246903123, options)); return $resultPromise; } /** - * SendNotificationWithActions sends a notification with the specified actions + * SendNotificationWithActions sends a notification with additional actions and inputs. + * A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. + * If a NotificationCategory is not registered a basic notification will be sent. + * (subtitle, category id, and data are only available on macOS) * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ diff --git a/v3/examples/notifications/frontend/dist/Inter-Medium.ttf b/v3/examples/notifications/frontend/dist/Inter-Medium.ttf deleted file mode 100644 index a01f3777a6fc284b7a720c0f8248a27066389ef9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 315132 zcmd>{3Ajzw|M0(S?X!n-?sds<&AMdHJY`De%rlit*Gxz*k|ZQaMWm8sCL|H5Orgje zLX;sYN}^G@hWmcjK4)L_tKaY+-sgFr_ul8T*4k_QuJ8KpwfA0opS?wiNG6<+$lZ18 z)h}DV>>3eWoroNFw`kt_=)7a6M2)O0s^ph46$l{1e>k6gWyQwEyWNY9Gz_3HOX&vyAf z)S{Q>5MAJ8?;gqBOFo}`FX>%Kuhg4}e4BH=#y0Xu!QTA`56g7y>@Ol2dy5p=(eJ@- z$>AZbE{NPwf$hEhlZOqA#4CsVv?oaelKb~){O#aW5vPqvIP<^B5&SN zzrXqG{ycsElt;op`!QDN*v#5b&hDJC`frju&adR?&uep=z_GS14*mY-l@WRR#%E^J z5gn_;)b6n*lGS$$ihj6P@4+ggNJ_r}gHSL1OfsF!hHQL}O9s)M+nsb6q^Qx|dn(6vPA zI=TUFBi#nKoleH>rm-LWq<#hWRsAaNOuY_wquz}Bk=}y4L+`}htv|#4+^Q|gs%JIC zZDKuyJJ=e6`-n9Tcf7Rn$I0&?vs26| zhFiiZfm_XC?3_kUBivR_Pu$*4Z`=o*2XF^C18^U9hKc1o;ygllxHE$A80QJxxz0jS zuIEyxThJ|tTgUBy+u7}m`?&iA?o;klxKF!J<38g~!kywy!JX<(#hvD&2lrK%QFa%* zi*es@m*OsSm*cK3;-OD(xHp{e)}Vk zj}jgoW^}?YgkQj&9-fZ-es~?J8^W6i?+WiGygz&h_el5{?w4U|4u2c|7WaG@4Tpb< z&3F~`P%|^Jmxw&?#K*!)a@fDd!depS)3LB6rR?`&;m{3vY^h|U1HT@J_`b2QD{bt= zSlAQKPKbrWk`y{03&#=O6AQ=R5YC{ItYxwI1gT)5Z@>Ob60rux!na7g)jbx@d_A7& zF41ZhjaN$YSmk12Emid&v9Kle_1m#?vid~S~a&&R@fB%ch5h4XS)iH$F^BublD{H+{eYRAG!9CZrB!ugRWM=V@`kdUjN zBuh7WfLsk_FyVgEhwba}^<)_FgGi|@50cvbPdWcF{jc){v8|mem2h13VpUJrSMT9Ty>3?!}(7+ojH-SDu#-J4JfsYA$L->-WxHJI`PNg0eR zrk)%OnM*bDYd9+u%CMXc}>W)X;S;MZTi-o7KTVyUt%M{ zpqpyy=F2mb5@zI$)P2a=gfb8NwcIE}lbcEgd7JyvnwADob^xWW$D|N5?1t^0zAS_O zQtAi&vUMquf)xFc*ywzS->W{9Gc5#~G(9rbkmBnx1>HsEAMVR+MkEQ{8BLp>rLbir zGrCS9&XgYD_t!`p9oeqL4kG72YyWz`jLr6f!IZesh8y~=80{Nt9gJqGN@@O6kj9Lc zv5gcd1xCxI{5E@$-W-c)!v1aS(MVgL6eDkvv?kP((8K7#*oWzf$r0U;dyvc6hZ(zQ zpG@0PYchFTv)7wZyDs_ln$4cljk3`iN|37^TSfn*nUt7Tjja8l6mAc+*oxXs%n;lp+B0Ju?NN%a&mjNx zQA%QOYv@ZAwTBy1qIx#6N9RXVm)WNV`Ln4R6=O?*1lLQJyvZW|tkd#HTL!IG;ff$? zK_%HvmWsrckxH~t1`Xbrs}-Zz6sjSqu?f?oo7-qboY_;%TtDcBTuC=cQU@IjWS%m1 z7|f>SXw48EVPi4Z+enfY7y8oNVG@2$=8*Bb|Yth z#wE~FX<80?P)sDQpt&yPN^GUn|6ii|e_rpkJ?_f1l28#`I0oDP{d)d+`M8MGzY({b zoVDP42V>h{^2j=f$(R9Lo&d7Uiy12EF<#m^3% zk;mAc3tNaQ3?C4lt$)Av9sZ_hKH0z`#ŹD@)<7ltOtn$SSm;LMTrPEA?sR43d= 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�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 diff --git a/v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js b/v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js deleted file mode 100644 index 297ce49b9..000000000 --- a/v3/examples/notifications/frontend/dist/assets/index-CS0sRFez.js +++ /dev/null @@ -1,6 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const s of r)if(s.type==="childList")for(const l of s.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&o(l)}).observe(document,{childList:!0,subtree:!0});function n(r){const s={};return r.integrity&&(s.integrity=r.integrity),r.referrerPolicy&&(s.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?s.credentials="include":r.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function o(r){if(r.ep)return;r.ep=!0;const s=n(r);fetch(r.href,s)}})();let L="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",O=(t=21)=>{let e="",n=t|0;for(;n--;)e+=L[Math.random()*64|0];return e};const _=window.location.origin+"/wails/runtime",h={Call:0,Events:3,ContextMenu:4,Dialog:5,Window:6,Browser:9,CancelCall:10};let k=O();function w(t,e){return function(n,o=null){return W(t,n,e,o)}}async function W(t,e,n,o){let r=new URL(_);t!=null&&r.searchParams.append("object",t),e!=null&&r.searchParams.append("method",e);let s={headers:{}};n&&(s.headers["x-wails-window-name"]=n),o&&r.searchParams.append("args",JSON.stringify(o)),s.headers["x-wails-client-id"]=k;let l=await fetch(r,s);if(!l.ok)throw new Error(await l.text());return l.headers.get("Content-Type")&&l.headers.get("Content-Type").indexOf("application/json")!==-1?l.json():l.text()}const P=(()=>{var t,e,n;try{if((t=window==null?void 0:window.chrome)!=null&&t.webview)return o=>window.chrome.webview.postMessage(o);if((n=(e=window==null?void 0:window.webkit)==null?void 0:e.messageHandlers)!=null&&n.external)return o=>window.webkit.messageHandlers.external.postMessage(o)}catch{console.warn(` -%c⚠️ Browser Environment Detected %c - -%cOnly UI previews are available in the browser. For full functionality, please run the application in desktop mode. -More information at: https://v3.wails.io/learn/build/#using-a-browser-for-development -`,"background: #ffffff; color: #000000; font-weight: bold; padding: 4px 8px; border-radius: 4px; border: 2px solid #000000;","background: transparent;","color: #ffffff; font-style: italic; font-weight: bold;")}return null})();function E(t){if(P)return P(t)}function H(){return window._wails.environment.OS==="windows"}function B(){return window._wails.environment.Debug===!0}window.addEventListener("contextmenu",Y);const U=w(h.ContextMenu,""),$=0;function Z(t,e,n,o){U($,{id:t,x:e,y:n,data:o})}function Y(t){let e=t.target,n=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu");if(n=n?n.trim():"",n){t.preventDefault();let o=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu-data");Z(n,t.clientX,t.clientY,o);return}j(t)}function j(t){if(B())return;const e=t.target;switch(window.getComputedStyle(e).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":t.preventDefault();return;default:if(e.isContentEditable)return;const r=window.getSelection(),s=r.toString().length>0;if(s)for(let l=0;lt.target.clientWidth||t.offsetY>t.target.clientHeight)return;p=!0}else p=!1}function V(){p=!1}function u(t){document.documentElement.style.cursor=t||G,S=t}function q(t){if(p&&(p=!1,(t.buttons!==void 0?t.buttons:t.which)>0)){E("wails:drag");return}if(!z||!H())return;let e=x("system.resizeHandleHeight")||5,n=x("system.resizeHandleWidth")||5,o=x("resizeCornerExtra")||10,r=window.outerWidth-t.clientXoe(type,{"call-id":e});let o=!1,r=!1,s=new Promise((l,a)=>{t["call-id"]=e,y.set(e,{resolve:l,reject:a}),ne(te,t).then(c=>{if(r=!0,o)return n()}).catch(c=>{a(c),y.delete(e)})});return s.cancel=()=>{if(r)return n();o=!0},s}function R(t,...e){return ae({methodID:t,args:e})}window._wails=window._wails||{};window._wails.dialogErrorCallback=we;window._wails.dialogResultCallback=he;const ce=2,ue=3,de=w(h.Dialog,""),f=new Map;function fe(){let t;do t=O();while(f.has(t));return t}function I(t,e={}){const n=fe();return e["dialog-id"]=n,new Promise((o,r)=>{f.set(n,{resolve:o,reject:r}),de(t,e).catch(s=>{r(s),f.delete(n)})})}function he(t,e,n){let o=f.get(t);o&&(f.delete(t),n?o.resolve(JSON.parse(e)):o.resolve(e))}function we(t,e){let n=f.get(t);n&&(f.delete(t),n.reject(new me(e)))}const me=t=>I(ce,t),ge=t=>I(ue,t);window._wails=window._wails||{};window._wails.dispatchWailsEvent=Ce;const pe=w(h.Events,""),Me=0,d=new Map;class be{constructor(e,n,o){this.eventName=e,this.maxCallbacks=o||-1,this.Callback=r=>(n(r),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}}class ye{constructor(e,n=null){this.name=e,this.data=n}}function Ce(t){let e=d.get(t.name);if(e){let n=e.filter(o=>{if(o.Callback(t))return!0});n.length>0&&(e=e.filter(o=>!n.includes(o)),e.length===0?d.delete(t.name):d.set(t.name,e))}}function Ee(t,e,n){let o=d.get(t)||[];const r=new be(t,e,n);return o.push(r),d.set(t,o),()=>Se(r)}function N(t,e){return Ee(t,e,-1)}function Se(t){const e=t.eventName;let n=d.get(e).filter(o=>o!==t);n.length===0?d.delete(e):d.set(e,n)}function ve(t){return pe(Me,t)}const Re=0,xe=1,Oe=2,Te=3,Pe=4,ze=5,De=6,Ie=7,Ne=8,Ae=9,Fe=10,Le=11,_e=12,ke=13,We=14,He=15,Be=16,Ue=17,$e=18,Ze=19,Ye=20,je=21,Ge=22,Je=23,Xe=24,Ve=25,qe=26,Ke=27,Qe=28,et=29,tt=30,nt=31,ot=32,rt=33,it=34,st=35,lt=36,at=37,ct=38,ut=39,dt=40,ft=41,ht=42,wt=43,mt=44,gt=45,pt=46,Mt=47,i=Symbol();class v{constructor(e=""){this[i]=w(h.Window,e);for(const n of Object.getOwnPropertyNames(v.prototype))n!=="constructor"&&typeof this[n]=="function"&&(this[n]=this[n].bind(this))}Get(e){return new v(e)}Position(){return this[i](Re)}Center(){return this[i](xe)}Close(){return this[i](Oe)}DisableSizeConstraints(){return this[i](Te)}EnableSizeConstraints(){return this[i](Pe)}Focus(){return this[i](ze)}ForceReload(){return this[i](De)}Fullscreen(){return this[i](Ie)}GetScreen(){return this[i](Ne)}GetZoom(){return this[i](Ae)}Height(){return this[i](Fe)}Hide(){return this[i](Le)}IsFocused(){return this[i](_e)}IsFullscreen(){return this[i](ke)}IsMaximised(){return this[i](We)}IsMinimised(){return this[i](He)}Maximise(){return this[i](Be)}Minimise(){return this[i](Ue)}Name(){return this[i]($e)}OpenDevTools(){return this[i](Ze)}RelativePosition(){return this[i](Ye)}Reload(){return this[i](je)}Resizable(){return this[i](Ge)}Restore(){return this[i](Je)}SetPosition(e,n){return this[i](Xe,{x:e,y:n})}SetAlwaysOnTop(e){return this[i](Ve,{alwaysOnTop:e})}SetBackgroundColour(e,n,o,r){return this[i](qe,{r:e,g:n,b:o,a:r})}SetFrameless(e){return this[i](Ke,{frameless:e})}SetFullscreenButtonEnabled(e){return this[i](Qe,{enabled:e})}SetMaxSize(e,n){return this[i](et,{width:e,height:n})}SetMinSize(e,n){return this[i](tt,{width:e,height:n})}SetRelativePosition(e,n){return this[i](nt,{x:e,y:n})}SetResizable(e){return this[i](ot,{resizable:e})}SetSize(e,n){return this[i](rt,{width:e,height:n})}SetTitle(e){return this[i](it,{title:e})}SetZoom(e){return this[i](st,{zoom:e})}Show(){return this[i](lt)}Size(){return this[i](at)}ToggleFullscreen(){return this[i](ct)}ToggleMaximise(){return this[i](ut)}UnFullscreen(){return this[i](dt)}UnMaximise(){return this[i](ft)}UnMinimise(){return this[i](ht)}Width(){return this[i](wt)}Zoom(){return this[i](mt)}ZoomIn(){return this[i](gt)}ZoomOut(){return this[i](pt)}ZoomReset(){return this[i](Mt)}}const bt=new v("");function yt(){if(!EventTarget||!AbortSignal||!AbortController)return!1;let t=!0;const e=new EventTarget,n=new AbortController;return e.addEventListener("test",()=>{t=!1},{signal:n.signal}),n.abort(),e.dispatchEvent(new CustomEvent("test")),t}document.addEventListener("DOMContentLoaded",()=>!0);function Ct(t,e=null){ve(new ye(t,e))}function Et(t,e){const n=bt.Get(t),o=n[e];if(typeof o!="function"){console.error(`Window method '${e}' not found`);return}try{o.call(n)}catch(r){console.error(`Error calling window method '${e}': `,r)}}function St(t){const e=t.currentTarget;function n(r="Yes"){if(r!=="Yes")return;const s=e.getAttribute("data-wml-event"),l=e.getAttribute("data-wml-target-window")||"",a=e.getAttribute("data-wml-window"),c=e.getAttribute("data-wml-openURL");s!==null&&Ct(s),a!==null&&Et(l,a),c!==null&&ee(c)}const o=e.getAttribute("data-wml-confirm");o?ge({Title:"Confirm",Message:o,Detached:!1,Buttons:[{Label:"Yes"},{Label:"No",IsDefault:!0}]}).then(n):n()}const C=Symbol();class vt{constructor(){this[C]=new AbortController}set(e,n){return{signal:this[C].signal}}reset(){this[C].abort(),this[C]=new AbortController}}const b=Symbol(),g=Symbol();class Rt{constructor(){this[b]=new WeakMap,this[g]=0}set(e,n){return this[g]+=!this[b].has(e),this[b].set(e,n),{}}reset(){if(!(this[g]<=0)){for(const e of document.body.querySelectorAll("*")){if(this[g]<=0)break;const n=this[b].get(e);this[g]-=typeof n<"u";for(const o of n||[])e.removeEventListener(o,St)}this[b]=new WeakMap,this[g]=0}}}yt()?new vt:new Rt;window._wails=window._wails||{};let A=!1;function xt(){window._wails.invoke=E,E("wails:runtime:ready"),A=!0}window.addEventListener("load",()=>{A||xt()});function Ot(t){return R(2679064664,t)}function F(){return R(3412125712)}function Tt(t,e,n,o){return R(2246903123,t,e,n,o)}function Pt(t){return R(1615199806,t)}const zt=document.getElementById("time"),Dt=document.getElementById("notifications");window.sendNotification=async()=>{await F()&&await Tt("some-uuid-fronted","Frontend Notificaiton","","Notificaiton sent through JS!")};window.sendComplexNotification=async()=>{await F()&&(await Ot({id:"FRONTEND_NOTIF",actions:[{id:"VIEW_ACTION",title:"View"},{id:"MARK_READ_ACTION",title:"Mark as Read"},{id:"DELETE_ACTION",title:"Delete",destructive:!0}],hasReplyField:!0,replyButtonTitle:"Reply",replyPlaceholder:"Reply to frontend..."}),await Pt({id:"some-uuid-complex",title:"Complex Frontend Notification",subtitle:"From: Jane Doe",body:"Is it rainging today where you are?",categoryId:"FRONTEND_NOTIF",data:{messageId:"msg-456",senderId:"user-456",timestamp:Date.now()}}))};N("time",t=>{zt.innerText=t.data});N("notificationResponse",t=>{Dt.innerText+=JSON.stringify(t.data[0].data)}); diff --git a/v3/examples/notifications/frontend/dist/index.html b/v3/examples/notifications/frontend/dist/index.html deleted file mode 100644 index 39216bd8d..000000000 --- a/v3/examples/notifications/frontend/dist/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - Wails App - - - - - - diff --git a/v3/examples/notifications/frontend/dist/javascript.svg b/v3/examples/notifications/frontend/dist/javascript.svg deleted file mode 100644 index f9abb2b72..000000000 --- a/v3/examples/notifications/frontend/dist/javascript.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/v3/examples/notifications/frontend/dist/style.css b/v3/examples/notifications/frontend/dist/style.css deleted file mode 100644 index 127799eda..000000000 --- a/v3/examples/notifications/frontend/dist/style.css +++ /dev/null @@ -1,160 +0,0 @@ -:root { - font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", - "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - font-size: 16px; - line-height: 24px; - font-weight: 400; - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: rgba(27, 38, 54, 1); - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -* { - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; -} - -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 400; - src: local(""), - url("./Inter-Medium.ttf") format("truetype"); -} - -h3 { - font-size: 3em; - line-height: 1.1; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} - -a:hover { - color: #535bf2; -} - -button { - /* width: 60px; */ - height: 30px; - line-height: 30px; - border-radius: 3px; - border: none; - margin: 0 0 0 20px; - padding: 0 8px; - cursor: pointer; -} - -.result { - height: 20px; - line-height: 20px; -} - -body { - margin: 0; - display: flex; - place-items: center; - place-content: center; - min-width: 320px; - min-height: 100vh; -} - -.container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -#app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; -} - -.logo:hover { - filter: drop-shadow(0 0 2em #e80000aa); -} - -.logo.vanilla:hover { - filter: drop-shadow(0 0 2em #f7df1eaa); -} - -.result { - height: 20px; - line-height: 20px; - margin: 1.5rem auto; - text-align: center; -} - -.footer { - margin-top: 1rem; - align-content: center; - text-align: center; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - - a:hover { - color: #747bff; - } - - button { - background-color: #f9f9f9; - } -} - - -.input-box .btn:hover { - background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); - color: #333333; -} - -.input-box .input { - border: none; - border-radius: 3px; - outline: none; - height: 30px; - line-height: 30px; - padding: 0 10px; - color: black; - background-color: rgba(240, 240, 240, 1); - -webkit-font-smoothing: antialiased; -} - -.input-box .input:hover { - border: none; - background-color: rgba(255, 255, 255, 1); -} - -.input-box .input:focus { - border: none; - background-color: rgba(255, 255, 255, 1); -} \ No newline at end of file diff --git a/v3/examples/notifications/frontend/dist/wails.png b/v3/examples/notifications/frontend/dist/wails.png deleted file mode 100644 index 8bdf424833bfb5b6b34a0807224e94533f738f2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9057 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 { const granted = await Notifications.RequestUserNotificationAuthorization(); if (granted) { - const uuid = crypto.randomUUID(); - await Notifications.SendNotification(uuid, "Frontend Notification", "", "Notification sent through JS!"); + const id = System.IsWindows() ? "Wails Notification Demo" : crypto.randomUUID() + await Notifications.SendNotification({ + id, + title: "Title", + body: "Body!", + data: { + messageId: "msg-123", + senderId: "user-123", + timestamp: Date.now(), + } + }); } } @@ -20,19 +29,18 @@ window.sendComplexNotification = async () => { actions: [ { id: "VIEW_ACTION", title: "View" }, { id: "MARK_READ_ACTION", title: "Mark as Read" }, - { id: "DELETE_ACTION", title: "Delete", destructive: true }, ], hasReplyField: true, replyButtonTitle: "Reply", replyPlaceholder: "Reply to frontend...", }); - const uuid = crypto.randomUUID(); + const id = System.IsWindows() ? "Wails Notification Demo" : crypto.randomUUID() await Notifications.SendNotificationWithActions({ - id: uuid, + id, title: "Complex Frontend Notification", subtitle: "From: Jane Doe", - body: "Is it raining today where you are?", + body: "Is it rainging today where you are?", categoryId: "FRONTEND_NOTIF", data: { messageId: "msg-456", @@ -48,5 +56,6 @@ Events.On('time', (time) => { }); Events.On("notificationResponse", (response) => { + console.log(response) notificationsElement.innerText += JSON.stringify(response.data[0].data); }); \ No newline at end of file diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index 8c2e941df..d69bf3f93 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -9,18 +9,29 @@ import ( "time" "github.com/wailsapp/wails/v3/pkg/application" - "github.com/wailsapp/wails/v3/pkg/events" "github.com/wailsapp/wails/v3/pkg/services/notifications" ) +// Wails uses Go's `embed` package to embed the frontend files into the binary. +// Any files in the frontend/dist folder will be embedded into the binary and +// made available to the frontend. +// See https://pkg.go.dev/embed for more information. + //go:embed all:frontend/dist var assets embed.FS +// main function serves as the application's entry point. It initializes the application, creates a window, +// and starts a goroutine that emits a time-based event every second. It subsequently runs the application and +// logs any error that might occur. func main() { NotificationService := notifications.New() - + // Create a new Wails application by providing the necessary options. + // Variables 'Name' and 'Description' are for application metadata. + // 'Assets' configures the asset server with the 'FS' variable pointing to the frontend files. + // 'Bind' is a list of Go struct instances. The frontend has access to the methods of these instances. + // 'Mac' options tailor the application when running an macOS. app := application.New(application.Options{ - Name: "notifications", + Name: "notifications_demo", Description: "A demo of using raw HTML & CSS", Services: []application.Service{ application.NewService(NotificationService), @@ -33,6 +44,11 @@ func main() { }, }) + // Create a new window with the necessary options. + // 'Title' is the title of the window. + // 'Mac' options tailor the window when running on macOS. + // 'BackgroundColour' is the background colour of the window. + // 'URL' is the URL that will be loaded into the webview. app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Window 1", Mac: application.MacWindow{ @@ -44,85 +60,52 @@ func main() { URL: "/", }) - app.OnApplicationEvent(events.Mac.ApplicationDidFinishLaunching, func(event *application.ApplicationEvent) { - // Request pemission to send notifications - granted, err := NotificationService.RequestUserNotificationAuthorization() - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } - - if granted { - // Send notification with no actions - err = NotificationService.SendNotification("some-uuid", "Title", "", "body!") - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } - - err = NotificationService.RegisterNotificationCategory(notifications.NotificationCategory{ - ID: "MESSAGE_CATEGORY", - Actions: []notifications.NotificationAction{ - {ID: "VIEW_ACTION", Title: "View"}, - {ID: "MARK_READ_ACTION", Title: "Mark as Read"}, - {ID: "DELETE_ACTION", Title: "Delete", Destructive: true}, - }, - HasReplyField: true, - ReplyPlaceholder: "Type your reply...", - ReplyButtonTitle: "Reply", - }) - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } - - err = NotificationService.SendNotificationWithActions(notifications.NotificationOptions{ - ID: "some-other-uuid", - Title: "New Message", - Subtitle: "From: Jane Doe", - Body: "Is it raining today where you are?", - CategoryID: "MESSAGE_CATEGORY", - Data: map[string]interface{}{ - "messageId": "msg-123", - "senderId": "user-123", - "timestamp": time.Now().Unix(), - }, - }) - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } - } - }) - - app.OnEvent("notificationResponse", func(event *application.CustomEvent) { - data, _ := json.Marshal(event.Data) - fmt.Printf("%s\n", string(data)) - }) - go func() { - time.Sleep(time.Second * 5) - // Sometime later check if you are still authorized - granted, err := NotificationService.CheckNotificationAuthorization() - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } - println(granted) + app.OnEvent("notificationResponse", func(event *application.CustomEvent) { + data, _ := json.Marshal(event.Data) + fmt.Printf("%s\n", string(data)) + }) - // Sometime later remove delivered notification by identifier - err = NotificationService.RemoveDeliveredNotification("some-uuid") - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } - }() + NotificationService.RequestUserNotificationAuthorization() + NotificationService.CheckNotificationAuthorization() - go func() { - time.Sleep(time.Second * 10) - // Sometime later remove all pending and delivered notifications - err := NotificationService.RemoveAllPendingNotifications() - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } - err = NotificationService.RemoveAllDeliveredNotifications() - if err != nil { - log.Default().Printf("WARNING: %s\n", err) - } + time.Sleep(time.Second * 2) + NotificationService.SendNotification(notifications.NotificationOptions{ + ID: "Wails Notification Demo", + Title: "Title!", + Body: "Body!", + Data: map[string]interface{}{ + "messageId": "msg-123", + "senderId": "user-123", + "timestamp": time.Now().String(), + }, + }) + + time.Sleep(time.Second * 2) + NotificationService.RegisterNotificationCategory(notifications.NotificationCategory{ + ID: "BACKEND_NOTIF", + Actions: []notifications.NotificationAction{ + {ID: "VIEW_ACTION", Title: "View"}, + {ID: "MARK_READ_ACTION", Title: "Mark as Read"}, + {ID: "DELETE_ACTION", Title: "Delete", Destructive: true}, + }, + HasReplyField: true, + ReplyButtonTitle: "Reply", + ReplyPlaceholder: "Reply to backend...", + }) + + NotificationService.SendNotificationWithActions(notifications.NotificationOptions{ + ID: "Wails Notification Demo", + Title: "Complex Backend Notification", + Subtitle: "Should not show on Windows", + Body: "Is it raining today where you are?", + CategoryID: "BACKEND_NOTIF", + Data: map[string]interface{}{ + "messageId": "msg-456", + "senderId": "user-456", + "timestamp": time.Now().String(), + }, + }) }() // Run the application. This blocks until the application has been exited. From c904433ff345677026f326cacbf77d25e51824a5 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sun, 23 Feb 2025 16:30:13 -0800 Subject: [PATCH 021/136] update example --- v3/examples/notifications/frontend/main.js | 5 -- v3/examples/notifications/main.go | 99 +++++++++++++--------- 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js index 9f1ac1d69..79fc8dcca 100644 --- a/v3/examples/notifications/frontend/main.js +++ b/v3/examples/notifications/frontend/main.js @@ -1,7 +1,6 @@ import * as Notifications from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service"; import { Events, System } from "@wailsio/runtime"; -const timeElement = document.getElementById('time'); const notificationsElement = document.getElementById('notifications'); window.sendNotification = async () => { @@ -51,10 +50,6 @@ window.sendComplexNotification = async () => { } } -Events.On('time', (time) => { - timeElement.innerText = time.data; -}); - Events.On("notificationResponse", (response) => { console.log(response) notificationsElement.innerText += JSON.stringify(response.data[0].data); diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index d69bf3f93..dc9fec9c9 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -60,52 +60,69 @@ func main() { URL: "/", }) + app.OnEvent("notificationResponse", func(event *application.CustomEvent) { + data, _ := json.Marshal(event.Data) + fmt.Printf("%s\n", string(data)) + }) + go func() { - app.OnEvent("notificationResponse", func(event *application.CustomEvent) { - data, _ := json.Marshal(event.Data) - fmt.Printf("%s\n", string(data)) - }) + granted, err := NotificationService.RequestUserNotificationAuthorization() + if err != nil { + log.Default().Printf("WARNING: %s\n", err) + return + } - NotificationService.RequestUserNotificationAuthorization() - NotificationService.CheckNotificationAuthorization() + if granted { + time.Sleep(time.Second * 2) - time.Sleep(time.Second * 2) - NotificationService.SendNotification(notifications.NotificationOptions{ - ID: "Wails Notification Demo", - Title: "Title!", - Body: "Body!", - Data: map[string]interface{}{ - "messageId": "msg-123", - "senderId": "user-123", - "timestamp": time.Now().String(), - }, - }) + var uuid1 string = "Wails Notification Demo" + if application.Get().Environment().OS == "darwin" { + uuid1 = "uuid1" + } - time.Sleep(time.Second * 2) - NotificationService.RegisterNotificationCategory(notifications.NotificationCategory{ - ID: "BACKEND_NOTIF", - Actions: []notifications.NotificationAction{ - {ID: "VIEW_ACTION", Title: "View"}, - {ID: "MARK_READ_ACTION", Title: "Mark as Read"}, - {ID: "DELETE_ACTION", Title: "Delete", Destructive: true}, - }, - HasReplyField: true, - ReplyButtonTitle: "Reply", - ReplyPlaceholder: "Reply to backend...", - }) + NotificationService.SendNotification(notifications.NotificationOptions{ + ID: uuid1, + Title: "Title!", + Body: "Body!", + Data: map[string]interface{}{ + "messageId": "msg-123", + "senderId": "user-123", + "timestamp": time.Now().String(), + }, + }) - NotificationService.SendNotificationWithActions(notifications.NotificationOptions{ - ID: "Wails Notification Demo", - Title: "Complex Backend Notification", - Subtitle: "Should not show on Windows", - Body: "Is it raining today where you are?", - CategoryID: "BACKEND_NOTIF", - Data: map[string]interface{}{ - "messageId": "msg-456", - "senderId": "user-456", - "timestamp": time.Now().String(), - }, - }) + time.Sleep(time.Second * 2) + + var uuid2 string = "Wails Notification Demo" + if application.Get().Environment().OS == "darwin" { + uuid2 = "uuid2" + } + + NotificationService.RegisterNotificationCategory(notifications.NotificationCategory{ + ID: "BACKEND_NOTIF", + Actions: []notifications.NotificationAction{ + {ID: "VIEW_ACTION", Title: "View"}, + {ID: "MARK_READ_ACTION", Title: "Mark as Read"}, + {ID: "DELETE_ACTION", Title: "Delete", Destructive: true}, + }, + HasReplyField: true, + ReplyButtonTitle: "Reply", + ReplyPlaceholder: "Reply to backend...", + }) + + NotificationService.SendNotificationWithActions(notifications.NotificationOptions{ + ID: uuid2, + Title: "Complex Backend Notification", + Subtitle: "Should not show on Windows", + Body: "Is it raining today where you are?", + CategoryID: "BACKEND_NOTIF", + Data: map[string]interface{}{ + "messageId": "msg-456", + "senderId": "user-456", + "timestamp": time.Now().String(), + }, + }) + } }() // Run the application. This blocks until the application has been exited. From 983c25f69fe0e989ab87bcefe3129690a4788a54 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 21:59:27 -0800 Subject: [PATCH 022/136] rw safety --- .../notifications/notifications_windows.go | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 078a3cb08..56e939cd3 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -9,13 +9,15 @@ import ( "os" "path/filepath" "strings" + "sync" "git.sr.ht/~jackmordaunt/go-toast" "github.com/wailsapp/wails/v3/pkg/application" "golang.org/x/sys/windows/registry" ) -var NotificationCategories map[string]NotificationCategory = make(map[string]NotificationCategory) +var NotificationLock sync.RWMutex +var NotificationCategories = make(map[string]NotificationCategory) const ( defaultAction = "defaultActionIdentifier" @@ -57,6 +59,9 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi application.Get().EmitEvent("notificationResponse", response) }) + + NotificationLock.Lock() + defer NotificationLock.Unlock() return loadCategoriesFromRegistry() } @@ -112,7 +117,9 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // If a NotificationCategory is not registered a basic notification will be sent. // (subtitle, category id, and data are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + NotificationLock.RLock() nCategory := NotificationCategories[options.CategoryID] + NotificationLock.RUnlock() n := toast.Notification{ AppID: options.ID, @@ -160,6 +167,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { + NotificationLock.Lock() NotificationCategories[category.ID] = NotificationCategory{ ID: category.ID, Actions: category.Actions, @@ -167,13 +175,17 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e ReplyPlaceholder: category.ReplyPlaceholder, ReplyButtonTitle: category.ReplyButtonTitle, } + NotificationLock.Unlock() return saveCategoriesToRegistry() } // RemoveNotificationCategory removes a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { + NotificationLock.Lock() delete(NotificationCategories, categoryId) + NotificationLock.Unlock() + return saveCategoriesToRegistry() } @@ -236,7 +248,9 @@ func saveCategoriesToRegistry() error { } defer key.Close() + NotificationLock.RLock() data, err := json.Marshal(NotificationCategories) + NotificationLock.RUnlock() if err != nil { return err } @@ -269,7 +283,16 @@ func loadCategoriesFromRegistry() error { return err } - return json.Unmarshal([]byte(data), &NotificationCategories) + categories := make(map[string]NotificationCategory) + if err := json.Unmarshal([]byte(data), &categories); err != nil { + return err + } + + NotificationLock.Lock() + NotificationCategories = categories + NotificationLock.Unlock() + + return nil } func getUserText(data []toast.UserData) (string, bool) { From 1e3511c0d3127faf0def240a1bbdf64eaa8b286d Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 22:18:07 -0800 Subject: [PATCH 023/136] fix deadlock --- v3/pkg/services/notifications/notifications_windows.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 56e939cd3..23a2f787e 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -60,8 +60,6 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi application.Get().EmitEvent("notificationResponse", response) }) - NotificationLock.Lock() - defer NotificationLock.Unlock() return loadCategoriesFromRegistry() } From 3dbf0589ce497ea17011ed3cd291b8faf0e45ade Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Sun, 23 Feb 2025 22:25:12 -0800 Subject: [PATCH 024/136] update comments --- v3/pkg/services/notifications/notifications_windows.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 23a2f787e..0dfb1a367 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -87,7 +87,7 @@ func (ns *Service) CheckNotificationAuthorization() bool { } // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. -// (subtitle, category id, and data are only available on macOS) +// (subtitle and category id are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { n := toast.Notification{ AppID: options.ID, @@ -113,7 +113,7 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // SendNotificationWithActions sends a notification with additional actions and inputs. // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. -// (subtitle, category id, and data are only available on macOS) +// (subtitle and category id are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { NotificationLock.RLock() nCategory := NotificationCategories[options.CategoryID] @@ -164,6 +164,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. +// Registering a category with the same name as a previously registered NotificationCategory will override it. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { NotificationLock.Lock() NotificationCategories[category.ID] = NotificationCategory{ From be716fc0ee580445178a4d6dda87b26840b7cc95 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Mon, 24 Feb 2025 16:47:19 -0800 Subject: [PATCH 025/136] fix input id --- v3/go.mod | 2 +- v3/go.sum | 4 ++-- .../services/notifications/notifications_windows.go | 13 ++++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/v3/go.mod b/v3/go.mod index fd4383baa..cf9dd83c7 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -3,7 +3,7 @@ module github.com/wailsapp/wails/v3 go 1.24.0 require ( - git.sr.ht/~jackmordaunt/go-toast v1.1.2 + git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 github.com/Masterminds/semver v1.5.0 github.com/adrg/xdg v0.5.3 github.com/atterpac/refresh v0.8.4 diff --git a/v3/go.sum b/v3/go.sum index faf9d7aff..052246286 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -8,8 +8,8 @@ atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -git.sr.ht/~jackmordaunt/go-toast v1.1.2 h1:/yrfI55LRt1M7H1vkaw+NaH1+L1CDxrqDltwm5euVuE= -git.sr.ht/~jackmordaunt/go-toast v1.1.2/go.mod h1:jA4OqHKTQ4AFBdwrSnwnskUIIS3HYzlJSgdzCKqfavo= +git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 h1:N3IGoHHp9pb6mj1cbXbuaSXV/UMKwmbKLf53nQmtqMA= +git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3/go.mod h1:QtOLZGz8olr4qH2vWK0QH0w0O4T9fEIjMuWpKUsH7nc= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 0dfb1a367..2496b7669 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - "git.sr.ht/~jackmordaunt/go-toast" + "git.sr.ht/~jackmordaunt/go-toast/v2" "github.com/wailsapp/wails/v3/pkg/application" "golang.org/x/sys/windows/registry" ) @@ -36,7 +36,15 @@ func (ns *Service) ServiceName() string { // ServiceStartup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + toast.SetAppData(toast.AppData{ + AppID: "Notifications", + GUID: "{8F2E1A3D-C497-42B6-9E5D-72F8A169B051}", + IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", + ActivationExe: "C:\\Users\\Zach\\Development\\notifications_demo\\bin\\Notifications.exe", + }) + toast.SetActivationCallback(func(args string, data []toast.UserData) { + println("HERE!") actionIdentifier, userInfo := parseNotificationResponse(args) response := NotificationResponse{ Name: "notification", @@ -94,6 +102,7 @@ func (ns *Service) SendNotification(options NotificationOptions) error { Title: options.Title, Body: options.Body, ActivationArguments: defaultAction, + Audio: toast.IM, } if options.Data != nil { @@ -124,6 +133,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro Title: options.Title, Body: options.Body, ActivationArguments: defaultAction, + Audio: toast.IM, } for _, action := range nCategory.Actions { @@ -143,6 +153,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro n.Actions = append(n.Actions, toast.Action{ Content: nCategory.ReplyButtonTitle, Arguments: "TEXT_REPLY", + InputID: "userText", }) } From 8da998191a8fa99d3e104c325c8ee2c9d34e3bd1 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Mon, 24 Feb 2025 17:58:05 -0800 Subject: [PATCH 026/136] for review --- .../notifications/notifications_windows.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 2496b7669..977ddae40 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -36,15 +36,17 @@ func (ns *Service) ServiceName() string { // ServiceStartup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - toast.SetAppData(toast.AppData{ - AppID: "Notifications", - GUID: "{8F2E1A3D-C497-42B6-9E5D-72F8A169B051}", - IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", - ActivationExe: "C:\\Users\\Zach\\Development\\notifications_demo\\bin\\Notifications.exe", - }) + // Need to get App Name and generate a UUID on first launch + // + // toast.SetAppData(toast.AppData{ + // AppID: "Notifications", + // GUID: "{8F2E1A3D-C497-42B6-9E5D-72F8A169B051}", + // IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", + // ActivationExe: "C:\\Users\\Zach\\Development\\notifications_demo\\bin\\Notifications.exe", + // }) + // toast.SetActivationCallback(func(args string, data []toast.UserData) { - println("HERE!") actionIdentifier, userInfo := parseNotificationResponse(args) response := NotificationResponse{ Name: "notification", From e8ad42aa3f666865163bdeddcf1159b5f846a727 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Feb 2025 21:54:38 -0800 Subject: [PATCH 027/136] switch to callback style --- .../services/notifications/notifications.go | 35 +++++++++++++------ .../notifications/notifications_darwin.go | 25 +++++++++---- .../notifications/notifications_darwin.m | 2 -- .../notifications/notifications_windows.go | 28 ++++++++------- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 57715b11e..78bd6e120 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -1,14 +1,16 @@ package notifications +// Service represents the notifications service type Service struct { + // responseCallback is called when a notification response is received + Callback func(response NotificationResponse) } // NotificationAction represents an action button for a notification type NotificationAction = struct { - ID string `json:"id,omitempty"` - Title string `json:"title,omitempty"` - Destructive bool `json:"destructive,omitempty"` - AuthenticationRequired bool `json:"authenticationRequired,omitempty"` + ID string `json:"id,omitempty"` + Title string `json:"title,omitempty"` + Destructive bool `json:"destructive,omitempty"` // macOS only } // NotificationCategory groups actions for notifications @@ -30,8 +32,10 @@ type NotificationOptions = struct { Data map[string]interface{} `json:"data,omitempty"` } -// NotificationResponseData -type NotificationResponseData = struct { +var DefaultActionIdentifier = "DEFAULT_ACTION" + +// NotificationResponse represents a user's response to a notification +type NotificationResponse = struct { ID string `json:"id,omitempty"` ActionIdentifier string `json:"actionIdentifier,omitempty"` CategoryID string `json:"categoryIdentifier,omitempty"` @@ -42,8 +46,19 @@ type NotificationResponseData = struct { UserInfo map[string]interface{} `json:"userInfo,omitempty"` } -// NotificationResponse -type NotificationResponse = struct { - Name string `json:"name"` - Data NotificationResponseData `json:"data"` +// OnNotificationResponse registers a callback function that will be called when +// a notification response is received from the user +func (ns *Service) OnNotificationResponse(callback func(response NotificationResponse)) { + if ns.Callback != nil { + return + } + ns.Callback = callback +} + +// handleNotificationResponse is an internal method to handle notification responses +// and invoke the registered callback if one exists +func (ns *Service) handleNotificationResponse(response NotificationResponse) { + if ns.Callback != nil { + ns.Callback(response) + } } diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index b95d93078..34e49e079 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -17,10 +17,16 @@ import ( "github.com/wailsapp/wails/v3/pkg/application" ) +var NotificationService *Service +var AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" + // Creates a new Notifications Service. // Your app must be packaged and signed for this feature to work. func New() *Service { - return &Service{} + if NotificationService == nil { + NotificationService = &Service{} + } + return NotificationService } // ServiceName returns the name of the service. @@ -201,17 +207,24 @@ func (ns *Service) RemoveDeliveredNotification(identifier string) error { return nil } +func (ns *Service) forwardResponse(response NotificationResponse) { + if NotificationService != nil { + NotificationService.handleNotificationResponse(response) + } +} + //export didReceiveNotificationResponse func didReceiveNotificationResponse(jsonPayload *C.char) { payload := C.GoString(jsonPayload) - var response NotificationResponseData + var response NotificationResponse if err := json.Unmarshal([]byte(payload), &response); err != nil { return } - application.Get().EmitEvent("notificationResponse", NotificationResponse{ - Name: "notification", - Data: response, - }) + if response.ActionIdentifier == AppleDefaultActionIdentifier { + response.ActionIdentifier = DefaultActionIdentifier + } + + NotificationService.forwardResponse(response) } diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 3c3fe4978..3a52bd34b 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -233,12 +233,10 @@ void registerNotificationCategory(const char *categoryId, const char *actions_js NSString *actionId = actionDict[@"id"]; NSString *actionTitle = actionDict[@"title"]; BOOL destructive = [actionDict[@"destructive"] boolValue]; - BOOL authRequired = [actionDict[@"authenticationRequired"] boolValue]; if (actionId && actionTitle) { UNNotificationActionOptions options = UNNotificationActionOptionNone; if (destructive) options |= UNNotificationActionOptionDestructive; - if (authRequired) options |= UNNotificationActionOptionAuthenticationRequired; UNNotificationAction *action = [UNNotificationAction actionWithIdentifier:actionId diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 977ddae40..6a266bbee 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -16,16 +16,19 @@ import ( "golang.org/x/sys/windows/registry" ) +var NotificationService *Service var NotificationLock sync.RWMutex var NotificationCategories = make(map[string]NotificationCategory) const ( - defaultAction = "defaultActionIdentifier" dataSeparator = ":::" ) func New() *Service { - return &Service{} + if NotificationService == nil { + NotificationService = &Service{} + } + return NotificationService } // ServiceName returns the name of the service @@ -49,25 +52,24 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi toast.SetActivationCallback(func(args string, data []toast.UserData) { actionIdentifier, userInfo := parseNotificationResponse(args) response := NotificationResponse{ - Name: "notification", - Data: NotificationResponseData{ - ActionIdentifier: actionIdentifier, - }, + ActionIdentifier: actionIdentifier, } if userInfo != "" { jsonStr := strings.ReplaceAll(userInfo, "'", "\"") var userInfoMap map[string]interface{} if err := json.Unmarshal([]byte(jsonStr), &userInfoMap); err == nil { - response.Data.UserInfo = userInfoMap + response.UserInfo = userInfoMap } } if userText, found := getUserText(data); found { - response.Data.UserText = userText + response.UserText = userText } - application.Get().EmitEvent("notificationResponse", response) + if NotificationService != nil { + NotificationService.handleNotificationResponse(response) + } }) return loadCategoriesFromRegistry() @@ -103,14 +105,14 @@ func (ns *Service) SendNotification(options NotificationOptions) error { AppID: options.ID, Title: options.Title, Body: options.Body, - ActivationArguments: defaultAction, + ActivationArguments: DefaultActionIdentifier, Audio: toast.IM, } if options.Data != nil { jsonData, err := json.Marshal(options.Data) if err == nil { - n.ActivationArguments = defaultAction + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") + n.ActivationArguments = DefaultActionIdentifier + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") } } @@ -134,7 +136,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro AppID: options.ID, Title: options.Title, Body: options.Body, - ActivationArguments: defaultAction, + ActivationArguments: DefaultActionIdentifier, Audio: toast.IM, } @@ -162,7 +164,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro if options.Data != nil { jsonData, err := json.Marshal(options.Data) if err == nil { - n.ActivationArguments = defaultAction + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") + n.ActivationArguments = DefaultActionIdentifier + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") for index := range n.Actions { n.Actions[index].Arguments = n.Actions[index].Arguments + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") } From 67adc452cbb898b4fdb30910542a4fd10f7c763b Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Feb 2025 22:00:58 -0800 Subject: [PATCH 028/136] update example --- .../v3/pkg/services/notifications/models.js | 3 +- .../v3/pkg/services/notifications/service.js | 53 +++++++++++-------- v3/examples/notifications/frontend/index.html | 2 +- v3/examples/notifications/frontend/main.js | 5 +- v3/examples/notifications/main.go | 43 +++++---------- 5 files changed, 47 insertions(+), 59 deletions(-) diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js index 958e7d79c..c52cbf1c2 100644 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js @@ -11,8 +11,7 @@ import {Create as $Create} from "@wailsio/runtime"; * @typedef {Object} NotificationAction * @property {string} [id] * @property {string} [title] - * @property {boolean} [destructive] - * @property {boolean} [authenticationRequired] + * @property {boolean} [destructive] - macOS only */ /** diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js index 85da85975..ef81ee81a 100644 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js @@ -2,6 +2,11 @@ // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // This file is automatically generated. DO NOT EDIT +/** + * Service represents the notifications service + * @module + */ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unused imports import {Call as $Call, Create as $Create} from "@wailsio/runtime"; @@ -11,8 +16,7 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime"; import * as $models from "./models.js"; /** - * CheckNotificationAuthorization is a Windows stub that always returns true. - * (user authorization is macOS-specific) + * CheckNotificationAuthorization checks current notification permission status. * @returns {Promise & { cancel(): void }} */ export function CheckNotificationAuthorization() { @@ -20,8 +24,20 @@ export function CheckNotificationAuthorization() { return $resultPromise; } +/** + * OnNotificationResponse registers a callback function that will be called when + * a notification response is received from the user + * @param {any} callback + * @returns {Promise & { cancel(): void }} + */ +export function OnNotificationResponse(callback) { + let $resultPromise = /** @type {any} */($Call.ByID(2829398511, callback)); + return $resultPromise; +} + /** * RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. + * Registering a category with the same name as a previously registered NotificationCategory will override it. * @param {$models.NotificationCategory} category * @returns {Promise & { cancel(): void }} */ @@ -31,8 +47,7 @@ export function RegisterNotificationCategory(category) { } /** - * RemoveAllDeliveredNotifications is a Windows stub that always returns nil. - * (macOS-specific) + * RemoveAllDeliveredNotifications removes all delivered notifications. * @returns {Promise & { cancel(): void }} */ export function RemoveAllDeliveredNotifications() { @@ -41,8 +56,7 @@ export function RemoveAllDeliveredNotifications() { } /** - * RemoveAllPendingNotifications is a Windows stub that always returns nil. - * (macOS-specific) + * RemoveAllPendingNotifications removes all pending notifications. * @returns {Promise & { cancel(): void }} */ export function RemoveAllPendingNotifications() { @@ -51,18 +65,17 @@ export function RemoveAllPendingNotifications() { } /** - * RemoveDeliveredNotification is a Windows stub that always returns nil. - * (macOS-specific) - * @param {string} $0 + * RemoveDeliveredNotification removes a delivered notification matching the unique identifier. + * @param {string} identifier * @returns {Promise & { cancel(): void }} */ -export function RemoveDeliveredNotification($0) { - let $resultPromise = /** @type {any} */($Call.ByID(149440045, $0)); +export function RemoveDeliveredNotification(identifier) { + let $resultPromise = /** @type {any} */($Call.ByID(149440045, identifier)); return $resultPromise; } /** - * RemoveNotificationCategory removes a previously registered NotificationCategory. + * RemoveNotificationCategory remove a previously registered NotificationCategory. * @param {string} categoryId * @returns {Promise & { cancel(): void }} */ @@ -72,19 +85,17 @@ export function RemoveNotificationCategory(categoryId) { } /** - * RemovePendingNotification is a Windows stub that always returns nil. - * (macOS-specific) - * @param {string} $0 + * RemovePendingNotification removes a pending notification matching the unique identifier. + * @param {string} identifier * @returns {Promise & { cancel(): void }} */ -export function RemovePendingNotification($0) { - let $resultPromise = /** @type {any} */($Call.ByID(3872412470, $0)); +export function RemovePendingNotification(identifier) { + let $resultPromise = /** @type {any} */($Call.ByID(3872412470, identifier)); return $resultPromise; } /** - * RequestUserNotificationAuthorization is a Windows stub that always returns true, nil. - * (user authorization is macOS-specific) + * RequestUserNotificationAuthorization requests permission for notifications. * @returns {Promise & { cancel(): void }} */ export function RequestUserNotificationAuthorization() { @@ -93,8 +104,7 @@ export function RequestUserNotificationAuthorization() { } /** - * SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. - * (subtitle, category id, and data are only available on macOS) + * SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ @@ -107,7 +117,6 @@ export function SendNotification(options) { * SendNotificationWithActions sends a notification with additional actions and inputs. * A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. * If a NotificationCategory is not registered a basic notification will be sent. - * (subtitle, category id, and data are only available on macOS) * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ diff --git a/v3/examples/notifications/frontend/index.html b/v3/examples/notifications/frontend/index.html index bde7d3124..3c0d45f85 100644 --- a/v3/examples/notifications/frontend/index.html +++ b/v3/examples/notifications/frontend/index.html @@ -21,7 +21,7 @@ diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js index 79fc8dcca..64624f34b 100644 --- a/v3/examples/notifications/frontend/main.js +++ b/v3/examples/notifications/frontend/main.js @@ -50,7 +50,6 @@ window.sendComplexNotification = async () => { } } -Events.On("notificationResponse", (response) => { - console.log(response) - notificationsElement.innerText += JSON.stringify(response.data[0].data); +Events.On("notification:response", (response) => { + notificationsElement.innerText = JSON.stringify(response.data[0]); }); \ No newline at end of file diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index dc9fec9c9..a1d34dd5e 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -12,29 +12,17 @@ import ( "github.com/wailsapp/wails/v3/pkg/services/notifications" ) -// Wails uses Go's `embed` package to embed the frontend files into the binary. -// Any files in the frontend/dist folder will be embedded into the binary and -// made available to the frontend. -// See https://pkg.go.dev/embed for more information. - //go:embed all:frontend/dist var assets embed.FS -// main function serves as the application's entry point. It initializes the application, creates a window, -// and starts a goroutine that emits a time-based event every second. It subsequently runs the application and -// logs any error that might occur. func main() { - NotificationService := notifications.New() - // Create a new Wails application by providing the necessary options. - // Variables 'Name' and 'Description' are for application metadata. - // 'Assets' configures the asset server with the 'FS' variable pointing to the frontend files. - // 'Bind' is a list of Go struct instances. The frontend has access to the methods of these instances. - // 'Mac' options tailor the application when running an macOS. + notificationService := notifications.New() + app := application.New(application.Options{ Name: "notifications_demo", Description: "A demo of using raw HTML & CSS", Services: []application.Service{ - application.NewService(NotificationService), + application.NewService(notificationService), }, Assets: application.AssetOptions{ Handler: application.AssetFileServerFS(assets), @@ -44,11 +32,6 @@ func main() { }, }) - // Create a new window with the necessary options. - // 'Title' is the title of the window. - // 'Mac' options tailor the window when running on macOS. - // 'BackgroundColour' is the background colour of the window. - // 'URL' is the URL that will be loaded into the webview. app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Window 1", Mac: application.MacWindow{ @@ -60,19 +43,19 @@ func main() { URL: "/", }) - app.OnEvent("notificationResponse", func(event *application.CustomEvent) { - data, _ := json.Marshal(event.Data) - fmt.Printf("%s\n", string(data)) - }) - go func() { - granted, err := NotificationService.RequestUserNotificationAuthorization() + granted, err := notificationService.RequestUserNotificationAuthorization() if err != nil { log.Default().Printf("WARNING: %s\n", err) return } if granted { + notificationService.OnNotificationResponse(func(response notifications.NotificationResponse) { + data, _ := json.Marshal(response) + fmt.Printf("%s\n", string(data)) + app.EmitEvent("notification:response", response) + }) time.Sleep(time.Second * 2) var uuid1 string = "Wails Notification Demo" @@ -80,7 +63,7 @@ func main() { uuid1 = "uuid1" } - NotificationService.SendNotification(notifications.NotificationOptions{ + notificationService.SendNotification(notifications.NotificationOptions{ ID: uuid1, Title: "Title!", Body: "Body!", @@ -98,7 +81,7 @@ func main() { uuid2 = "uuid2" } - NotificationService.RegisterNotificationCategory(notifications.NotificationCategory{ + notificationService.RegisterNotificationCategory(notifications.NotificationCategory{ ID: "BACKEND_NOTIF", Actions: []notifications.NotificationAction{ {ID: "VIEW_ACTION", Title: "View"}, @@ -110,7 +93,7 @@ func main() { ReplyPlaceholder: "Reply to backend...", }) - NotificationService.SendNotificationWithActions(notifications.NotificationOptions{ + notificationService.SendNotificationWithActions(notifications.NotificationOptions{ ID: uuid2, Title: "Complex Backend Notification", Subtitle: "Should not show on Windows", @@ -125,10 +108,8 @@ func main() { } }() - // Run the application. This blocks until the application has been exited. err := app.Run() - // If an error occurred while running the application, log it and exit. if err != nil { log.Fatal(err) } From 253f67243afe4bb9eecef573f89484576d224dc7 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Feb 2025 22:39:50 -0800 Subject: [PATCH 029/136] init linux --- v3/go.mod | 1 + v3/go.sum | 2 + .../services/notifications/notifications.go | 5 + .../notifications/notifications_darwin.go | 24 ++-- .../notifications/notifications_linux.go | 103 ++++++++++++++++++ .../notifications/notifications_windows.go | 12 +- 6 files changed, 131 insertions(+), 16 deletions(-) create mode 100644 v3/pkg/services/notifications/notifications_linux.go diff --git a/v3/go.mod b/v3/go.mod index cf9dd83c7..83799de5a 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -46,6 +46,7 @@ require ( require ( atomicgo.dev/schedule v0.1.0 // indirect + git.sr.ht/~whereswaldon/shout v0.0.0-20241212204820-26acea6b0007 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect ) diff --git a/v3/go.sum b/v3/go.sum index 052246286..16a7c6db4 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -10,6 +10,8 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 h1:N3IGoHHp9pb6mj1cbXbuaSXV/UMKwmbKLf53nQmtqMA= git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3/go.mod h1:QtOLZGz8olr4qH2vWK0QH0w0O4T9fEIjMuWpKUsH7nc= +git.sr.ht/~whereswaldon/shout v0.0.0-20241212204820-26acea6b0007 h1:5xMwYHPm3ym1ccRmVmUEj4hiESj5uqXMYPwG+1Ruf28= +git.sr.ht/~whereswaldon/shout v0.0.0-20241212204820-26acea6b0007/go.mod h1:VJjhIIJD+YFIyJSH6nCDqoo9ikvAEaD63tUo4uI86pA= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 78bd6e120..c53f77ba3 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -46,6 +46,11 @@ type NotificationResponse = struct { UserInfo map[string]interface{} `json:"userInfo,omitempty"` } +// ServiceName returns the name of the service. +func (ns *Service) ServiceName() string { + return "github.com/wailsapp/wails/v3/services/notifications" +} + // OnNotificationResponse registers a callback function that will be called when // a notification response is received from the user func (ns *Service) OnNotificationResponse(callback func(response NotificationResponse)) { diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 34e49e079..2197e6741 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -29,11 +29,6 @@ func New() *Service { return NotificationService } -// ServiceName returns the name of the service. -func (ns *Service) ServiceName() string { - return "github.com/wailsapp/wails/v3/services/notifications" -} - // ServiceStartup is called when the service is loaded. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { if !CheckBundleIdentifier() { @@ -207,10 +202,15 @@ func (ns *Service) RemoveDeliveredNotification(identifier string) error { return nil } -func (ns *Service) forwardResponse(response NotificationResponse) { - if NotificationService != nil { - NotificationService.handleNotificationResponse(response) - } +// RemoveNotification is a macOS stub that always returns nil. +// Use one of the following instead: +// RemoveAllPendingNotifications +// RemovePendingNotification +// RemoveAllDeliveredNotifications +// RemoveDeliveredNotification +// (Linux-specific) +func (ns *Service) RemoveNotification(identifier string) error { + return nil } //export didReceiveNotificationResponse @@ -222,9 +222,11 @@ func didReceiveNotificationResponse(jsonPayload *C.char) { return } - if response.ActionIdentifier == AppleDefaultActionIdentifier { + if response.ActionIdentifier == "com.apple.UNNotificationDefaultActionIdentifier" { response.ActionIdentifier = DefaultActionIdentifier } - NotificationService.forwardResponse(response) + if NotificationService != nil { + NotificationService.handleNotificationResponse(response) + } } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go new file mode 100644 index 000000000..b499d4788 --- /dev/null +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -0,0 +1,103 @@ +//go:build linux + +package notifications + +import ( + "context" + + "git.sr.ht/~whereswaldon/shout" + "github.com/wailsapp/wails/v3/pkg/application" +) + +var NotificationService *Service +var Notifier shout.Notifier + +// Creates a new Notifications Service. +func New() *Service { + if NotificationService == nil { + NotificationService = &Service{} + } + return NotificationService +} + +// ServiceStartup is called when the service is loaded +func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + return nil +} + +// ServiceShutdown is called when the service is unloaded +func (ns *Service) ServiceShutdown() error { + return nil +} + +// CheckBundleIdentifier is a Linux stub that always returns true. +// (bundle identifiers are macOS-specific) +func CheckBundleIdentifier() bool { + return true +} + +// RequestUserNotificationAuthorization is a Linux stub that always returns true, nil. +// (user authorization is macOS-specific) +func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { + return true, nil +} + +// CheckNotificationAuthorization is a Linux stub that always returns true. +// (user authorization is macOS-specific) +func (ns *Service) CheckNotificationAuthorization() bool { + return true +} + +// SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Linux. +// (subtitle and category id are only available on macOS) +func (ns *Service) SendNotification(options NotificationOptions) error { + return nil +} + +// SendNotificationWithActions sends a notification with additional actions and inputs. +// A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. +// If a NotificationCategory is not registered a basic notification will be sent. +// (subtitle and category id are only available on macOS) +func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + return nil +} + +// RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. +func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { + return nil +} + +// RemoveNotificationCategory removes a previously registered NotificationCategory. +func (ns *Service) RemoveNotificationCategory(categoryId string) error { + return nil +} + +// RemoveAllPendingNotifications is a Linux stub that always returns nil. +// (macOS-specific) +func (ns *Service) RemoveAllPendingNotifications() error { + return nil +} + +// RemovePendingNotification is a Linux stub that always returns nil. +// (macOS-specific) +func (ns *Service) RemovePendingNotification(_ string) error { + return nil +} + +// RemoveAllDeliveredNotifications is a Linux stub that always returns nil. +// (macOS-specific) +func (ns *Service) RemoveAllDeliveredNotifications() error { + return nil +} + +// RemoveDeliveredNotification is a Linux stub that always returns nil. +// (macOS-specific) +func (ns *Service) RemoveDeliveredNotification(_ string) error { + return nil +} + +// RemoveNotification removes a pending notification matching the unique identifier. +// (Linux-specific) +func (ns *Service) RemoveNotification(identifier string) error { + return nil +} diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 6a266bbee..e0fc917aa 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -24,6 +24,7 @@ const ( dataSeparator = ":::" ) +// Creates a new Notifications Service. func New() *Service { if NotificationService == nil { NotificationService = &Service{} @@ -31,11 +32,6 @@ func New() *Service { return NotificationService } -// ServiceName returns the name of the service -func (ns *Service) ServiceName() string { - return "github.com/wailsapp/wails/v3/services/notifications" -} - // ServiceStartup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { @@ -227,6 +223,12 @@ func (ns *Service) RemoveDeliveredNotification(_ string) error { return nil } +// RemoveNotification is a Windows stub that always returns nil. +// (Linux-specific) +func (ns *Service) RemoveNotification(identifier string) error { + return nil +} + func parseNotificationResponse(response string) (action string, data string) { parts := strings.Split(response, dataSeparator) if len(parts) == 1 { From 135defc40573570ec2d62d338f1783e341089932 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Tue, 25 Feb 2025 09:11:12 -0800 Subject: [PATCH 030/136] init test linux --- .../services/notifications/notifications.go | 4 +- .../notifications/notifications_darwin.go | 1 - .../notifications/notifications_linux.go | 216 ++++++++++++++++-- .../notifications/notifications_windows.go | 1 - 4 files changed, 204 insertions(+), 18 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index c53f77ba3..1a3102a08 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -2,10 +2,12 @@ package notifications // Service represents the notifications service type Service struct { - // responseCallback is called when a notification response is received + // Callback is called when a notification response is received Callback func(response NotificationResponse) } +var NotificationService *Service + // NotificationAction represents an action button for a notification type NotificationAction = struct { ID string `json:"id,omitempty"` diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 2197e6741..f001d6fde 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -17,7 +17,6 @@ import ( "github.com/wailsapp/wails/v3/pkg/application" ) -var NotificationService *Service var AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" // Creates a new Notifications Service. diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index b499d4788..0248b8bcd 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -4,12 +4,19 @@ package notifications import ( "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "sync" "git.sr.ht/~whereswaldon/shout" + "github.com/godbus/dbus/v5" "github.com/wailsapp/wails/v3/pkg/application" ) -var NotificationService *Service +var NotificationLock sync.RWMutex +var NotificationCategories = make(map[string]NotificationCategory) var Notifier shout.Notifier // Creates a new Notifications Service. @@ -22,12 +29,66 @@ func New() *Service { // ServiceStartup is called when the service is loaded func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + if err := loadCategories(); err != nil { + fmt.Printf("Failed to load notification categories: %v\n", err) + } + + conn, err := dbus.SessionBus() + if err != nil { + return fmt.Errorf("failed to connect to D-Bus session bus: %v", err) + } + + appName := "Wails Application" + + var iconPath string + + Notifier, err = shout.NewNotifier(conn, appName, iconPath, func(notificationID, action string, platformData map[string]dbus.Variant, target, notifierResponse dbus.Variant, err error) { + if err != nil { + return + } + + response := NotificationResponse{ + ID: notificationID, + ActionIdentifier: action, + } + + if action == "default" { + response.ActionIdentifier = DefaultActionIdentifier + } + + if target.Signature().String() == "s" { + var targetStr string + if err := target.Store(&targetStr); err == nil { + // Try to parse as JSON + var userInfo map[string]interface{} + if err := json.Unmarshal([]byte(targetStr), &userInfo); err == nil { + response.UserInfo = userInfo + } + } + } + + if notifierResponse.Signature().String() == "s" { + var userText string + if err := notifierResponse.Store(&userText); err == nil { + response.UserText = userText + } + } + + if NotificationService != nil { + NotificationService.handleNotificationResponse(response) + } + }) + + if err != nil { + return fmt.Errorf("failed to create notifier: %v", err) + } + return nil } // ServiceShutdown is called when the service is unloaded func (ns *Service) ServiceShutdown() error { - return nil + return saveCategories() } // CheckBundleIdentifier is a Linux stub that always returns true. @@ -44,32 +105,87 @@ func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { // CheckNotificationAuthorization is a Linux stub that always returns true. // (user authorization is macOS-specific) -func (ns *Service) CheckNotificationAuthorization() bool { - return true +func (ns *Service) CheckNotificationAuthorization() (bool, error) { + return true, nil } -// SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Linux. -// (subtitle and category id are only available on macOS) +// SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ns *Service) SendNotification(options NotificationOptions) error { - return nil + notification := shout.Notification{ + Title: options.Title, + Body: options.Body, + Priority: shout.Normal, + DefaultAction: "default", + } + + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + notification.DefaultActionTarget = dbus.MakeVariant(string(jsonData)) + } + } + + return Notifier.Send(options.ID, notification) } // SendNotificationWithActions sends a notification with additional actions and inputs. -// A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. -// If a NotificationCategory is not registered a basic notification will be sent. -// (subtitle and category id are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { - return nil + NotificationLock.RLock() + category, exists := NotificationCategories[options.CategoryID] + NotificationLock.RUnlock() + + if !exists { + return ns.SendNotification(options) + } + + notification := shout.Notification{ + Title: options.Title, + Body: options.Body, + Priority: shout.Normal, + DefaultAction: "default", + } + + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + notification.DefaultActionTarget = dbus.MakeVariant(string(jsonData)) + } + } + + for _, action := range category.Actions { + notification.Buttons = append(notification.Buttons, shout.Button{ + Label: action.Title, + Action: action.ID, + Target: "", // Will be set below if we have user data + }) + } + + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err == nil { + for i := range notification.Buttons { + notification.Buttons[i].Target = string(jsonData) + } + } + } + + return Notifier.Send(options.ID, notification) } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { - return nil + NotificationLock.Lock() + NotificationCategories[category.ID] = category + NotificationLock.Unlock() + return saveCategories() } // RemoveNotificationCategory removes a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { - return nil + NotificationLock.Lock() + delete(NotificationCategories, categoryId) + NotificationLock.Unlock() + return saveCategories() } // RemoveAllPendingNotifications is a Linux stub that always returns nil. @@ -96,8 +212,78 @@ func (ns *Service) RemoveDeliveredNotification(_ string) error { return nil } -// RemoveNotification removes a pending notification matching the unique identifier. -// (Linux-specific) +// RemoveNotification removes a notification by ID (Linux-specific) func (ns *Service) RemoveNotification(identifier string) error { + return Notifier.Remove(identifier) +} + +// getConfigFilePath returns the path to the configuration file for storing notification categories +func getConfigFilePath() (string, error) { + configDir, err := os.UserConfigDir() + if err != nil { + return "", fmt.Errorf("failed to get user config directory: %v", err) + } + + appName := "Wails Application" + + appConfigDir := filepath.Join(configDir, appName) + if err := os.MkdirAll(appConfigDir, 0755); err != nil { + return "", fmt.Errorf("failed to create config directory: %v", err) + } + + return filepath.Join(appConfigDir, "notification-categories.json"), nil +} + +// saveCategories saves the notification categories to a file. +func saveCategories() error { + filePath, err := getConfigFilePath() + if err != nil { + return err + } + + NotificationLock.RLock() + data, err := json.Marshal(NotificationCategories) + NotificationLock.RUnlock() + + if err != nil { + return fmt.Errorf("failed to marshal notification categories: %v", err) + } + + if err := os.WriteFile(filePath, data, 0644); err != nil { + return fmt.Errorf("failed to write notification categories to file: %v", err) + } + + return nil +} + +// loadCategories loads notification categories from a file. +func loadCategories() error { + filePath, err := getConfigFilePath() + if err != nil { + return err + } + + if _, err := os.Stat(filePath); os.IsNotExist(err) { + return nil + } + + data, err := os.ReadFile(filePath) + if err != nil { + return fmt.Errorf("failed to read notification categories file: %v", err) + } + + if len(data) == 0 { + return nil + } + + categories := make(map[string]NotificationCategory) + if err := json.Unmarshal(data, &categories); err != nil { + return fmt.Errorf("failed to unmarshal notification categories: %v", err) + } + + NotificationLock.Lock() + NotificationCategories = categories + NotificationLock.Unlock() + return nil } diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index e0fc917aa..28d439f68 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -16,7 +16,6 @@ import ( "golang.org/x/sys/windows/registry" ) -var NotificationService *Service var NotificationLock sync.RWMutex var NotificationCategories = make(map[string]NotificationCategory) From 7bbc27594b9133b76fe704ffb1fdc9c39b9ae5fe Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 09:32:52 -0800 Subject: [PATCH 031/136] fix windows --- .../notifications/notifications_windows.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 28d439f68..04dd6bc72 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -35,14 +35,13 @@ func New() *Service { // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { // Need to get App Name and generate a UUID on first launch - // - // toast.SetAppData(toast.AppData{ - // AppID: "Notifications", - // GUID: "{8F2E1A3D-C497-42B6-9E5D-72F8A169B051}", - // IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", - // ActivationExe: "C:\\Users\\Zach\\Development\\notifications_demo\\bin\\Notifications.exe", - // }) - // + // How do we grab the app icon properly? + toast.SetAppData(toast.AppData{ + AppID: "Notifications", + GUID: "{8F2E1A3D-C497-42B6-9E5D-72F8A169B051}", + IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", + ActivationExe: "C:\\Users\\Zach\\Development\\notifications_demo\\bin\\Notifications.exe", + }) toast.SetActivationCallback(func(args string, data []toast.UserData) { actionIdentifier, userInfo := parseNotificationResponse(args) @@ -97,7 +96,6 @@ func (ns *Service) CheckNotificationAuthorization() bool { // (subtitle and category id are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { n := toast.Notification{ - AppID: options.ID, Title: options.Title, Body: options.Body, ActivationArguments: DefaultActionIdentifier, @@ -128,7 +126,6 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro NotificationLock.RUnlock() n := toast.Notification{ - AppID: options.ID, Title: options.Title, Body: options.Body, ActivationArguments: DefaultActionIdentifier, From fa498f1c5e758e3d7c35c7cbf29bf005ae422978 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 11:20:43 -0800 Subject: [PATCH 032/136] encode user data on windows --- .../services/notifications/notifications.go | 6 +- .../notifications/notifications_windows.go | 76 ++++++++++++++----- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 1a3102a08..a40177af2 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -12,7 +12,7 @@ var NotificationService *Service type NotificationAction = struct { ID string `json:"id,omitempty"` Title string `json:"title,omitempty"` - Destructive bool `json:"destructive,omitempty"` // macOS only + Destructive bool `json:"destructive,omitempty"` // (macOS-specific) } // NotificationCategory groups actions for notifications @@ -28,7 +28,7 @@ type NotificationCategory = struct { type NotificationOptions = struct { ID string `json:"id,omitempty"` Title string `json:"title,omitempty"` - Subtitle string `json:"subtitle,omitempty"` + Subtitle string `json:"subtitle,omitempty"` // (macOS-specific) Body string `json:"body,omitempty"` CategoryID string `json:"categoryId,omitempty"` Data map[string]interface{} `json:"data,omitempty"` @@ -42,7 +42,7 @@ type NotificationResponse = struct { ActionIdentifier string `json:"actionIdentifier,omitempty"` CategoryID string `json:"categoryIdentifier,omitempty"` Title string `json:"title,omitempty"` - Subtitle string `json:"subtitle,omitempty"` + Subtitle string `json:"subtitle,omitempty"` // (macOS-specific) Body string `json:"body,omitempty"` UserText string `json:"userText,omitempty"` UserInfo map[string]interface{} `json:"userInfo,omitempty"` diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 04dd6bc72..390679b06 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -4,6 +4,7 @@ package notifications import ( "context" + "encoding/base64" "encoding/json" "fmt" "os" @@ -19,9 +20,11 @@ import ( var NotificationLock sync.RWMutex var NotificationCategories = make(map[string]NotificationCategory) -const ( - dataSeparator = ":::" -) +// NotificationPayload combines the action ID and user data into a single structure +type NotificationPayload struct { + Action string `json:"action"` + Data map[string]interface{} `json:"data,omitempty"` +} // Creates a new Notifications Service. func New() *Service { @@ -103,17 +106,13 @@ func (ns *Service) SendNotification(options NotificationOptions) error { } if options.Data != nil { - jsonData, err := json.Marshal(options.Data) + encodedPayload, err := encodePayload(DefaultActionIdentifier, options.Data) if err == nil { - n.ActivationArguments = DefaultActionIdentifier + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") + n.ActivationArguments = encodedPayload } } - err := n.Push() - if err != nil { - return err - } - return nil + return n.Push() } // SendNotificationWithActions sends a notification with additional actions and inputs. @@ -142,7 +141,6 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro if nCategory.HasReplyField { n.Inputs = append(n.Inputs, toast.Input{ ID: "userText", - Title: nCategory.ReplyButtonTitle, Placeholder: nCategory.ReplyPlaceholder, }) @@ -154,11 +152,10 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err == nil { - n.ActivationArguments = DefaultActionIdentifier + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") - for index := range n.Actions { - n.Actions[index].Arguments = n.Actions[index].Arguments + dataSeparator + strings.ReplaceAll(string(jsonData), "\"", "'") + for index := range n.Actions { + encodedPayload, err := encodePayload(n.Actions[index].Arguments, options.Data) + if err == nil { + n.Actions[index].Arguments = encodedPayload } } } @@ -225,12 +222,49 @@ func (ns *Service) RemoveNotification(identifier string) error { return nil } -func parseNotificationResponse(response string) (action string, data string) { - parts := strings.Split(response, dataSeparator) - if len(parts) == 1 { - return parts[0], "" +// encodePayload combines an action ID and user data into a single encoded string +func encodePayload(actionID string, data map[string]interface{}) (string, error) { + payload := NotificationPayload{ + Action: actionID, + Data: data, } - return parts[0], parts[1] + + jsonData, err := json.Marshal(payload) + if err != nil { + return actionID, err + } + + encodedPayload := base64.StdEncoding.EncodeToString(jsonData) + return encodedPayload, nil +} + +// decodePayload extracts the action ID and user data from an encoded payload +func decodePayload(encodedString string) (string, map[string]interface{}, error) { + jsonData, err := base64.StdEncoding.DecodeString(encodedString) + if err != nil { + return encodedString, nil, nil + } + + var payload NotificationPayload + if err := json.Unmarshal(jsonData, &payload); err != nil { + return encodedString, nil, nil + } + + return payload.Action, payload.Data, nil +} + +// parseNotificationResponse updated to use structured payload decoding +func parseNotificationResponse(response string) (action string, data string) { + actionID, userData, _ := decodePayload(response) + + if userData != nil { + userDataJSON, err := json.Marshal(userData) + if err == nil { + return actionID, string(userDataJSON) + } + } + + return actionID, "" } // Is there a better way for me to grab this from the Wails config? From 050e4ef1a81cf545b1f6753ec0f022ac9281c8ab Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 11:27:54 -0800 Subject: [PATCH 033/136] fix default complex action --- v3/examples/notifications/main.go | 20 +++++-------------- .../notifications/notifications_windows.go | 7 +++---- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index a1d34dd5e..9dbc07c23 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -19,7 +19,7 @@ func main() { notificationService := notifications.New() app := application.New(application.Options{ - Name: "notifications_demo", + Name: "Notifications", Description: "A demo of using raw HTML & CSS", Services: []application.Service{ application.NewService(notificationService), @@ -33,7 +33,7 @@ func main() { }) app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ - Title: "Window 1", + Title: "Notifications", Mac: application.MacWindow{ InvisibleTitleBarHeight: 50, Backdrop: application.MacBackdropTranslucent, @@ -58,13 +58,8 @@ func main() { }) time.Sleep(time.Second * 2) - var uuid1 string = "Wails Notification Demo" - if application.Get().Environment().OS == "darwin" { - uuid1 = "uuid1" - } - notificationService.SendNotification(notifications.NotificationOptions{ - ID: uuid1, + ID: "uuid1", Title: "Title!", Body: "Body!", Data: map[string]interface{}{ @@ -76,11 +71,6 @@ func main() { time.Sleep(time.Second * 2) - var uuid2 string = "Wails Notification Demo" - if application.Get().Environment().OS == "darwin" { - uuid2 = "uuid2" - } - notificationService.RegisterNotificationCategory(notifications.NotificationCategory{ ID: "BACKEND_NOTIF", Actions: []notifications.NotificationAction{ @@ -94,9 +84,9 @@ func main() { }) notificationService.SendNotificationWithActions(notifications.NotificationOptions{ - ID: uuid2, + ID: "uuid2", Title: "Complex Backend Notification", - Subtitle: "Should not show on Windows", + Subtitle: "From: Jane Doe", Body: "Is it raining today where you are?", CategoryID: "BACKEND_NOTIF", Data: map[string]interface{}{ diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 390679b06..f19b9035e 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -152,11 +152,10 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } if options.Data != nil { + n.ActivationArguments, _ = encodePayload(n.ActivationArguments, options.Data) + for index := range n.Actions { - encodedPayload, err := encodePayload(n.Actions[index].Arguments, options.Data) - if err == nil { - n.Actions[index].Arguments = encodedPayload - } + n.Actions[index].Arguments, _ = encodePayload(n.Actions[index].Arguments, options.Data) } } From 60c1a866f3fc54bc14a0975276789caff15712f8 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 11:37:11 -0800 Subject: [PATCH 034/136] update example --- .../v3/pkg/services/notifications/models.js | 4 +- .../v3/pkg/services/notifications/service.js | 47 +++++++++++++------ v3/examples/notifications/frontend/main.js | 10 ++-- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js index c52cbf1c2..1b53de966 100644 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js @@ -11,7 +11,7 @@ import {Create as $Create} from "@wailsio/runtime"; * @typedef {Object} NotificationAction * @property {string} [id] * @property {string} [title] - * @property {boolean} [destructive] - macOS only + * @property {boolean} [destructive] - (macOS-specific) */ /** @@ -29,7 +29,7 @@ import {Create as $Create} from "@wailsio/runtime"; * @typedef {Object} NotificationOptions * @property {string} [id] * @property {string} [title] - * @property {string} [subtitle] + * @property {string} [subtitle] - (macOS-specific) * @property {string} [body] * @property {string} [categoryId] * @property {{ [_: string]: any }} [data] diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js index ef81ee81a..85e54340f 100644 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js @@ -16,7 +16,8 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime"; import * as $models from "./models.js"; /** - * CheckNotificationAuthorization checks current notification permission status. + * CheckNotificationAuthorization is a Windows stub that always returns true. + * (user authorization is macOS-specific) * @returns {Promise & { cancel(): void }} */ export function CheckNotificationAuthorization() { @@ -47,7 +48,8 @@ export function RegisterNotificationCategory(category) { } /** - * RemoveAllDeliveredNotifications removes all delivered notifications. + * RemoveAllDeliveredNotifications is a Windows stub that always returns nil. + * (macOS-specific) * @returns {Promise & { cancel(): void }} */ export function RemoveAllDeliveredNotifications() { @@ -56,7 +58,8 @@ export function RemoveAllDeliveredNotifications() { } /** - * RemoveAllPendingNotifications removes all pending notifications. + * RemoveAllPendingNotifications is a Windows stub that always returns nil. + * (macOS-specific) * @returns {Promise & { cancel(): void }} */ export function RemoveAllPendingNotifications() { @@ -65,17 +68,29 @@ export function RemoveAllPendingNotifications() { } /** - * RemoveDeliveredNotification removes a delivered notification matching the unique identifier. - * @param {string} identifier + * RemoveDeliveredNotification is a Windows stub that always returns nil. + * (macOS-specific) + * @param {string} $0 * @returns {Promise & { cancel(): void }} */ -export function RemoveDeliveredNotification(identifier) { - let $resultPromise = /** @type {any} */($Call.ByID(149440045, identifier)); +export function RemoveDeliveredNotification($0) { + let $resultPromise = /** @type {any} */($Call.ByID(149440045, $0)); return $resultPromise; } /** - * RemoveNotificationCategory remove a previously registered NotificationCategory. + * RemoveNotification is a Windows stub that always returns nil. + * (Linux-specific) + * @param {string} identifier + * @returns {Promise & { cancel(): void }} + */ +export function RemoveNotification(identifier) { + let $resultPromise = /** @type {any} */($Call.ByID(3702062929, identifier)); + return $resultPromise; +} + +/** + * RemoveNotificationCategory removes a previously registered NotificationCategory. * @param {string} categoryId * @returns {Promise & { cancel(): void }} */ @@ -85,17 +100,19 @@ export function RemoveNotificationCategory(categoryId) { } /** - * RemovePendingNotification removes a pending notification matching the unique identifier. - * @param {string} identifier + * RemovePendingNotification is a Windows stub that always returns nil. + * (macOS-specific) + * @param {string} $0 * @returns {Promise & { cancel(): void }} */ -export function RemovePendingNotification(identifier) { - let $resultPromise = /** @type {any} */($Call.ByID(3872412470, identifier)); +export function RemovePendingNotification($0) { + let $resultPromise = /** @type {any} */($Call.ByID(3872412470, $0)); return $resultPromise; } /** - * RequestUserNotificationAuthorization requests permission for notifications. + * RequestUserNotificationAuthorization is a Windows stub that always returns true, nil. + * (user authorization is macOS-specific) * @returns {Promise & { cancel(): void }} */ export function RequestUserNotificationAuthorization() { @@ -104,7 +121,8 @@ export function RequestUserNotificationAuthorization() { } /** - * SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. + * SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. + * (subtitle and category id are only available on macOS) * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ @@ -117,6 +135,7 @@ export function SendNotification(options) { * SendNotificationWithActions sends a notification with additional actions and inputs. * A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. * If a NotificationCategory is not registered a basic notification will be sent. + * (subtitle and category id are only available on macOS) * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js index 64624f34b..718a9fb4f 100644 --- a/v3/examples/notifications/frontend/main.js +++ b/v3/examples/notifications/frontend/main.js @@ -1,14 +1,13 @@ import * as Notifications from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service"; -import { Events, System } from "@wailsio/runtime"; +import { Events } from "@wailsio/runtime"; const notificationsElement = document.getElementById('notifications'); window.sendNotification = async () => { const granted = await Notifications.RequestUserNotificationAuthorization(); if (granted) { - const id = System.IsWindows() ? "Wails Notification Demo" : crypto.randomUUID() await Notifications.SendNotification({ - id, + id: crypto.randomUUID(), title: "Title", body: "Body!", data: { @@ -33,10 +32,9 @@ window.sendComplexNotification = async () => { replyButtonTitle: "Reply", replyPlaceholder: "Reply to frontend...", }); - - const id = System.IsWindows() ? "Wails Notification Demo" : crypto.randomUUID() + await Notifications.SendNotificationWithActions({ - id, + id: crypto.randomUUID(), title: "Complex Frontend Notification", subtitle: "From: Jane Doe", body: "Is it rainging today where you are?", From 10ae1f6029c61a4ea9d8140828c881f89ec7da8b Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 15:04:05 -0800 Subject: [PATCH 035/136] export config from app --- v3/pkg/application/application.go | 4 ++ .../notifications/notifications_windows.go | 52 ++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 21c0792cc..b3a8f6f34 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -345,6 +345,10 @@ type App struct { singleInstanceManager *singleInstanceManager } +func (a *App) Config() Options { + return a.options +} + func (a *App) handleWarning(msg string) { if a.options.WarningHandler != nil { a.options.WarningHandler(msg) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index f19b9035e..63ce34017 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -13,6 +13,7 @@ import ( "sync" "git.sr.ht/~jackmordaunt/go-toast/v2" + "github.com/google/uuid" "github.com/wailsapp/wails/v3/pkg/application" "golang.org/x/sys/windows/registry" ) @@ -37,13 +38,20 @@ func New() *Service { // ServiceStartup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - // Need to get App Name and generate a UUID on first launch - // How do we grab the app icon properly? + appName := application.Get().Config().Name + icon := application.Get().Config().Icon + + println(icon) + + guid, err := getGUID(appName) + if err != nil { + return err + } + toast.SetAppData(toast.AppData{ - AppID: "Notifications", - GUID: "{8F2E1A3D-C497-42B6-9E5D-72F8A169B051}", - IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", - ActivationExe: "C:\\Users\\Zach\\Development\\notifications_demo\\bin\\Notifications.exe", + AppID: appName, + GUID: guid, + IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", }) toast.SetActivationCallback(func(args string, data []toast.UserData) { @@ -348,3 +356,35 @@ func getUserText(data []toast.UserData) (string, bool) { } return "", false } + +func getGUID(name string) (string, error) { + keyPath := `Software\Classes\AppUserModelId\` + name + + k, err := registry.OpenKey(registry.CURRENT_USER, keyPath, registry.QUERY_VALUE) + if err == nil { + guid, _, err := k.GetStringValue("CustomActivator") + k.Close() + if err == nil && guid != "" { + return guid, nil + } + } + + guid := generateGUID() + + k, _, err = registry.CreateKey(registry.CURRENT_USER, keyPath, registry.WRITE) + if err != nil { + return "", fmt.Errorf("failed to create registry key: %w", err) + } + defer k.Close() + + if err := k.SetStringValue("CustomActivator", guid); err != nil { + return "", fmt.Errorf("failed to write GUID to registry: %w", err) + } + + return guid, nil +} + +func generateGUID() string { + guid := uuid.New() + return fmt.Sprintf("{%s}", guid.String()) +} From a4c4ab6c8fcfa4c5c40446ab387ad233fdada100 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 15:55:28 -0800 Subject: [PATCH 036/136] add id to macOS payload --- v3/pkg/services/notifications/notifications_darwin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 3a52bd34b..4a1514e06 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -24,7 +24,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response NSMutableDictionary *payload = [NSMutableDictionary dictionary]; - [payload setObject:response.notification.request.identifier forKey:@"identifier"]; + [payload setObject:response.notification.request.identifier forKey:@"id"]; [payload setObject:response.actionIdentifier forKey:@"actionIdentifier"]; [payload setObject:response.notification.request.content.title ?: @"" forKey:@"title"]; [payload setObject:response.notification.request.content.body ?: @"" forKey:@"body"]; From acad85e6037a40925aa49fff97a61d3fe51ff0bc Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 15:59:27 -0800 Subject: [PATCH 037/136] update example --- v3/examples/notifications/main.go | 7 +++++-- v3/pkg/services/notifications/notifications_linux.go | 5 ++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index 9dbc07c23..34d711f3e 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -30,6 +30,9 @@ func main() { Mac: application.MacOptions{ ApplicationShouldTerminateAfterLastWindowClosed: true, }, + Windows: application.WindowsOptions{ + WndClass: "Notifications", + }, }) app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ @@ -65,7 +68,7 @@ func main() { Data: map[string]interface{}{ "messageId": "msg-123", "senderId": "user-123", - "timestamp": time.Now().String(), + "timestamp": time.Now().Unix(), }, }) @@ -92,7 +95,7 @@ func main() { Data: map[string]interface{}{ "messageId": "msg-456", "senderId": "user-456", - "timestamp": time.Now().String(), + "timestamp": time.Now().Unix(), }, }) } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 0248b8bcd..0d97691ff 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -38,7 +38,7 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi return fmt.Errorf("failed to connect to D-Bus session bus: %v", err) } - appName := "Wails Application" + appName := application.Get().Config().Name var iconPath string @@ -52,14 +52,13 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi ActionIdentifier: action, } - if action == "default" { + if action == "" { response.ActionIdentifier = DefaultActionIdentifier } if target.Signature().String() == "s" { var targetStr string if err := target.Store(&targetStr); err == nil { - // Try to parse as JSON var userInfo map[string]interface{} if err := json.Unmarshal([]byte(targetStr), &userInfo); err == nil { response.UserInfo = userInfo From 60ae0c15985feb466817ccc1d1b4369e6ca3ed51 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 16:25:06 -0800 Subject: [PATCH 038/136] test linux userInfo --- .../notifications/notifications_linux.go | 42 +++++++++---------- .../notifications/notifications_windows.go | 3 +- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 0d97691ff..e63fb6bf3 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -4,6 +4,7 @@ package notifications import ( "context" + "encoding/base64" "encoding/json" "fmt" "os" @@ -18,6 +19,7 @@ import ( var NotificationLock sync.RWMutex var NotificationCategories = make(map[string]NotificationCategory) var Notifier shout.Notifier +var appName = application.Get().Config().Name // Creates a new Notifications Service. func New() *Service { @@ -38,8 +40,6 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi return fmt.Errorf("failed to connect to D-Bus session bus: %v", err) } - appName := application.Get().Config().Name - var iconPath string Notifier, err = shout.NewNotifier(conn, appName, iconPath, func(notificationID, action string, platformData map[string]dbus.Variant, target, notifierResponse dbus.Variant, err error) { @@ -52,26 +52,28 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi ActionIdentifier: action, } - if action == "" { - response.ActionIdentifier = DefaultActionIdentifier - } - if target.Signature().String() == "s" { var targetStr string if err := target.Store(&targetStr); err == nil { var userInfo map[string]interface{} - if err := json.Unmarshal([]byte(targetStr), &userInfo); err == nil { + userInfoStr, err := base64.StdEncoding.DecodeString(targetStr) + if err != nil { + if err := json.Unmarshal([]byte(targetStr), &userInfo); err == nil { + response.UserInfo = userInfo + } + } + if err := json.Unmarshal(userInfoStr, &userInfo); err == nil { response.UserInfo = userInfo } } } - if notifierResponse.Signature().String() == "s" { - var userText string - if err := notifierResponse.Store(&userText); err == nil { - response.UserText = userText - } - } + // if notifierResponse.Signature().String() == "s" { + // var userText string + // if err := notifierResponse.Store(&userText); err == nil { + // response.UserText = userText + // } + // } if NotificationService != nil { NotificationService.handleNotificationResponse(response) @@ -114,13 +116,13 @@ func (ns *Service) SendNotification(options NotificationOptions) error { Title: options.Title, Body: options.Body, Priority: shout.Normal, - DefaultAction: "default", + DefaultAction: DefaultActionIdentifier, } if options.Data != nil { jsonData, err := json.Marshal(options.Data) if err == nil { - notification.DefaultActionTarget = dbus.MakeVariant(string(jsonData)) + notification.DefaultActionTarget = dbus.MakeVariant(base64.StdEncoding.EncodeToString(jsonData)) } } @@ -141,13 +143,13 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro Title: options.Title, Body: options.Body, Priority: shout.Normal, - DefaultAction: "default", + DefaultAction: DefaultActionIdentifier, } if options.Data != nil { jsonData, err := json.Marshal(options.Data) if err == nil { - notification.DefaultActionTarget = dbus.MakeVariant(string(jsonData)) + notification.DefaultActionTarget = dbus.MakeVariant(base64.StdEncoding.EncodeToString(jsonData)) } } @@ -162,8 +164,8 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro if options.Data != nil { jsonData, err := json.Marshal(options.Data) if err == nil { - for i := range notification.Buttons { - notification.Buttons[i].Target = string(jsonData) + for index := range notification.Buttons { + notification.Buttons[index].Target = string(jsonData) } } } @@ -223,8 +225,6 @@ func getConfigFilePath() (string, error) { return "", fmt.Errorf("failed to get user config directory: %v", err) } - appName := "Wails Application" - appConfigDir := filepath.Join(configDir, appName) if err := os.MkdirAll(appConfigDir, 0755); err != nil { return "", fmt.Errorf("failed to create config directory: %v", err) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 63ce34017..1e1cf7f9e 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -61,9 +61,8 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi } if userInfo != "" { - jsonStr := strings.ReplaceAll(userInfo, "'", "\"") var userInfoMap map[string]interface{} - if err := json.Unmarshal([]byte(jsonStr), &userInfoMap); err == nil { + if err := json.Unmarshal([]byte(userInfo), &userInfoMap); err == nil { response.UserInfo = userInfoMap } } From 47e5b109c08db3684c9ff1442e45caca0e39a7c3 Mon Sep 17 00:00:00 2001 From: Zach Date: Tue, 25 Feb 2025 16:32:10 -0800 Subject: [PATCH 039/136] add debug --- v3/pkg/services/notifications/notifications_linux.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index e63fb6bf3..51bcabb5f 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -19,7 +19,7 @@ import ( var NotificationLock sync.RWMutex var NotificationCategories = make(map[string]NotificationCategory) var Notifier shout.Notifier -var appName = application.Get().Config().Name +var appName string // Creates a new Notifications Service. func New() *Service { @@ -31,6 +31,8 @@ func New() *Service { // ServiceStartup is called when the service is loaded func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + appName = application.Get().Config().Name + if err := loadCategories(); err != nil { fmt.Printf("Failed to load notification categories: %v\n", err) } @@ -47,6 +49,14 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi return } + fmt.Printf("\n---------- NOTIFICATION RESPONSE DEBUG ----------\n") + fmt.Printf("notificationID: %s\n", notificationID) + fmt.Printf("action: %s\n", action) + fmt.Printf("platformData: %+v\n", platformData) + fmt.Printf("target: %+v (signature: %s)\n", target, target.Signature()) + fmt.Printf("response: %+v (signature: %s)\n", notifierResponse, notifierResponse.Signature()) + fmt.Printf("----------------------------------------------\n") + response := NotificationResponse{ ID: notificationID, ActionIdentifier: action, From 5ad3d73001b33f8fe3eb6968db36ede702590f54 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 16:40:14 -0800 Subject: [PATCH 040/136] wrangle variants --- .../notifications/notifications_linux.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 51bcabb5f..c6734e83f 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -164,22 +164,19 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } for _, action := range category.Actions { + var targetStr string = "" + if options.Data != nil { + if jsonData, err := json.Marshal(options.Data); err == nil { + targetStr = base64.StdEncoding.EncodeToString(jsonData) + } + } notification.Buttons = append(notification.Buttons, shout.Button{ Label: action.Title, Action: action.ID, - Target: "", // Will be set below if we have user data + Target: targetStr, }) } - if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err == nil { - for index := range notification.Buttons { - notification.Buttons[index].Target = string(jsonData) - } - } - } - return Notifier.Send(options.ID, notification) } From e86cf68b179b013b497ffd1d4e8c3f3ea49ae774 Mon Sep 17 00:00:00 2001 From: Zach Date: Tue, 25 Feb 2025 17:58:24 -0800 Subject: [PATCH 041/136] linux? --- .../notifications/notifications_linux.go | 566 ++++++++++++++---- 1 file changed, 455 insertions(+), 111 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index c6734e83f..3d575dda6 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -4,24 +4,79 @@ package notifications import ( "context" - "encoding/base64" "encoding/json" + "errors" "fmt" "os" + "os/exec" "path/filepath" "sync" - "git.sr.ht/~whereswaldon/shout" "github.com/godbus/dbus/v5" "github.com/wailsapp/wails/v3/pkg/application" ) -var NotificationLock sync.RWMutex -var NotificationCategories = make(map[string]NotificationCategory) -var Notifier shout.Notifier -var appName string +const ( + dbusObjectPath = "/org/freedesktop/Notifications" + dbusNotificationsInterface = "org.freedesktop.Notifications" + signalNotificationClosed = "org.freedesktop.Notifications.NotificationClosed" + signalActionInvoked = "org.freedesktop.Notifications.ActionInvoked" + callGetCapabilities = "org.freedesktop.Notifications.GetCapabilities" + callCloseNotification = "org.freedesktop.Notifications.CloseNotification" -// Creates a new Notifications Service. + MethodNotifySend = "notify-send" + MethodDbus = "dbus" + MethodKdialog = "kdialog" + + notifyChannelBufferSize = 25 +) + +var ( + notificationLock sync.RWMutex + notificationCategories = make(map[string]NotificationCategory) + appName string + initOnce sync.Once +) + +type closedReason uint32 + +func (r closedReason) string() string { + switch r { + case 1: + return "expired" + case 2: + return "dismissed-by-user" + case 3: + return "closed-by-call" + case 4: + return "unknown" + case 5: + return "activated-by-user" + default: + return "other" + } +} + +// internalNotifier handles the actual notification sending via dbus or command line +type notificationContext struct { + ID string + SystemID uint32 + Actions map[string]string // Maps action keys to display labels + UserData map[string]interface{} // The original user data +} + +type internalNotifier struct { + sync.Mutex + method string + dbusConn *dbus.Conn + sendPath string + activeNotifs map[string]uint32 // Maps our notification IDs to system IDs + contexts map[string]*notificationContext // Stores notification contexts by our ID +} + +var notifier *internalNotifier + +// New creates a new Notifications Service func New() *Service { if NotificationService == nil { NotificationService = &Service{} @@ -37,78 +92,236 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi fmt.Printf("Failed to load notification categories: %v\n", err) } - conn, err := dbus.SessionBus() - if err != nil { - return fmt.Errorf("failed to connect to D-Bus session bus: %v", err) + notifier = &internalNotifier{ + activeNotifs: make(map[string]uint32), + contexts: make(map[string]*notificationContext), } - var iconPath string - - Notifier, err = shout.NewNotifier(conn, appName, iconPath, func(notificationID, action string, platformData map[string]dbus.Variant, target, notifierResponse dbus.Variant, err error) { - if err != nil { - return - } - - fmt.Printf("\n---------- NOTIFICATION RESPONSE DEBUG ----------\n") - fmt.Printf("notificationID: %s\n", notificationID) - fmt.Printf("action: %s\n", action) - fmt.Printf("platformData: %+v\n", platformData) - fmt.Printf("target: %+v (signature: %s)\n", target, target.Signature()) - fmt.Printf("response: %+v (signature: %s)\n", notifierResponse, notifierResponse.Signature()) - fmt.Printf("----------------------------------------------\n") - - response := NotificationResponse{ - ID: notificationID, - ActionIdentifier: action, - } - - if target.Signature().String() == "s" { - var targetStr string - if err := target.Store(&targetStr); err == nil { - var userInfo map[string]interface{} - userInfoStr, err := base64.StdEncoding.DecodeString(targetStr) - if err != nil { - if err := json.Unmarshal([]byte(targetStr), &userInfo); err == nil { - response.UserInfo = userInfo - } - } - if err := json.Unmarshal(userInfoStr, &userInfo); err == nil { - response.UserInfo = userInfo - } - } - } - - // if notifierResponse.Signature().String() == "s" { - // var userText string - // if err := notifierResponse.Store(&userText); err == nil { - // response.UserText = userText - // } - // } - - if NotificationService != nil { - NotificationService.handleNotificationResponse(response) - } + var err error + initOnce.Do(func() { + err = notifier.init() }) - if err != nil { - return fmt.Errorf("failed to create notifier: %v", err) - } - - return nil + return err } // ServiceShutdown is called when the service is unloaded func (ns *Service) ServiceShutdown() error { + if notifier != nil && notifier.dbusConn != nil { + notifier.dbusConn.Close() + } return saveCategories() } +// Initialize the notifier and choose the best available notification method +func (n *internalNotifier) init() error { + var err error + + checkDbus := func() (*dbus.Conn, error) { + conn, err := dbus.SessionBusPrivate() + if err != nil { + return conn, err + } + + if err = conn.Auth(nil); err != nil { + return conn, err + } + + if err = conn.Hello(); err != nil { + return conn, err + } + + obj := conn.Object(dbusNotificationsInterface, dbusObjectPath) + call := obj.Call(callGetCapabilities, 0) + if call.Err != nil { + return conn, call.Err + } + + var ret []string + err = call.Store(&ret) + if err != nil { + return conn, err + } + + // Add a listener for notification signals + err = conn.AddMatchSignal( + dbus.WithMatchObjectPath(dbusObjectPath), + dbus.WithMatchInterface(dbusNotificationsInterface), + ) + if err != nil { + return nil, err + } + + return conn, nil + } + + // Try dbus first + n.dbusConn, err = checkDbus() + if err == nil { + n.method = MethodDbus + // Start the dbus signal listener + go n.startDBusListener() + return nil + } + if n.dbusConn != nil { + n.dbusConn.Close() + n.dbusConn = nil + } + + // Try notify-send + send, err := exec.LookPath("notify-send") + if err == nil { + n.sendPath = send + n.method = MethodNotifySend + return nil + } + + // Try sw-notify-send + send, err = exec.LookPath("sw-notify-send") + if err == nil { + n.sendPath = send + n.method = MethodNotifySend + return nil + } + + // No method available + n.method = "none" + n.sendPath = "" + + return errors.New("no notification method is available") +} + +// startDBusListener listens for DBus signals for notification actions and closures +func (n *internalNotifier) startDBusListener() { + signal := make(chan *dbus.Signal, notifyChannelBufferSize) + n.dbusConn.Signal(signal) + + for s := range signal { + if s == nil || len(s.Body) < 2 { + continue + } + + switch s.Name { + case signalNotificationClosed: + systemID := s.Body[0].(uint32) + reason := closedReason(s.Body[1].(uint32)).string() + n.handleNotificationClosed(systemID, reason) + case signalActionInvoked: + systemID := s.Body[0].(uint32) + actionKey := s.Body[1].(string) + n.handleActionInvoked(systemID, actionKey) + } + } +} + +// handleNotificationClosed processes notification closed signals +func (n *internalNotifier) handleNotificationClosed(systemID uint32, reason string) { + // Find our notification ID for this system ID + var notifID string + var userData map[string]interface{} + + n.Lock() + for id, sysID := range n.activeNotifs { + if sysID == systemID { + notifID = id + // Get the user data from context if available + if ctx, exists := n.contexts[id]; exists { + userData = ctx.UserData + } + break + } + } + n.Unlock() + + if notifID != "" && NotificationService != nil { + response := NotificationResponse{ + ID: notifID, + ActionIdentifier: DefaultActionIdentifier, + UserInfo: userData, + } + + // Add reason to UserInfo or create it if none exists + if response.UserInfo == nil { + response.UserInfo = map[string]interface{}{ + "reason": reason, + } + } else { + response.UserInfo["reason"] = reason + } + + NotificationService.handleNotificationResponse(response) + + // Clean up the context + n.Lock() + delete(n.contexts, notifID) + delete(n.activeNotifs, notifID) + n.Unlock() + } +} + +// handleActionInvoked processes action invoked signals +func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string) { + // Find our notification ID and context for this system ID + var notifID string + var ctx *notificationContext + + n.Lock() + for id, sysID := range n.activeNotifs { + if sysID == systemID { + notifID = id + ctx = n.contexts[id] + break + } + } + n.Unlock() + + if notifID != "" && NotificationService != nil { + // First, send the action response with the user data + response := NotificationResponse{ + ID: notifID, + ActionIdentifier: actionKey, + } + + // Include the user data if we have it + if ctx != nil { + response.UserInfo = ctx.UserData + } + + NotificationService.handleNotificationResponse(response) + + // Then, trigger a closed event with "activated-by-user" reason + closeResponse := NotificationResponse{ + ID: notifID, + ActionIdentifier: DefaultActionIdentifier, + } + + // Include the same user data in the close response + if ctx != nil { + closeResponse.UserInfo = ctx.UserData + } else { + closeResponse.UserInfo = map[string]interface{}{} + } + + // Add the reason to the user info + closeResponse.UserInfo["reason"] = closedReason(5).string() // "activated-by-user" + + NotificationService.handleNotificationResponse(closeResponse) + + // Clean up the context + n.Lock() + delete(n.contexts, notifID) + delete(n.activeNotifs, notifID) + n.Unlock() + } +} + // CheckBundleIdentifier is a Linux stub that always returns true. // (bundle identifiers are macOS-specific) -func CheckBundleIdentifier() bool { +func (ns *Service) CheckBundleIdentifier() bool { return true } -// RequestUserNotificationAuthorization is a Linux stub that always returns true, nil. +// RequestUserNotificationAuthorization is a Linux stub that always returns true. // (user authorization is macOS-specific) func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { return true, nil @@ -122,77 +335,191 @@ func (ns *Service) CheckNotificationAuthorization() (bool, error) { // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ns *Service) SendNotification(options NotificationOptions) error { - notification := shout.Notification{ - Title: options.Title, - Body: options.Body, - Priority: shout.Normal, - DefaultAction: DefaultActionIdentifier, + if notifier == nil { + return errors.New("notification service not initialized") } - if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err == nil { - notification.DefaultActionTarget = dbus.MakeVariant(base64.StdEncoding.EncodeToString(jsonData)) + notifier.Lock() + defer notifier.Unlock() + + var ( + systemID uint32 + err error + ) + + switch notifier.method { + case MethodDbus: + systemID, err = notifier.sendViaDbus(options, nil) + case MethodNotifySend: + systemID, err = notifier.sendViaNotifySend(options) + default: + err = errors.New("no notification method is available") + } + + if err == nil && systemID > 0 { + // Store the system ID mapping + notifier.activeNotifs[options.ID] = systemID + + // Create and store the notification context + ctx := ¬ificationContext{ + ID: options.ID, + SystemID: systemID, + UserData: options.Data, } + notifier.contexts[options.ID] = ctx } - return Notifier.Send(options.ID, notification) + return err } -// SendNotificationWithActions sends a notification with additional actions and inputs. +// SendNotificationWithActions sends a notification with additional actions. func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { - NotificationLock.RLock() - category, exists := NotificationCategories[options.CategoryID] - NotificationLock.RUnlock() + if notifier == nil { + return errors.New("notification service not initialized") + } + + notificationLock.RLock() + category, exists := notificationCategories[options.CategoryID] + notificationLock.RUnlock() if !exists { return ns.SendNotification(options) } - notification := shout.Notification{ - Title: options.Title, - Body: options.Body, - Priority: shout.Normal, - DefaultAction: DefaultActionIdentifier, + notifier.Lock() + defer notifier.Unlock() + + var ( + systemID uint32 + err error + ) + + switch notifier.method { + case MethodDbus: + systemID, err = notifier.sendViaDbus(options, &category) + case MethodNotifySend: + // notify-send doesn't support actions, fall back to basic notification + systemID, err = notifier.sendViaNotifySend(options) + default: + err = errors.New("no notification method is available") } - if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err == nil { - notification.DefaultActionTarget = dbus.MakeVariant(base64.StdEncoding.EncodeToString(jsonData)) + if err == nil && systemID > 0 { + // Store the system ID mapping + notifier.activeNotifs[options.ID] = systemID + + // Create and store the notification context with actions + ctx := ¬ificationContext{ + ID: options.ID, + SystemID: systemID, + UserData: options.Data, + Actions: make(map[string]string), } - } - for _, action := range category.Actions { - var targetStr string = "" - if options.Data != nil { - if jsonData, err := json.Marshal(options.Data); err == nil { - targetStr = base64.StdEncoding.EncodeToString(jsonData) + // Store action mappings + if exists { + for _, action := range category.Actions { + ctx.Actions[action.ID] = action.Title } } - notification.Buttons = append(notification.Buttons, shout.Button{ - Label: action.Title, - Action: action.ID, - Target: targetStr, - }) + + notifier.contexts[options.ID] = ctx } - return Notifier.Send(options.ID, notification) + return err +} + +// sendViaDbus sends a notification via dbus +func (n *internalNotifier) sendViaDbus(options NotificationOptions, category *NotificationCategory) (result uint32, err error) { + // Prepare actions + var actions []string + if category != nil { + for _, action := range category.Actions { + actions = append(actions, action.ID, action.Title) + } + } + + // Default timeout (-1 means use system default) + timeout := int32(-1) + + // Prepare hints + hints := map[string]dbus.Variant{ + // Normal urgency by default + "urgency": dbus.MakeVariant(byte(1)), + } + + // Add user data to hints if available + if options.Data != nil { + if userData, err := json.Marshal(options.Data); err == nil { + hints["x-wails-user-data"] = dbus.MakeVariant(string(userData)) + } + } + + // Send the notification + obj := n.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) + dbusArgs := []interface{}{ + appName, // App name + uint32(0), // Replaces ID (0 means new notification) + "", // App icon (empty for now) + options.Title, // Title + options.Body, // Body + actions, // Actions + hints, // Hints + timeout, // Timeout + } + + call := obj.Call("org.freedesktop.Notifications.Notify", 0, dbusArgs...) + if call.Err != nil { + return 0, fmt.Errorf("dbus notification error: %v", call.Err) + } + + err = call.Store(&result) + if err != nil { + return 0, err + } + + return result, nil +} + +// sendViaNotifySend sends a notification via notify-send command +func (n *internalNotifier) sendViaNotifySend(options NotificationOptions) (uint32, error) { + args := []string{ + options.Title, + options.Body, + } + + // Add icon if eventually supported + // if options.Icon != "" { ... } + + // Add urgency (normal by default) + args = append(args, "--urgency=normal") + + // Execute the command + cmd := exec.Command(n.sendPath, args...) + err := cmd.Run() + if err != nil { + return 0, fmt.Errorf("notify-send error: %v", err) + } + + // notify-send doesn't return IDs, so we use 0 + return 0, nil } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { - NotificationLock.Lock() - NotificationCategories[category.ID] = category - NotificationLock.Unlock() + notificationLock.Lock() + notificationCategories[category.ID] = category + notificationLock.Unlock() + return saveCategories() } // RemoveNotificationCategory removes a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { - NotificationLock.Lock() - delete(NotificationCategories, categoryId) - NotificationLock.Unlock() + notificationLock.Lock() + delete(notificationCategories, categoryId) + notificationLock.Unlock() + return saveCategories() } @@ -222,7 +549,24 @@ func (ns *Service) RemoveDeliveredNotification(_ string) error { // RemoveNotification removes a notification by ID (Linux-specific) func (ns *Service) RemoveNotification(identifier string) error { - return Notifier.Remove(identifier) + if notifier == nil || notifier.method != MethodDbus || notifier.dbusConn == nil { + return errors.New("dbus not available for closing notifications") + } + + // Get the system ID for this notification + notifier.Lock() + systemID, exists := notifier.activeNotifs[identifier] + notifier.Unlock() + + if !exists { + return nil // Already closed or unknown + } + + // Call CloseNotification on dbus + obj := notifier.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) + call := obj.Call(callCloseNotification, 0, systemID) + + return call.Err } // getConfigFilePath returns the path to the configuration file for storing notification categories @@ -247,9 +591,9 @@ func saveCategories() error { return err } - NotificationLock.RLock() - data, err := json.Marshal(NotificationCategories) - NotificationLock.RUnlock() + notificationLock.RLock() + data, err := json.Marshal(notificationCategories) + notificationLock.RUnlock() if err != nil { return fmt.Errorf("failed to marshal notification categories: %v", err) @@ -287,9 +631,9 @@ func loadCategories() error { return fmt.Errorf("failed to unmarshal notification categories: %v", err) } - NotificationLock.Lock() - NotificationCategories = categories - NotificationLock.Unlock() + notificationLock.Lock() + notificationCategories = categories + notificationLock.Unlock() return nil } From db2cab7b7cfd3101e03cc0485a29b01000b55753 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Tue, 25 Feb 2025 18:04:08 -0800 Subject: [PATCH 042/136] grab icon from app for notifications on windows --- .../notifications/notifications_windows.go | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 1e1cf7f9e..53a879522 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -9,7 +9,6 @@ import ( "fmt" "os" "path/filepath" - "strings" "sync" "git.sr.ht/~jackmordaunt/go-toast/v2" @@ -39,9 +38,6 @@ func New() *Service { // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { appName := application.Get().Config().Name - icon := application.Get().Config().Icon - - println(icon) guid, err := getGUID(appName) if err != nil { @@ -51,7 +47,7 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi toast.SetAppData(toast.AppData{ AppID: appName, GUID: guid, - IconPath: "C:\\Users\\Zach\\Development\\notifications_demo\\build\\appicon.ico", + IconPath: filepath.Join(os.TempDir(), appName+guid+".png"), }) toast.SetActivationCallback(func(args string, data []toast.UserData) { @@ -105,11 +101,14 @@ func (ns *Service) CheckNotificationAuthorization() bool { // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { + if err := saveIconToDir(); err != nil { + fmt.Printf("Error saving icon: %v\n", err) + } + n := toast.Notification{ Title: options.Title, Body: options.Body, ActivationArguments: DefaultActionIdentifier, - Audio: toast.IM, } if options.Data != nil { @@ -127,6 +126,10 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // If a NotificationCategory is not registered a basic notification will be sent. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + if err := saveIconToDir(); err != nil { + fmt.Printf("Error saving icon: %v\n", err) + } + NotificationLock.RLock() nCategory := NotificationCategories[options.CategoryID] NotificationLock.RUnlock() @@ -135,7 +138,6 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro Title: options.Title, Body: options.Body, ActivationArguments: DefaultActionIdentifier, - Audio: toast.IM, } for _, action := range nCategory.Actions { @@ -273,18 +275,27 @@ func parseNotificationResponse(response string) (action string, data string) { return actionID, "" } -// Is there a better way for me to grab this from the Wails config? -func getExeName() string { - executable, err := os.Executable() - if err != nil { - return "" +func saveIconToDir() error { + options := application.Get().Config() + appName := options.Name + icon := options.Icon + + if len(icon) == 0 { + return fmt.Errorf("failed to retrieve icon from application") } - return strings.TrimSuffix(filepath.Base(executable), filepath.Ext(executable)) + guid, err := getGUID(appName) + if err != nil { + return fmt.Errorf("failed to retrieve application guid from registry") + } + + iconPath := filepath.Join(os.TempDir(), appName+guid+".png") + + return os.WriteFile(iconPath, icon, 0644) } func saveCategoriesToRegistry() error { - appName := getExeName() + appName := application.Get().Config().Name if appName == "" { return fmt.Errorf("failed to save categories to registry: empty executable name") } @@ -311,7 +322,7 @@ func saveCategoriesToRegistry() error { } func loadCategoriesFromRegistry() error { - appName := getExeName() + appName := application.Get().Config().Name if appName == "" { return fmt.Errorf("failed to save categories to registry: empty executable name") } From e216b3e513acf59f340b32ce6d36b8e105befcd1 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Wed, 26 Feb 2025 09:32:32 -0800 Subject: [PATCH 043/136] set icon --- .../notifications/notifications_darwin.go | 7 ++++- .../notifications/notifications_linux.go | 2 ++ .../notifications/notifications_windows.go | 26 ++++++++++++------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index f001d6fde..81b6364c4 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -212,6 +212,11 @@ func (ns *Service) RemoveNotification(identifier string) error { return nil } +// SetIcon is a macOS stub. The application icon is used automatically. +func (ns *Service) SetIcon(_ []byte) { + return +} + //export didReceiveNotificationResponse func didReceiveNotificationResponse(jsonPayload *C.char) { payload := C.GoString(jsonPayload) @@ -221,7 +226,7 @@ func didReceiveNotificationResponse(jsonPayload *C.char) { return } - if response.ActionIdentifier == "com.apple.UNNotificationDefaultActionIdentifier" { + if response.ActionIdentifier == AppleDefaultActionIdentifier { response.ActionIdentifier = DefaultActionIdentifier } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index c6734e83f..29c5270af 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -1,5 +1,7 @@ //go:build linux +// WIP - WILL NOT WORK PROPERLY + package notifications import ( diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 53a879522..51de4311c 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -4,6 +4,7 @@ package notifications import ( "context" + _ "embed" "encoding/base64" "encoding/json" "fmt" @@ -19,6 +20,7 @@ import ( var NotificationLock sync.RWMutex var NotificationCategories = make(map[string]NotificationCategory) +var Icon []byte // NotificationPayload combines the action ID and user data into a single structure type NotificationPayload struct { @@ -101,8 +103,10 @@ func (ns *Service) CheckNotificationAuthorization() bool { // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { - if err := saveIconToDir(); err != nil { - fmt.Printf("Error saving icon: %v\n", err) + if len(Icon) > 0 { + if err := saveIconToDir(); err != nil { + fmt.Printf("Error saving icon: %v\n", err) + } } n := toast.Notification{ @@ -126,8 +130,10 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // If a NotificationCategory is not registered a basic notification will be sent. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { - if err := saveIconToDir(); err != nil { - fmt.Printf("Error saving icon: %v\n", err) + if len(Icon) > 0 { + if err := saveIconToDir(); err != nil { + fmt.Printf("Error saving icon: %v\n", err) + } } NotificationLock.RLock() @@ -230,6 +236,11 @@ func (ns *Service) RemoveNotification(identifier string) error { return nil } +// SetIcon sets the notifications icon. +func (ns *Service) SetIcon(icon []byte) { + Icon = icon +} + // encodePayload combines an action ID and user data into a single encoded string func encodePayload(actionID string, data map[string]interface{}) (string, error) { payload := NotificationPayload{ @@ -278,11 +289,6 @@ func parseNotificationResponse(response string) (action string, data string) { func saveIconToDir() error { options := application.Get().Config() appName := options.Name - icon := options.Icon - - if len(icon) == 0 { - return fmt.Errorf("failed to retrieve icon from application") - } guid, err := getGUID(appName) if err != nil { @@ -291,7 +297,7 @@ func saveIconToDir() error { iconPath := filepath.Join(os.TempDir(), appName+guid+".png") - return os.WriteFile(iconPath, icon, 0644) + return os.WriteFile(iconPath, Icon, 0644) } func saveCategoriesToRegistry() error { From 3bdb3ddba359c99a07b38bc06cda61f7adea645e Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Wed, 26 Feb 2025 12:30:31 -0800 Subject: [PATCH 044/136] use app icon --- .../notifications/notifications_windows.go | 81 ++++---- .../notifications_windows_icon.go | 173 ++++++++++++++++++ 2 files changed, 210 insertions(+), 44 deletions(-) create mode 100644 v3/pkg/services/notifications/notifications_windows_icon.go diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 51de4311c..ddb71f528 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -15,12 +15,24 @@ import ( "git.sr.ht/~jackmordaunt/go-toast/v2" "github.com/google/uuid" "github.com/wailsapp/wails/v3/pkg/application" + "github.com/wailsapp/wails/v3/pkg/w32" "golang.org/x/sys/windows/registry" ) -var NotificationLock sync.RWMutex -var NotificationCategories = make(map[string]NotificationCategory) -var Icon []byte +var ( + NotificationLock sync.RWMutex + NotificationCategories = make(map[string]NotificationCategory) + AppName string + AppGUID string + IconPath string +) + +const ( + ToastRegistryPath = `Software\Classes\AppUserModelId\` + ToastRegistryGuidKey = "CustomActivator" + NotificationCategoriesRegistryPath = `SOFTWARE\%s\NotificationCategories` + NotificationCategoriesRegistryKey = "Categories" +) // NotificationPayload combines the action ID and user data into a single structure type NotificationPayload struct { @@ -39,17 +51,20 @@ func New() *Service { // ServiceStartup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - appName := application.Get().Config().Name + AppName = application.Get().Config().Name - guid, err := getGUID(appName) + guid, err := getGUID() if err != nil { return err } + AppGUID = guid + + IconPath = filepath.Join(os.TempDir(), AppName+guid+".png") toast.SetAppData(toast.AppData{ - AppID: appName, + AppID: AppName, GUID: guid, - IconPath: filepath.Join(os.TempDir(), appName+guid+".png"), + IconPath: IconPath, }) toast.SetActivationCallback(func(args string, data []toast.UserData) { @@ -103,10 +118,8 @@ func (ns *Service) CheckNotificationAuthorization() bool { // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { - if len(Icon) > 0 { - if err := saveIconToDir(); err != nil { - fmt.Printf("Error saving icon: %v\n", err) - } + if err := saveIconToDir(); err != nil { + fmt.Printf("Error saving icon: %v\n", err) } n := toast.Notification{ @@ -130,10 +143,8 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // If a NotificationCategory is not registered a basic notification will be sent. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { - if len(Icon) > 0 { - if err := saveIconToDir(); err != nil { - fmt.Printf("Error saving icon: %v\n", err) - } + if err := saveIconToDir(); err != nil { + fmt.Printf("Error saving icon: %v\n", err) } NotificationLock.RLock() @@ -236,11 +247,6 @@ func (ns *Service) RemoveNotification(identifier string) error { return nil } -// SetIcon sets the notifications icon. -func (ns *Service) SetIcon(icon []byte) { - Icon = icon -} - // encodePayload combines an action ID and user data into a single encoded string func encodePayload(actionID string, data map[string]interface{}) (string, error) { payload := NotificationPayload{ @@ -287,25 +293,16 @@ func parseNotificationResponse(response string) (action string, data string) { } func saveIconToDir() error { - options := application.Get().Config() - appName := options.Name - - guid, err := getGUID(appName) + icon, err := application.NewIconFromResource(w32.GetModuleHandle(""), uint16(3)) if err != nil { - return fmt.Errorf("failed to retrieve application guid from registry") + return fmt.Errorf("failed to retrieve application icon") } - iconPath := filepath.Join(os.TempDir(), appName+guid+".png") - - return os.WriteFile(iconPath, Icon, 0644) + return saveHIconAsPNG(icon, IconPath) } func saveCategoriesToRegistry() error { - appName := application.Get().Config().Name - if appName == "" { - return fmt.Errorf("failed to save categories to registry: empty executable name") - } - registryPath := fmt.Sprintf(`SOFTWARE\%s\NotificationCategories`, appName) + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, AppName) key, _, err := registry.CreateKey( registry.CURRENT_USER, @@ -324,15 +321,11 @@ func saveCategoriesToRegistry() error { return err } - return key.SetStringValue("Categories", string(data)) + return key.SetStringValue(NotificationCategoriesRegistryKey, string(data)) } func loadCategoriesFromRegistry() error { - appName := application.Get().Config().Name - if appName == "" { - return fmt.Errorf("failed to save categories to registry: empty executable name") - } - registryPath := fmt.Sprintf(`SOFTWARE\%s\NotificationCategories`, appName) + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, AppName) key, err := registry.OpenKey( registry.CURRENT_USER, @@ -347,7 +340,7 @@ func loadCategoriesFromRegistry() error { } defer key.Close() - data, _, err := key.GetStringValue("Categories") + data, _, err := key.GetStringValue(NotificationCategoriesRegistryKey) if err != nil { return err } @@ -373,12 +366,12 @@ func getUserText(data []toast.UserData) (string, bool) { return "", false } -func getGUID(name string) (string, error) { - keyPath := `Software\Classes\AppUserModelId\` + name +func getGUID() (string, error) { + keyPath := ToastRegistryPath + AppName k, err := registry.OpenKey(registry.CURRENT_USER, keyPath, registry.QUERY_VALUE) if err == nil { - guid, _, err := k.GetStringValue("CustomActivator") + guid, _, err := k.GetStringValue(ToastRegistryGuidKey) k.Close() if err == nil && guid != "" { return guid, nil @@ -393,7 +386,7 @@ func getGUID(name string) (string, error) { } defer k.Close() - if err := k.SetStringValue("CustomActivator", guid); err != nil { + if err := k.SetStringValue(ToastRegistryGuidKey, guid); err != nil { return "", fmt.Errorf("failed to write GUID to registry: %w", err) } diff --git a/v3/pkg/services/notifications/notifications_windows_icon.go b/v3/pkg/services/notifications/notifications_windows_icon.go new file mode 100644 index 000000000..aed560594 --- /dev/null +++ b/v3/pkg/services/notifications/notifications_windows_icon.go @@ -0,0 +1,173 @@ +//go:build windows + +package notifications + +import ( + "image" + "image/color" + "image/png" + "os" + "syscall" + "unsafe" + + "github.com/wailsapp/wails/v3/pkg/w32" +) + +// Windows API constants +const ( + SRCCOPY = 0x00CC0020 + BI_RGB = 0 + DIB_RGB_COLORS = 0 +) + +// Windows structures +type ICONINFO struct { + FIcon int32 + XHotspot int32 + YHotspot int32 + HbmMask syscall.Handle + HbmColor syscall.Handle +} + +type BITMAP struct { + BmType int32 + BmWidth int32 + BmHeight int32 + BmWidthBytes int32 + BmPlanes uint16 + BmBitsPixel uint16 + BmBits uintptr +} + +type BITMAPINFOHEADER struct { + BiSize uint32 + BiWidth int32 + BiHeight int32 + BiPlanes uint16 + BiBitCount uint16 + BiCompression uint32 + BiSizeImage uint32 + BiXPelsPerMeter int32 + BiYPelsPerMeter int32 + BiClrUsed uint32 + BiClrImportant uint32 +} + +type RGBQUAD struct { + RgbBlue byte + RgbGreen byte + RgbRed byte + RgbReserved byte +} + +type BITMAPINFO struct { + BmiHeader BITMAPINFOHEADER + BmiColors [1]RGBQUAD +} + +func saveHIconAsPNG(hIcon w32.HICON, filePath string) error { + // Load necessary DLLs + user32 := syscall.NewLazyDLL("user32.dll") + gdi32 := syscall.NewLazyDLL("gdi32.dll") + + // Get procedures + getIconInfo := user32.NewProc("GetIconInfo") + getObject := gdi32.NewProc("GetObjectW") + createCompatibleDC := gdi32.NewProc("CreateCompatibleDC") + selectObject := gdi32.NewProc("SelectObject") + getDIBits := gdi32.NewProc("GetDIBits") + deleteObject := gdi32.NewProc("DeleteObject") + deleteDC := gdi32.NewProc("DeleteDC") + + // Get icon info + var iconInfo ICONINFO + ret, _, err := getIconInfo.Call( + uintptr(hIcon), + uintptr(unsafe.Pointer(&iconInfo)), + ) + if ret == 0 { + return err + } + defer deleteObject.Call(uintptr(iconInfo.HbmMask)) + defer deleteObject.Call(uintptr(iconInfo.HbmColor)) + + // Get bitmap info + var bmp BITMAP + ret, _, err = getObject.Call( + uintptr(iconInfo.HbmColor), + unsafe.Sizeof(bmp), + uintptr(unsafe.Pointer(&bmp)), + ) + if ret == 0 { + return err + } + + // Create DC + hdc, _, _ := createCompatibleDC.Call(0) + if hdc == 0 { + return syscall.EINVAL + } + defer deleteDC.Call(hdc) + + // Select bitmap into DC + oldBitmap, _, _ := selectObject.Call(hdc, uintptr(iconInfo.HbmColor)) + defer selectObject.Call(hdc, oldBitmap) + + // Prepare bitmap info header + var bi BITMAPINFO + bi.BmiHeader.BiSize = uint32(unsafe.Sizeof(bi.BmiHeader)) + bi.BmiHeader.BiWidth = bmp.BmWidth + bi.BmiHeader.BiHeight = bmp.BmHeight + bi.BmiHeader.BiPlanes = 1 + bi.BmiHeader.BiBitCount = 32 + bi.BmiHeader.BiCompression = BI_RGB + + // Allocate memory for bitmap bits + width, height := int(bmp.BmWidth), int(bmp.BmHeight) + bufferSize := width * height * 4 + bits := make([]byte, bufferSize) + + // Get bitmap bits + ret, _, err = getDIBits.Call( + hdc, + uintptr(iconInfo.HbmColor), + 0, + uintptr(bmp.BmHeight), + uintptr(unsafe.Pointer(&bits[0])), + uintptr(unsafe.Pointer(&bi)), + DIB_RGB_COLORS, + ) + if ret == 0 { + return err + } + + // Create Go image + img := image.NewRGBA(image.Rect(0, 0, width, height)) + + // Convert DIB to RGBA + for y := 0; y < height; y++ { + for x := 0; x < width; x++ { + // DIB is bottom-up, so we need to invert Y + dibIndex := ((height-1-y)*width + x) * 4 + + // BGRA to RGBA + b := bits[dibIndex] + g := bits[dibIndex+1] + r := bits[dibIndex+2] + a := bits[dibIndex+3] + + // Set pixel in the image + img.Set(x, y, color.RGBA{R: r, G: g, B: b, A: a}) + } + } + + // Create output file + outFile, err := os.Create(filePath) + if err != nil { + return err + } + defer outFile.Close() + + // Encode and save the image + return png.Encode(outFile, img) +} From a807c269cca0d629dca14f9efbd3d8f588177aae Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Wed, 26 Feb 2025 18:45:46 -0800 Subject: [PATCH 045/136] better interop with obj-c --- .../services/notifications/notifications.go | 27 ++-- .../notifications/notifications_darwin.go | 133 ++++++++++++++++-- .../notifications/notifications_darwin.h | 8 +- .../notifications/notifications_darwin.m | 38 ++--- .../notifications/notifications_windows.go | 51 +++---- 5 files changed, 183 insertions(+), 74 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index a40177af2..d971959ac 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -1,12 +1,17 @@ package notifications +import "sync" + // Service represents the notifications service type Service struct { - // Callback is called when a notification response is received - Callback func(response NotificationResponse) + // notificationResponseCallback is called when a notification response is received + notificationResponseCallback func(response NotificationResponse) + + callbackLock sync.RWMutex } var NotificationService *Service +var notificationServiceLock sync.RWMutex // NotificationAction represents an action button for a notification type NotificationAction = struct { @@ -54,18 +59,22 @@ func (ns *Service) ServiceName() string { } // OnNotificationResponse registers a callback function that will be called when -// a notification response is received from the user +// a notification response is received from the user. func (ns *Service) OnNotificationResponse(callback func(response NotificationResponse)) { - if ns.Callback != nil { - return - } - ns.Callback = callback + ns.callbackLock.Lock() + defer ns.callbackLock.Unlock() + + ns.notificationResponseCallback = callback } // handleNotificationResponse is an internal method to handle notification responses // and invoke the registered callback if one exists func (ns *Service) handleNotificationResponse(response NotificationResponse) { - if ns.Callback != nil { - ns.Callback(response) + ns.callbackLock.RLock() + callback := ns.notificationResponseCallback + ns.callbackLock.RUnlock() + + if callback != nil { + callback(response) } } diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 81b6364c4..2781ceb7c 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -12,16 +12,32 @@ import ( "context" "encoding/json" "fmt" + "sync" "unsafe" "github.com/wailsapp/wails/v3/pkg/application" ) -var AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" +type notificationChannel struct { + authorized bool + err error +} + +var ( + notificationChannels = make(map[int]chan notificationChannel) + notificationChannelsLock sync.Mutex + nextChannelID int +) + +const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" +const BundleIdentifierError = fmt.Errorf("notifications require a bundled application with a unique bundle identifier") // Creates a new Notifications Service. // Your app must be packaged and signed for this feature to work. func New() *Service { + notificationServiceLock.Lock() + defer notificationServiceLock.Unlock() + if NotificationService == nil { NotificationService = &Service{} } @@ -31,7 +47,7 @@ func New() *Service { // ServiceStartup is called when the service is loaded. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") + return BundleIdentifierError } return nil } @@ -45,21 +61,32 @@ func CheckBundleIdentifier() bool { return bool(C.checkBundleIdentifier()) } -// RequestUserNotificationAuthorization requests permission for notifications. -func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { +// RequestNotificationAuthorization requests permission for notifications. +func (ns *Service) RequestNotificationAuthorization() (bool, err) { if !CheckBundleIdentifier() { - return false, fmt.Errorf("notifications require a bundled application with a unique bundle identifier") + return false, BundleIdentifierError } - result := C.requestUserNotificationAuthorization(nil) - return result == true, nil + + id, resultCh := registerChannel() + + C.requestNotificationAuthorization(C.int(id)) + + result := <-resultCh + return result.authorized, result.err } // CheckNotificationAuthorization checks current notification permission status. -func (ns *Service) CheckNotificationAuthorization() (bool, error) { +func (ns *Service) CheckNotificationAuthorization() (bool, err) { if !CheckBundleIdentifier() { - return false, fmt.Errorf("notifications require a bundled application with a unique bundle identifier") + return false, BundleIdentifierError } - return bool(C.checkNotificationAuthorization()), nil + + id, resultCh := registerChannel() + + C.checkNotificationAuthorization(C.int(id)) + + result := <-resultCh + return result.authorized, result.err } // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. @@ -212,9 +239,48 @@ func (ns *Service) RemoveNotification(identifier string) error { return nil } -// SetIcon is a macOS stub. The application icon is used automatically. -func (ns *Service) SetIcon(_ []byte) { - return +//export requestNotificationAuthorizationResponse +func requestNotificationAuthorizationResponse(channelID C.int, authorized C.bool, errorMsg *C.char) { + resultCh, exists := getAndDeleteChannel(int(channelID)) + if !exists { + // handle this + return + } + + var err error + if errorMsg != nil { + err = fmt.Errorf("%s", C.GoString(errorMsg)) + C.free(unsafe.Pointer(errorMsg)) + } + + resultCh <- notificationChannel{ + authorized: bool(authorized), + err: err, + } + + close(resultCh) +} + +//export checkNotificationAuthorizationResponse +func checkNotificationAuthorizationResponse(channelID C.int, authorized C.bool, errorMsg *C.char) { + resultCh, exists := getAndDeleteChannel(int(channelID)) + if !exists { + // handle this + return + } + + var err error + if errorMsg != nil { + err = fmt.Errorf("%s", C.GoString(errorMsg)) + C.free(unsafe.Pointer(errorMsg)) + } + + resultCh <- notificationChannel{ + authorized: bool(authorized), + err: err, + } + + close(resultCh) } //export didReceiveNotificationResponse @@ -230,7 +296,44 @@ func didReceiveNotificationResponse(jsonPayload *C.char) { response.ActionIdentifier = DefaultActionIdentifier } - if NotificationService != nil { - NotificationService.handleNotificationResponse(response) + notificationServiceLock.RLock() + ns := NotificationService + notificationServiceLock.RUnlock() + + if service != nil { + ns.callbackLock.RLock() + callback := ns.notificationResponseCallback + ns.callbackLock.RUnlock() + + if callback != nil { + callback(response) + } } } + +func registerChannel() (int, chan notificationChannel) { + notificationChannelsLock.Lock() + defer notificationChannelsLock.Unlock() + + id := nextChannelID + nextChannelID++ + + resultCh := make(chan notificationChannel{ + authorized bool + err error + }, 1) + + notificationChannels[id] = resultCh + return id, resultCh +} + +func getChannel(id int) (chan notificationChannel, bool) { + notificationChannelsLock.Lock() + defer notificationChannelsLock.Unlock() + + ch, exists := notificationChannels[id] + if exists { + delete(notificationChannels, id) + } + return ch, exists +} diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index 21a210289..9b2bb6774 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -6,8 +6,8 @@ #import bool checkBundleIdentifier(void); -bool requestUserNotificationAuthorization(void *completion); -bool checkNotificationAuthorization(void); +bool requestNotificationAuthorization(void *channelPtr); +bool checkNotificationAuthorization(void *channelPtr); void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json, void *completion); void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json, void *completion); void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); @@ -17,4 +17,8 @@ void removePendingNotification(const char *identifier); void removeAllDeliveredNotifications(void); void removeDeliveredNotification(const char *identifier); +extern void requestNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); +extern void checkNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); +extern void didReceiveNotificationResponse(const char *jsonPayload); + #endif /* NOTIFICATIONS_DARWIN_H */ \ No newline at end of file diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 4a1514e06..3469d69d4 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -2,8 +2,6 @@ #import #import -extern void didReceiveNotificationResponse(const char *jsonPayload); - @interface NotificationsDelegate : NSObject @end @@ -71,8 +69,8 @@ static void ensureDelegateInitialized(void) { bool checkBundleIdentifier(void) { NSBundle *main = [NSBundle mainBundle]; if (main.bundleIdentifier == nil) { - NSLog(@"Error: Cannot use notifications in development mode.\n" - " Notifications require the app to be properly bundled with a bundle identifier.\n" + NSLog(@"Error: Cannot use the notification API in development mode.\n" + " Notifications require the app to be properly bundled with a bundle identifier and signed.\n" " To test notifications:\n" " 1. Build and package your app using 'wails3 package'\n" " 2. Sign the packaged .app\n" @@ -82,40 +80,32 @@ bool checkBundleIdentifier(void) { return true; } -bool requestUserNotificationAuthorization(void *completion) { - if (!checkBundleIdentifier()) { - return false; - } - +bool requestNotificationAuthorization(int channelID) { ensureDelegateInitialized(); UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; + [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) { - if (completion != NULL) { - void (^callback)(NSError *, BOOL) = completion; - callback(error, granted); + if (error) { + requestNotificationAuthorizationResponse(channelID, false, [[error localizedDescription] UTF8String]); + } else { + requestNotificationAuthorizationResponse(channelID, granted, NULL); } }]; - return true; } -bool checkNotificationAuthorization(void) { +bool checkNotificationAuthorization(int channelID) { ensureDelegateInitialized(); - __block BOOL isAuthorized = NO; - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { - isAuthorized = (settings.authorizationStatus == UNAuthorizationStatusAuthorized); - dispatch_semaphore_signal(semaphore); + [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) { + BOOL isAuthorized = (settings.authorizationStatus == UNAuthorizationStatusAuthorized); + checkNotificationAuthorizationResponse(channelID, isAuthorized, NULL); }]; - - // Wait for response with a timeout - dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC)); - return isAuthorized; } void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json, void *completion) { diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index ddb71f528..36466de94 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -20,11 +20,11 @@ import ( ) var ( - NotificationLock sync.RWMutex - NotificationCategories = make(map[string]NotificationCategory) - AppName string - AppGUID string - IconPath string + NotificationCategories = make(map[string]NotificationCategory) + notificationCategoriesLock sync.RWMutex + appName string + appGUID string + iconPath string ) const ( @@ -42,6 +42,9 @@ type NotificationPayload struct { // Creates a new Notifications Service. func New() *Service { + notificationServiceLock.Lock() + defer notificationServiceLock.Unlock() + if NotificationService == nil { NotificationService = &Service{} } @@ -51,20 +54,20 @@ func New() *Service { // ServiceStartup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - AppName = application.Get().Config().Name + appName = application.Get().Config().Name guid, err := getGUID() if err != nil { return err } - AppGUID = guid + appGUID = guid - IconPath = filepath.Join(os.TempDir(), AppName+guid+".png") + iconPath = filepath.Join(os.TempDir(), appName+appGUID+".png") toast.SetAppData(toast.AppData{ - AppID: AppName, + AppID: appName, GUID: guid, - IconPath: IconPath, + IconPath: iconPath, }) toast.SetActivationCallback(func(args string, data []toast.UserData) { @@ -147,9 +150,9 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro fmt.Printf("Error saving icon: %v\n", err) } - NotificationLock.RLock() + notificationCategoriesLock.RLock() nCategory := NotificationCategories[options.CategoryID] - NotificationLock.RUnlock() + notificationCategoriesLock.RUnlock() n := toast.Notification{ Title: options.Title, @@ -195,7 +198,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. // Registering a category with the same name as a previously registered NotificationCategory will override it. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { - NotificationLock.Lock() + notificationCategoriesLock.Lock() NotificationCategories[category.ID] = NotificationCategory{ ID: category.ID, Actions: category.Actions, @@ -203,16 +206,16 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e ReplyPlaceholder: category.ReplyPlaceholder, ReplyButtonTitle: category.ReplyButtonTitle, } - NotificationLock.Unlock() + notificationCategoriesLock.Unlock() return saveCategoriesToRegistry() } // RemoveNotificationCategory removes a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { - NotificationLock.Lock() + notificationCategoriesLock.Lock() delete(NotificationCategories, categoryId) - NotificationLock.Unlock() + notificationCategoriesLock.Unlock() return saveCategoriesToRegistry() } @@ -298,11 +301,11 @@ func saveIconToDir() error { return fmt.Errorf("failed to retrieve application icon") } - return saveHIconAsPNG(icon, IconPath) + return saveHIconAsPNG(icon, iconPath) } func saveCategoriesToRegistry() error { - registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, AppName) + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, appName) key, _, err := registry.CreateKey( registry.CURRENT_USER, @@ -314,9 +317,9 @@ func saveCategoriesToRegistry() error { } defer key.Close() - NotificationLock.RLock() + notificationCategoriesLock.RLock() data, err := json.Marshal(NotificationCategories) - NotificationLock.RUnlock() + notificationCategoriesLock.RUnlock() if err != nil { return err } @@ -325,7 +328,7 @@ func saveCategoriesToRegistry() error { } func loadCategoriesFromRegistry() error { - registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, AppName) + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, appName) key, err := registry.OpenKey( registry.CURRENT_USER, @@ -350,9 +353,9 @@ func loadCategoriesFromRegistry() error { return err } - NotificationLock.Lock() + notificationCategoriesLock.Lock() NotificationCategories = categories - NotificationLock.Unlock() + notificationCategoriesLock.Unlock() return nil } @@ -367,7 +370,7 @@ func getUserText(data []toast.UserData) (string, bool) { } func getGUID() (string, error) { - keyPath := ToastRegistryPath + AppName + keyPath := ToastRegistryPath + appName k, err := registry.OpenKey(registry.CURRENT_USER, keyPath, registry.QUERY_VALUE) if err == nil { From ad749721e90cfa5d998dfa0f078ded3afd8cca21 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Wed, 26 Feb 2025 19:57:21 -0800 Subject: [PATCH 046/136] can you tell i'm not a go programmer? --- .../notifications/notifications_darwin.go | 33 +++++++++---------- .../notifications/notifications_darwin.h | 8 ++--- .../notifications/notifications_darwin.m | 11 ++++--- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 2781ceb7c..2789324ae 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -28,9 +28,9 @@ var ( notificationChannelsLock sync.Mutex nextChannelID int ) +var BundleIdentifierError = fmt.Errorf("notifications require a bundled application with a unique bundle identifier") const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" -const BundleIdentifierError = fmt.Errorf("notifications require a bundled application with a unique bundle identifier") // Creates a new Notifications Service. // Your app must be packaged and signed for this feature to work. @@ -62,7 +62,7 @@ func CheckBundleIdentifier() bool { } // RequestNotificationAuthorization requests permission for notifications. -func (ns *Service) RequestNotificationAuthorization() (bool, err) { +func (ns *Service) RequestNotificationAuthorization() (bool, error) { if !CheckBundleIdentifier() { return false, BundleIdentifierError } @@ -76,7 +76,7 @@ func (ns *Service) RequestNotificationAuthorization() (bool, err) { } // CheckNotificationAuthorization checks current notification permission status. -func (ns *Service) CheckNotificationAuthorization() (bool, err) { +func (ns *Service) CheckNotificationAuthorization() (bool, error) { if !CheckBundleIdentifier() { return false, BundleIdentifierError } @@ -241,17 +241,17 @@ func (ns *Service) RemoveNotification(identifier string) error { //export requestNotificationAuthorizationResponse func requestNotificationAuthorizationResponse(channelID C.int, authorized C.bool, errorMsg *C.char) { - resultCh, exists := getAndDeleteChannel(int(channelID)) + resultCh, exists := getChannel(int(channelID)) if !exists { // handle this return } var err error - if errorMsg != nil { - err = fmt.Errorf("%s", C.GoString(errorMsg)) - C.free(unsafe.Pointer(errorMsg)) - } + if errorMsg != nil { + err = fmt.Errorf("%s", C.GoString(errorMsg)) + C.free(unsafe.Pointer(errorMsg)) + } resultCh <- notificationChannel{ authorized: bool(authorized), @@ -263,17 +263,17 @@ func requestNotificationAuthorizationResponse(channelID C.int, authorized C.bool //export checkNotificationAuthorizationResponse func checkNotificationAuthorizationResponse(channelID C.int, authorized C.bool, errorMsg *C.char) { - resultCh, exists := getAndDeleteChannel(int(channelID)) + resultCh, exists := getChannel(int(channelID)) if !exists { // handle this return } var err error - if errorMsg != nil { - err = fmt.Errorf("%s", C.GoString(errorMsg)) - C.free(unsafe.Pointer(errorMsg)) - } + if errorMsg != nil { + err = fmt.Errorf("%s", C.GoString(errorMsg)) + C.free(unsafe.Pointer(errorMsg)) + } resultCh <- notificationChannel{ authorized: bool(authorized), @@ -300,7 +300,7 @@ func didReceiveNotificationResponse(jsonPayload *C.char) { ns := NotificationService notificationServiceLock.RUnlock() - if service != nil { + if ns != nil { ns.callbackLock.RLock() callback := ns.notificationResponseCallback ns.callbackLock.RUnlock() @@ -318,10 +318,7 @@ func registerChannel() (int, chan notificationChannel) { id := nextChannelID nextChannelID++ - resultCh := make(chan notificationChannel{ - authorized bool - err error - }, 1) + resultCh := make(chan notificationChannel, 1) notificationChannels[id] = resultCh return id, resultCh diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index 9b2bb6774..c6bacaf79 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -6,8 +6,8 @@ #import bool checkBundleIdentifier(void); -bool requestNotificationAuthorization(void *channelPtr); -bool checkNotificationAuthorization(void *channelPtr); +void requestNotificationAuthorization(int channelID); +void checkNotificationAuthorization(int channelID); void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json, void *completion); void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json, void *completion); void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); @@ -17,8 +17,4 @@ void removePendingNotification(const char *identifier); void removeAllDeliveredNotifications(void); void removeDeliveredNotification(const char *identifier); -extern void requestNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); -extern void checkNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); -extern void didReceiveNotificationResponse(const char *jsonPayload); - #endif /* NOTIFICATIONS_DARWIN_H */ \ No newline at end of file diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 3469d69d4..5ac99c0a3 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -2,6 +2,10 @@ #import #import +extern void requestNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); +extern void checkNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); +extern void didReceiveNotificationResponse(const char *jsonPayload); + @interface NotificationsDelegate : NSObject @end @@ -80,15 +84,12 @@ bool checkBundleIdentifier(void) { return true; } -bool requestNotificationAuthorization(int channelID) { +void requestNotificationAuthorization(int channelID) { ensureDelegateInitialized(); UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; - [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) { if (error) { requestNotificationAuthorizationResponse(channelID, false, [[error localizedDescription] UTF8String]); @@ -98,7 +99,7 @@ bool requestNotificationAuthorization(int channelID) { }]; } -bool checkNotificationAuthorization(int channelID) { +void checkNotificationAuthorization(int channelID) { ensureDelegateInitialized(); UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; From d9af6dec328404418cd311712623155ce9b6720e Mon Sep 17 00:00:00 2001 From: Zach Botterman <6074435+popaprozac@users.noreply.github.com> Date: Sun, 2 Mar 2025 22:49:31 -0800 Subject: [PATCH 047/136] ignore bindings notification callback Co-authored-by: Lea Anthony --- v3/pkg/services/notifications/notifications.go | 1 + 1 file changed, 1 insertion(+) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index d971959ac..c23b8edf5 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -60,6 +60,7 @@ func (ns *Service) ServiceName() string { // OnNotificationResponse registers a callback function that will be called when // a notification response is received from the user. +//wails:ignore func (ns *Service) OnNotificationResponse(callback func(response NotificationResponse)) { ns.callbackLock.Lock() defer ns.callbackLock.Unlock() From 833d8ec7dc91ff28e9db354293234ccf400e0228 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Tue, 4 Mar 2025 20:07:23 -0800 Subject: [PATCH 048/136] refactor macos --- .../notifications/notifications_darwin.go | 80 +++++-------------- .../notifications/notifications_darwin.h | 4 +- .../notifications/notifications_darwin.m | 22 ++--- 3 files changed, 29 insertions(+), 77 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 2789324ae..426b7a411 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -9,13 +9,10 @@ package notifications */ import "C" import ( - "context" "encoding/json" "fmt" "sync" "unsafe" - - "github.com/wailsapp/wails/v3/pkg/application" ) type notificationChannel struct { @@ -28,13 +25,21 @@ var ( notificationChannelsLock sync.Mutex nextChannelID int ) -var BundleIdentifierError = fmt.Errorf("notifications require a bundled application with a unique bundle identifier") const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" // Creates a new Notifications Service. // Your app must be packaged and signed for this feature to work. func New() *Service { + if !CheckBundleIdentifier() { + panic("\nError: Cannot use the notification API in development mode on macOS.\n" + + "Notifications require the app to be properly bundled with a bundle identifier and signed.\n" + + "To use the notification API on macOS:\n" + + " 1. Build and package your app using 'wails3 package'\n" + + " 2. Sign the packaged .app\n" + + " 3. Run the signed .app bundle") + } + notificationServiceLock.Lock() defer notificationServiceLock.Unlock() @@ -44,29 +49,12 @@ func New() *Service { return NotificationService } -// ServiceStartup is called when the service is loaded. -func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - if !CheckBundleIdentifier() { - return BundleIdentifierError - } - return nil -} - -// ServiceShutdown is called when the service is unloaded. -func (ns *Service) ServiceShutdown() error { - return nil -} - func CheckBundleIdentifier() bool { return bool(C.checkBundleIdentifier()) } // RequestNotificationAuthorization requests permission for notifications. func (ns *Service) RequestNotificationAuthorization() (bool, error) { - if !CheckBundleIdentifier() { - return false, BundleIdentifierError - } - id, resultCh := registerChannel() C.requestNotificationAuthorization(C.int(id)) @@ -77,10 +65,6 @@ func (ns *Service) RequestNotificationAuthorization() (bool, error) { // CheckNotificationAuthorization checks current notification permission status. func (ns *Service) CheckNotificationAuthorization() (bool, error) { - if !CheckBundleIdentifier() { - return false, BundleIdentifierError - } - id, resultCh := registerChannel() C.checkNotificationAuthorization(C.int(id)) @@ -91,9 +75,6 @@ func (ns *Service) CheckNotificationAuthorization() (bool, error) { // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ns *Service) SendNotification(options NotificationOptions) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) cSubtitle := C.CString(options.Subtitle) @@ -106,13 +87,14 @@ func (ns *Service) SendNotification(options NotificationOptions) error { var cDataJSON *C.char if options.Data != nil { jsonData, err := json.Marshal(options.Data) - if err == nil { - cDataJSON = C.CString(string(jsonData)) - defer C.free(unsafe.Pointer(cDataJSON)) + if err != nil { + return fmt.Errorf("failed to marshal notification data: %w", err) } + cDataJSON = C.CString(string(jsonData)) + defer C.free(unsafe.Pointer(cDataJSON)) } - C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, cDataJSON, nil) + C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, cDataJSON) return nil } @@ -120,9 +102,6 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) cSubtitle := C.CString(options.Subtitle) @@ -134,31 +113,29 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro defer C.free(unsafe.Pointer(cBody)) defer C.free(unsafe.Pointer(cCategoryID)) - var cActionsJSON *C.char + var cDataJSON *C.char if options.Data != nil { jsonData, err := json.Marshal(options.Data) - if err == nil { - cActionsJSON = C.CString(string(jsonData)) - defer C.free(unsafe.Pointer(cActionsJSON)) + if err != nil { + return fmt.Errorf("failed to marshal notification data: %w", err) } + cDataJSON = C.CString(string(jsonData)) + defer C.free(unsafe.Pointer(cDataJSON)) } - C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cActionsJSON, nil) + C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cDataJSON) return nil } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. // Registering a category with the same name as a previously registered NotificationCategory will override it. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } cCategoryID := C.CString(category.ID) defer C.free(unsafe.Pointer(cCategoryID)) actionsJSON, err := json.Marshal(category.Actions) if err != nil { - return err + return fmt.Errorf("failed to marshal notification category: %w", err) } cActionsJSON := C.CString(string(actionsJSON)) defer C.free(unsafe.Pointer(cActionsJSON)) @@ -178,9 +155,6 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e // RemoveNotificationCategory remove a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } cCategoryID := C.CString(categoryId) defer C.free(unsafe.Pointer(cCategoryID)) @@ -190,18 +164,12 @@ func (ns *Service) RemoveNotificationCategory(categoryId string) error { // RemoveAllPendingNotifications removes all pending notifications. func (ns *Service) RemoveAllPendingNotifications() error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } C.removeAllPendingNotifications() return nil } // RemovePendingNotification removes a pending notification matching the unique identifier. func (ns *Service) RemovePendingNotification(identifier string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } cIdentifier := C.CString(identifier) defer C.free(unsafe.Pointer(cIdentifier)) C.removePendingNotification(cIdentifier) @@ -210,18 +178,12 @@ func (ns *Service) RemovePendingNotification(identifier string) error { // RemoveAllDeliveredNotifications removes all delivered notifications. func (ns *Service) RemoveAllDeliveredNotifications() error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } C.removeAllDeliveredNotifications() return nil } // RemoveDeliveredNotification removes a delivered notification matching the unique identifier. func (ns *Service) RemoveDeliveredNotification(identifier string) error { - if !CheckBundleIdentifier() { - return fmt.Errorf("notifications require a bundled application with a unique bundle identifier") - } cIdentifier := C.CString(identifier) defer C.free(unsafe.Pointer(cIdentifier)) C.removeDeliveredNotification(cIdentifier) diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index c6bacaf79..6848dc68e 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -8,8 +8,8 @@ bool checkBundleIdentifier(void); void requestNotificationAuthorization(int channelID); void checkNotificationAuthorization(int channelID); -void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json, void *completion); -void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json, void *completion); +void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json); +void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json); void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); void removeNotificationCategory(const char *categoryId); void removeAllPendingNotifications(void); diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 5ac99c0a3..8329cdc26 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -73,12 +73,6 @@ static void ensureDelegateInitialized(void) { bool checkBundleIdentifier(void) { NSBundle *main = [NSBundle mainBundle]; if (main.bundleIdentifier == nil) { - NSLog(@"Error: Cannot use the notification API in development mode.\n" - " Notifications require the app to be properly bundled with a bundle identifier and signed.\n" - " To test notifications:\n" - " 1. Build and package your app using 'wails3 package'\n" - " 2. Sign the packaged .app\n" - " 3. Run the signed .app bundle"); return false; } return true; @@ -109,7 +103,7 @@ void checkNotificationAuthorization(int channelID) { }]; } -void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json, void *completion) { +void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json) { ensureDelegateInitialized(); NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; @@ -136,7 +130,6 @@ void sendNotification(const char *identifier, const char *title, const char *sub content.body = nsBody; content.sound = [UNNotificationSound defaultSound]; - // Add custom data if available if (customData.count > 0) { content.userInfo = customData; } @@ -146,15 +139,14 @@ void sendNotification(const char *identifier, const char *title, const char *sub UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { - if (completion != NULL) { - void (^callback)(NSError *) = completion; - callback(error); + if (error) { + NSLog(@"Error scheduling notification: %@", error.localizedDescription); } }]; } void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, - const char *body, const char *categoryId, const char *actions_json, void *completion) { + const char *body, const char *categoryId, const char *actions_json) { ensureDelegateInitialized(); NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; @@ -185,7 +177,6 @@ void sendNotificationWithActions(const char *identifier, const char *title, cons content.sound = [UNNotificationSound defaultSound]; content.categoryIdentifier = nsCategoryId; - // Add custom data if available if (customData.count > 0) { content.userInfo = customData; } @@ -195,9 +186,8 @@ void sendNotificationWithActions(const char *identifier, const char *title, cons UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { - if (completion != NULL) { - void (^callback)(NSError *) = completion; - callback(error); + if (error) { + NSLog(@"Error scheduling notification: %@", error.localizedDescription); } }]; } From 742b802cf75981b6e94e61559db2a3f1630818bf Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sat, 15 Jun 2024 07:56:55 +1000 Subject: [PATCH 049/136] adding http.CloseNotifier and http.Flusher interface to assetserver.contentTypeSniffer, for Gin (and other framework) compatibility. --- v3/internal/assetserver/assetserver.go | 2 +- .../assetserver/assetserver_webview.go | 2 +- .../assetserver/content_type_sniffer.go | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/v3/internal/assetserver/assetserver.go b/v3/internal/assetserver/assetserver.go index be862a3e2..6ff1b169f 100644 --- a/v3/internal/assetserver/assetserver.go +++ b/v3/internal/assetserver/assetserver.go @@ -59,7 +59,7 @@ func NewAssetServer(options *Options) (*AssetServer, error) { func (a *AssetServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { start := time.Now() - wrapped := &contentTypeSniffer{rw: rw} + wrapped := newContentTypeSniffer(rw) defer func() { if _, err := wrapped.complete(); err != nil { a.options.Logger.Error("Error writing response data.", "uri", req.RequestURI, "error", err) diff --git a/v3/internal/assetserver/assetserver_webview.go b/v3/internal/assetserver/assetserver_webview.go index b569a4743..637642914 100644 --- a/v3/internal/assetserver/assetserver_webview.go +++ b/v3/internal/assetserver/assetserver_webview.go @@ -74,7 +74,7 @@ func (a *AssetServer) processWebViewRequestInternal(r webview.Request) { } }() - rw := &contentTypeSniffer{rw: wrw} // Make sure we have a Content-Type sniffer + var rw http.ResponseWriter = newContentTypeSniffer(wrw) // Make sure we have a Content-Type sniffer defer func() { if _, err := rw.complete(); err != nil { a.options.Logger.Error("Error writing response data.", "uri", uri, "error", err) diff --git a/v3/internal/assetserver/content_type_sniffer.go b/v3/internal/assetserver/content_type_sniffer.go index 44e4ceb39..e36db90e8 100644 --- a/v3/internal/assetserver/content_type_sniffer.go +++ b/v3/internal/assetserver/content_type_sniffer.go @@ -4,12 +4,20 @@ import ( "net/http" ) +func newContentTypeSniffer(rw http.ResponseWriter) *contentTypeSniffer { + return &contentTypeSniffer{ + rw: rw, + closeChannel: make(chan bool, 1), + } +} + type contentTypeSniffer struct { rw http.ResponseWriter prefix []byte status int headerCommitted bool headerWritten bool + closeChannel chan bool } // Unwrap returns the wrapped [http.ResponseWriter] for use with [http.ResponseController]. @@ -108,3 +116,19 @@ func (rw *contentTypeSniffer) complete() (n int, err error) { return } + +// CloseNotify implements the http.CloseNotifier interface. +func (rw *contentTypeSniffer) CloseNotify() <-chan bool { + return rw.closeChannel +} + +func (rw *contentTypeSniffer) closeClient() { + rw.closeChannel <- true +} + +// Flush implements the http.Flusher interface. +func (rw *contentTypeSniffer) Flush() { + if f, ok := rw.rw.(http.Flusher); ok { + f.Flush() + } +} From d95b77ad049c769e0fce69cfbb704cc54ee22b98 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sun, 16 Jun 2024 01:20:25 +1000 Subject: [PATCH 050/136] update changelog. --- mkdocs-website/docs/en/changelog.md | 89 +++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/mkdocs-website/docs/en/changelog.md b/mkdocs-website/docs/en/changelog.md index e69de29bb..9350cdac1 100644 --- a/mkdocs-website/docs/en/changelog.md +++ b/mkdocs-website/docs/en/changelog.md @@ -0,0 +1,89 @@ +# Changelog + + + +## [Unreleased] + +### Added +- [darwin] add Event ApplicationShouldHandleReopen to be able to handle dock icon click by @5aaee9 in [#2991](https://github.com/wailsapp/wails/pull/2991) +- [darwin] add getPrimaryScreen/getScreens to impl by @tmclane in [#2618](https://github.com/wailsapp/wails/pull/2618) +- [darwin] add option for showing the toolbar in fullscreen mode on macOS by [@fbbdev](https://github.com/fbbdev) in [#3282](https://github.com/wailsapp/wails/pull/3282) +- [linux] add onKeyPress logic to convert linux keypress into an accelerator @[Atterpac](https://github.com/Atterpac) in[#3022](https://github.com/wailsapp/wails/pull/3022]) +- [linux] add task `run:linux` by [@marcus-crane](https://github.com/marcus-crane) in [#3146](https://github.com/wailsapp/wails/pull/3146) +- Export `SetIcon` method by @almas1992 in [PR](https://github.com/wailsapp/wails/pull/3147) +- Improve `OnShutdown` by @almas1992 in [PR](https://github.com/wailsapp/wails/pull/3189) +- Restore `ToggleMaximise` method in `Window` interface by [@fbbdev](https://github.com/fbbdev) in [#3281](https://github.com/wailsapp/wails/pull/3281) +- Added more information to `Environment()`. By @leaanthony in [aba82cc](https://github.com/wailsapp/wails/commit/aba82cc52787c97fb99afa58b8b63a0004b7ff6c) based on [PR](https://github.com/wailsapp/wails/pull/2044) by @Mai-Lapyst +- Expose the `WebviewWindow.IsFocused` method on the `Window` interface by [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- Support multiple space-separated trigger events in the WML system by [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- Add ESM exports from the bundled JS runtime script by [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- Add binding generator flag for using the bundled JS runtime script instead of the npm package by [@fbbdev](https://github.com/fbbdev) in [#3334](https://github.com/wailsapp/wails/pull/3334) +- Implement `setIcon` on linux by [@abichinger](https://github.com/abichinger) in [#3354](https://github.com/wailsapp/wails/pull/3354) +- Add flag `-port` to dev command and support environment variable `WAILS_VITE_PORT` by [@abichinger](https://github.com/abichinger) in [#3429](https://github.com/wailsapp/wails/pull/3429) +- Add tests for bound method calls by [@abichinger](https://github.com/abichinger) in [#3431](https://github.com/wailsapp/wails/pull/3431) + +### Fixed + +- [linux] Fixed theme handling error on NixOS by [tmclane](https://github.com/tmclane) in [#3515)(https://github.com/wailsapp/wails/pull/3515) +- Fixed cross volume project install for windows by [atterpac](https://github.com/atterac) in [#3512](https://github.com/wailsapp/wails/pull/3512) +- Fixed react template css to show footer by [atterpac](https://github.com/atterpac) in [#3477](https://github.com/wailsapp/wails/pull/3477) +- Fixed zombie processes when working in devmode by updating to latest refresh by [Atterpac](https://github.com/atterpac) in [#3320](https://github.com/wailsapp/wails/pull/3320). +- Fixed appimage webkit file sourcing by [Atterpac](https://github.com/atterpac) in [#3306](https://github.com/wailsapp/wails/pull/3306). +- Fixed Doctor apt package verify by [Atterpac](https://github.com/Atterpac) in [#2972](https://github.com/wailsapp/wails/pull/2972). +- Fixed application frozen when quit (Darwin) by @5aaee9 in [#2982](https://github.com/wailsapp/wails/pull/2982) +- Fixed background colours of examples on Windows by [mmgvh](https://github.com/mmghv) in [#2750](https://github.com/wailsapp/wails/pull/2750). +- Fixed default context menus by [mmgvh](https://github.com/mmghv) in [#2753](https://github.com/wailsapp/wails/pull/2753). +- Fixed hex values for arrow keys on Darwin by [jaybeecave](https://github.com/jaybeecave) in [#3052](https://github.com/wailsapp/wails/pull/3052). +- Set drag-n-drop for windows to working. Added by [@pylotlight](https://github.com/pylotlight) in [PR](https://github.com/wailsapp/wails/pull/3039) +- Fixed bug for linux in doctor in the event user doesn't have proper drivers installed. Added by [@pylotlight](https://github.com/pylotlight) in [PR](https://github.com/wailsapp/wails/pull/3032) +- Fix dpi scaling on start up (windows). Changed by @almas1992 in [PR](https://github.com/wailsapp/wails/pull/3145) +- Fix replace line in `go.mod` to use relative paths. Fixes Windows paths with spaces - @leaanthony. +- Fix MacOS systray click handling when no attached window by [thomas-senechal](https://github.com/thomas-senechal) in PR [#3207](https://github.com/wailsapp/wails/pull/3207) +- Fix failing Windows build due to unknown option by [thomas-senechal](https://github.com/thomas-senechal) in PR [#3208](https://github.com/wailsapp/wails/pull/3208) +- Fix crash on windows left clicking the systray icon when not having an attached window [tw1nk](https://github.com/tw1nk) in PR [#3271](https://github.com/wailsapp/wails/pull/3271) +- Fix wrong baseURL when open window twice by @5aaee9 in PR [#3273](https://github.com/wailsapp/wails/pull/3273) +- Fix ordering of if branches in `WebviewWindow.Restore` method by [@fbbdev](https://github.com/fbbdev) in [#3279](https://github.com/wailsapp/wails/pull/3279) +- Correctly compute `startURL` across multiple `GetStartURL` invocations when `FRONTEND_DEVSERVER_URL` is present. [#3299](https://github.com/wailsapp/wails/pull/3299) +- Fix the JS type of the `Screen` struct to match its Go counterpart by [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- Fix the `WML.Reload` method to ensure proper cleanup of registered event listeners by [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- Fix custom context menu closing immediately on linux by [@abichinger](https://github.com/abichinger) in [#3330](https://github.com/wailsapp/wails/pull/3330) +- Fix the output path and extension of model files produced by the binding generator by [@fbbdev](https://github.com/fbbdev) in [#3334](https://github.com/wailsapp/wails/pull/3334) +- Fix the import paths of model files in JS code produced by the binding generator by [@fbbdev](https://github.com/fbbdev) in [#3334](https://github.com/wailsapp/wails/pull/3334) +- Fix drag-n-drop on some linux distros by [@abichinger](https://github.com/abichinger) in [#3346](https://github.com/wailsapp/wails/pull/3346) +- Fix missing task for macOS when using `wails3 task dev` by [@hfoxy](https://github.com/hfoxy) in [#3417](https://github.com/wailsapp/wails/pull/3417) +- Fix registering events causing a nil map assignment by [@hfoxy](https://github.com/hfoxy) in [#3426](https://github.com/wailsapp/wails/pull/3426) +- Fix unmarshaling of bound method parameters by [@fbbdev](https://github.com/fbbdev) in [#3431](https://github.com/wailsapp/wails/pull/3431) +- Fix handling of multiple return values from bound methods by [@fbbdev](https://github.com/fbbdev) in [#3431](https://github.com/wailsapp/wails/pull/3431) +- Fix doctor detection of npm that is not installed with system package manager by [@pekim](https://github.com/pekim) in [#3458](https://github.com/wailsapp/wails/pull/3458) + +### Changed + +- Update linux webkit dependency to webkit2gtk-4.1 over webkitgtk2-4.0 to support Ubuntu 24.04 LTS by [atterpac](https://github.com/atterpac) in [#3461](https://github.com/wailsapp/wails/pull/3461) +- The bundled JS runtime script is now an ESM module: script tags importing it must have the `type="module"` attribute. By [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- The `@wailsio/runtime` package does not publish its API on the `window.wails` object, and does not start the WML system. This has been done to improve encapsulation. The WML system can be started manually if desired by calling the new `WML.Enable` method. The bundled JS runtime script still performs both operations automatically. By [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- The Window API module `@wailsio/runtime/src/window` now exposes the containing window object as a default export. It is not possible anymore to import individual methods through ESM named or namespace import syntax. +- The JS window API has been updated to match the current Go `WebviewWindow` API. Some methods have changed name or prototype, specifically: `Screen` becomes `GetScreen`; `GetZoomLevel`/`SetZoomLevel` become `GetZoom`/`SetZoom`; `GetZoom`, `Width` and `Height` now return values directly instead of wrapping them within objects. By [@fbbdev](https://github.com/fbbdev) in [#3295](https://github.com/wailsapp/wails/pull/3295) +- The binding generator now uses calls by ID by default. The `-id` CLI option has been removed. Use the `-names` CLI option to switch back to calls by name. By [@fbbdev](https://github.com/fbbdev) in [#3468](https://github.com/wailsapp/wails/pull/3468) +- New binding code layout: output files were previously organised in folders named after their containing package; now full Go import paths are used, including the module path. By [@fbbdev](https://github.com/fbbdev) in [#3468](https://github.com/wailsapp/wails/pull/3468) +- The struct field `application.Options.Bind` has been renamed to `application.Options.Services`. By [@fbbdev](https://github.com/fbbdev) in [#3468](https://github.com/wailsapp/wails/pull/3468) +- New syntax for binding services: service instances must now be wrapped in a call to `application.NewService`. By [@fbbdev](https://github.com/fbbdev) in [#3468](https://github.com/wailsapp/wails/pull/3468) +- Modified the `contentTypeSniffer` struct to include the `http.CloseNotifier` interface. Now compatible with Gin framework. By [@AnalogJ](https://github.com/AnalogJ) in [#3537](https://github.com/wailsapp/wails/pull/3537) + +### Removed + +### Deprecated + +### Security From 15b9118077d684379c69fea599cfb23e404ec808 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 8 Mar 2025 15:30:11 +1100 Subject: [PATCH 051/136] Add gin example --- v3/examples/gin-example/README.md | 104 +++++++++ v3/examples/gin-example/go.mod | 76 +++++++ v3/examples/gin-example/go.sum | 250 ++++++++++++++++++++++ v3/examples/gin-example/main.go | 109 ++++++++++ v3/examples/gin-example/static/index.html | 64 ++++++ 5 files changed, 603 insertions(+) create mode 100644 v3/examples/gin-example/README.md create mode 100644 v3/examples/gin-example/go.mod create mode 100644 v3/examples/gin-example/go.sum create mode 100644 v3/examples/gin-example/main.go create mode 100644 v3/examples/gin-example/static/index.html diff --git a/v3/examples/gin-example/README.md b/v3/examples/gin-example/README.md new file mode 100644 index 000000000..b4d85cb9b --- /dev/null +++ b/v3/examples/gin-example/README.md @@ -0,0 +1,104 @@ +# Gin Example + +This example demonstrates how to use the [Gin web framework](https://github.com/gin-gonic/gin) with Wails. + +## Overview + +This example shows how to: + +- Set up Gin as the asset handler for a Wails application +- Create a middleware that routes requests between Wails and Gin +- Define API endpoints with Gin +- Communicate between the Gin-served frontend and Wails backend +- Implement custom Gin middleware + +## Running the Example + +```bash +cd v3/examples/gin-example +go mod tidy +go run . +``` + +## How It Works + +The example uses Gin's HTTP router to serve the frontend content whilst still allowing Wails to handle its internal routes. This is achieved through: + +1. Creating a Gin router with routes for the frontend +2. Implementing a middleware function that decides whether to pass requests to Gin or let Wails handle them +3. Configuring the Wails application to use both the Gin router as the asset handler and the custom middleware + +### Wails-Gin Integration + +The key part of the integration is the middleware function: + +```go +func GinMiddleware(ginEngine *gin.Engine) application.Middleware { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Wails handle its internal routes + if r.URL.Path == "/wails/runtime.js" || r.URL.Path == "/wails/ipc" { + next.ServeHTTP(w, r) + return + } + + // Let Gin handle everything else + ginEngine.ServeHTTP(w, r) + }) + } +} +``` + +This allows you to leverage Gin's powerful routing and middleware capabilities whilst still maintaining full access to Wails features. + +### Custom Gin Middleware + +The example also demonstrates how to create custom Gin middleware: + +```go +func LoggingMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + // Start timer + startTime := time.Now() + + // Process request + c.Next() + + // Calculate latency + latency := time.Since(startTime) + + // Log request details + log.Printf("[GIN] %s | %s | %s | %d | %s", + c.Request.Method, + c.Request.URL.Path, + c.ClientIP(), + c.Writer.Status(), + latency, + ) + } +} +``` + +This middleware is applied to all Gin routes and logs details about each request. + +### Application Configuration + +The Wails application is configured to use Gin as follows: + +```go +app := application.New(application.Options{ + Name: "Gin Example", + Description: "A demo of using Gin with Wails", + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + Assets: application.AssetOptions{ + Handler: ginEngine, + Middleware: GinMiddleware(ginEngine), + }, +}) +``` + +This configuration tells Wails to: +1. Use the Gin engine as the primary handler for HTTP requests +2. Use our custom middleware to route requests between Wails and Gin diff --git a/v3/examples/gin-example/go.mod b/v3/examples/gin-example/go.mod new file mode 100644 index 000000000..6631f24cf --- /dev/null +++ b/v3/examples/gin-example/go.mod @@ -0,0 +1,76 @@ +module gin-example + +go 1.22.4 + +toolchain go1.23.4 + +require ( + github.com/gin-gonic/gin v1.9.1 + github.com/wailsapp/wails/v3 v3.0.0 +) + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/bep/debounce v1.2.1 // indirect + github.com/bytedance/sonic v1.9.1 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/ebitengine/purego v0.4.0-alpha.4 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.11.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leaanthony/go-ansi-parser v1.6.1 // indirect + github.com/leaanthony/u v1.1.0 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/lmittmann/tint v1.0.4 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/samber/lo v1.38.1 // indirect + github.com/sergi/go-diff v1.2.0 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + github.com/wailsapp/go-webview2 v1.0.9 // indirect + github.com/wailsapp/mimetype v1.4.1 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/tools v0.21.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/wailsapp/wails/v3 => ../../ diff --git a/v3/examples/gin-example/go.sum b/v3/examples/gin-example/go.sum new file mode 100644 index 000000000..b0db8e43f --- /dev/null +++ b/v3/examples/gin-example/go.sum @@ -0,0 +1,250 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= +github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.4.0-alpha.4 h1:Y7yIV06Yo5M2BAdD7EVPhfp6LZ0tEcQo5770OhYUVes= +github.com/ebitengine/purego v0.4.0-alpha.4/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A= +github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= +github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI= +github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= +github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= +github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/wailsapp/go-webview2 v1.0.9 h1:lrU+q0cf1wgLdR69rN+ZnRtMJNaJRrcQ4ELxoO7/xjs= +github.com/wailsapp/go-webview2 v1.0.9/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= +github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= +github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/v3/examples/gin-example/main.go b/v3/examples/gin-example/main.go new file mode 100644 index 000000000..374e52182 --- /dev/null +++ b/v3/examples/gin-example/main.go @@ -0,0 +1,109 @@ +package main + +import ( + "embed" + "log" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "github.com/wailsapp/wails/v3/pkg/application" +) + +//go:embed static +var staticFiles embed.FS + +// GinMiddleware creates a middleware that passes requests to Gin if they're not handled by Wails +func GinMiddleware(ginEngine *gin.Engine) application.Middleware { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Gin handle everything else + ginEngine.ServeHTTP(w, r) + }) + } +} + +// LoggingMiddleware is a Gin middleware that logs request details +func LoggingMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + // Start timer + startTime := time.Now() + + // Process request + c.Next() + + // Calculate latency + latency := time.Since(startTime) + + // Log request details + log.Printf("[GIN] %s | %s | %s | %d | %s", + c.Request.Method, + c.Request.URL.Path, + c.ClientIP(), + c.Writer.Status(), + latency, + ) + } +} + +func main() { + // Create a new Gin router + ginEngine := gin.New() // Using New() instead of Default() to add our own middleware + + // Add middlewares + ginEngine.Use(gin.Recovery()) + ginEngine.Use(LoggingMiddleware()) + + // Serve embedded static files + ginEngine.StaticFS("/static", http.FS(staticFiles)) + + // Define routes + ginEngine.GET("/", func(c *gin.Context) { + file, err := staticFiles.ReadFile("static/index.html") + if err != nil { + c.String(http.StatusInternalServerError, "Error reading index.html") + return + } + c.Data(http.StatusOK, "text/html; charset=utf-8", file) + }) + + ginEngine.GET("/api/hello", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "Hello from Gin API!", + "time": time.Now().Format(time.RFC3339), + }) + }) + + // Create a new Wails application + app := application.New(application.Options{ + Name: "Gin Example", + Description: "A demo of using Gin with Wails", + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + Assets: application.AssetOptions{ + Handler: ginEngine, + Middleware: GinMiddleware(ginEngine), + }, + }) + + // Register event handler + app.Events.On("gin-button-clicked", func(event *application.WailsEvent) { + log.Printf("Received event from frontend: %v", event.Data) + }) + + // Create window + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Title: "Wails + Gin Example", + Width: 900, + Height: 700, + Centered: true, + URL: "/", + }) + + // Run the app + err := app.Run() + if err != nil { + log.Fatal(err) + } +} diff --git a/v3/examples/gin-example/static/index.html b/v3/examples/gin-example/static/index.html new file mode 100644 index 000000000..7d980038f --- /dev/null +++ b/v3/examples/gin-example/static/index.html @@ -0,0 +1,64 @@ + + + Wails + Gin Example + + + +
+

Wails + Gin Integration

+
+

API Example

+

Try the Gin API endpoint:

+ +
+
+
+ + + From 38a4299883c46ad5ff9a43930f142a2351e4704a Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 8 Mar 2025 15:33:33 +1100 Subject: [PATCH 052/136] Add gin guide --- docs/src/content/docs/guides/gin.mdx | 442 +++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 docs/src/content/docs/guides/gin.mdx diff --git a/docs/src/content/docs/guides/gin.mdx b/docs/src/content/docs/guides/gin.mdx new file mode 100644 index 000000000..afef5640d --- /dev/null +++ b/docs/src/content/docs/guides/gin.mdx @@ -0,0 +1,442 @@ +--- +title: Using Gin with Wails +description: A comprehensive guide to integrating Gin web framework with Wails v3 applications +--- + +# Using Gin with Wails + +This guide demonstrates how to integrate the [Gin web framework](https://github.com/gin-gonic/gin) with Wails v3. Gin is a high-performance HTTP web framework written in Go that makes it easy to build web applications and APIs. + +## Overview + +Wails v3 provides a flexible asset system that allows you to use any HTTP handler, including popular web frameworks like Gin. This integration enables you to: + +- Serve web content using Gin's powerful routing and middleware capabilities +- Create RESTful APIs that can be accessed from your Wails application +- Leverage Gin's extensive feature set whilst maintaining the benefits of Wails +- Build hybrid applications that combine native desktop features with web technologies + +## Setting Up Gin with Wails + +To integrate Gin with Wails, you need to create a Gin router and configure it as the asset handler in your Wails application. Here's a step-by-step guide: + +### 1. Install Dependencies + +First, ensure you have the Gin package installed: + +```bash +go get -u github.com/gin-gonic/gin +``` + +### 2. Create a Middleware for Gin + +Create a middleware function that will handle the integration between Wails and Gin: + +```go +// GinMiddleware creates a middleware that passes requests to Gin +func GinMiddleware(ginEngine *gin.Engine) application.Middleware { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Gin handle everything + ginEngine.ServeHTTP(w, r) + }) + } +} +``` + +This middleware passes all HTTP requests to the Gin router. If you need to let Wails handle specific routes (like the Wails runtime), you can modify the middleware to check the request path: + +```go +// GinMiddleware creates a middleware that passes requests to Gin if they're not handled by Wails +func GinMiddleware(ginEngine *gin.Engine) application.Middleware { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Wails handle its internal routes + if r.URL.Path == "/wails/runtime.js" || r.URL.Path == "/wails/ipc" { + next.ServeHTTP(w, r) + return + } + + // Let Gin handle everything else + ginEngine.ServeHTTP(w, r) + }) + } +} +``` + +### 3. Configure Your Gin Router + +Set up your Gin router with routes, middlewares, and handlers: + +```go +// Create a new Gin router +ginEngine := gin.New() // Using New() instead of Default() to add custom middleware + +// Add middlewares +ginEngine.Use(gin.Recovery()) +ginEngine.Use(LoggingMiddleware()) // Your custom middleware + +// Define routes +ginEngine.GET("/", func(c *gin.Context) { + // Serve your main page +}) + +ginEngine.GET("/api/hello", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "Hello from Gin API!", + "time": time.Now().Format(time.RFC3339), + }) +}) +``` + +### 4. Integrate with Wails Application + +Configure your Wails application to use the Gin router as its asset handler: + +```go +// Create a new Wails application +app := application.New(application.Options{ + Name: "Gin Example", + Description: "A demo of using Gin with Wails", + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + Assets: application.AssetOptions{ + Handler: ginEngine, + Middleware: GinMiddleware(ginEngine), + }, +}) + +// Create window +app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Title: "Wails + Gin Example", + Width: 900, + Height: 700, + Centered: true, + URL: "/", // This will load the route handled by Gin +}) +``` + +## Serving Static Content + +There are several ways to serve static content with Gin in a Wails application: + +### Option 1: Using Go's embed Package + +The recommended approach is to use Go's `embed` package to embed static files into your binary: + +```go +//go:embed static +var staticFiles embed.FS + +// In your main function: +ginEngine.StaticFS("/static", http.FS(staticFiles)) + +// Serve index.html +ginEngine.GET("/", func(c *gin.Context) { + file, err := staticFiles.ReadFile("static/index.html") + if err != nil { + c.String(http.StatusInternalServerError, "Error reading index.html") + return + } + c.Data(http.StatusOK, "text/html; charset=utf-8", file) +}) +``` + +### Option 2: Serving from Disk + +For development purposes, you might prefer to serve files directly from disk: + +```go +// Serve static files from the "static" directory +ginEngine.Static("/static", "./static") + +// Serve index.html +ginEngine.GET("/", func(c *gin.Context) { + c.File("./static/index.html") +}) +``` + +## Custom Middleware + +Gin allows you to create custom middleware for various purposes. Here's an example of a logging middleware: + +```go +// LoggingMiddleware is a Gin middleware that logs request details +func LoggingMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + // Start timer + startTime := time.Now() + + // Process request + c.Next() + + // Calculate latency + latency := time.Since(startTime) + + // Log request details + log.Printf("[GIN] %s | %s | %s | %d | %s", + c.Request.Method, + c.Request.URL.Path, + c.ClientIP(), + c.Writer.Status(), + latency, + ) + } +} +``` + +## Handling API Requests + +Gin makes it easy to create RESTful APIs. Here's how to define API endpoints: + +```go +// GET endpoint +ginEngine.GET("/api/users", func(c *gin.Context) { + c.JSON(http.StatusOK, users) +}) + +// POST endpoint with JSON binding +ginEngine.POST("/api/users", func(c *gin.Context) { + var newUser User + if err := c.ShouldBindJSON(&newUser); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + // Process the new user... + c.JSON(http.StatusCreated, newUser) +}) + +// Path parameters +ginEngine.GET("/api/users/:id", func(c *gin.Context) { + id := c.Param("id") + // Find user by ID... + c.JSON(http.StatusOK, user) +}) + +// Query parameters +ginEngine.GET("/api/search", func(c *gin.Context) { + query := c.DefaultQuery("q", "") + limit := c.DefaultQuery("limit", "10") + // Perform search... + c.JSON(http.StatusOK, results) +}) +``` + +## Interacting with Wails + +Your Gin-served web content can interact with Wails features like events and bindings: + +### Handling Wails Events in Go + +```go +// Register event handler +app.Events.On("my-event", func(event *application.WailsEvent) { + log.Printf("Received event from frontend: %v", event.Data) + // Process the event... +}) +``` + +### Emitting Events from JavaScript + +```html + +``` + +## Advanced Configuration + +### CORS Configuration + +If your application needs to handle Cross-Origin Resource Sharing (CORS), you can use Gin's CORS middleware: + +```go +import "github.com/gin-contrib/cors" + +// In your main function: +ginEngine.Use(cors.New(cors.Config{ + AllowOrigins: []string{"*"}, + AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, + AllowHeaders: []string{"Origin", "Content-Type", "Authorization"}, + ExposeHeaders: []string{"Content-Length"}, + AllowCredentials: true, + MaxAge: 12 * time.Hour, +})) +``` + +### Customising Gin's Mode + +Gin has three modes: debug, release, and test. For production applications, you should use release mode: + +```go +// Set Gin to release mode +gin.SetMode(gin.ReleaseMode) + +// Create a new Gin router +ginEngine := gin.New() +``` + +### Handling WebSockets + +You can integrate WebSockets with Gin using libraries like Gorilla WebSocket: + +```go +import "github.com/gorilla/websocket" + +var upgrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + CheckOrigin: func(r *http.Request) bool { + return true // Allow all connections + }, +} + +// In your route handler: +ginEngine.GET("/ws", func(c *gin.Context) { + conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + log.Println(err) + return + } + defer conn.Close() + + // Handle WebSocket connection... +}) +``` + +## Complete Example + +Here's a complete example of integrating Gin with Wails: + +```go +package main + +import ( + "embed" + "log" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "github.com/wailsapp/wails/v3/pkg/application" +) + +//go:embed static +var staticFiles embed.FS + +// GinMiddleware creates a middleware that passes requests to Gin +func GinMiddleware(ginEngine *gin.Engine) application.Middleware { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Gin handle everything + ginEngine.ServeHTTP(w, r) + }) + } +} + +// LoggingMiddleware is a Gin middleware that logs request details +func LoggingMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + startTime := time.Now() + c.Next() + latency := time.Since(startTime) + log.Printf("[GIN] %s | %s | %s | %d | %s", + c.Request.Method, + c.Request.URL.Path, + c.ClientIP(), + c.Writer.Status(), + latency, + ) + } +} + +func main() { + // Set Gin to release mode for production + // gin.SetMode(gin.ReleaseMode) + + // Create a new Gin router + ginEngine := gin.New() + + // Add middlewares + ginEngine.Use(gin.Recovery()) + ginEngine.Use(LoggingMiddleware()) + + // Serve embedded static files + ginEngine.StaticFS("/static", http.FS(staticFiles)) + + // Define routes + ginEngine.GET("/", func(c *gin.Context) { + file, err := staticFiles.ReadFile("static/index.html") + if err != nil { + c.String(http.StatusInternalServerError, "Error reading index.html") + return + } + c.Data(http.StatusOK, "text/html; charset=utf-8", file) + }) + + ginEngine.GET("/api/hello", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "Hello from Gin API!", + "time": time.Now().Format(time.RFC3339), + }) + }) + + // Create a new Wails application + app := application.New(application.Options{ + Name: "Gin Example", + Description: "A demo of using Gin with Wails", + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + Assets: application.AssetOptions{ + Handler: ginEngine, + Middleware: GinMiddleware(ginEngine), + }, + }) + + // Register event handler + app.Events.On("gin-button-clicked", func(event *application.WailsEvent) { + log.Printf("Received event from frontend: %v", event.Data) + }) + + // Create window + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Title: "Wails + Gin Example", + Width: 900, + Height: 700, + Centered: true, + URL: "/", + }) + + // Run the app + err := app.Run() + if err != nil { + log.Fatal(err) + } +} +``` + +## Best Practices + +- **Use Go's embed Package:** Embed static files into your binary for better distribution. +- **Separate Concerns:** Keep your API logic separate from your UI logic. +- **Error Handling:** Implement proper error handling in both Gin routes and frontend code. +- **Security:** Be mindful of security considerations, especially when handling user input. +- **Performance:** Use Gin's release mode in production for better performance. +- **Testing:** Write tests for your Gin routes using Gin's testing utilities. + +## Conclusion + +Integrating Gin with Wails provides a powerful combination for building desktop applications with web technologies. Gin's performance and feature set complement Wails' desktop integration capabilities, allowing you to create sophisticated applications that leverage the best of both worlds. + +For more information, refer to the [Gin documentation](https://github.com/gin-gonic/gin) and the [Wails documentation](https://wails.io). From e4d6e54c63eb67256be15379f3c9f45b8e1e8986 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 9 Mar 2025 15:58:50 +1100 Subject: [PATCH 053/136] Add gin guide, fix asset server merge, add gin example --- docs/src/content/docs/guides/gin.mdx | 262 +++++++++--------- v3/examples/gin-example/go.mod | 62 ++--- v3/examples/gin-example/go.sum | 195 +++++-------- v3/examples/gin-example/main.go | 16 +- v3/examples/gin-example/static/index.html | 20 +- .../assetserver/assetserver_webview.go | 2 +- 6 files changed, 252 insertions(+), 305 deletions(-) diff --git a/docs/src/content/docs/guides/gin.mdx b/docs/src/content/docs/guides/gin.mdx index afef5640d..236996674 100644 --- a/docs/src/content/docs/guides/gin.mdx +++ b/docs/src/content/docs/guides/gin.mdx @@ -3,18 +3,15 @@ title: Using Gin with Wails description: A comprehensive guide to integrating Gin web framework with Wails v3 applications --- -# Using Gin with Wails - This guide demonstrates how to integrate the [Gin web framework](https://github.com/gin-gonic/gin) with Wails v3. Gin is a high-performance HTTP web framework written in Go that makes it easy to build web applications and APIs. -## Overview +## Introduction Wails v3 provides a flexible asset system that allows you to use any HTTP handler, including popular web frameworks like Gin. This integration enables you to: - Serve web content using Gin's powerful routing and middleware capabilities - Create RESTful APIs that can be accessed from your Wails application - Leverage Gin's extensive feature set whilst maintaining the benefits of Wails -- Build hybrid applications that combine native desktop features with web technologies ## Setting Up Gin with Wails @@ -37,6 +34,11 @@ Create a middleware function that will handle the integration between Wails and func GinMiddleware(ginEngine *gin.Engine) application.Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Wails handle the `/wails` route + if r.URL.Path == "/wails" { + next.ServeHTTP(w, r) + return + } // Let Gin handle everything ginEngine.ServeHTTP(w, r) }) @@ -44,25 +46,7 @@ func GinMiddleware(ginEngine *gin.Engine) application.Middleware { } ``` -This middleware passes all HTTP requests to the Gin router. If you need to let Wails handle specific routes (like the Wails runtime), you can modify the middleware to check the request path: - -```go -// GinMiddleware creates a middleware that passes requests to Gin if they're not handled by Wails -func GinMiddleware(ginEngine *gin.Engine) application.Middleware { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Let Wails handle its internal routes - if r.URL.Path == "/wails/runtime.js" || r.URL.Path == "/wails/ipc" { - next.ServeHTTP(w, r) - return - } - - // Let Gin handle everything else - ginEngine.ServeHTTP(w, r) - }) - } -} -``` +This middleware passes all HTTP requests to the Gin router. ### 3. Configure Your Gin Router @@ -225,13 +209,14 @@ ginEngine.GET("/api/search", func(c *gin.Context) { ## Interacting with Wails -Your Gin-served web content can interact with Wails features like events and bindings: +Your Gin-served web content can interact with Wails features like events and bindings. To enable this interaction, you +must use the JavaScript API package `@wailsio/runtime`. ### Handling Wails Events in Go ```go // Register event handler -app.Events.On("my-event", func(event *application.WailsEvent) { +app.OnEvent("my-event", func(event *application.CustomEvent) { log.Printf("Received event from frontend: %v", event.Data) // Process the event... }) @@ -240,40 +225,22 @@ app.Events.On("my-event", func(event *application.WailsEvent) { ### Emitting Events from JavaScript ```html - + ``` ## Advanced Configuration -### CORS Configuration - -If your application needs to handle Cross-Origin Resource Sharing (CORS), you can use Gin's CORS middleware: - -```go -import "github.com/gin-contrib/cors" - -// In your main function: -ginEngine.Use(cors.New(cors.Config{ - AllowOrigins: []string{"*"}, - AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, - AllowHeaders: []string{"Origin", "Content-Type", "Authorization"}, - ExposeHeaders: []string{"Content-Length"}, - AllowCredentials: true, - MaxAge: 12 * time.Hour, -})) -``` - ### Customising Gin's Mode Gin has three modes: debug, release, and test. For production applications, you should use release mode: @@ -286,6 +253,25 @@ gin.SetMode(gin.ReleaseMode) ginEngine := gin.New() ``` +You can use Go's build tags to set the mode based on the build environment: + +```go[main_prod.go] +// +build production + +var ginMode = gin.ReleaseMode +``` + +```go[main_dev.go] +// +build !production + +var ginMode = gin.DebugMode +``` + +```go [main.go] +// In your main function: +gin.SetMode(ginMode) +``` + ### Handling WebSockets You can integrate WebSockets with Gin using libraries like Gorilla WebSocket: @@ -322,107 +308,115 @@ Here's a complete example of integrating Gin with Wails: package main import ( - "embed" - "log" - "net/http" - "time" + "embed" + "log" + "net/http" + "time" - "github.com/gin-gonic/gin" - "github.com/wailsapp/wails/v3/pkg/application" + "github.com/gin-gonic/gin" + "github.com/wailsapp/wails/v3/pkg/application" ) //go:embed static var staticFiles embed.FS -// GinMiddleware creates a middleware that passes requests to Gin +// GinMiddleware creates a middleware that passes requests to Gin if they're not handled by Wails func GinMiddleware(ginEngine *gin.Engine) application.Middleware { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Let Gin handle everything - ginEngine.ServeHTTP(w, r) - }) - } + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Wails handle the `/wails` route + if r.URL.Path == "/wails" { + next.ServeHTTP(w, r) + return + } + // Let Gin handle everything else + ginEngine.ServeHTTP(w, r) + }) + } } // LoggingMiddleware is a Gin middleware that logs request details func LoggingMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - startTime := time.Now() - c.Next() - latency := time.Since(startTime) - log.Printf("[GIN] %s | %s | %s | %d | %s", - c.Request.Method, - c.Request.URL.Path, - c.ClientIP(), - c.Writer.Status(), - latency, - ) - } + return func(c *gin.Context) { + // Start timer + startTime := time.Now() + + // Process request + c.Next() + + // Calculate latency + latency := time.Since(startTime) + + // Log request details + log.Printf("[GIN] %s | %s | %s | %d | %s", + c.Request.Method, + c.Request.URL.Path, + c.ClientIP(), + c.Writer.Status(), + latency, + ) + } } func main() { - // Set Gin to release mode for production - // gin.SetMode(gin.ReleaseMode) + // Create a new Gin router + ginEngine := gin.New() // Using New() instead of Default() to add our own middleware - // Create a new Gin router - ginEngine := gin.New() + // Add middlewares + ginEngine.Use(gin.Recovery()) + ginEngine.Use(LoggingMiddleware()) - // Add middlewares - ginEngine.Use(gin.Recovery()) - ginEngine.Use(LoggingMiddleware()) + // Serve embedded static files + ginEngine.StaticFS("/static", http.FS(staticFiles)) - // Serve embedded static files - ginEngine.StaticFS("/static", http.FS(staticFiles)) + // Define routes + ginEngine.GET("/", func(c *gin.Context) { + file, err := staticFiles.ReadFile("static/index.html") + if err != nil { + c.String(http.StatusInternalServerError, "Error reading index.html") + return + } + c.Data(http.StatusOK, "text/html; charset=utf-8", file) + }) - // Define routes - ginEngine.GET("/", func(c *gin.Context) { - file, err := staticFiles.ReadFile("static/index.html") - if err != nil { - c.String(http.StatusInternalServerError, "Error reading index.html") - return - } - c.Data(http.StatusOK, "text/html; charset=utf-8", file) - }) + ginEngine.GET("/api/hello", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "Hello from Gin API!", + "time": time.Now().Format(time.RFC3339), + }) + }) - ginEngine.GET("/api/hello", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "message": "Hello from Gin API!", - "time": time.Now().Format(time.RFC3339), - }) - }) + // Create a new Wails application + app := application.New(application.Options{ + Name: "Gin Example", + Description: "A demo of using Gin with Wails", + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + Assets: application.AssetOptions{ + Handler: ginEngine, + Middleware: GinMiddleware(ginEngine), + }, + }) - // Create a new Wails application - app := application.New(application.Options{ - Name: "Gin Example", - Description: "A demo of using Gin with Wails", - Mac: application.MacOptions{ - ApplicationShouldTerminateAfterLastWindowClosed: true, - }, - Assets: application.AssetOptions{ - Handler: ginEngine, - Middleware: GinMiddleware(ginEngine), - }, - }) + // Register event handler + app.OnEvent("gin-button-clicked", func(event *application.CustomEvent) { + log.Printf("Received event from frontend: %v", event.Data) + }) - // Register event handler - app.Events.On("gin-button-clicked", func(event *application.WailsEvent) { - log.Printf("Received event from frontend: %v", event.Data) - }) + // Create window + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Title: "Wails + Gin Example", + Width: 900, + Height: 700, + URL: "/", + }) - // Create window - app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ - Title: "Wails + Gin Example", - Width: 900, - Height: 700, - Centered: true, - URL: "/", - }) - - // Run the app - err := app.Run() - if err != nil { - log.Fatal(err) - } + // Run the app + err := app.Run() + if err != nil { + log.Fatal(err) + } } ``` diff --git a/v3/examples/gin-example/go.mod b/v3/examples/gin-example/go.mod index 6631f24cf..964a64312 100644 --- a/v3/examples/gin-example/go.mod +++ b/v3/examples/gin-example/go.mod @@ -1,8 +1,6 @@ module gin-example -go 1.22.4 - -toolchain go1.23.4 +go 1.24.0 require ( github.com/gin-gonic/gin v1.9.1 @@ -10,65 +8,63 @@ require ( ) require ( - dario.cat/mergo v1.0.0 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + dario.cat/mergo v1.0.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v1.1.5 // indirect + github.com/adrg/xdg v0.5.3 // indirect github.com/bep/debounce v1.2.1 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/cloudflare/circl v1.3.7 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/ebitengine/purego v0.4.0-alpha.4 // indirect + github.com/cloudflare/circl v1.6.0 // indirect + github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/ebitengine/purego v0.8.2 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.11.0 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-git/go-billy/v5 v5.6.2 // indirect + github.com/go-git/go-git/v5 v5.13.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/leaanthony/go-ansi-parser v1.6.1 // indirect - github.com/leaanthony/u v1.1.0 // indirect + github.com/leaanthony/u v1.1.1 // indirect github.com/leodido/go-urn v1.2.4 // indirect - github.com/lmittmann/tint v1.0.4 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/lmittmann/tint v1.0.7 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/samber/lo v1.38.1 // indirect - github.com/sergi/go-diff v1.2.0 // indirect - github.com/skeema/knownhosts v1.2.1 // indirect + github.com/samber/lo v1.49.1 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.3.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect - github.com/wailsapp/go-webview2 v1.0.9 // indirect + github.com/wailsapp/go-webview2 v1.0.19 // indirect github.com/wailsapp/mimetype v1.4.1 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/tools v0.21.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/v3/examples/gin-example/go.sum b/v3/examples/gin-example/go.sum index b0db8e43f..02b224ce4 100644 --- a/v3/examples/gin-example/go.sum +++ b/v3/examples/gin-example/go.sum @@ -1,35 +1,35 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= +github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= +github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= +github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.4.0-alpha.4 h1:Y7yIV06Yo5M2BAdD7EVPhfp6LZ0tEcQo5770OhYUVes= -github.com/ebitengine/purego v0.4.0-alpha.4/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= +github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= +github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -38,18 +38,18 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= -github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= +github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= -github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -62,15 +62,13 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= @@ -80,8 +78,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -91,17 +89,17 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A= github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= -github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI= -github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= +github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M= +github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= -github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= -github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/lmittmann/tint v1.0.7 h1:D/0OqWZ0YOGZ6AyC+5Y2kD8PBEzBk6rFHVSfOqCkF9Y= +github.com/lmittmann/tint v1.0.7/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= +github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -109,14 +107,14 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= +github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -124,15 +122,15 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= -github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew= +github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= -github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= +github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -145,105 +143,60 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/wailsapp/go-webview2 v1.0.9 h1:lrU+q0cf1wgLdR69rN+ZnRtMJNaJRrcQ4ELxoO7/xjs= -github.com/wailsapp/go-webview2 v1.0.9/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= +github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU= +github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs= +golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/v3/examples/gin-example/main.go b/v3/examples/gin-example/main.go index 374e52182..6a4d0b00d 100644 --- a/v3/examples/gin-example/main.go +++ b/v3/examples/gin-example/main.go @@ -17,6 +17,11 @@ var staticFiles embed.FS func GinMiddleware(ginEngine *gin.Engine) application.Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Wails handle the `/wails` route + if r.URL.Path == "/wails" { + next.ServeHTTP(w, r) + return + } // Let Gin handle everything else ginEngine.ServeHTTP(w, r) }) @@ -88,17 +93,16 @@ func main() { }) // Register event handler - app.Events.On("gin-button-clicked", func(event *application.WailsEvent) { + app.OnEvent("gin-button-clicked", func(event *application.CustomEvent) { log.Printf("Received event from frontend: %v", event.Data) }) // Create window app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ - Title: "Wails + Gin Example", - Width: 900, - Height: 700, - Centered: true, - URL: "/", + Title: "Wails + Gin Example", + Width: 900, + Height: 700, + URL: "/", }) // Run the app diff --git a/v3/examples/gin-example/static/index.html b/v3/examples/gin-example/static/index.html index 7d980038f..982717e1a 100644 --- a/v3/examples/gin-example/static/index.html +++ b/v3/examples/gin-example/static/index.html @@ -49,16 +49,16 @@ diff --git a/v3/internal/assetserver/assetserver_webview.go b/v3/internal/assetserver/assetserver_webview.go index 637642914..0d029a34e 100644 --- a/v3/internal/assetserver/assetserver_webview.go +++ b/v3/internal/assetserver/assetserver_webview.go @@ -74,7 +74,7 @@ func (a *AssetServer) processWebViewRequestInternal(r webview.Request) { } }() - var rw http.ResponseWriter = newContentTypeSniffer(wrw) // Make sure we have a Content-Type sniffer + rw := newContentTypeSniffer(wrw) // Make sure we have a Content-Type sniffer defer func() { if _, err := rw.complete(); err != nil { a.options.Logger.Error("Error writing response data.", "uri", uri, "error", err) From a5eed9a48629305529725a45955f4f6916b63d6e Mon Sep 17 00:00:00 2001 From: robinsamuel Date: Sun, 9 Mar 2025 23:18:34 +0100 Subject: [PATCH 054/136] fix: remove prefix from default version in config.yml to avoid nsis error --- v3/internal/commands/build_assets/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/internal/commands/build_assets/config.yml b/v3/internal/commands/build_assets/config.yml index bc09a6d28..5451e31d5 100644 --- a/v3/internal/commands/build_assets/config.yml +++ b/v3/internal/commands/build_assets/config.yml @@ -11,7 +11,7 @@ info: description: "A program that does X" # The application description copyright: "(c) 2025, My Company" # Copyright text comments: "Some Product Comments" # Comments - version: "v0.0.1" # The application version + version: "0.0.1" # The application version # Dev mode configuration dev_mode: From d0d1691004e40e73dabbc4c93d06f0b5d00ca8ee Mon Sep 17 00:00:00 2001 From: robinsamuel Date: Mon, 10 Mar 2025 15:30:10 +0100 Subject: [PATCH 055/136] feat: update changelog --- docs/src/content/docs/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index b18c0bcd6..ad3a97459 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -108,6 +108,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The dragging and resizing mechanism is now more robust and matches expected platform behaviour more closely by [@fbbdev](https://github.com/fbbdev) in [#4100](https://github.com/wailsapp/wails/pull/4100) - Fixed [#4097](https://github.com/wailsapp/wails/issues/4097) Webpack/angular discards runtime init code by [@fbbdev](https://github.com/fbbdev) in [#4100](https://github.com/wailsapp/wails/pull/4100) - Fixed assetFileServer not serving `.html` files when non-extension request when `[request]` doesn't exist but `[request].html` does +- Fixed NSIS Error because of incorrect prefix on default version in config by [@robin-samuel](https://github.com/robin-samuel) in [#4126](https://github.com/wailsapp/wails/pull/4126) ### Changed From b72782c35d929af104c4cd03c9fb2a3cdeb5bd58 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 9 Mar 2025 16:16:43 +1100 Subject: [PATCH 056/136] Update docs + examples. Serve runtime from assetserver if requested. --- .../docs/guides/{gin.mdx => gin-routing.mdx} | 172 +++++++- docs/src/content/docs/guides/gin-services.mdx | 409 ++++++++++++++++++ v3/examples/gin-example/main.go | 3 +- v3/examples/gin-example/static/index.html | 52 ++- v3/examples/gin-service/assets/index.html | 219 ++++++++++ v3/examples/gin-service/go.mod | 74 ++++ v3/examples/gin-service/go.sum | 208 +++++++++ v3/examples/gin-service/main.go | 45 ++ .../gin-service/services/gin_service.go | 220 ++++++++++ v3/pkg/application/application.go | 6 + 10 files changed, 1385 insertions(+), 23 deletions(-) rename docs/src/content/docs/guides/{gin.mdx => gin-routing.mdx} (68%) create mode 100644 docs/src/content/docs/guides/gin-services.mdx create mode 100644 v3/examples/gin-service/assets/index.html create mode 100644 v3/examples/gin-service/go.mod create mode 100644 v3/examples/gin-service/go.sum create mode 100644 v3/examples/gin-service/main.go create mode 100644 v3/examples/gin-service/services/gin_service.go diff --git a/docs/src/content/docs/guides/gin.mdx b/docs/src/content/docs/guides/gin-routing.mdx similarity index 68% rename from docs/src/content/docs/guides/gin.mdx rename to docs/src/content/docs/guides/gin-routing.mdx index 236996674..9d7c0da08 100644 --- a/docs/src/content/docs/guides/gin.mdx +++ b/docs/src/content/docs/guides/gin-routing.mdx @@ -30,19 +30,19 @@ go get -u github.com/gin-gonic/gin Create a middleware function that will handle the integration between Wails and Gin: ```go -// GinMiddleware creates a middleware that passes requests to Gin +// GinMiddleware creates a middleware that passes requests to Gin if they're not handled by Wails func GinMiddleware(ginEngine *gin.Engine) application.Middleware { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Let Wails handle the `/wails` route - if r.URL.Path == "/wails" { - next.ServeHTTP(w, r) - return - } - // Let Gin handle everything - ginEngine.ServeHTTP(w, r) - }) - } + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Let Wails handle the `/wails` route + if strings.HasPrefix(r.URL.Path, "/wails") { + next.ServeHTTP(w, r) + return + } + // Let Gin handle everything else + ginEngine.ServeHTTP(w, r) + }) + } } ``` @@ -207,6 +207,154 @@ ginEngine.GET("/api/search", func(c *gin.Context) { }) ``` +## Event Communication + +One of the powerful features of Wails is its event system, which allows for communication between the frontend and backend. When using Gin as a service, you can still leverage this event system by serving the Wails runtime.js file to your frontend. + +### Serving the Wails Runtime + +To enable event communication, you need to serve the Wails runtime.js file at the `/wails/runtime.js` path. Here's how to implement this in your Gin service: + +```go +import ( + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/wailsapp/wails/v3/pkg/application" + "github.com/wailsapp/wails/v3/pkg/runtime" +) + +// GinService implements a Wails service that uses Gin for HTTP handling +type GinService struct { + ginEngine *gin.Engine + app *application.App + // Other fields... +} + +// ServeHTTP implements the http.Handler interface +func (s *GinService) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Special handling for Wails runtime.js + if r.URL.Path == "/wails/runtime.js" { + s.serveWailsRuntime(w, r) + return + } + + // All other requests go to the Gin router + s.ginEngine.ServeHTTP(w, r) +} + +// serveWailsRuntime serves the Wails runtime.js file +func (s *GinService) serveWailsRuntime(w http.ResponseWriter, r *http.Request) { + // Open the runtime.js file from the public runtime package + runtimeFile, err := runtime.Assets.Open(runtime.RuntimeJSPath) + if err != nil { + http.Error(w, "Failed to access runtime assets", http.StatusInternalServerError) + return + } + defer runtimeFile.Close() + + // Set the content type + w.Header().Set("Content-Type", "application/javascript") + + // Copy the file to the response + _, err = io.Copy(w, runtimeFile) + if err != nil { + http.Error(w, "Failed to serve runtime.js", http.StatusInternalServerError) + } +} +``` + +### Handling Events + +You'll also need to add an endpoint to handle events from the frontend. This endpoint will bridge the gap between the HTTP requests and the Wails event system: + +```go +// In your setupRoutes method +func (s *GinService) setupRoutes() { + // Event handling endpoint + s.ginEngine.POST("/events/emit", func(c *gin.Context) { + var eventData struct { + Name string `json:"name" binding:"required"` + Data interface{} `json:"data"` + } + + if err := c.ShouldBindJSON(&eventData); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + // Process the event using the Wails event system + s.app.EmitEvent(eventData.Name, eventData.Data) + + c.JSON(http.StatusOK, gin.H{ + "success": true, + "message": "Event processed successfully", + }) + }) + + // Other routes... +} +``` + +### Using Events in the Frontend + +In your frontend HTML, include the Wails runtime.js script and use the event API: + +```html + + + + + + + +

+    
+    
+
+
+```
+
+This approach allows you to use the Wails event system seamlessly with your Gin service, providing a consistent experience across your application.
+
 ## Interacting with Wails
 
 Your Gin-served web content can interact with Wails features like events and bindings. To enable this interaction, you
diff --git a/docs/src/content/docs/guides/gin-services.mdx b/docs/src/content/docs/guides/gin-services.mdx
new file mode 100644
index 000000000..55d713b45
--- /dev/null
+++ b/docs/src/content/docs/guides/gin-services.mdx
@@ -0,0 +1,409 @@
+---
+title: Using Gin in Services
+description: A guide to integrating the Gin web framework with Wails v3 Services
+---
+
+Wails v3 Services provide a powerful way to organize your application logic into reusable, modular components. By implementing the `http.Handler` interface in your services, you can mount them at specific routes in your application, allowing for a clean separation of concerns and more maintainable code.
+
+Integrating Gin with Wails Services enables you to create modular, mountable HTTP APIs using Gin's powerful routing and middleware capabilities. You can organize your application into domain-specific services, mount multiple Gin-based services at different routes, leverage Gin's extensive feature set while maintaining the benefits of Wails Services, and seamlessly integrate with the Wails event system for real-time communication.
+
+## Creating a Gin-based Service
+
+To create a Wails Service that uses Gin for HTTP handling, you need to implement both the Wails Service interface and the `http.Handler` interface. This combination allows your service to be managed by the Wails application lifecycle and handle HTTP requests. Let's walk through each step of the process:
+
+### 1. Define Your Service Structure
+
+First, create a new service structure that will hold your Gin router and any state your service needs. This structure serves as the foundation of your service, encapsulating both the HTTP handling capabilities and any business logic or data your service requires. The use of a mutex ensures thread-safe access to shared resources, which is essential for concurrent request handling.
+
+```go
+package services
+
+import (
+	"context"
+	"net/http"
+	"sync"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	"github.com/wailsapp/wails/v3/pkg/application"
+)
+
+// User represents a user in the system
+type User struct {
+	ID        int       `json:"id"`
+	Name      string    `json:"name"`
+	Email     string    `json:"email"`
+	CreatedAt time.Time `json:"createdAt"`
+}
+
+// GinService implements a Wails service that uses Gin for HTTP handling
+type GinService struct {
+	ginEngine *gin.Engine
+	users     []User
+	nextID    int
+	mu        sync.RWMutex
+	app       *application.App
+}
+
+// NewGinService creates a new GinService instance
+func NewGinService() *GinService {
+	// Create a new Gin router
+	ginEngine := gin.New()
+
+	// Add middlewares
+	ginEngine.Use(gin.Recovery())
+	ginEngine.Use(LoggingMiddleware())
+
+	service := &GinService{
+		ginEngine: ginEngine,
+		users: []User{
+			{ID: 1, Name: "Alice", Email: "alice@example.com", CreatedAt: time.Now().Add(-72 * time.Hour)},
+			{ID: 2, Name: "Bob", Email: "bob@example.com", CreatedAt: time.Now().Add(-48 * time.Hour)},
+			{ID: 3, Name: "Charlie", Email: "charlie@example.com", CreatedAt: time.Now().Add(-24 * time.Hour)},
+		},
+		nextID: 4,
+	}
+
+	// Define routes
+	service.setupRoutes()
+
+	return service
+}
+```
+
+### 2. Implement the Wails Service Interface
+
+Your service needs to implement the Wails Service interface with the required methods. The `ServiceName` method provides a human-readable identifier for your service. The `ServiceStartup` method is called when the service starts and gives you access to the Wails application instance, which you can use to register event handlers and access other Wails features. The `ServiceShutdown` method allows you to clean up resources when the service is shutting down.
+
+```go
+// ServiceName returns the name of the service
+func (s *GinService) ServiceName() string {
+	return "Gin API Service"
+}
+
+// ServiceStartup is called when the service starts
+func (s *GinService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
+	// Store the application instance for later use
+	s.app = application.Get()
+
+	// Register an event handler that can be triggered from the frontend
+	s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) {
+		// Log the event data
+		s.app.Logger.Info("Received event from frontend", "data", event.Data)
+
+		// Emit an event back to the frontend
+		s.app.EmitEvent("gin-api-response", map[string]interface{}{
+			"message": "Response from Gin API Service",
+			"time":    time.Now().Format(time.RFC3339),
+		})
+	})
+
+	return nil
+}
+
+// ServiceShutdown is called when the service shuts down
+func (s *GinService) ServiceShutdown(ctx context.Context) error {
+	// Clean up resources if needed
+	return nil
+}
+```
+
+### 3. Implement the http.Handler Interface
+
+To make your service mountable at a specific route, implement the `http.Handler` interface. This single method, `ServeHTTP`, is the gateway for all HTTP requests to your service. It delegates the request handling to the Gin router, allowing you to use all of Gin's powerful features for routing and middleware.
+
+```go
+// ServeHTTP implements the http.Handler interface
+func (s *GinService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	// All requests go to the Gin router
+	s.ginEngine.ServeHTTP(w, r)
+}
+```
+
+### 4. Set Up Your Routes
+
+Define your API routes in a separate method for better organization. This approach keeps your code clean and makes it easier to understand the structure of your API. The Gin router provides a fluent API for defining routes, including support for route groups, which help organize related endpoints.
+
+```go
+// setupRoutes configures the API routes
+func (s *GinService) setupRoutes() {
+	// Basic info endpoint
+	s.ginEngine.GET("/info", func(c *gin.Context) {
+		c.JSON(http.StatusOK, gin.H{
+			"service": "Gin API Service",
+			"version": "1.0.0",
+			"time":    time.Now().Format(time.RFC3339),
+		})
+	})
+
+	// Users group
+	users := s.ginEngine.Group("/users")
+	{
+		// Get all users
+		users.GET("", func(c *gin.Context) {
+			s.mu.RLock()
+			defer s.mu.RUnlock()
+			c.JSON(http.StatusOK, s.users)
+		})
+
+		// Get user by ID
+		users.GET("/:id", func(c *gin.Context) {
+			id, err := strconv.Atoi(c.Param("id"))
+			if err != nil {
+				c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
+				return
+			}
+
+			s.mu.RLock()
+			defer s.mu.RUnlock()
+
+			for _, user := range s.users {
+				if user.ID == id {
+					c.JSON(http.StatusOK, user)
+					return
+				}
+			}
+
+			c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
+		})
+
+		// Create a new user
+		users.POST("", func(c *gin.Context) {
+			var newUser User
+			if err := c.ShouldBindJSON(&newUser); err != nil {
+				c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+				return
+			}
+
+			s.mu.Lock()
+			defer s.mu.Unlock()
+
+			// Set the ID and creation time
+			newUser.ID = s.nextID
+			newUser.CreatedAt = time.Now()
+			s.nextID++
+
+			// Add to the users slice
+			s.users = append(s.users, newUser)
+
+			c.JSON(http.StatusCreated, newUser)
+
+			// Emit an event to notify about the new user
+			s.app.EmitEvent("user-created", newUser)
+		})
+	}
+}
+```
+
+### 5. Create Custom Middleware
+
+You can create custom Gin middleware to enhance your service. Middleware functions in Gin are executed in the order they are added to the router and can perform tasks such as logging, authentication, and error handling. This example shows a simple logging middleware that records request details.
+
+```go
+// LoggingMiddleware is a Gin middleware that logs request details
+func LoggingMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		// Start timer
+		start := time.Now()
+
+		// Process request
+		c.Next()
+
+		// Calculate latency
+		latency := time.Since(start)
+
+		// Log request details
+		log.Printf("[GIN] %s %s %d %s", c.Request.Method, c.Request.URL.Path, c.Writer.Status(), latency)
+	}
+}
+```
+
+## Registering Your Service
+
+To use your Gin-based service in a Wails application, you need to register it with the application and specify the route where it should be mounted. This is done when creating the Wails application instance. The route you specify becomes the base path for all endpoints defined in your Gin router.
+
+```go
+app := application.New(application.Options{
+    Name:        "Gin Service Demo",
+    Description: "A demo of using Gin in Wails services",
+    Mac: application.MacOptions{
+        ApplicationShouldTerminateAfterLastWindowClosed: true,
+    },
+    LogLevel: slog.LevelDebug,
+    Services: []application.Service{
+        application.NewServiceWithOptions(services.NewGinService(), application.ServiceOptions{
+            Route: "/api",
+        }),
+    },
+    Assets: application.AssetOptions{
+        Handler: application.BundledAssetFileServer(assets),
+    },
+})
+```
+
+In this example, the Gin service is mounted at the `/api` route. This means that if your Gin router has an endpoint defined as `/info`, it will be accessible at `/api/info` in your application. This approach allows you to organize your API endpoints logically and avoid conflicts with other parts of your application.
+
+## Integrating with the Wails Event System
+
+One of the powerful features of using Gin with Wails Services is the ability to seamlessly integrate with the Wails event system. This allows for real-time communication between your backend service and the frontend.
+
+In your service's `ServiceStartup` method, you can register event handlers to process events from the frontend:
+
+```go
+s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) {
+    // Log the event data
+    s.app.Logger.Info("Received event from frontend", "data", event.Data)
+
+    // Emit an event back to the frontend
+    s.app.EmitEvent("gin-api-response", map[string]interface{}{
+        "message": "Response from Gin API Service",
+        "time":    time.Now().Format(time.RFC3339),
+    })
+})
+```
+
+You can also emit events to the frontend from your Gin routes or other parts of your service:
+
+```go
+// After creating a new user
+s.app.EmitEvent("user-created", newUser)
+```
+
+## Frontend Integration
+
+To interact with your Gin service from the frontend, you'll need to import the Wails runtime, make HTTP requests to your API endpoints, and use the Wails event system for real-time communication.
+
+For production use, it's recommended to use the `@wailsio/runtime` package instead of directly importing `/wails/runtime.js`. This ensures type safety, better IDE support, version management through npm, and compatibility with modern JavaScript tooling.
+
+Install the package:
+```bash
+npm install @wailsio/runtime
+```
+
+Then use it in your code:
+```javascript
+import * as wails from '@wailsio/runtime';
+
+// Event emission
+wails.Events.Emit({name: 'gin-api-event', data: eventData});
+```
+
+Here's an example of how to set up frontend integration:
+
+```html
+
+
+
+    
+    
+    Gin Service Example
+    
+
+
+    

Gin Service Example

+ +
+

API Endpoints

+

Try the Gin API endpoints mounted at /api:

+ + + + + + +
+
Results will appear here...
+
+
+ +
+

Event Communication

+

Trigger an event to communicate with the Gin service:

+ + + +
+
Event responses will appear here...
+
+
+ + + + + + +``` + +## Best Practices + +When using Gin with Wails Services, consider these best practices for creating maintainable and efficient applications: + +- Modular Design: Organize your API endpoints into logical groups using Gin's router groups. This makes your code more readable and easier to maintain. + +- Concurrency Safety: Use mutexes or other synchronization primitives when accessing shared state. This prevents race conditions and ensures data integrity. + +- Error Handling: Implement consistent error handling across your API endpoints. This provides a better user experience and makes debugging easier. + +- Logging: Use the Wails logger for consistent logging throughout your application. This helps with debugging and monitoring. + +- Event-Driven Communication: Use the Wails event system for real-time updates and notifications. This creates a more responsive and interactive user experience. + +- Security: Implement proper authentication and authorization for your API endpoints. This protects your application and user data. + +## Closing Thoughts + +Integrating the Gin web framework with Wails v3 Services provides a powerful and flexible approach to building modular, maintainable web applications. By leveraging Gin's routing and middleware capabilities alongside the Wails event system, you can create rich, interactive applications with clean separation of concerns. + +The complete example code for this guide can be found in the Wails repository under `v3/examples/gin-service`. diff --git a/v3/examples/gin-example/main.go b/v3/examples/gin-example/main.go index 6a4d0b00d..d3992cdb1 100644 --- a/v3/examples/gin-example/main.go +++ b/v3/examples/gin-example/main.go @@ -4,6 +4,7 @@ import ( "embed" "log" "net/http" + "strings" "time" "github.com/gin-gonic/gin" @@ -18,7 +19,7 @@ func GinMiddleware(ginEngine *gin.Engine) application.Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Let Wails handle the `/wails` route - if r.URL.Path == "/wails" { + if strings.HasPrefix(r.URL.Path, "/wails") { next.ServeHTTP(w, r) return } diff --git a/v3/examples/gin-example/static/index.html b/v3/examples/gin-example/static/index.html index 982717e1a..df02b840f 100644 --- a/v3/examples/gin-example/static/index.html +++ b/v3/examples/gin-example/static/index.html @@ -41,6 +41,13 @@

Wails + Gin Integration

+
+

Hello World!

+

This page is being served by Gin.

+

Click the button below to trigger a Wails event:

+ + +

API Example

Try the Gin API endpoint:

@@ -48,17 +55,42 @@
- diff --git a/v3/examples/gin-service/assets/index.html b/v3/examples/gin-service/assets/index.html new file mode 100644 index 000000000..40dccf552 --- /dev/null +++ b/v3/examples/gin-service/assets/index.html @@ -0,0 +1,219 @@ + + + + + + Gin Service Example + + + +

Gin Service Example

+ +
+

API Endpoints

+

Try the Gin API endpoints mounted at /api:

+ + + + + + +
+
Results will appear here...
+
+
+ +
+

Event Communication

+

Trigger an event to communicate with the Gin service:

+ + + +
+
Event responses will appear here...
+
+
+ + + + + + diff --git a/v3/examples/gin-service/go.mod b/v3/examples/gin-service/go.mod new file mode 100644 index 000000000..be466601b --- /dev/null +++ b/v3/examples/gin-service/go.mod @@ -0,0 +1,74 @@ +module gin-service + +go 1.24.0 + +require ( + github.com/gin-gonic/gin v1.10.0 + github.com/wailsapp/wails/v3 v3.0.0-alpha.9 +) + +require ( + dario.cat/mergo v1.0.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v1.1.5 // indirect + github.com/adrg/xdg v0.5.3 // indirect + github.com/bep/debounce v1.2.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudflare/circl v1.6.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/ebitengine/purego v0.8.2 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.6.2 // indirect + github.com/go-git/go-git/v5 v5.13.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/leaanthony/go-ansi-parser v1.6.1 // indirect + github.com/leaanthony/u v1.1.1 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/lmittmann/tint v1.0.7 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/samber/lo v1.49.1 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.3.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/wailsapp/go-webview2 v1.0.19 // indirect + github.com/wailsapp/mimetype v1.4.1 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/wailsapp/wails/v3 v3.0.0-alpha.9 => ../.. diff --git a/v3/examples/gin-service/go.sum b/v3/examples/gin-service/go.sum new file mode 100644 index 000000000..5615e40c4 --- /dev/null +++ b/v3/examples/gin-service/go.sum @@ -0,0 +1,208 @@ +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= +github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= +github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= +github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= +github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= +github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= +github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= +github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A= +github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= +github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M= +github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lmittmann/tint v1.0.7 h1:D/0OqWZ0YOGZ6AyC+5Y2kD8PBEzBk6rFHVSfOqCkF9Y= +github.com/lmittmann/tint v1.0.7/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= +github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= +github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew= +github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= +github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU= +github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc= +github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= +github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs= +golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/v3/examples/gin-service/main.go b/v3/examples/gin-service/main.go new file mode 100644 index 000000000..b27b1903b --- /dev/null +++ b/v3/examples/gin-service/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "embed" + "log/slog" + "os" + + "gin-service/services" + "github.com/wailsapp/wails/v3/pkg/application" +) + +//go:embed assets/* +var assets embed.FS + +func main() { + app := application.New(application.Options{ + Name: "Gin Service Demo", + Description: "A demo of using Gin in Wails services", + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + LogLevel: slog.LevelDebug, + Services: []application.Service{ + application.NewServiceWithOptions(services.NewGinService(), application.ServiceOptions{ + Route: "/api", + }), + }, + Assets: application.AssetOptions{ + Handler: application.BundledAssetFileServer(assets), + }, + }) + + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Title: "Gin Service Demo", + Width: 1024, + Height: 768, + }) + + err := app.Run() + + if err != nil { + println(err.Error()) + os.Exit(1) + } +} diff --git a/v3/examples/gin-service/services/gin_service.go b/v3/examples/gin-service/services/gin_service.go new file mode 100644 index 000000000..6c3ef9f70 --- /dev/null +++ b/v3/examples/gin-service/services/gin_service.go @@ -0,0 +1,220 @@ +package services + +import ( + "context" + "net/http" + "strconv" + "sync" + "time" + + "github.com/gin-gonic/gin" + "github.com/wailsapp/wails/v3/pkg/application" +) + +// User represents a user in the system +type User struct { + ID int `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + CreatedAt time.Time `json:"createdAt"` +} + +// GinService implements a Wails service that uses Gin for HTTP handling +type GinService struct { + ginEngine *gin.Engine + users []User + nextID int + mu sync.RWMutex + app *application.App +} + +type EventData struct { + Message string `json:"message"` + Timestamp string `json:"timestamp"` +} + +// NewGinService creates a new GinService instance +func NewGinService() *GinService { + // Create a new Gin router + ginEngine := gin.New() + + // Add middlewares + ginEngine.Use(gin.Recovery()) + ginEngine.Use(LoggingMiddleware()) + + service := &GinService{ + ginEngine: ginEngine, + users: []User{ + {ID: 1, Name: "Alice", Email: "alice@example.com", CreatedAt: time.Now().Add(-72 * time.Hour)}, + {ID: 2, Name: "Bob", Email: "bob@example.com", CreatedAt: time.Now().Add(-48 * time.Hour)}, + {ID: 3, Name: "Charlie", Email: "charlie@example.com", CreatedAt: time.Now().Add(-24 * time.Hour)}, + }, + nextID: 4, + } + + // Define routes + service.setupRoutes() + + return service +} + +// ServiceName returns the name of the service +func (s *GinService) ServiceName() string { + return "Gin API Service" +} + +// ServiceStartup is called when the service starts +func (s *GinService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { + // You can access the application instance via ctx + s.app = application.Get() + + // Register an event handler that can be triggered from the frontend + s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) { + // Log the event data + // Parse the event data + s.app.Logger.Info("Received event from frontend", "data", event.Data) + + // You could also emit an event back to the frontend + s.app.EmitEvent("gin-api-response", map[string]interface{}{ + "message": "Response from Gin API Service", + "time": time.Now().Format(time.RFC3339), + }) + }) + + return nil +} + +// ServiceShutdown is called when the service shuts down +func (s *GinService) ServiceShutdown(ctx context.Context) error { + return nil +} + +// ServeHTTP implements the http.Handler interface +func (s *GinService) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // All other requests go to the Gin router + s.ginEngine.ServeHTTP(w, r) +} + +// setupRoutes configures the API routes +func (s *GinService) setupRoutes() { + // Basic info endpoint + s.ginEngine.GET("/info", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "service": "Gin API Service", + "version": "1.0.0", + "time": time.Now().Format(time.RFC3339), + }) + }) + + // Users group + users := s.ginEngine.Group("/users") + { + // Get all users + users.GET("", func(c *gin.Context) { + s.mu.RLock() + defer s.mu.RUnlock() + c.JSON(http.StatusOK, s.users) + }) + + // Get user by ID + users.GET("/:id", func(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) + return + } + + s.mu.RLock() + defer s.mu.RUnlock() + + for _, user := range s.users { + if user.ID == id { + c.JSON(http.StatusOK, user) + return + } + } + + c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) + }) + + // Create a new user + users.POST("", func(c *gin.Context) { + var newUser User + if err := c.ShouldBindJSON(&newUser); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + s.mu.Lock() + defer s.mu.Unlock() + + // Set the ID and creation time + newUser.ID = s.nextID + newUser.CreatedAt = time.Now() + s.nextID++ + + // Add to the users slice + s.users = append(s.users, newUser) + + c.JSON(http.StatusCreated, newUser) + + // Emit an event to notify about the new user + s.app.EmitEvent("user-created", newUser) + }) + + // Delete a user + users.DELETE("/:id", func(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) + return + } + + s.mu.Lock() + defer s.mu.Unlock() + + for i, user := range s.users { + if user.ID == id { + // Remove the user from the slice + s.users = append(s.users[:i], s.users[i+1:]...) + c.JSON(http.StatusOK, gin.H{"message": "User deleted"}) + return + } + } + + c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) + }) + } +} + +// LoggingMiddleware is a Gin middleware that logs request details +func LoggingMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + // Start timer + start := time.Now() + + // Process request + c.Next() + + // Calculate latency + latency := time.Since(start) + + // Log request details + statusCode := c.Writer.Status() + clientIP := c.ClientIP() + method := c.Request.Method + path := c.Request.URL.Path + + // Get the application instance + app := application.Get() + if app != nil { + app.Logger.Info("HTTP Request", + "status", statusCode, + "method", method, + "path", path, + "ip", clientIP, + "latency", latency, + ) + } + } +} diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 21c0792cc..6650106c8 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/wailsapp/wails/v3/internal/assetserver/bundledassets" "io" "log/slog" "net/http" @@ -98,6 +99,11 @@ func New(appOptions Options) *App { return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { path := req.URL.Path switch path { + case "/wails/runtime.js": + err := assetserver.ServeFile(rw, path, bundledassets.RuntimeJS) + if err != nil { + result.fatal("unable to serve runtime.js: %w", err) + } case "/wails/runtime": messageProc.ServeHTTP(rw, req) case "/wails/capabilities": From da99ea47b00b1899d736262c467c49d3e14757bd Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sat, 15 Jun 2024 07:56:55 +1000 Subject: [PATCH 057/136] Update docs + examples. Serve runtime from assetserver if requested. Add gin guide, fix asset server merge, add gin example adding http.CloseNotifier and http.Flusher interface to assetserver.contentTypeSniffer, for Gin (and other framework) compatibility. --- docs/src/content/docs/guides/gin-routing.mdx | 2 +- docs/src/content/docs/guides/gin-services.mdx | 209 +++++++++++++++--- v3/examples/events/assets/index.html | 2 +- v3/examples/gin-routing/README.md | 26 +++ v3/examples/gin-routing/go.mod | 72 ++++++ v3/examples/gin-routing/go.sum | 203 +++++++++++++++++ v3/examples/gin-routing/main.go | 114 ++++++++++ v3/examples/gin-routing/static/index.html | 94 ++++++++ v3/examples/gin-service/README.md | 26 +++ v3/examples/gin-service/assets/index.html | 30 +++ .../bundledassets/runtime.debug.js | 10 +- .../assetserver/bundledassets/runtime.js | 2 +- .../desktop/@wailsio/runtime/src/events.ts | 18 +- 13 files changed, 767 insertions(+), 41 deletions(-) create mode 100644 v3/examples/gin-routing/README.md create mode 100644 v3/examples/gin-routing/go.mod create mode 100644 v3/examples/gin-routing/go.sum create mode 100644 v3/examples/gin-routing/main.go create mode 100644 v3/examples/gin-routing/static/index.html create mode 100644 v3/examples/gin-service/README.md diff --git a/docs/src/content/docs/guides/gin-routing.mdx b/docs/src/content/docs/guides/gin-routing.mdx index 9d7c0da08..b9f59cb77 100644 --- a/docs/src/content/docs/guides/gin-routing.mdx +++ b/docs/src/content/docs/guides/gin-routing.mdx @@ -1,5 +1,5 @@ --- -title: Using Gin with Wails +title: Using Gin for Routing description: A comprehensive guide to integrating Gin web framework with Wails v3 applications --- diff --git a/docs/src/content/docs/guides/gin-services.mdx b/docs/src/content/docs/guides/gin-services.mdx index 55d713b45..73c56afba 100644 --- a/docs/src/content/docs/guides/gin-services.mdx +++ b/docs/src/content/docs/guides/gin-services.mdx @@ -1,19 +1,41 @@ --- -title: Using Gin in Services +title: Using Gin for Services description: A guide to integrating the Gin web framework with Wails v3 Services --- -Wails v3 Services provide a powerful way to organize your application logic into reusable, modular components. By implementing the `http.Handler` interface in your services, you can mount them at specific routes in your application, allowing for a clean separation of concerns and more maintainable code. +# Using Gin for Services -Integrating Gin with Wails Services enables you to create modular, mountable HTTP APIs using Gin's powerful routing and middleware capabilities. You can organize your application into domain-specific services, mount multiple Gin-based services at different routes, leverage Gin's extensive feature set while maintaining the benefits of Wails Services, and seamlessly integrate with the Wails event system for real-time communication. +The Gin web framework is a popular choice for building HTTP services in Go. With Wails v3, you can easily integrate Gin-based services into your application, providing a powerful way to handle HTTP requests, implement RESTful APIs, and serve web content. -## Creating a Gin-based Service +This guide will walk you through creating a Gin-based service that can be mounted at a specific route in your Wails application. We'll build a complete example that demonstrates how to: -To create a Wails Service that uses Gin for HTTP handling, you need to implement both the Wails Service interface and the `http.Handler` interface. This combination allows your service to be managed by the Wails application lifecycle and handle HTTP requests. Let's walk through each step of the process: +1. Create a Gin-based service +2. Implement the Wails Service interface +3. Set up routes and middleware +4. Integrate with the Wails event system +5. Interact with the service from the frontend -### 1. Define Your Service Structure +## Prerequisites -First, create a new service structure that will hold your Gin router and any state your service needs. This structure serves as the foundation of your service, encapsulating both the HTTP handling capabilities and any business logic or data your service requires. The use of a mutex ensures thread-safe access to shared resources, which is essential for concurrent request handling. +Before you begin, make sure you have: + +- Wails v3 installed +- Basic knowledge of Go and the Gin framework +- Familiarity with HTTP concepts and RESTful APIs + +You'll need to add the Gin framework to your project: + +```bash +go get github.com/gin-gonic/gin +``` + +## Creating a Gin-Based Service + +Let's start by creating a Gin service that implements the Wails Service interface. Our service will manage a collection of users and provide API endpoints for retrieving and creating user records. + +### 1. Define Your Data Models + +First, define the data structures your service will work with: ```go package services @@ -21,6 +43,7 @@ package services import ( "context" "net/http" + "strconv" "sync" "time" @@ -36,6 +59,18 @@ type User struct { CreatedAt time.Time `json:"createdAt"` } +// EventData represents data sent in events +type EventData struct { + Message string `json:"message"` + Timestamp string `json:"timestamp"` +} +``` + +### 2. Create Your Service Structure + +Next, define the service structure that will hold your Gin router and any state your service needs to maintain: + +```go // GinService implements a Wails service that uses Gin for HTTP handling type GinService struct { ginEngine *gin.Engine @@ -71,9 +106,9 @@ func NewGinService() *GinService { } ``` -### 2. Implement the Wails Service Interface +### 3. Implement the Service Interface -Your service needs to implement the Wails Service interface with the required methods. The `ServiceName` method provides a human-readable identifier for your service. The `ServiceStartup` method is called when the service starts and gives you access to the Wails application instance, which you can use to register event handlers and access other Wails features. The `ServiceShutdown` method allows you to clean up resources when the service is shutting down. +Implement the required methods for the Wails Service interface: ```go // ServiceName returns the name of the service @@ -122,7 +157,7 @@ func (s *GinService) ServeHTTP(w http.ResponseWriter, r *http.Request) { ### 4. Set Up Your Routes -Define your API routes in a separate method for better organization. This approach keeps your code clean and makes it easier to understand the structure of your API. The Gin router provides a fluent API for defining routes, including support for route groups, which help organize related endpoints. +Define your API routes in a separate method for better organisation. This approach keeps your code clean and makes it easier to understand the structure of your API. The Gin router provides a fluent API for defining routes, including support for route groups, which help organise related endpoints. ```go // setupRoutes configures the API routes @@ -191,6 +226,29 @@ func (s *GinService) setupRoutes() { // Emit an event to notify about the new user s.app.EmitEvent("user-created", newUser) }) + + // Delete a user + users.DELETE("/:id", func(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) + return + } + + s.mu.Lock() + defer s.mu.Unlock() + + for i, user := range s.users { + if user.ID == id { + // Remove the user from the slice + s.users = append(s.users[:i], s.users[i+1:]...) + c.JSON(http.StatusOK, gin.H{"message": "User deleted"}) + return + } + } + + c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) + }) } } ``` @@ -241,7 +299,7 @@ app := application.New(application.Options{ }) ``` -In this example, the Gin service is mounted at the `/api` route. This means that if your Gin router has an endpoint defined as `/info`, it will be accessible at `/api/info` in your application. This approach allows you to organize your API endpoints logically and avoid conflicts with other parts of your application. +In this example, the Gin service is mounted at the `/api` route. This means that if your Gin router has an endpoint defined as `/info`, it will be accessible at `/api/info` in your application. This approach allows you to organise your API endpoints logically and avoid conflicts with other parts of your application. ## Integrating with the Wails Event System @@ -285,7 +343,7 @@ Then use it in your code: import * as wails from '@wailsio/runtime'; // Event emission -wails.Events.Emit({name: 'gin-api-event', data: eventData}); +wails.Events.Emit('gin-api-event', eventData); ``` Here's an example of how to set up frontend integration: @@ -310,7 +368,8 @@ Here's an example of how to set up frontend integration: - + +
Results will appear here...
@@ -327,8 +386,23 @@ Here's an example of how to set up frontend integration: - - + + + + diff --git a/v3/examples/gin-service/README.md b/v3/examples/gin-service/README.md new file mode 100644 index 000000000..ed9c2b908 --- /dev/null +++ b/v3/examples/gin-service/README.md @@ -0,0 +1,26 @@ +# Gin Service Example + +This example demonstrates how to use the [Gin web framework](https://github.com/gin-gonic/gin) in a Wails Service. + +## Overview + +This example shows how to: + +- Set up Gin as the asset handler for a Wails application +- Create a middleware that routes requests between Wails and Gin +- Define API endpoints with Gin +- Communicate between the Gin-served frontend and Wails backend +- Implement custom Gin middleware + +## Running the Example + +```bash +cd v3/examples/gin-routing +go mod tidy +go run . +``` + +## Documentation + +Please consult the [Using Gin for Routing](https://v3.wails.io/guides/gin-routing/) guide for a detailed explanation of the example. + diff --git a/v3/examples/gin-service/assets/index.html b/v3/examples/gin-service/assets/index.html index 40dccf552..34324b89f 100644 --- a/v3/examples/gin-service/assets/index.html +++ b/v3/examples/gin-service/assets/index.html @@ -73,6 +73,7 @@ +
Results will appear here...
@@ -188,6 +189,27 @@ } }); + document.getElementById('deleteUser').addEventListener('click', async () => { + const userId = prompt('Enter user ID to delete:'); + if (userId) { + try { + await fetchAPI(`/users/${userId}`, { + method: 'DELETE' + }); + + // Show success message + document.getElementById('apiResponse').textContent = JSON.stringify({ + message: `User with ID ${userId} deleted successfully` + }, null, 2); + + // Refresh the user list + setTimeout(() => fetchAPI('/users'), 1000); + } catch (error) { + console.error('Error deleting user:', error); + } + } + }); + // Using Wails Events API for event communication document.getElementById('triggerEvent').addEventListener('click', async () => { // Display the event being sent @@ -211,6 +233,14 @@ document.getElementById('eventResponse').textContent = JSON.stringify(data, null, 2); }); + // Also listen for user-created events + wails.Events.On("user-created", (data) => { + document.getElementById('eventResponse').textContent = JSON.stringify({ + event: "user-created", + user: data + }, null, 2); + }); + // Initial API call to get service info fetchAPI('/info'); }); diff --git a/v3/internal/assetserver/bundledassets/runtime.debug.js b/v3/internal/assetserver/bundledassets/runtime.debug.js index fc1340c40..c4976e7f6 100644 --- a/v3/internal/assetserver/bundledassets/runtime.debug.js +++ b/v3/internal/assetserver/bundledassets/runtime.debug.js @@ -512,7 +512,13 @@ function Off(...eventNames) { function OffAll() { eventListeners.clear(); } -function Emit(event) { +function Emit(name, data) { + let event; + if (typeof name === "object" && name !== null && "name" in name && "data" in name) { + event = new WailsEvent(name["name"], name["data"]); + } else { + event = new WailsEvent(name, data); + } return call3(EmitMethod, event); } @@ -2507,4 +2513,4 @@ export { wml_exports as WML, window_default as Window }; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2luZGV4LnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy93bWwudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2Jyb3dzZXIudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL25hbm9pZC50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvcnVudGltZS50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvZGlhbG9ncy50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvZXZlbnRzLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9saXN0ZW5lci50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvZXZlbnRfdHlwZXMudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL3V0aWxzLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy93aW5kb3cudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL2NvbXBpbGVkL21haW4uanMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL3N5c3RlbS50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvY29udGV4dG1lbnUudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2ZsYWdzLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9kcmFnLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9hcHBsaWNhdGlvbi50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvY2FsbHMudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2NhbGxhYmxlLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9jYW5jZWxsYWJsZS50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvY2xpcGJvYXJkLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9jcmVhdGUudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL3NjcmVlbnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vLyBTZXR1cFxud2luZG93Ll93YWlscyA9IHdpbmRvdy5fd2FpbHMgfHwge307XG5cbmltcG9ydCBcIi4vY29udGV4dG1lbnUuanNcIjtcbmltcG9ydCBcIi4vZHJhZy5qc1wiO1xuXG4vLyBSZS1leHBvcnQgcHVibGljIEFQSVxuaW1wb3J0ICogYXMgQXBwbGljYXRpb24gZnJvbSBcIi4vYXBwbGljYXRpb24uanNcIjtcbmltcG9ydCAqIGFzIEJyb3dzZXIgZnJvbSBcIi4vYnJvd3Nlci5qc1wiO1xuaW1wb3J0ICogYXMgQ2FsbCBmcm9tIFwiLi9jYWxscy5qc1wiO1xuaW1wb3J0ICogYXMgQ2xpcGJvYXJkIGZyb20gXCIuL2NsaXBib2FyZC5qc1wiO1xuaW1wb3J0ICogYXMgQ3JlYXRlIGZyb20gXCIuL2NyZWF0ZS5qc1wiO1xuaW1wb3J0ICogYXMgRGlhbG9ncyBmcm9tIFwiLi9kaWFsb2dzLmpzXCI7XG5pbXBvcnQgKiBhcyBFdmVudHMgZnJvbSBcIi4vZXZlbnRzLmpzXCI7XG5pbXBvcnQgKiBhcyBGbGFncyBmcm9tIFwiLi9mbGFncy5qc1wiO1xuaW1wb3J0ICogYXMgU2NyZWVucyBmcm9tIFwiLi9zY3JlZW5zLmpzXCI7XG5pbXBvcnQgKiBhcyBTeXN0ZW0gZnJvbSBcIi4vc3lzdGVtLmpzXCI7XG5pbXBvcnQgV2luZG93IGZyb20gXCIuL3dpbmRvdy5qc1wiO1xuaW1wb3J0ICogYXMgV01MIGZyb20gXCIuL3dtbC5qc1wiO1xuXG5leHBvcnQge1xuICAgIEFwcGxpY2F0aW9uLFxuICAgIEJyb3dzZXIsXG4gICAgQ2FsbCxcbiAgICBDbGlwYm9hcmQsXG4gICAgRGlhbG9ncyxcbiAgICBFdmVudHMsXG4gICAgRmxhZ3MsXG4gICAgU2NyZWVucyxcbiAgICBTeXN0ZW0sXG4gICAgV2luZG93LFxuICAgIFdNTFxufTtcblxuLyoqXG4gKiBBbiBpbnRlcm5hbCB1dGlsaXR5IGNvbnN1bWVkIGJ5IHRoZSBiaW5kaW5nIGdlbmVyYXRvci5cbiAqXG4gKiBAaWdub3JlXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IHsgQ3JlYXRlIH07XG5cbmV4cG9ydCAqIGZyb20gXCIuL2NhbmNlbGxhYmxlLmpzXCI7XG5cbi8vIE5vdGlmeSBiYWNrZW5kXG53aW5kb3cuX3dhaWxzLmludm9rZSA9IFN5c3RlbS5pbnZva2U7XG5TeXN0ZW0uaW52b2tlKFwid2FpbHM6cnVudGltZTpyZWFkeVwiKTtcbiIsICIvKlxuIF8gICAgIF9fICAgICBfIF9fXG58IHwgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuaW1wb3J0IHsgT3BlblVSTCB9IGZyb20gXCIuL2Jyb3dzZXIuanNcIjtcbmltcG9ydCB7IFF1ZXN0aW9uIH0gZnJvbSBcIi4vZGlhbG9ncy5qc1wiO1xuaW1wb3J0IHsgRW1pdCwgV2FpbHNFdmVudCB9IGZyb20gXCIuL2V2ZW50cy5qc1wiO1xuaW1wb3J0IHsgY2FuQWJvcnRMaXN0ZW5lcnMsIHdoZW5SZWFkeSB9IGZyb20gXCIuL3V0aWxzLmpzXCI7XG5pbXBvcnQgV2luZG93IGZyb20gXCIuL3dpbmRvdy5qc1wiO1xuXG4vKipcbiAqIFNlbmRzIGFuIGV2ZW50IHdpdGggdGhlIGdpdmVuIG5hbWUgYW5kIG9wdGlvbmFsIGRhdGEuXG4gKlxuICogQHBhcmFtIGV2ZW50TmFtZSAtIC0gVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHNlbmQuXG4gKiBAcGFyYW0gW2RhdGE9bnVsbF0gLSAtIE9wdGlvbmFsIGRhdGEgdG8gc2VuZCBhbG9uZyB3aXRoIHRoZSBldmVudC5cbiAqL1xuZnVuY3Rpb24gc2VuZEV2ZW50KGV2ZW50TmFtZTogc3RyaW5nLCBkYXRhOiBhbnkgPSBudWxsKTogdm9pZCB7XG4gICAgRW1pdChuZXcgV2FpbHNFdmVudChldmVudE5hbWUsIGRhdGEpKTtcbn1cblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvbiBhIHNwZWNpZmllZCB3aW5kb3cuXG4gKlxuICogQHBhcmFtIHdpbmRvd05hbWUgLSBUaGUgbmFtZSBvZiB0aGUgd2luZG93IHRvIGNhbGwgdGhlIG1ldGhvZCBvbi5cbiAqIEBwYXJhbSBtZXRob2ROYW1lIC0gVGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0byBjYWxsLlxuICovXG5mdW5jdGlvbiBjYWxsV2luZG93TWV0aG9kKHdpbmRvd05hbWU6IHN0cmluZywgbWV0aG9kTmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgdGFyZ2V0V2luZG93ID0gV2luZG93LkdldCh3aW5kb3dOYW1lKTtcbiAgICBjb25zdCBtZXRob2QgPSAodGFyZ2V0V2luZG93IGFzIGFueSlbbWV0aG9kTmFtZV07XG5cbiAgICBpZiAodHlwZW9mIG1ldGhvZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFdpbmRvdyBtZXRob2QgJyR7bWV0aG9kTmFtZX0nIG5vdCBmb3VuZGApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgbWV0aG9kLmNhbGwodGFyZ2V0V2luZG93KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGNhbGxpbmcgd2luZG93IG1ldGhvZCAnJHttZXRob2ROYW1lfSc6IGAsIGUpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZXNwb25kcyB0byBhIHRyaWdnZXJpbmcgZXZlbnQgYnkgcnVubmluZyBhcHByb3ByaWF0ZSBXTUwgYWN0aW9ucyBmb3IgdGhlIGN1cnJlbnQgdGFyZ2V0LlxuICovXG5mdW5jdGlvbiBvbldNTFRyaWdnZXJlZChldjogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBlbGVtZW50ID0gZXYuY3VycmVudFRhcmdldCBhcyBFbGVtZW50O1xuXG4gICAgZnVuY3Rpb24gcnVuRWZmZWN0KGNob2ljZSA9IFwiWWVzXCIpIHtcbiAgICAgICAgaWYgKGNob2ljZSAhPT0gXCJZZXNcIilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBldmVudFR5cGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWV2ZW50JykgfHwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtd21sLWV2ZW50Jyk7XG4gICAgICAgIGNvbnN0IHRhcmdldFdpbmRvdyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtdGFyZ2V0LXdpbmRvdycpIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXdtbC10YXJnZXQtd2luZG93JykgfHwgXCJcIjtcbiAgICAgICAgY29uc3Qgd2luZG93TWV0aG9kID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC13aW5kb3cnKSB8fCBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS13bWwtd2luZG93Jyk7XG4gICAgICAgIGNvbnN0IHVybCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtb3BlbnVybCcpIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXdtbC1vcGVudXJsJyk7XG5cbiAgICAgICAgaWYgKGV2ZW50VHlwZSAhPT0gbnVsbClcbiAgICAgICAgICAgIHNlbmRFdmVudChldmVudFR5cGUpO1xuICAgICAgICBpZiAod2luZG93TWV0aG9kICE9PSBudWxsKVxuICAgICAgICAgICAgY2FsbFdpbmRvd01ldGhvZCh0YXJnZXRXaW5kb3csIHdpbmRvd01ldGhvZCk7XG4gICAgICAgIGlmICh1cmwgIT09IG51bGwpXG4gICAgICAgICAgICB2b2lkIE9wZW5VUkwodXJsKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25maXJtID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC1jb25maXJtJykgfHwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtd21sLWNvbmZpcm0nKTtcblxuICAgIGlmIChjb25maXJtKSB7XG4gICAgICAgIFF1ZXN0aW9uKHtcbiAgICAgICAgICAgIFRpdGxlOiBcIkNvbmZpcm1cIixcbiAgICAgICAgICAgIE1lc3NhZ2U6IGNvbmZpcm0sXG4gICAgICAgICAgICBEZXRhY2hlZDogZmFsc2UsXG4gICAgICAgICAgICBCdXR0b25zOiBbXG4gICAgICAgICAgICAgICAgeyBMYWJlbDogXCJZZXNcIiB9LFxuICAgICAgICAgICAgICAgIHsgTGFiZWw6IFwiTm9cIiwgSXNEZWZhdWx0OiB0cnVlIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgfSkudGhlbihydW5FZmZlY3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJ1bkVmZmVjdCgpO1xuICAgIH1cbn1cblxuLy8gUHJpdmF0ZSBmaWVsZCBuYW1lcy5cbmNvbnN0IGNvbnRyb2xsZXJTeW0gPSBTeW1ib2woXCJjb250cm9sbGVyXCIpO1xuY29uc3QgdHJpZ2dlck1hcFN5bSA9IFN5bWJvbChcInRyaWdnZXJNYXBcIik7XG5jb25zdCBlbGVtZW50Q291bnRTeW0gPSBTeW1ib2woXCJlbGVtZW50Q291bnRcIik7XG5cbi8qKlxuICogQWJvcnRDb250cm9sbGVyUmVnaXN0cnkgZG9lcyBub3QgYWN0dWFsbHkgcmVtZW1iZXIgYWN0aXZlIGV2ZW50IGxpc3RlbmVyczogaW5zdGVhZFxuICogaXQgdGllcyB0aGVtIHRvIGFuIEFib3J0U2lnbmFsIGFuZCB1c2VzIGFuIEFib3J0Q29udHJvbGxlciB0byByZW1vdmUgdGhlbSBhbGwgYXQgb25jZS5cbiAqL1xuY2xhc3MgQWJvcnRDb250cm9sbGVyUmVnaXN0cnkge1xuICAgIC8vIFByaXZhdGUgZmllbGRzLlxuICAgIFtjb250cm9sbGVyU3ltXTogQWJvcnRDb250cm9sbGVyO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXNbY29udHJvbGxlclN5bV0gPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBvcHRpb25zIG9iamVjdCBmb3IgYWRkRXZlbnRMaXN0ZW5lciB0aGF0IHRpZXMgdGhlIGxpc3RlbmVyXG4gICAgICogdG8gdGhlIEFib3J0U2lnbmFsIGZyb20gdGhlIGN1cnJlbnQgQWJvcnRDb250cm9sbGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVsZW1lbnQgLSBBbiBIVE1MIGVsZW1lbnRcbiAgICAgKiBAcGFyYW0gdHJpZ2dlcnMgLSBUaGUgbGlzdCBvZiBhY3RpdmUgV01MIHRyaWdnZXIgZXZlbnRzIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnRzXG4gICAgICovXG4gICAgc2V0KGVsZW1lbnQ6IEVsZW1lbnQsIHRyaWdnZXJzOiBzdHJpbmdbXSk6IEFkZEV2ZW50TGlzdGVuZXJPcHRpb25zIHtcbiAgICAgICAgcmV0dXJuIHsgc2lnbmFsOiB0aGlzW2NvbnRyb2xsZXJTeW1dLnNpZ25hbCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIHJlZ2lzdGVyZWQgZXZlbnQgbGlzdGVuZXJzIGFuZCByZXNldHMgdGhlIHJlZ2lzdHJ5LlxuICAgICAqL1xuICAgIHJlc2V0KCk6IHZvaWQge1xuICAgICAgICB0aGlzW2NvbnRyb2xsZXJTeW1dLmFib3J0KCk7XG4gICAgICAgIHRoaXNbY29udHJvbGxlclN5bV0gPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxufVxuXG4vKipcbiAqIFdlYWtNYXBSZWdpc3RyeSBtYXBzIGFjdGl2ZSB0cmlnZ2VyIGV2ZW50cyB0byBlYWNoIERPTSBlbGVtZW50IHRocm91Z2ggYSBXZWFrTWFwLlxuICogVGhpcyBlbnN1cmVzIHRoYXQgdGhlIG1hcHBpbmcgcmVtYWlucyBwcml2YXRlIHRvIHRoaXMgbW9kdWxlLCB3aGlsZSBzdGlsbCBhbGxvd2luZyBnYXJiYWdlXG4gKiBjb2xsZWN0aW9uIG9mIHRoZSBpbnZvbHZlZCBlbGVtZW50cy5cbiAqL1xuY2xhc3MgV2Vha01hcFJlZ2lzdHJ5IHtcbiAgICAvKiogU3RvcmVzIHRoZSBjdXJyZW50IGVsZW1lbnQtdG8tdHJpZ2dlciBtYXBwaW5nLiAqL1xuICAgIFt0cmlnZ2VyTWFwU3ltXTogV2Vha01hcDxFbGVtZW50LCBzdHJpbmdbXT47XG4gICAgLyoqIENvdW50cyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHdpdGggYWN0aXZlIFdNTCB0cmlnZ2Vycy4gKi9cbiAgICBbZWxlbWVudENvdW50U3ltXTogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXNbdHJpZ2dlck1hcFN5bV0gPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB0aGlzW2VsZW1lbnRDb3VudFN5bV0gPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgYWN0aXZlIHRyaWdnZXJzIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZWxlbWVudCAtIEFuIEhUTUwgZWxlbWVudFxuICAgICAqIEBwYXJhbSB0cmlnZ2VycyAtIFRoZSBsaXN0IG9mIGFjdGl2ZSBXTUwgdHJpZ2dlciBldmVudHMgZm9yIHRoZSBzcGVjaWZpZWQgZWxlbWVudFxuICAgICAqL1xuICAgIHNldChlbGVtZW50OiBFbGVtZW50LCB0cmlnZ2Vyczogc3RyaW5nW10pOiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucyB7XG4gICAgICAgIGlmICghdGhpc1t0cmlnZ2VyTWFwU3ltXS5oYXMoZWxlbWVudCkpIHsgdGhpc1tlbGVtZW50Q291bnRTeW1dKys7IH1cbiAgICAgICAgdGhpc1t0cmlnZ2VyTWFwU3ltXS5zZXQoZWxlbWVudCwgdHJpZ2dlcnMpO1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgcmVnaXN0ZXJlZCBldmVudCBsaXN0ZW5lcnMuXG4gICAgICovXG4gICAgcmVzZXQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzW2VsZW1lbnRDb3VudFN5bV0gPD0gMClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZG9jdW1lbnQuYm9keS5xdWVyeVNlbGVjdG9yQWxsKCcqJykpIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2VsZW1lbnRDb3VudFN5bV0gPD0gMClcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY29uc3QgdHJpZ2dlcnMgPSB0aGlzW3RyaWdnZXJNYXBTeW1dLmdldChlbGVtZW50KTtcbiAgICAgICAgICAgIGlmICh0cmlnZ2VycyAhPSBudWxsKSB7IHRoaXNbZWxlbWVudENvdW50U3ltXS0tOyB9XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgdHJpZ2dlciBvZiB0cmlnZ2VycyB8fCBbXSlcbiAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHJpZ2dlciwgb25XTUxUcmlnZ2VyZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpc1t0cmlnZ2VyTWFwU3ltXSA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIHRoaXNbZWxlbWVudENvdW50U3ltXSA9IDA7XG4gICAgfVxufVxuXG5jb25zdCB0cmlnZ2VyUmVnaXN0cnkgPSBjYW5BYm9ydExpc3RlbmVycygpID8gbmV3IEFib3J0Q29udHJvbGxlclJlZ2lzdHJ5KCkgOiBuZXcgV2Vha01hcFJlZ2lzdHJ5KCk7XG5cbi8qKlxuICogQWRkcyBldmVudCBsaXN0ZW5lcnMgdG8gdGhlIHNwZWNpZmllZCBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBhZGRXTUxMaXN0ZW5lcnMoZWxlbWVudDogRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRyaWdnZXJSZWdFeHAgPSAvXFxTKy9nO1xuICAgIGNvbnN0IHRyaWdnZXJBdHRyID0gKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtdHJpZ2dlcicpIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXdtbC10cmlnZ2VyJykgfHwgXCJjbGlja1wiKTtcbiAgICBjb25zdCB0cmlnZ2Vyczogc3RyaW5nW10gPSBbXTtcblxuICAgIGxldCBtYXRjaDtcbiAgICB3aGlsZSAoKG1hdGNoID0gdHJpZ2dlclJlZ0V4cC5leGVjKHRyaWdnZXJBdHRyKSkgIT09IG51bGwpXG4gICAgICAgIHRyaWdnZXJzLnB1c2gobWF0Y2hbMF0pO1xuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRyaWdnZXJSZWdpc3RyeS5zZXQoZWxlbWVudCwgdHJpZ2dlcnMpO1xuICAgIGZvciAoY29uc3QgdHJpZ2dlciBvZiB0cmlnZ2VycylcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHRyaWdnZXIsIG9uV01MVHJpZ2dlcmVkLCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBTY2hlZHVsZXMgYW4gYXV0b21hdGljIHJlbG9hZCBvZiBXTUwgdG8gYmUgcGVyZm9ybWVkIGFzIHNvb24gYXMgdGhlIGRvY3VtZW50IGlzIGZ1bGx5IGxvYWRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEVuYWJsZSgpOiB2b2lkIHtcbiAgICB3aGVuUmVhZHkoUmVsb2FkKTtcbn1cblxuLyoqXG4gKiBSZWxvYWRzIHRoZSBXTUwgcGFnZSBieSBhZGRpbmcgbmVjZXNzYXJ5IGV2ZW50IGxpc3RlbmVycyBhbmQgYnJvd3NlciBsaXN0ZW5lcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBSZWxvYWQoKTogdm9pZCB7XG4gICAgdHJpZ2dlclJlZ2lzdHJ5LnJlc2V0KCk7XG4gICAgZG9jdW1lbnQuYm9keS5xdWVyeVNlbGVjdG9yQWxsKCdbd21sLWV2ZW50XSwgW3dtbC13aW5kb3ddLCBbd21sLW9wZW51cmxdLCBbZGF0YS13bWwtZXZlbnRdLCBbZGF0YS13bWwtd2luZG93XSwgW2RhdGEtd21sLW9wZW51cmxdJykuZm9yRWFjaChhZGRXTUxMaXN0ZW5lcnMpO1xufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG5pbXBvcnQgeyBuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lcyB9IGZyb20gXCIuL3J1bnRpbWUuanNcIjtcblxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuQnJvd3Nlcik7XG5cbmNvbnN0IEJyb3dzZXJPcGVuVVJMID0gMDtcblxuLyoqXG4gKiBPcGVuIGEgYnJvd3NlciB3aW5kb3cgdG8gdGhlIGdpdmVuIFVSTC5cbiAqXG4gKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCB0byBvcGVuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBPcGVuVVJMKHVybDogc3RyaW5nIHwgVVJMKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGNhbGwoQnJvd3Nlck9wZW5VUkwsIHt1cmw6IHVybC50b1N0cmluZygpfSk7XG59XG4iLCAiLy8gU291cmNlOiBodHRwczovL2dpdGh1Yi5jb20vYWkvbmFub2lkXG5cbi8vIFRoZSBNSVQgTGljZW5zZSAoTUlUKVxuLy9cbi8vIENvcHlyaWdodCAyMDE3IEFuZHJleSBTaXRuaWsgPGFuZHJleUBzaXRuaWsucnU+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZlxuLy8gdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpblxuLy8gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0b1xuLy8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2Zcbi8vIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbyxcbi8vICAgICBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyAgICAgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4vLyBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vICAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTU1xuLy8gRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SXG4vLyBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVJcbi8vIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOXG4vLyBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBUaGlzIGFscGhhYmV0IHVzZXMgYEEtWmEtejAtOV8tYCBzeW1ib2xzLlxuLy8gVGhlIG9yZGVyIG9mIGNoYXJhY3RlcnMgaXMgb3B0aW1pemVkIGZvciBiZXR0ZXIgZ3ppcCBhbmQgYnJvdGxpIGNvbXByZXNzaW9uLlxuLy8gUmVmZXJlbmNlcyB0byB0aGUgc2FtZSBmaWxlICh3b3JrcyBib3RoIGZvciBnemlwIGFuZCBicm90bGkpOlxuLy8gYCd1c2VgLCBgYW5kb21gLCBhbmQgYHJpY3QnYFxuLy8gUmVmZXJlbmNlcyB0byB0aGUgYnJvdGxpIGRlZmF1bHQgZGljdGlvbmFyeTpcbi8vIGAtMjZUYCwgYDE5ODNgLCBgNDBweGAsIGA3NXB4YCwgYGJ1c2hgLCBgamFja2AsIGBtaW5kYCwgYHZlcnlgLCBhbmQgYHdvbGZgXG5jb25zdCB1cmxBbHBoYWJldCA9XG4gICAgJ3VzZWFuZG9tLTI2VDE5ODM0MFBYNzVweEpBQ0tWRVJZTUlOREJVU0hXT0xGX0dRWmJmZ2hqa2xxdnd5enJpY3QnXG5cbmV4cG9ydCBmdW5jdGlvbiBuYW5vaWQoc2l6ZTogbnVtYmVyID0gMjEpOiBzdHJpbmcge1xuICAgIGxldCBpZCA9ICcnXG4gICAgLy8gQSBjb21wYWN0IGFsdGVybmF0aXZlIGZvciBgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGVwOyBpKyspYC5cbiAgICBsZXQgaSA9IHNpemUgfCAwXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgICAvLyBgfCAwYCBpcyBtb3JlIGNvbXBhY3QgYW5kIGZhc3RlciB0aGFuIGBNYXRoLmZsb29yKClgLlxuICAgICAgICBpZCArPSB1cmxBbHBoYWJldFsoTWF0aC5yYW5kb20oKSAqIDY0KSB8IDBdXG4gICAgfVxuICAgIHJldHVybiBpZFxufVxuIiwgIi8qXG4gXyAgICAgX18gICAgIF8gX19cbnwgfCAgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tICcuL25hbm9pZC5qcyc7XG5cbmNvbnN0IHJ1bnRpbWVVUkwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgXCIvd2FpbHMvcnVudGltZVwiO1xuXG4vLyBPYmplY3QgTmFtZXNcbmV4cG9ydCBjb25zdCBvYmplY3ROYW1lcyA9IE9iamVjdC5mcmVlemUoe1xuICAgIENhbGw6IDAsXG4gICAgQ2xpcGJvYXJkOiAxLFxuICAgIEFwcGxpY2F0aW9uOiAyLFxuICAgIEV2ZW50czogMyxcbiAgICBDb250ZXh0TWVudTogNCxcbiAgICBEaWFsb2c6IDUsXG4gICAgV2luZG93OiA2LFxuICAgIFNjcmVlbnM6IDcsXG4gICAgU3lzdGVtOiA4LFxuICAgIEJyb3dzZXI6IDksXG4gICAgQ2FuY2VsQ2FsbDogMTAsXG59KTtcbmV4cG9ydCBsZXQgY2xpZW50SWQgPSBuYW5vaWQoKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHJ1bnRpbWUgY2FsbGVyIHdpdGggc3BlY2lmaWVkIElELlxuICpcbiAqIEBwYXJhbSBvYmplY3QgLSBUaGUgb2JqZWN0IHRvIGludm9rZSB0aGUgbWV0aG9kIG9uLlxuICogQHBhcmFtIHdpbmRvd05hbWUgLSBUaGUgbmFtZSBvZiB0aGUgd2luZG93LlxuICogQHJldHVybiBUaGUgbmV3IHJ1bnRpbWUgY2FsbGVyIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmV3UnVudGltZUNhbGxlcihvYmplY3Q6IG51bWJlciwgd2luZG93TmFtZTogc3RyaW5nID0gJycpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZDogbnVtYmVyLCBhcmdzOiBhbnkgPSBudWxsKSB7XG4gICAgICAgIHJldHVybiBydW50aW1lQ2FsbFdpdGhJRChvYmplY3QsIG1ldGhvZCwgd2luZG93TmFtZSwgYXJncyk7XG4gICAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVudGltZUNhbGxXaXRoSUQob2JqZWN0SUQ6IG51bWJlciwgbWV0aG9kOiBudW1iZXIsIHdpbmRvd05hbWU6IHN0cmluZywgYXJnczogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICBsZXQgdXJsID0gbmV3IFVSTChydW50aW1lVVJMKTtcbiAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm9iamVjdFwiLCBvYmplY3RJRC50b1N0cmluZygpKTtcbiAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm1ldGhvZFwiLCBtZXRob2QudG9TdHJpbmcoKSk7XG4gICAgaWYgKGFyZ3MpIHsgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJhcmdzXCIsIEpTT04uc3RyaW5naWZ5KGFyZ3MpKTsgfVxuXG4gICAgbGV0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgIFtcIngtd2FpbHMtY2xpZW50LWlkXCJdOiBjbGllbnRJZFxuICAgIH1cbiAgICBpZiAod2luZG93TmFtZSkge1xuICAgICAgICBoZWFkZXJzW1wieC13YWlscy13aW5kb3ctbmFtZVwiXSA9IHdpbmRvd05hbWU7XG4gICAgfVxuXG4gICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7IGhlYWRlcnMgfSk7XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYXdhaXQgcmVzcG9uc2UudGV4dCgpKTtcbiAgICB9XG5cbiAgICBpZiAoKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpPy5pbmRleE9mKFwiYXBwbGljYXRpb24vanNvblwiKSA/PyAtMSkgIT09IC0xKSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKTtcbiAgICB9XG59XG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbmltcG9ydCB7bmV3UnVudGltZUNhbGxlciwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWUuanNcIjtcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJy4vbmFub2lkLmpzJztcblxuLy8gc2V0dXBcbndpbmRvdy5fd2FpbHMgPSB3aW5kb3cuX3dhaWxzIHx8IHt9O1xud2luZG93Ll93YWlscy5kaWFsb2dFcnJvckNhbGxiYWNrID0gZGlhbG9nRXJyb3JDYWxsYmFjaztcbndpbmRvdy5fd2FpbHMuZGlhbG9nUmVzdWx0Q2FsbGJhY2sgPSBkaWFsb2dSZXN1bHRDYWxsYmFjaztcblxudHlwZSBQcm9taXNlUmVzb2x2ZXJzID0gT21pdDxQcm9taXNlV2l0aFJlc29sdmVyczxhbnk+LCBcInByb21pc2VcIj47XG5cbmNvbnN0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyKG9iamVjdE5hbWVzLkRpYWxvZyk7XG5jb25zdCBkaWFsb2dSZXNwb25zZXMgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZVJlc29sdmVycz4oKTtcblxuLy8gRGVmaW5lIGNvbnN0YW50cyBmcm9tIHRoZSBgbWV0aG9kc2Agb2JqZWN0IGluIFRpdGxlIENhc2VcbmNvbnN0IERpYWxvZ0luZm8gPSAwO1xuY29uc3QgRGlhbG9nV2FybmluZyA9IDE7XG5jb25zdCBEaWFsb2dFcnJvciA9IDI7XG5jb25zdCBEaWFsb2dRdWVzdGlvbiA9IDM7XG5jb25zdCBEaWFsb2dPcGVuRmlsZSA9IDQ7XG5jb25zdCBEaWFsb2dTYXZlRmlsZSA9IDU7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkZpbGVEaWFsb2dPcHRpb25zIHtcbiAgICAvKiogSW5kaWNhdGVzIGlmIGRpcmVjdG9yaWVzIGNhbiBiZSBjaG9zZW4uICovXG4gICAgQ2FuQ2hvb3NlRGlyZWN0b3JpZXM/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgZmlsZXMgY2FuIGJlIGNob3Nlbi4gKi9cbiAgICBDYW5DaG9vc2VGaWxlcz86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBkaXJlY3RvcmllcyBjYW4gYmUgY3JlYXRlZC4gKi9cbiAgICBDYW5DcmVhdGVEaXJlY3Rvcmllcz86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBoaWRkZW4gZmlsZXMgc2hvdWxkIGJlIHNob3duLiAqL1xuICAgIFNob3dIaWRkZW5GaWxlcz86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBhbGlhc2VzIHNob3VsZCBiZSByZXNvbHZlZC4gKi9cbiAgICBSZXNvbHZlc0FsaWFzZXM/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgbXVsdGlwbGUgc2VsZWN0aW9uIGlzIGFsbG93ZWQuICovXG4gICAgQWxsb3dzTXVsdGlwbGVTZWxlY3Rpb24/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgdGhlIGV4dGVuc2lvbiBzaG91bGQgYmUgaGlkZGVuLiAqL1xuICAgIEhpZGVFeHRlbnNpb24/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgaGlkZGVuIGV4dGVuc2lvbnMgY2FuIGJlIHNlbGVjdGVkLiAqL1xuICAgIENhblNlbGVjdEhpZGRlbkV4dGVuc2lvbj86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBmaWxlIHBhY2thZ2VzIHNob3VsZCBiZSB0cmVhdGVkIGFzIGRpcmVjdG9yaWVzLiAqL1xuICAgIFRyZWF0c0ZpbGVQYWNrYWdlc0FzRGlyZWN0b3JpZXM/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgb3RoZXIgZmlsZSB0eXBlcyBhcmUgYWxsb3dlZC4gKi9cbiAgICBBbGxvd3NPdGhlckZpbGV0eXBlcz86IGJvb2xlYW47XG4gICAgLyoqIEFycmF5IG9mIGZpbGUgZmlsdGVycy4gKi9cbiAgICBGaWx0ZXJzPzogRmlsZUZpbHRlcltdO1xuICAgIC8qKiBUaXRsZSBvZiB0aGUgZGlhbG9nLiAqL1xuICAgIFRpdGxlPzogc3RyaW5nO1xuICAgIC8qKiBNZXNzYWdlIHRvIHNob3cgaW4gdGhlIGRpYWxvZy4gKi9cbiAgICBNZXNzYWdlPzogc3RyaW5nO1xuICAgIC8qKiBUZXh0IHRvIGRpc3BsYXkgb24gdGhlIGJ1dHRvbi4gKi9cbiAgICBCdXR0b25UZXh0Pzogc3RyaW5nO1xuICAgIC8qKiBEaXJlY3RvcnkgdG8gb3BlbiBpbiB0aGUgZGlhbG9nLiAqL1xuICAgIERpcmVjdG9yeT86IHN0cmluZztcbiAgICAvKiogSW5kaWNhdGVzIGlmIHRoZSBkaWFsb2cgc2hvdWxkIGFwcGVhciBkZXRhY2hlZCBmcm9tIHRoZSBtYWluIHdpbmRvdy4gKi9cbiAgICBEZXRhY2hlZD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2F2ZUZpbGVEaWFsb2dPcHRpb25zIHtcbiAgICAvKiogRGVmYXVsdCBmaWxlbmFtZSB0byB1c2UgaW4gdGhlIGRpYWxvZy4gKi9cbiAgICBGaWxlbmFtZT86IHN0cmluZztcbiAgICAvKiogSW5kaWNhdGVzIGlmIGRpcmVjdG9yaWVzIGNhbiBiZSBjaG9zZW4uICovXG4gICAgQ2FuQ2hvb3NlRGlyZWN0b3JpZXM/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgZmlsZXMgY2FuIGJlIGNob3Nlbi4gKi9cbiAgICBDYW5DaG9vc2VGaWxlcz86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBkaXJlY3RvcmllcyBjYW4gYmUgY3JlYXRlZC4gKi9cbiAgICBDYW5DcmVhdGVEaXJlY3Rvcmllcz86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBoaWRkZW4gZmlsZXMgc2hvdWxkIGJlIHNob3duLiAqL1xuICAgIFNob3dIaWRkZW5GaWxlcz86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBhbGlhc2VzIHNob3VsZCBiZSByZXNvbHZlZC4gKi9cbiAgICBSZXNvbHZlc0FsaWFzZXM/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgdGhlIGV4dGVuc2lvbiBzaG91bGQgYmUgaGlkZGVuLiAqL1xuICAgIEhpZGVFeHRlbnNpb24/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgaGlkZGVuIGV4dGVuc2lvbnMgY2FuIGJlIHNlbGVjdGVkLiAqL1xuICAgIENhblNlbGVjdEhpZGRlbkV4dGVuc2lvbj86IGJvb2xlYW47XG4gICAgLyoqIEluZGljYXRlcyBpZiBmaWxlIHBhY2thZ2VzIHNob3VsZCBiZSB0cmVhdGVkIGFzIGRpcmVjdG9yaWVzLiAqL1xuICAgIFRyZWF0c0ZpbGVQYWNrYWdlc0FzRGlyZWN0b3JpZXM/OiBib29sZWFuO1xuICAgIC8qKiBJbmRpY2F0ZXMgaWYgb3RoZXIgZmlsZSB0eXBlcyBhcmUgYWxsb3dlZC4gKi9cbiAgICBBbGxvd3NPdGhlckZpbGV0eXBlcz86IGJvb2xlYW47XG4gICAgLyoqIEFycmF5IG9mIGZpbGUgZmlsdGVycy4gKi9cbiAgICBGaWx0ZXJzPzogRmlsZUZpbHRlcltdO1xuICAgIC8qKiBUaXRsZSBvZiB0aGUgZGlhbG9nLiAqL1xuICAgIFRpdGxlPzogc3RyaW5nO1xuICAgIC8qKiBNZXNzYWdlIHRvIHNob3cgaW4gdGhlIGRpYWxvZy4gKi9cbiAgICBNZXNzYWdlPzogc3RyaW5nO1xuICAgIC8qKiBUZXh0IHRvIGRpc3BsYXkgb24gdGhlIGJ1dHRvbi4gKi9cbiAgICBCdXR0b25UZXh0Pzogc3RyaW5nO1xuICAgIC8qKiBEaXJlY3RvcnkgdG8gb3BlbiBpbiB0aGUgZGlhbG9nLiAqL1xuICAgIERpcmVjdG9yeT86IHN0cmluZztcbiAgICAvKiogSW5kaWNhdGVzIGlmIHRoZSBkaWFsb2cgc2hvdWxkIGFwcGVhciBkZXRhY2hlZCBmcm9tIHRoZSBtYWluIHdpbmRvdy4gKi9cbiAgICBEZXRhY2hlZD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVzc2FnZURpYWxvZ09wdGlvbnMge1xuICAgIC8qKiBUaGUgdGl0bGUgb2YgdGhlIGRpYWxvZyB3aW5kb3cuICovXG4gICAgVGl0bGU/OiBzdHJpbmc7XG4gICAgLyoqIFRoZSBtYWluIG1lc3NhZ2UgdG8gc2hvdyBpbiB0aGUgZGlhbG9nLiAqL1xuICAgIE1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgLyoqIEFycmF5IG9mIGJ1dHRvbiBvcHRpb25zIHRvIHNob3cgaW4gdGhlIGRpYWxvZy4gKi9cbiAgICBCdXR0b25zPzogQnV0dG9uW107XG4gICAgLyoqIFRydWUgaWYgdGhlIGRpYWxvZyBzaG91bGQgYXBwZWFyIGRldGFjaGVkIGZyb20gdGhlIG1haW4gd2luZG93IChpZiBhcHBsaWNhYmxlKS4gKi9cbiAgICBEZXRhY2hlZD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnV0dG9uIHtcbiAgICAvKiogVGV4dCB0aGF0IGFwcGVhcnMgd2l0aGluIHRoZSBidXR0b24uICovXG4gICAgTGFiZWw/OiBzdHJpbmc7XG4gICAgLyoqIFRydWUgaWYgdGhlIGJ1dHRvbiBzaG91bGQgY2FuY2VsIGFuIG9wZXJhdGlvbiB3aGVuIGNsaWNrZWQuICovXG4gICAgSXNDYW5jZWw/OiBib29sZWFuO1xuICAgIC8qKiBUcnVlIGlmIHRoZSBidXR0b24gc2hvdWxkIGJlIHRoZSBkZWZhdWx0IGFjdGlvbiB3aGVuIHRoZSB1c2VyIHByZXNzZXMgZW50ZXIuICovXG4gICAgSXNEZWZhdWx0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWxlRmlsdGVyIHtcbiAgICAvKiogRGlzcGxheSBuYW1lIGZvciB0aGUgZmlsdGVyLCBpdCBjb3VsZCBiZSBcIlRleHQgRmlsZXNcIiwgXCJJbWFnZXNcIiBldGMuICovXG4gICAgRGlzcGxheU5hbWU/OiBzdHJpbmc7XG4gICAgLyoqIFBhdHRlcm4gdG8gbWF0Y2ggZm9yIHRoZSBmaWx0ZXIsIGUuZy4gXCIqLnR4dDsqLm1kXCIgZm9yIHRleHQgbWFya2Rvd24gZmlsZXMuICovXG4gICAgUGF0dGVybj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBIYW5kbGVzIHRoZSByZXN1bHQgb2YgYSBkaWFsb2cgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gaWQgLSBUaGUgaWQgb2YgdGhlIHJlcXVlc3QgdG8gaGFuZGxlIHRoZSByZXN1bHQgZm9yLlxuICogQHBhcmFtIGRhdGEgLSBUaGUgcmVzdWx0IGRhdGEgb2YgdGhlIHJlcXVlc3QuXG4gKiBAcGFyYW0gaXNKU09OIC0gSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGRhdGEgaXMgSlNPTiBvciBub3QuXG4gKi9cbmZ1bmN0aW9uIGRpYWxvZ1Jlc3VsdENhbGxiYWNrKGlkOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgaXNKU09OOiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IHJlc29sdmVycyA9IGdldEFuZERlbGV0ZVJlc3BvbnNlKGlkKTtcbiAgICBpZiAoIXJlc29sdmVycykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzSlNPTikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzb2x2ZXJzLnJlc29sdmUoSlNPTi5wYXJzZShkYXRhKSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICByZXNvbHZlcnMucmVqZWN0KG5ldyBUeXBlRXJyb3IoXCJjb3VsZCBub3QgcGFyc2UgcmVzdWx0OiBcIiArIGVyci5tZXNzYWdlLCB7IGNhdXNlOiBlcnIgfSkpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZXJzLnJlc29sdmUoZGF0YSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEhhbmRsZXMgdGhlIGVycm9yIGZyb20gYSBkaWFsb2cgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gaWQgLSBUaGUgaWQgb2YgdGhlIHByb21pc2UgaGFuZGxlci5cbiAqIEBwYXJhbSBtZXNzYWdlIC0gQW4gZXJyb3IgbWVzc2FnZS5cbiAqL1xuZnVuY3Rpb24gZGlhbG9nRXJyb3JDYWxsYmFjayhpZDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBnZXRBbmREZWxldGVSZXNwb25zZShpZCk/LnJlamVjdChuZXcgd2luZG93LkVycm9yKG1lc3NhZ2UpKTtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIHJlc3BvbnNlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gSUQgZnJvbSB0aGUgZGlhbG9nUmVzcG9uc2VzIG1hcC5cbiAqXG4gKiBAcGFyYW0gaWQgLSBUaGUgSUQgb2YgdGhlIHJlc3BvbnNlIHRvIGJlIHJldHJpZXZlZCBhbmQgcmVtb3ZlZC5cbiAqIEByZXR1cm5zIFRoZSByZXNwb25zZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBJRCwgaWYgYW55LlxuICovXG5mdW5jdGlvbiBnZXRBbmREZWxldGVSZXNwb25zZShpZDogc3RyaW5nKTogUHJvbWlzZVJlc29sdmVycyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBkaWFsb2dSZXNwb25zZXMuZ2V0KGlkKTtcbiAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcbiAgICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgdW5pcXVlIElEIHVzaW5nIHRoZSBuYW5vaWQgbGlicmFyeS5cbiAqXG4gKiBAcmV0dXJucyBBIHVuaXF1ZSBJRCB0aGF0IGRvZXMgbm90IGV4aXN0IGluIHRoZSBkaWFsb2dSZXNwb25zZXMgc2V0LlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUlEKCk6IHN0cmluZyB7XG4gICAgbGV0IHJlc3VsdDtcbiAgICBkbyB7XG4gICAgICAgIHJlc3VsdCA9IG5hbm9pZCgpO1xuICAgIH0gd2hpbGUgKGRpYWxvZ1Jlc3BvbnNlcy5oYXMocmVzdWx0KSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBQcmVzZW50cyBhIGRpYWxvZyBvZiBzcGVjaWZpZWQgdHlwZSB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB0eXBlIC0gRGlhbG9nIHR5cGUuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbnMgZm9yIHRoZSBkaWFsb2cuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHJlc3VsdCBvZiBkaWFsb2cuXG4gKi9cbmZ1bmN0aW9uIGRpYWxvZyh0eXBlOiBudW1iZXIsIG9wdGlvbnM6IE1lc3NhZ2VEaWFsb2dPcHRpb25zIHwgT3BlbkZpbGVEaWFsb2dPcHRpb25zIHwgU2F2ZUZpbGVEaWFsb2dPcHRpb25zID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGlkID0gZ2VuZXJhdGVJRCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5zZXQoaWQsIHsgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgICBjYWxsKHR5cGUsIE9iamVjdC5hc3NpZ24oeyBcImRpYWxvZy1pZFwiOiBpZCB9LCBvcHRpb25zKSkuY2F0Y2goKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcbiAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBQcmVzZW50cyBhbiBpbmZvIGRpYWxvZy5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsYWJlbCBvZiB0aGUgY2hvc2VuIGJ1dHRvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEluZm8ob3B0aW9uczogTWVzc2FnZURpYWxvZ09wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4geyByZXR1cm4gZGlhbG9nKERpYWxvZ0luZm8sIG9wdGlvbnMpOyB9XG5cbi8qKlxuICogUHJlc2VudHMgYSB3YXJuaW5nIGRpYWxvZy5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zLlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbGFiZWwgb2YgdGhlIGNob3NlbiBidXR0b24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXYXJuaW5nKG9wdGlvbnM6IE1lc3NhZ2VEaWFsb2dPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHsgcmV0dXJuIGRpYWxvZyhEaWFsb2dXYXJuaW5nLCBvcHRpb25zKTsgfVxuXG4vKipcbiAqIFByZXNlbnRzIGFuIGVycm9yIGRpYWxvZy5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zLlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbGFiZWwgb2YgdGhlIGNob3NlbiBidXR0b24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFcnJvcihvcHRpb25zOiBNZXNzYWdlRGlhbG9nT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7IHJldHVybiBkaWFsb2coRGlhbG9nRXJyb3IsIG9wdGlvbnMpOyB9XG5cbi8qKlxuICogUHJlc2VudHMgYSBxdWVzdGlvbiBkaWFsb2cuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBEaWFsb2cgb3B0aW9ucy5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxhYmVsIG9mIHRoZSBjaG9zZW4gYnV0dG9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gUXVlc3Rpb24ob3B0aW9uczogTWVzc2FnZURpYWxvZ09wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4geyByZXR1cm4gZGlhbG9nKERpYWxvZ1F1ZXN0aW9uLCBvcHRpb25zKTsgfVxuXG4vKipcbiAqIFByZXNlbnRzIGEgZmlsZSBzZWxlY3Rpb24gZGlhbG9nIHRvIHBpY2sgb25lIG9yIG1vcmUgZmlsZXMgdG8gb3Blbi5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zLlxuICogQHJldHVybnMgU2VsZWN0ZWQgZmlsZSBvciBsaXN0IG9mIGZpbGVzLCBvciBhIGJsYW5rIHN0cmluZy9lbXB0eSBsaXN0IGlmIG5vIGZpbGUgaGFzIGJlZW4gc2VsZWN0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBPcGVuRmlsZShvcHRpb25zOiBPcGVuRmlsZURpYWxvZ09wdGlvbnMgJiB7IEFsbG93c011bHRpcGxlU2VsZWN0aW9uOiB0cnVlIH0pOiBQcm9taXNlPHN0cmluZ1tdPjtcbmV4cG9ydCBmdW5jdGlvbiBPcGVuRmlsZShvcHRpb25zOiBPcGVuRmlsZURpYWxvZ09wdGlvbnMgJiB7IEFsbG93c011bHRpcGxlU2VsZWN0aW9uPzogZmFsc2UgfCB1bmRlZmluZWQgfSk6IFByb21pc2U8c3RyaW5nPjtcbmV4cG9ydCBmdW5jdGlvbiBPcGVuRmlsZShvcHRpb25zOiBPcGVuRmlsZURpYWxvZ09wdGlvbnMpOiBQcm9taXNlPHN0cmluZyB8IHN0cmluZ1tdPjtcbmV4cG9ydCBmdW5jdGlvbiBPcGVuRmlsZShvcHRpb25zOiBPcGVuRmlsZURpYWxvZ09wdGlvbnMpOiBQcm9taXNlPHN0cmluZyB8IHN0cmluZ1tdPiB7IHJldHVybiBkaWFsb2coRGlhbG9nT3BlbkZpbGUsIG9wdGlvbnMpID8/IFtdOyB9XG5cbi8qKlxuICogUHJlc2VudHMgYSBmaWxlIHNlbGVjdGlvbiBkaWFsb2cgdG8gcGljayBhIGZpbGUgdG8gc2F2ZS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zLlxuICogQHJldHVybnMgU2VsZWN0ZWQgZmlsZSwgb3IgYSBibGFuayBzdHJpbmcgaWYgbm8gZmlsZSBoYXMgYmVlbiBzZWxlY3RlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNhdmVGaWxlKG9wdGlvbnM6IFNhdmVGaWxlRGlhbG9nT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7IHJldHVybiBkaWFsb2coRGlhbG9nU2F2ZUZpbGUsIG9wdGlvbnMpOyB9XG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbmltcG9ydCB7IG5ld1J1bnRpbWVDYWxsZXIsIG9iamVjdE5hbWVzIH0gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xuaW1wb3J0IHsgZXZlbnRMaXN0ZW5lcnMsIExpc3RlbmVyLCBsaXN0ZW5lck9mZiB9IGZyb20gXCIuL2xpc3RlbmVyLmpzXCI7XG5cbi8vIFNldHVwXG53aW5kb3cuX3dhaWxzID0gd2luZG93Ll93YWlscyB8fCB7fTtcbndpbmRvdy5fd2FpbHMuZGlzcGF0Y2hXYWlsc0V2ZW50ID0gZGlzcGF0Y2hXYWlsc0V2ZW50O1xuXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcihvYmplY3ROYW1lcy5FdmVudHMpO1xuY29uc3QgRW1pdE1ldGhvZCA9IDA7XG5cbmV4cG9ydCB7IFR5cGVzIH0gZnJvbSBcIi4vZXZlbnRfdHlwZXMuanNcIjtcblxuLyoqXG4gKiBUaGUgdHlwZSBvZiBoYW5kbGVycyBmb3IgYSBnaXZlbiBldmVudC5cbiAqL1xuZXhwb3J0IHR5cGUgQ2FsbGJhY2sgPSAoZXY6IFdhaWxzRXZlbnQpID0+IHZvaWQ7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHN5c3RlbSBldmVudCBvciBhIGN1c3RvbSBldmVudCBlbWl0dGVkIHRocm91Z2ggd2FpbHMtcHJvdmlkZWQgZmFjaWxpdGllcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFdhaWxzRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cbiAgICAgKi9cbiAgICBuYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgZW1pdHRlZCBldmVudC5cbiAgICAgKi9cbiAgICBkYXRhOiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBOYW1lIG9mIHRoZSBvcmlnaW5hdGluZyB3aW5kb3cuIE9taXR0ZWQgZm9yIGFwcGxpY2F0aW9uIGV2ZW50cy5cbiAgICAgKiBXaWxsIGJlIG92ZXJyaWRkZW4gaWYgc2V0IG1hbnVhbGx5LlxuICAgICAqL1xuICAgIHNlbmRlcj86IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZywgZGF0YTogYW55ID0gbnVsbCkge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hXYWlsc0V2ZW50KGV2ZW50OiBhbnkpIHtcbiAgICBsZXQgbGlzdGVuZXJzID0gZXZlbnRMaXN0ZW5lcnMuZ2V0KGV2ZW50Lm5hbWUpO1xuICAgIGlmICghbGlzdGVuZXJzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgd2FpbHNFdmVudCA9IG5ldyBXYWlsc0V2ZW50KGV2ZW50Lm5hbWUsIGV2ZW50LmRhdGEpO1xuICAgIGlmICgnc2VuZGVyJyBpbiBldmVudCkge1xuICAgICAgICB3YWlsc0V2ZW50LnNlbmRlciA9IGV2ZW50LnNlbmRlcjtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuZmlsdGVyKGxpc3RlbmVyID0+ICFsaXN0ZW5lci5kaXNwYXRjaCh3YWlsc0V2ZW50KSk7XG4gICAgaWYgKGxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50Lm5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLnNldChldmVudC5uYW1lLCBsaXN0ZW5lcnMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZWdpc3RlciBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyBmb3IgYSBzcGVjaWZpYyBldmVudC5cbiAqXG4gKiBAcGFyYW0gZXZlbnROYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlZ2lzdGVyIHRoZSBjYWxsYmFjayBmb3IuXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIHRyaWdnZXJlZC5cbiAqIEBwYXJhbSBtYXhDYWxsYmFja3MgLSBUaGUgbWF4aW11bSBudW1iZXIgb2YgdGltZXMgdGhlIGNhbGxiYWNrIGNhbiBiZSBjYWxsZWQgZm9yIHRoZSBldmVudC4gT25jZSB0aGUgbWF4aW11bSBudW1iZXIgaXMgcmVhY2hlZCwgdGhlIGNhbGxiYWNrIHdpbGwgbm8gbG9uZ2VyIGJlIGNhbGxlZC5cbiAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsIHdpbGwgdW5yZWdpc3RlciB0aGUgY2FsbGJhY2sgZnJvbSB0aGUgZXZlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBPbk11bHRpcGxlKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjazogQ2FsbGJhY2ssIG1heENhbGxiYWNrczogbnVtYmVyKSB7XG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChldmVudE5hbWUpIHx8IFtdO1xuICAgIGNvbnN0IHRoaXNMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpO1xuICAgIGxpc3RlbmVycy5wdXNoKHRoaXNMaXN0ZW5lcik7XG4gICAgZXZlbnRMaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbGlzdGVuZXJzKTtcbiAgICByZXR1cm4gKCkgPT4gbGlzdGVuZXJPZmYodGhpc0xpc3RlbmVyKTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCB3aGVuIHRoZSBzcGVjaWZpZWQgZXZlbnQgb2NjdXJzLlxuICpcbiAqIEBwYXJhbSBldmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVnaXN0ZXIgdGhlIGNhbGxiYWNrIGZvci5cbiAqIEBwYXJhbSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkLlxuICogQHJldHVybnMgQSBmdW5jdGlvbiB0aGF0LCB3aGVuIGNhbGxlZCwgd2lsbCB1bnJlZ2lzdGVyIHRoZSBjYWxsYmFjayBmcm9tIHRoZSBldmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE9uKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjazogQ2FsbGJhY2spOiAoKSA9PiB2b2lkIHtcbiAgICByZXR1cm4gT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCAtMSk7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgb25seSBvbmNlIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICpcbiAqIEBwYXJhbSBldmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVnaXN0ZXIgdGhlIGNhbGxiYWNrIGZvci5cbiAqIEBwYXJhbSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkLlxuICogQHJldHVybnMgQSBmdW5jdGlvbiB0aGF0LCB3aGVuIGNhbGxlZCwgd2lsbCB1bnJlZ2lzdGVyIHRoZSBjYWxsYmFjayBmcm9tIHRoZSBldmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE9uY2UoZXZlbnROYW1lOiBzdHJpbmcsIGNhbGxiYWNrOiBDYWxsYmFjayk6ICgpID0+IHZvaWQge1xuICAgIHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIDEpO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgZXZlbnQgbGlzdGVuZXJzIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50IG5hbWVzLlxuICpcbiAqIEBwYXJhbSBldmVudE5hbWVzIC0gVGhlIG5hbWUgb2YgdGhlIGV2ZW50cyB0byByZW1vdmUgbGlzdGVuZXJzIGZvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE9mZiguLi5ldmVudE5hbWVzOiBbc3RyaW5nLCAuLi5zdHJpbmdbXV0pOiB2b2lkIHtcbiAgICBldmVudE5hbWVzLmZvckVhY2goZXZlbnROYW1lID0+IGV2ZW50TGlzdGVuZXJzLmRlbGV0ZShldmVudE5hbWUpKTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBldmVudCBsaXN0ZW5lcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBPZmZBbGwoKTogdm9pZCB7XG4gICAgZXZlbnRMaXN0ZW5lcnMuY2xlYXIoKTtcbn1cblxuLyoqXG4gKiBFbWl0cyB0aGUgZ2l2ZW4gZXZlbnQuXG4gKlxuICogQHBhcmFtIGV2ZW50IC0gVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGVtaXQuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCBvbmNlIHRoZSBldmVudCBoYXMgYmVlbiBlbWl0dGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gRW1pdChldmVudDogV2FpbHNFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBjYWxsKEVtaXRNZXRob2QsIGV2ZW50KTtcbn1cbiIsICIvKlxuIF9cdCAgIF9fXHQgIF8gX19cbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuLy8gVGhlIGZvbGxvd2luZyB1dGlsaXRpZXMgaGF2ZSBiZWVuIGZhY3RvcmVkIG91dCBvZiAuL2V2ZW50cy50c1xuLy8gZm9yIHRlc3RpbmcgcHVycG9zZXMuXG5cbmV4cG9ydCBjb25zdCBldmVudExpc3RlbmVycyA9IG5ldyBNYXA8c3RyaW5nLCBMaXN0ZW5lcltdPigpO1xuXG5leHBvcnQgY2xhc3MgTGlzdGVuZXIge1xuICAgIGV2ZW50TmFtZTogc3RyaW5nO1xuICAgIGNhbGxiYWNrOiAoZGF0YTogYW55KSA9PiB2b2lkO1xuICAgIG1heENhbGxiYWNrczogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoZXZlbnROYW1lOiBzdHJpbmcsIGNhbGxiYWNrOiAoZGF0YTogYW55KSA9PiB2b2lkLCBtYXhDYWxsYmFja3M6IG51bWJlcikge1xuICAgICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgICAgICB0aGlzLm1heENhbGxiYWNrcyA9IG1heENhbGxiYWNrcyB8fCAtMTtcbiAgICB9XG5cbiAgICBkaXNwYXRjaChkYXRhOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2soZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubWF4Q2FsbGJhY2tzID09PSAtMSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB0aGlzLm1heENhbGxiYWNrcyAtPSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5tYXhDYWxsYmFja3MgPT09IDA7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbGlzdGVuZXJPZmYobGlzdGVuZXI6IExpc3RlbmVyKTogdm9pZCB7XG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChsaXN0ZW5lci5ldmVudE5hbWUpO1xuICAgIGlmICghbGlzdGVuZXJzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuZmlsdGVyKGwgPT4gbCAhPT0gbGlzdGVuZXIpO1xuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lci5ldmVudE5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLnNldChsaXN0ZW5lci5ldmVudE5hbWUsIGxpc3RlbmVycyk7XG4gICAgfVxufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vLyBDeW5oeXJjaHd5ZCB5IGZmZWlsIGhvbiB5biBhd3RvbWF0aWcuIFBFSURJV0NIIFx1MDBDMiBNT0RJV0xcbi8vIFRoaXMgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZC4gRE8gTk9UIEVESVRcblxuZXhwb3J0IGNvbnN0IFR5cGVzID0gT2JqZWN0LmZyZWV6ZSh7XG5cdFdpbmRvd3M6IE9iamVjdC5mcmVlemUoe1xuXHRcdEFQTVBvd2VyU2V0dGluZ0NoYW5nZTogXCJ3aW5kb3dzOkFQTVBvd2VyU2V0dGluZ0NoYW5nZVwiLFxuXHRcdEFQTVBvd2VyU3RhdHVzQ2hhbmdlOiBcIndpbmRvd3M6QVBNUG93ZXJTdGF0dXNDaGFuZ2VcIixcblx0XHRBUE1SZXN1bWVBdXRvbWF0aWM6IFwid2luZG93czpBUE1SZXN1bWVBdXRvbWF0aWNcIixcblx0XHRBUE1SZXN1bWVTdXNwZW5kOiBcIndpbmRvd3M6QVBNUmVzdW1lU3VzcGVuZFwiLFxuXHRcdEFQTVN1c3BlbmQ6IFwid2luZG93czpBUE1TdXNwZW5kXCIsXG5cdFx0QXBwbGljYXRpb25TdGFydGVkOiBcIndpbmRvd3M6QXBwbGljYXRpb25TdGFydGVkXCIsXG5cdFx0U3lzdGVtVGhlbWVDaGFuZ2VkOiBcIndpbmRvd3M6U3lzdGVtVGhlbWVDaGFuZ2VkXCIsXG5cdFx0V2ViVmlld05hdmlnYXRpb25Db21wbGV0ZWQ6IFwid2luZG93czpXZWJWaWV3TmF2aWdhdGlvbkNvbXBsZXRlZFwiLFxuXHRcdFdpbmRvd0FjdGl2ZTogXCJ3aW5kb3dzOldpbmRvd0FjdGl2ZVwiLFxuXHRcdFdpbmRvd0JhY2tncm91bmRFcmFzZTogXCJ3aW5kb3dzOldpbmRvd0JhY2tncm91bmRFcmFzZVwiLFxuXHRcdFdpbmRvd0NsaWNrQWN0aXZlOiBcIndpbmRvd3M6V2luZG93Q2xpY2tBY3RpdmVcIixcblx0XHRXaW5kb3dDbG9zaW5nOiBcIndpbmRvd3M6V2luZG93Q2xvc2luZ1wiLFxuXHRcdFdpbmRvd0RpZE1vdmU6IFwid2luZG93czpXaW5kb3dEaWRNb3ZlXCIsXG5cdFx0V2luZG93RGlkUmVzaXplOiBcIndpbmRvd3M6V2luZG93RGlkUmVzaXplXCIsXG5cdFx0V2luZG93RFBJQ2hhbmdlZDogXCJ3aW5kb3dzOldpbmRvd0RQSUNoYW5nZWRcIixcblx0XHRXaW5kb3dEcmFnRHJvcDogXCJ3aW5kb3dzOldpbmRvd0RyYWdEcm9wXCIsXG5cdFx0V2luZG93RHJhZ0VudGVyOiBcIndpbmRvd3M6V2luZG93RHJhZ0VudGVyXCIsXG5cdFx0V2luZG93RHJhZ0xlYXZlOiBcIndpbmRvd3M6V2luZG93RHJhZ0xlYXZlXCIsXG5cdFx0V2luZG93RHJhZ092ZXI6IFwid2luZG93czpXaW5kb3dEcmFnT3ZlclwiLFxuXHRcdFdpbmRvd0VuZE1vdmU6IFwid2luZG93czpXaW5kb3dFbmRNb3ZlXCIsXG5cdFx0V2luZG93RW5kUmVzaXplOiBcIndpbmRvd3M6V2luZG93RW5kUmVzaXplXCIsXG5cdFx0V2luZG93RnVsbHNjcmVlbjogXCJ3aW5kb3dzOldpbmRvd0Z1bGxzY3JlZW5cIixcblx0XHRXaW5kb3dIaWRlOiBcIndpbmRvd3M6V2luZG93SGlkZVwiLFxuXHRcdFdpbmRvd0luYWN0aXZlOiBcIndpbmRvd3M6V2luZG93SW5hY3RpdmVcIixcblx0XHRXaW5kb3dLZXlEb3duOiBcIndpbmRvd3M6V2luZG93S2V5RG93blwiLFxuXHRcdFdpbmRvd0tleVVwOiBcIndpbmRvd3M6V2luZG93S2V5VXBcIixcblx0XHRXaW5kb3dLaWxsRm9jdXM6IFwid2luZG93czpXaW5kb3dLaWxsRm9jdXNcIixcblx0XHRXaW5kb3dOb25DbGllbnRIaXQ6IFwid2luZG93czpXaW5kb3dOb25DbGllbnRIaXRcIixcblx0XHRXaW5kb3dOb25DbGllbnRNb3VzZURvd246IFwid2luZG93czpXaW5kb3dOb25DbGllbnRNb3VzZURvd25cIixcblx0XHRXaW5kb3dOb25DbGllbnRNb3VzZUxlYXZlOiBcIndpbmRvd3M6V2luZG93Tm9uQ2xpZW50TW91c2VMZWF2ZVwiLFxuXHRcdFdpbmRvd05vbkNsaWVudE1vdXNlTW92ZTogXCJ3aW5kb3dzOldpbmRvd05vbkNsaWVudE1vdXNlTW92ZVwiLFxuXHRcdFdpbmRvd05vbkNsaWVudE1vdXNlVXA6IFwid2luZG93czpXaW5kb3dOb25DbGllbnRNb3VzZVVwXCIsXG5cdFx0V2luZG93UGFpbnQ6IFwid2luZG93czpXaW5kb3dQYWludFwiLFxuXHRcdFdpbmRvd1Jlc3RvcmU6IFwid2luZG93czpXaW5kb3dSZXN0b3JlXCIsXG5cdFx0V2luZG93U2V0Rm9jdXM6IFwid2luZG93czpXaW5kb3dTZXRGb2N1c1wiLFxuXHRcdFdpbmRvd1Nob3c6IFwid2luZG93czpXaW5kb3dTaG93XCIsXG5cdFx0V2luZG93U3RhcnRNb3ZlOiBcIndpbmRvd3M6V2luZG93U3RhcnRNb3ZlXCIsXG5cdFx0V2luZG93U3RhcnRSZXNpemU6IFwid2luZG93czpXaW5kb3dTdGFydFJlc2l6ZVwiLFxuXHRcdFdpbmRvd1VuRnVsbHNjcmVlbjogXCJ3aW5kb3dzOldpbmRvd1VuRnVsbHNjcmVlblwiLFxuXHRcdFdpbmRvd1pPcmRlckNoYW5nZWQ6IFwid2luZG93czpXaW5kb3daT3JkZXJDaGFuZ2VkXCIsXG5cdFx0V2luZG93TWluaW1pc2U6IFwid2luZG93czpXaW5kb3dNaW5pbWlzZVwiLFxuXHRcdFdpbmRvd1VuTWluaW1pc2U6IFwid2luZG93czpXaW5kb3dVbk1pbmltaXNlXCIsXG5cdFx0V2luZG93TWF4aW1pc2U6IFwid2luZG93czpXaW5kb3dNYXhpbWlzZVwiLFxuXHRcdFdpbmRvd1VuTWF4aW1pc2U6IFwid2luZG93czpXaW5kb3dVbk1heGltaXNlXCIsXG5cdH0pLFxuXHRNYWM6IE9iamVjdC5mcmVlemUoe1xuXHRcdEFwcGxpY2F0aW9uRGlkQmVjb21lQWN0aXZlOiBcIm1hYzpBcHBsaWNhdGlvbkRpZEJlY29tZUFjdGl2ZVwiLFxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlQmFja2luZ1Byb3BlcnRpZXM6IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlQmFja2luZ1Byb3BlcnRpZXNcIixcblx0XHRBcHBsaWNhdGlvbkRpZENoYW5nZUVmZmVjdGl2ZUFwcGVhcmFuY2U6IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlRWZmZWN0aXZlQXBwZWFyYW5jZVwiLFxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlSWNvbjogXCJtYWM6QXBwbGljYXRpb25EaWRDaGFuZ2VJY29uXCIsXG5cdFx0QXBwbGljYXRpb25EaWRDaGFuZ2VPY2NsdXNpb25TdGF0ZTogXCJtYWM6QXBwbGljYXRpb25EaWRDaGFuZ2VPY2NsdXNpb25TdGF0ZVwiLFxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlU2NyZWVuUGFyYW1ldGVyczogXCJtYWM6QXBwbGljYXRpb25EaWRDaGFuZ2VTY3JlZW5QYXJhbWV0ZXJzXCIsXG5cdFx0QXBwbGljYXRpb25EaWRDaGFuZ2VTdGF0dXNCYXJGcmFtZTogXCJtYWM6QXBwbGljYXRpb25EaWRDaGFuZ2VTdGF0dXNCYXJGcmFtZVwiLFxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlU3RhdHVzQmFyT3JpZW50YXRpb246IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlU3RhdHVzQmFyT3JpZW50YXRpb25cIixcblx0XHRBcHBsaWNhdGlvbkRpZENoYW5nZVRoZW1lOiBcIm1hYzpBcHBsaWNhdGlvbkRpZENoYW5nZVRoZW1lXCIsXG5cdFx0QXBwbGljYXRpb25EaWRGaW5pc2hMYXVuY2hpbmc6IFwibWFjOkFwcGxpY2F0aW9uRGlkRmluaXNoTGF1bmNoaW5nXCIsXG5cdFx0QXBwbGljYXRpb25EaWRIaWRlOiBcIm1hYzpBcHBsaWNhdGlvbkRpZEhpZGVcIixcblx0XHRBcHBsaWNhdGlvbkRpZFJlc2lnbkFjdGl2ZTogXCJtYWM6QXBwbGljYXRpb25EaWRSZXNpZ25BY3RpdmVcIixcblx0XHRBcHBsaWNhdGlvbkRpZFVuaGlkZTogXCJtYWM6QXBwbGljYXRpb25EaWRVbmhpZGVcIixcblx0XHRBcHBsaWNhdGlvbkRpZFVwZGF0ZTogXCJtYWM6QXBwbGljYXRpb25EaWRVcGRhdGVcIixcblx0XHRBcHBsaWNhdGlvblNob3VsZEhhbmRsZVJlb3BlbjogXCJtYWM6QXBwbGljYXRpb25TaG91bGRIYW5kbGVSZW9wZW5cIixcblx0XHRBcHBsaWNhdGlvbldpbGxCZWNvbWVBY3RpdmU6IFwibWFjOkFwcGxpY2F0aW9uV2lsbEJlY29tZUFjdGl2ZVwiLFxuXHRcdEFwcGxpY2F0aW9uV2lsbEZpbmlzaExhdW5jaGluZzogXCJtYWM6QXBwbGljYXRpb25XaWxsRmluaXNoTGF1bmNoaW5nXCIsXG5cdFx0QXBwbGljYXRpb25XaWxsSGlkZTogXCJtYWM6QXBwbGljYXRpb25XaWxsSGlkZVwiLFxuXHRcdEFwcGxpY2F0aW9uV2lsbFJlc2lnbkFjdGl2ZTogXCJtYWM6QXBwbGljYXRpb25XaWxsUmVzaWduQWN0aXZlXCIsXG5cdFx0QXBwbGljYXRpb25XaWxsVGVybWluYXRlOiBcIm1hYzpBcHBsaWNhdGlvbldpbGxUZXJtaW5hdGVcIixcblx0XHRBcHBsaWNhdGlvbldpbGxVbmhpZGU6IFwibWFjOkFwcGxpY2F0aW9uV2lsbFVuaGlkZVwiLFxuXHRcdEFwcGxpY2F0aW9uV2lsbFVwZGF0ZTogXCJtYWM6QXBwbGljYXRpb25XaWxsVXBkYXRlXCIsXG5cdFx0TWVudURpZEFkZEl0ZW06IFwibWFjOk1lbnVEaWRBZGRJdGVtXCIsXG5cdFx0TWVudURpZEJlZ2luVHJhY2tpbmc6IFwibWFjOk1lbnVEaWRCZWdpblRyYWNraW5nXCIsXG5cdFx0TWVudURpZENsb3NlOiBcIm1hYzpNZW51RGlkQ2xvc2VcIixcblx0XHRNZW51RGlkRGlzcGxheUl0ZW06IFwibWFjOk1lbnVEaWREaXNwbGF5SXRlbVwiLFxuXHRcdE1lbnVEaWRFbmRUcmFja2luZzogXCJtYWM6TWVudURpZEVuZFRyYWNraW5nXCIsXG5cdFx0TWVudURpZEhpZ2hsaWdodEl0ZW06IFwibWFjOk1lbnVEaWRIaWdobGlnaHRJdGVtXCIsXG5cdFx0TWVudURpZE9wZW46IFwibWFjOk1lbnVEaWRPcGVuXCIsXG5cdFx0TWVudURpZFBvcFVwOiBcIm1hYzpNZW51RGlkUG9wVXBcIixcblx0XHRNZW51RGlkUmVtb3ZlSXRlbTogXCJtYWM6TWVudURpZFJlbW92ZUl0ZW1cIixcblx0XHRNZW51RGlkU2VuZEFjdGlvbjogXCJtYWM6TWVudURpZFNlbmRBY3Rpb25cIixcblx0XHRNZW51RGlkU2VuZEFjdGlvblRvSXRlbTogXCJtYWM6TWVudURpZFNlbmRBY3Rpb25Ub0l0ZW1cIixcblx0XHRNZW51RGlkVXBkYXRlOiBcIm1hYzpNZW51RGlkVXBkYXRlXCIsXG5cdFx0TWVudVdpbGxBZGRJdGVtOiBcIm1hYzpNZW51V2lsbEFkZEl0ZW1cIixcblx0XHRNZW51V2lsbEJlZ2luVHJhY2tpbmc6IFwibWFjOk1lbnVXaWxsQmVnaW5UcmFja2luZ1wiLFxuXHRcdE1lbnVXaWxsRGlzcGxheUl0ZW06IFwibWFjOk1lbnVXaWxsRGlzcGxheUl0ZW1cIixcblx0XHRNZW51V2lsbEVuZFRyYWNraW5nOiBcIm1hYzpNZW51V2lsbEVuZFRyYWNraW5nXCIsXG5cdFx0TWVudVdpbGxIaWdobGlnaHRJdGVtOiBcIm1hYzpNZW51V2lsbEhpZ2hsaWdodEl0ZW1cIixcblx0XHRNZW51V2lsbE9wZW46IFwibWFjOk1lbnVXaWxsT3BlblwiLFxuXHRcdE1lbnVXaWxsUG9wVXA6IFwibWFjOk1lbnVXaWxsUG9wVXBcIixcblx0XHRNZW51V2lsbFJlbW92ZUl0ZW06IFwibWFjOk1lbnVXaWxsUmVtb3ZlSXRlbVwiLFxuXHRcdE1lbnVXaWxsU2VuZEFjdGlvbjogXCJtYWM6TWVudVdpbGxTZW5kQWN0aW9uXCIsXG5cdFx0TWVudVdpbGxTZW5kQWN0aW9uVG9JdGVtOiBcIm1hYzpNZW51V2lsbFNlbmRBY3Rpb25Ub0l0ZW1cIixcblx0XHRNZW51V2lsbFVwZGF0ZTogXCJtYWM6TWVudVdpbGxVcGRhdGVcIixcblx0XHRXZWJWaWV3RGlkQ29tbWl0TmF2aWdhdGlvbjogXCJtYWM6V2ViVmlld0RpZENvbW1pdE5hdmlnYXRpb25cIixcblx0XHRXZWJWaWV3RGlkRmluaXNoTmF2aWdhdGlvbjogXCJtYWM6V2ViVmlld0RpZEZpbmlzaE5hdmlnYXRpb25cIixcblx0XHRXZWJWaWV3RGlkUmVjZWl2ZVNlcnZlclJlZGlyZWN0Rm9yUHJvdmlzaW9uYWxOYXZpZ2F0aW9uOiBcIm1hYzpXZWJWaWV3RGlkUmVjZWl2ZVNlcnZlclJlZGlyZWN0Rm9yUHJvdmlzaW9uYWxOYXZpZ2F0aW9uXCIsXG5cdFx0V2ViVmlld0RpZFN0YXJ0UHJvdmlzaW9uYWxOYXZpZ2F0aW9uOiBcIm1hYzpXZWJWaWV3RGlkU3RhcnRQcm92aXNpb25hbE5hdmlnYXRpb25cIixcblx0XHRXaW5kb3dEaWRCZWNvbWVLZXk6IFwibWFjOldpbmRvd0RpZEJlY29tZUtleVwiLFxuXHRcdFdpbmRvd0RpZEJlY29tZU1haW46IFwibWFjOldpbmRvd0RpZEJlY29tZU1haW5cIixcblx0XHRXaW5kb3dEaWRCZWdpblNoZWV0OiBcIm1hYzpXaW5kb3dEaWRCZWdpblNoZWV0XCIsXG5cdFx0V2luZG93RGlkQ2hhbmdlQWxwaGE6IFwibWFjOldpbmRvd0RpZENoYW5nZUFscGhhXCIsXG5cdFx0V2luZG93RGlkQ2hhbmdlQmFja2luZ0xvY2F0aW9uOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VCYWNraW5nTG9jYXRpb25cIixcblx0XHRXaW5kb3dEaWRDaGFuZ2VCYWNraW5nUHJvcGVydGllczogXCJtYWM6V2luZG93RGlkQ2hhbmdlQmFja2luZ1Byb3BlcnRpZXNcIixcblx0XHRXaW5kb3dEaWRDaGFuZ2VDb2xsZWN0aW9uQmVoYXZpb3I6IFwibWFjOldpbmRvd0RpZENoYW5nZUNvbGxlY3Rpb25CZWhhdmlvclwiLFxuXHRcdFdpbmRvd0RpZENoYW5nZUVmZmVjdGl2ZUFwcGVhcmFuY2U6IFwibWFjOldpbmRvd0RpZENoYW5nZUVmZmVjdGl2ZUFwcGVhcmFuY2VcIixcblx0XHRXaW5kb3dEaWRDaGFuZ2VPY2NsdXNpb25TdGF0ZTogXCJtYWM6V2luZG93RGlkQ2hhbmdlT2NjbHVzaW9uU3RhdGVcIixcblx0XHRXaW5kb3dEaWRDaGFuZ2VPcmRlcmluZ01vZGU6IFwibWFjOldpbmRvd0RpZENoYW5nZU9yZGVyaW5nTW9kZVwiLFxuXHRcdFdpbmRvd0RpZENoYW5nZVNjcmVlbjogXCJtYWM6V2luZG93RGlkQ2hhbmdlU2NyZWVuXCIsXG5cdFx0V2luZG93RGlkQ2hhbmdlU2NyZWVuUGFyYW1ldGVyczogXCJtYWM6V2luZG93RGlkQ2hhbmdlU2NyZWVuUGFyYW1ldGVyc1wiLFxuXHRcdFdpbmRvd0RpZENoYW5nZVNjcmVlblByb2ZpbGU6IFwibWFjOldpbmRvd0RpZENoYW5nZVNjcmVlblByb2ZpbGVcIixcblx0XHRXaW5kb3dEaWRDaGFuZ2VTY3JlZW5TcGFjZTogXCJtYWM6V2luZG93RGlkQ2hhbmdlU2NyZWVuU3BhY2VcIixcblx0XHRXaW5kb3dEaWRDaGFuZ2VTY3JlZW5TcGFjZVByb3BlcnRpZXM6IFwibWFjOldpbmRvd0RpZENoYW5nZVNjcmVlblNwYWNlUHJvcGVydGllc1wiLFxuXHRcdFdpbmRvd0RpZENoYW5nZVNoYXJpbmdUeXBlOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VTaGFyaW5nVHlwZVwiLFxuXHRcdFdpbmRvd0RpZENoYW5nZVNwYWNlOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VTcGFjZVwiLFxuXHRcdFdpbmRvd0RpZENoYW5nZVNwYWNlT3JkZXJpbmdNb2RlOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VTcGFjZU9yZGVyaW5nTW9kZVwiLFxuXHRcdFdpbmRvd0RpZENoYW5nZVRpdGxlOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VUaXRsZVwiLFxuXHRcdFdpbmRvd0RpZENoYW5nZVRvb2xiYXI6IFwibWFjOldpbmRvd0RpZENoYW5nZVRvb2xiYXJcIixcblx0XHRXaW5kb3dEaWREZW1pbmlhdHVyaXplOiBcIm1hYzpXaW5kb3dEaWREZW1pbmlhdHVyaXplXCIsXG5cdFx0V2luZG93RGlkRW5kU2hlZXQ6IFwibWFjOldpbmRvd0RpZEVuZFNoZWV0XCIsXG5cdFx0V2luZG93RGlkRW50ZXJGdWxsU2NyZWVuOiBcIm1hYzpXaW5kb3dEaWRFbnRlckZ1bGxTY3JlZW5cIixcblx0XHRXaW5kb3dEaWRFbnRlclZlcnNpb25Ccm93c2VyOiBcIm1hYzpXaW5kb3dEaWRFbnRlclZlcnNpb25Ccm93c2VyXCIsXG5cdFx0V2luZG93RGlkRXhpdEZ1bGxTY3JlZW46IFwibWFjOldpbmRvd0RpZEV4aXRGdWxsU2NyZWVuXCIsXG5cdFx0V2luZG93RGlkRXhpdFZlcnNpb25Ccm93c2VyOiBcIm1hYzpXaW5kb3dEaWRFeGl0VmVyc2lvbkJyb3dzZXJcIixcblx0XHRXaW5kb3dEaWRFeHBvc2U6IFwibWFjOldpbmRvd0RpZEV4cG9zZVwiLFxuXHRcdFdpbmRvd0RpZEZvY3VzOiBcIm1hYzpXaW5kb3dEaWRGb2N1c1wiLFxuXHRcdFdpbmRvd0RpZE1pbmlhdHVyaXplOiBcIm1hYzpXaW5kb3dEaWRNaW5pYXR1cml6ZVwiLFxuXHRcdFdpbmRvd0RpZE1vdmU6IFwibWFjOldpbmRvd0RpZE1vdmVcIixcblx0XHRXaW5kb3dEaWRPcmRlck9mZlNjcmVlbjogXCJtYWM6V2luZG93RGlkT3JkZXJPZmZTY3JlZW5cIixcblx0XHRXaW5kb3dEaWRPcmRlck9uU2NyZWVuOiBcIm1hYzpXaW5kb3dEaWRPcmRlck9uU2NyZWVuXCIsXG5cdFx0V2luZG93RGlkUmVzaWduS2V5OiBcIm1hYzpXaW5kb3dEaWRSZXNpZ25LZXlcIixcblx0XHRXaW5kb3dEaWRSZXNpZ25NYWluOiBcIm1hYzpXaW5kb3dEaWRSZXNpZ25NYWluXCIsXG5cdFx0V2luZG93RGlkUmVzaXplOiBcIm1hYzpXaW5kb3dEaWRSZXNpemVcIixcblx0XHRXaW5kb3dEaWRVcGRhdGU6IFwibWFjOldpbmRvd0RpZFVwZGF0ZVwiLFxuXHRcdFdpbmRvd0RpZFVwZGF0ZUFscGhhOiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVBbHBoYVwiLFxuXHRcdFdpbmRvd0RpZFVwZGF0ZUNvbGxlY3Rpb25CZWhhdmlvcjogXCJtYWM6V2luZG93RGlkVXBkYXRlQ29sbGVjdGlvbkJlaGF2aW9yXCIsXG5cdFx0V2luZG93RGlkVXBkYXRlQ29sbGVjdGlvblByb3BlcnRpZXM6IFwibWFjOldpbmRvd0RpZFVwZGF0ZUNvbGxlY3Rpb25Qcm9wZXJ0aWVzXCIsXG5cdFx0V2luZG93RGlkVXBkYXRlU2hhZG93OiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVTaGFkb3dcIixcblx0XHRXaW5kb3dEaWRVcGRhdGVUaXRsZTogXCJtYWM6V2luZG93RGlkVXBkYXRlVGl0bGVcIixcblx0XHRXaW5kb3dEaWRVcGRhdGVUb29sYmFyOiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVUb29sYmFyXCIsXG5cdFx0V2luZG93RGlkWm9vbTogXCJtYWM6V2luZG93RGlkWm9vbVwiLFxuXHRcdFdpbmRvd0ZpbGVEcmFnZ2luZ0VudGVyZWQ6IFwibWFjOldpbmRvd0ZpbGVEcmFnZ2luZ0VudGVyZWRcIixcblx0XHRXaW5kb3dGaWxlRHJhZ2dpbmdFeGl0ZWQ6IFwibWFjOldpbmRvd0ZpbGVEcmFnZ2luZ0V4aXRlZFwiLFxuXHRcdFdpbmRvd0ZpbGVEcmFnZ2luZ1BlcmZvcm1lZDogXCJtYWM6V2luZG93RmlsZURyYWdnaW5nUGVyZm9ybWVkXCIsXG5cdFx0V2luZG93SGlkZTogXCJtYWM6V2luZG93SGlkZVwiLFxuXHRcdFdpbmRvd01heGltaXNlOiBcIm1hYzpXaW5kb3dNYXhpbWlzZVwiLFxuXHRcdFdpbmRvd1VuTWF4aW1pc2U6IFwibWFjOldpbmRvd1VuTWF4aW1pc2VcIixcblx0XHRXaW5kb3dNaW5pbWlzZTogXCJtYWM6V2luZG93TWluaW1pc2VcIixcblx0XHRXaW5kb3dVbk1pbmltaXNlOiBcIm1hYzpXaW5kb3dVbk1pbmltaXNlXCIsXG5cdFx0V2luZG93U2hvdWxkQ2xvc2U6IFwibWFjOldpbmRvd1Nob3VsZENsb3NlXCIsXG5cdFx0V2luZG93U2hvdzogXCJtYWM6V2luZG93U2hvd1wiLFxuXHRcdFdpbmRvd1dpbGxCZWNvbWVLZXk6IFwibWFjOldpbmRvd1dpbGxCZWNvbWVLZXlcIixcblx0XHRXaW5kb3dXaWxsQmVjb21lTWFpbjogXCJtYWM6V2luZG93V2lsbEJlY29tZU1haW5cIixcblx0XHRXaW5kb3dXaWxsQmVnaW5TaGVldDogXCJtYWM6V2luZG93V2lsbEJlZ2luU2hlZXRcIixcblx0XHRXaW5kb3dXaWxsQ2hhbmdlT3JkZXJpbmdNb2RlOiBcIm1hYzpXaW5kb3dXaWxsQ2hhbmdlT3JkZXJpbmdNb2RlXCIsXG5cdFx0V2luZG93V2lsbENsb3NlOiBcIm1hYzpXaW5kb3dXaWxsQ2xvc2VcIixcblx0XHRXaW5kb3dXaWxsRGVtaW5pYXR1cml6ZTogXCJtYWM6V2luZG93V2lsbERlbWluaWF0dXJpemVcIixcblx0XHRXaW5kb3dXaWxsRW50ZXJGdWxsU2NyZWVuOiBcIm1hYzpXaW5kb3dXaWxsRW50ZXJGdWxsU2NyZWVuXCIsXG5cdFx0V2luZG93V2lsbEVudGVyVmVyc2lvbkJyb3dzZXI6IFwibWFjOldpbmRvd1dpbGxFbnRlclZlcnNpb25Ccm93c2VyXCIsXG5cdFx0V2luZG93V2lsbEV4aXRGdWxsU2NyZWVuOiBcIm1hYzpXaW5kb3dXaWxsRXhpdEZ1bGxTY3JlZW5cIixcblx0XHRXaW5kb3dXaWxsRXhpdFZlcnNpb25Ccm93c2VyOiBcIm1hYzpXaW5kb3dXaWxsRXhpdFZlcnNpb25Ccm93c2VyXCIsXG5cdFx0V2luZG93V2lsbEZvY3VzOiBcIm1hYzpXaW5kb3dXaWxsRm9jdXNcIixcblx0XHRXaW5kb3dXaWxsTWluaWF0dXJpemU6IFwibWFjOldpbmRvd1dpbGxNaW5pYXR1cml6ZVwiLFxuXHRcdFdpbmRvd1dpbGxNb3ZlOiBcIm1hYzpXaW5kb3dXaWxsTW92ZVwiLFxuXHRcdFdpbmRvd1dpbGxPcmRlck9mZlNjcmVlbjogXCJtYWM6V2luZG93V2lsbE9yZGVyT2ZmU2NyZWVuXCIsXG5cdFx0V2luZG93V2lsbE9yZGVyT25TY3JlZW46IFwibWFjOldpbmRvd1dpbGxPcmRlck9uU2NyZWVuXCIsXG5cdFx0V2luZG93V2lsbFJlc2lnbk1haW46IFwibWFjOldpbmRvd1dpbGxSZXNpZ25NYWluXCIsXG5cdFx0V2luZG93V2lsbFJlc2l6ZTogXCJtYWM6V2luZG93V2lsbFJlc2l6ZVwiLFxuXHRcdFdpbmRvd1dpbGxVbmZvY3VzOiBcIm1hYzpXaW5kb3dXaWxsVW5mb2N1c1wiLFxuXHRcdFdpbmRvd1dpbGxVcGRhdGU6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVcIixcblx0XHRXaW5kb3dXaWxsVXBkYXRlQWxwaGE6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVBbHBoYVwiLFxuXHRcdFdpbmRvd1dpbGxVcGRhdGVDb2xsZWN0aW9uQmVoYXZpb3I6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVDb2xsZWN0aW9uQmVoYXZpb3JcIixcblx0XHRXaW5kb3dXaWxsVXBkYXRlQ29sbGVjdGlvblByb3BlcnRpZXM6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVDb2xsZWN0aW9uUHJvcGVydGllc1wiLFxuXHRcdFdpbmRvd1dpbGxVcGRhdGVTaGFkb3c6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVTaGFkb3dcIixcblx0XHRXaW5kb3dXaWxsVXBkYXRlVGl0bGU6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVUaXRsZVwiLFxuXHRcdFdpbmRvd1dpbGxVcGRhdGVUb29sYmFyOiBcIm1hYzpXaW5kb3dXaWxsVXBkYXRlVG9vbGJhclwiLFxuXHRcdFdpbmRvd1dpbGxVcGRhdGVWaXNpYmlsaXR5OiBcIm1hYzpXaW5kb3dXaWxsVXBkYXRlVmlzaWJpbGl0eVwiLFxuXHRcdFdpbmRvd1dpbGxVc2VTdGFuZGFyZEZyYW1lOiBcIm1hYzpXaW5kb3dXaWxsVXNlU3RhbmRhcmRGcmFtZVwiLFxuXHRcdFdpbmRvd1pvb21JbjogXCJtYWM6V2luZG93Wm9vbUluXCIsXG5cdFx0V2luZG93Wm9vbU91dDogXCJtYWM6V2luZG93Wm9vbU91dFwiLFxuXHRcdFdpbmRvd1pvb21SZXNldDogXCJtYWM6V2luZG93Wm9vbVJlc2V0XCIsXG5cdH0pLFxuXHRMaW51eDogT2JqZWN0LmZyZWV6ZSh7XG5cdFx0QXBwbGljYXRpb25TdGFydHVwOiBcImxpbnV4OkFwcGxpY2F0aW9uU3RhcnR1cFwiLFxuXHRcdFN5c3RlbVRoZW1lQ2hhbmdlZDogXCJsaW51eDpTeXN0ZW1UaGVtZUNoYW5nZWRcIixcblx0XHRXaW5kb3dEZWxldGVFdmVudDogXCJsaW51eDpXaW5kb3dEZWxldGVFdmVudFwiLFxuXHRcdFdpbmRvd0RpZE1vdmU6IFwibGludXg6V2luZG93RGlkTW92ZVwiLFxuXHRcdFdpbmRvd0RpZFJlc2l6ZTogXCJsaW51eDpXaW5kb3dEaWRSZXNpemVcIixcblx0XHRXaW5kb3dGb2N1c0luOiBcImxpbnV4OldpbmRvd0ZvY3VzSW5cIixcblx0XHRXaW5kb3dGb2N1c091dDogXCJsaW51eDpXaW5kb3dGb2N1c091dFwiLFxuXHRcdFdpbmRvd0xvYWRDaGFuZ2VkOiBcImxpbnV4OldpbmRvd0xvYWRDaGFuZ2VkXCIsXG5cdH0pLFxuXHRDb21tb246IE9iamVjdC5mcmVlemUoe1xuXHRcdEFwcGxpY2F0aW9uT3BlbmVkV2l0aEZpbGU6IFwiY29tbW9uOkFwcGxpY2F0aW9uT3BlbmVkV2l0aEZpbGVcIixcblx0XHRBcHBsaWNhdGlvblN0YXJ0ZWQ6IFwiY29tbW9uOkFwcGxpY2F0aW9uU3RhcnRlZFwiLFxuXHRcdFRoZW1lQ2hhbmdlZDogXCJjb21tb246VGhlbWVDaGFuZ2VkXCIsXG5cdFx0V2luZG93Q2xvc2luZzogXCJjb21tb246V2luZG93Q2xvc2luZ1wiLFxuXHRcdFdpbmRvd0RpZE1vdmU6IFwiY29tbW9uOldpbmRvd0RpZE1vdmVcIixcblx0XHRXaW5kb3dEaWRSZXNpemU6IFwiY29tbW9uOldpbmRvd0RpZFJlc2l6ZVwiLFxuXHRcdFdpbmRvd0RQSUNoYW5nZWQ6IFwiY29tbW9uOldpbmRvd0RQSUNoYW5nZWRcIixcblx0XHRXaW5kb3dGaWxlc0Ryb3BwZWQ6IFwiY29tbW9uOldpbmRvd0ZpbGVzRHJvcHBlZFwiLFxuXHRcdFdpbmRvd0ZvY3VzOiBcImNvbW1vbjpXaW5kb3dGb2N1c1wiLFxuXHRcdFdpbmRvd0Z1bGxzY3JlZW46IFwiY29tbW9uOldpbmRvd0Z1bGxzY3JlZW5cIixcblx0XHRXaW5kb3dIaWRlOiBcImNvbW1vbjpXaW5kb3dIaWRlXCIsXG5cdFx0V2luZG93TG9zdEZvY3VzOiBcImNvbW1vbjpXaW5kb3dMb3N0Rm9jdXNcIixcblx0XHRXaW5kb3dNYXhpbWlzZTogXCJjb21tb246V2luZG93TWF4aW1pc2VcIixcblx0XHRXaW5kb3dNaW5pbWlzZTogXCJjb21tb246V2luZG93TWluaW1pc2VcIixcblx0XHRXaW5kb3dSZXN0b3JlOiBcImNvbW1vbjpXaW5kb3dSZXN0b3JlXCIsXG5cdFx0V2luZG93UnVudGltZVJlYWR5OiBcImNvbW1vbjpXaW5kb3dSdW50aW1lUmVhZHlcIixcblx0XHRXaW5kb3dTaG93OiBcImNvbW1vbjpXaW5kb3dTaG93XCIsXG5cdFx0V2luZG93VW5GdWxsc2NyZWVuOiBcImNvbW1vbjpXaW5kb3dVbkZ1bGxzY3JlZW5cIixcblx0XHRXaW5kb3dVbk1heGltaXNlOiBcImNvbW1vbjpXaW5kb3dVbk1heGltaXNlXCIsXG5cdFx0V2luZG93VW5NaW5pbWlzZTogXCJjb21tb246V2luZG93VW5NaW5pbWlzZVwiLFxuXHRcdFdpbmRvd1pvb206IFwiY29tbW9uOldpbmRvd1pvb21cIixcblx0XHRXaW5kb3dab29tSW46IFwiY29tbW9uOldpbmRvd1pvb21JblwiLFxuXHRcdFdpbmRvd1pvb21PdXQ6IFwiY29tbW9uOldpbmRvd1pvb21PdXRcIixcblx0XHRXaW5kb3dab29tUmVzZXQ6IFwiY29tbW9uOldpbmRvd1pvb21SZXNldFwiLFxuXHR9KSxcbn0pO1xuIiwgIi8qXG4gXyAgICAgX18gICAgIF8gX19cbnwgfCAgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKipcbiAqIExvZ3MgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlIHdpdGggY3VzdG9tIGZvcm1hdHRpbmcuXG4gKlxuICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWJ1Z0xvZyhtZXNzYWdlOiBhbnkpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgJyVjIHdhaWxzMyAlYyAnICsgbWVzc2FnZSArICcgJyxcbiAgICAgICAgJ2JhY2tncm91bmQ6ICNhYTAwMDA7IGNvbG9yOiAjZmZmOyBib3JkZXItcmFkaXVzOiAzcHggMHB4IDBweCAzcHg7IHBhZGRpbmc6IDFweDsgZm9udC1zaXplOiAwLjdyZW0nLFxuICAgICAgICAnYmFja2dyb3VuZDogIzAwOTkwMDsgY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDBweCAzcHggM3B4IDBweDsgcGFkZGluZzogMXB4OyBmb250LXNpemU6IDAuN3JlbSdcbiAgICApO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB3ZWJ2aWV3IHN1cHBvcnRzIHRoZSB7QGxpbmsgTW91c2VFdmVudCNidXR0b25zfSBwcm9wZXJ0eS5cbiAqIExvb2tpbmcgYXQgeW91IG1hY09TIEhpZ2ggU2llcnJhIVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FuVHJhY2tCdXR0b25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAobmV3IE1vdXNlRXZlbnQoJ21vdXNlZG93bicpKS5idXR0b25zID09PSAwO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBicm93c2VyIHN1cHBvcnRzIHJlbW92aW5nIGxpc3RlbmVycyBieSB0cmlnZ2VyaW5nIGFuIEFib3J0U2lnbmFsXG4gKiAoc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9hZGRFdmVudExpc3RlbmVyI3NpZ25hbCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYW5BYm9ydExpc3RlbmVycygpIHtcbiAgICBpZiAoIUV2ZW50VGFyZ2V0IHx8ICFBYm9ydFNpZ25hbCB8fCAhQWJvcnRDb250cm9sbGVyKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBsZXQgcmVzdWx0ID0gdHJ1ZTtcblxuICAgIGNvbnN0IHRhcmdldCA9IG5ldyBFdmVudFRhcmdldCgpO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCAoKSA9PiB7IHJlc3VsdCA9IGZhbHNlOyB9LCB7IHNpZ25hbDogY29udHJvbGxlci5zaWduYWwgfSk7XG4gICAgY29udHJvbGxlci5hYm9ydCgpO1xuICAgIHRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudCgndGVzdCcpKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIGNsb3Nlc3QgSFRNTEVsZW1lbnQgYW5jZXN0b3Igb2YgYW4gZXZlbnQncyB0YXJnZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBldmVudFRhcmdldChldmVudDogRXZlbnQpOiBIVE1MRWxlbWVudCB7XG4gICAgaWYgKGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBldmVudC50YXJnZXQ7XG4gICAgfSBlbHNlIGlmICghKGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSAmJiBldmVudC50YXJnZXQgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICAgIHJldHVybiBldmVudC50YXJnZXQucGFyZW50RWxlbWVudCA/PyBkb2N1bWVudC5ib2R5O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5ib2R5O1xuICAgIH1cbn1cblxuLyoqKlxuIFRoaXMgdGVjaG5pcXVlIGZvciBwcm9wZXIgbG9hZCBkZXRlY3Rpb24gaXMgdGFrZW4gZnJvbSBIVE1YOlxuXG4gQlNEIDItQ2xhdXNlIExpY2Vuc2VcblxuIENvcHlyaWdodCAoYykgMjAyMCwgQmlnIFNreSBTb2Z0d2FyZVxuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuXG4gMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SXG4gU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFXG4gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblxuICoqKi9cblxubGV0IGlzUmVhZHkgPSBmYWxzZTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCAoKSA9PiB7IGlzUmVhZHkgPSB0cnVlIH0pO1xuXG5leHBvcnQgZnVuY3Rpb24gd2hlblJlYWR5KGNhbGxiYWNrOiAoKSA9PiB2b2lkKSB7XG4gICAgaWYgKGlzUmVhZHkgfHwgZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2NvbXBsZXRlJykge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBjYWxsYmFjayk7XG4gICAgfVxufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG5pbXBvcnQge25ld1J1bnRpbWVDYWxsZXIsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNjcmVlbiB9IGZyb20gXCIuL3NjcmVlbnMuanNcIjtcblxuY29uc3QgUG9zaXRpb25NZXRob2QgICAgICAgICAgICAgICAgICAgID0gMDtcbmNvbnN0IENlbnRlck1ldGhvZCAgICAgICAgICAgICAgICAgICAgICA9IDE7XG5jb25zdCBDbG9zZU1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgPSAyO1xuY29uc3QgRGlzYWJsZVNpemVDb25zdHJhaW50c01ldGhvZCAgICAgID0gMztcbmNvbnN0IEVuYWJsZVNpemVDb25zdHJhaW50c01ldGhvZCAgICAgICA9IDQ7XG5jb25zdCBGb2N1c01ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgPSA1O1xuY29uc3QgRm9yY2VSZWxvYWRNZXRob2QgICAgICAgICAgICAgICAgID0gNjtcbmNvbnN0IEZ1bGxzY3JlZW5NZXRob2QgICAgICAgICAgICAgICAgICA9IDc7XG5jb25zdCBHZXRTY3JlZW5NZXRob2QgICAgICAgICAgICAgICAgICAgPSA4O1xuY29uc3QgR2V0Wm9vbU1ldGhvZCAgICAgICAgICAgICAgICAgICAgID0gOTtcbmNvbnN0IEhlaWdodE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICA9IDEwO1xuY29uc3QgSGlkZU1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgID0gMTE7XG5jb25zdCBJc0ZvY3VzZWRNZXRob2QgICAgICAgICAgICAgICAgICAgPSAxMjtcbmNvbnN0IElzRnVsbHNjcmVlbk1ldGhvZCAgICAgICAgICAgICAgICA9IDEzO1xuY29uc3QgSXNNYXhpbWlzZWRNZXRob2QgICAgICAgICAgICAgICAgID0gMTQ7XG5jb25zdCBJc01pbmltaXNlZE1ldGhvZCAgICAgICAgICAgICAgICAgPSAxNTtcbmNvbnN0IE1heGltaXNlTWV0aG9kICAgICAgICAgICAgICAgICAgICA9IDE2O1xuY29uc3QgTWluaW1pc2VNZXRob2QgICAgICAgICAgICAgICAgICAgID0gMTc7XG5jb25zdCBOYW1lTWV0aG9kICAgICAgICAgICAgICAgICAgICAgICAgPSAxODtcbmNvbnN0IE9wZW5EZXZUb29sc01ldGhvZCAgICAgICAgICAgICAgICA9IDE5O1xuY29uc3QgUmVsYXRpdmVQb3NpdGlvbk1ldGhvZCAgICAgICAgICAgID0gMjA7XG5jb25zdCBSZWxvYWRNZXRob2QgICAgICAgICAgICAgICAgICAgICAgPSAyMTtcbmNvbnN0IFJlc2l6YWJsZU1ldGhvZCAgICAgICAgICAgICAgICAgICA9IDIyO1xuY29uc3QgUmVzdG9yZU1ldGhvZCAgICAgICAgICAgICAgICAgICAgID0gMjM7XG5jb25zdCBTZXRQb3NpdGlvbk1ldGhvZCAgICAgICAgICAgICAgICAgPSAyNDtcbmNvbnN0IFNldEFsd2F5c09uVG9wTWV0aG9kICAgICAgICAgICAgICA9IDI1O1xuY29uc3QgU2V0QmFja2dyb3VuZENvbG91ck1ldGhvZCAgICAgICAgID0gMjY7XG5jb25zdCBTZXRGcmFtZWxlc3NNZXRob2QgICAgICAgICAgICAgICAgPSAyNztcbmNvbnN0IFNldEZ1bGxzY3JlZW5CdXR0b25FbmFibGVkTWV0aG9kICA9IDI4O1xuY29uc3QgU2V0TWF4U2l6ZU1ldGhvZCAgICAgICAgICAgICAgICAgID0gMjk7XG5jb25zdCBTZXRNaW5TaXplTWV0aG9kICAgICAgICAgICAgICAgICAgPSAzMDtcbmNvbnN0IFNldFJlbGF0aXZlUG9zaXRpb25NZXRob2QgICAgICAgICA9IDMxO1xuY29uc3QgU2V0UmVzaXphYmxlTWV0aG9kICAgICAgICAgICAgICAgID0gMzI7XG5jb25zdCBTZXRTaXplTWV0aG9kICAgICAgICAgICAgICAgICAgICAgPSAzMztcbmNvbnN0IFNldFRpdGxlTWV0aG9kICAgICAgICAgICAgICAgICAgICA9IDM0O1xuY29uc3QgU2V0Wm9vbU1ldGhvZCAgICAgICAgICAgICAgICAgICAgID0gMzU7XG5jb25zdCBTaG93TWV0aG9kICAgICAgICAgICAgICAgICAgICAgICAgPSAzNjtcbmNvbnN0IFNpemVNZXRob2QgICAgICAgICAgICAgICAgICAgICAgICA9IDM3O1xuY29uc3QgVG9nZ2xlRnVsbHNjcmVlbk1ldGhvZCAgICAgICAgICAgID0gMzg7XG5jb25zdCBUb2dnbGVNYXhpbWlzZU1ldGhvZCAgICAgICAgICAgICAgPSAzOTtcbmNvbnN0IFVuRnVsbHNjcmVlbk1ldGhvZCAgICAgICAgICAgICAgICA9IDQwO1xuY29uc3QgVW5NYXhpbWlzZU1ldGhvZCAgICAgICAgICAgICAgICAgID0gNDE7XG5jb25zdCBVbk1pbmltaXNlTWV0aG9kICAgICAgICAgICAgICAgICAgPSA0MjtcbmNvbnN0IFdpZHRoTWV0aG9kICAgICAgICAgICAgICAgICAgICAgICA9IDQzO1xuY29uc3QgWm9vbU1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgID0gNDQ7XG5jb25zdCBab29tSW5NZXRob2QgICAgICAgICAgICAgICAgICAgICAgPSA0NTtcbmNvbnN0IFpvb21PdXRNZXRob2QgICAgICAgICAgICAgICAgICAgICA9IDQ2O1xuY29uc3QgWm9vbVJlc2V0TWV0aG9kICAgICAgICAgICAgICAgICAgID0gNDc7XG5cbi8qKlxuICogQSByZWNvcmQgZGVzY3JpYmluZyB0aGUgcG9zaXRpb24gb2YgYSB3aW5kb3cuXG4gKi9cbmludGVyZmFjZSBQb3NpdGlvbiB7XG4gICAgLyoqIFRoZSBob3Jpem9udGFsIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuICovXG4gICAgeDogbnVtYmVyO1xuICAgIC8qKiBUaGUgdmVydGljYWwgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy4gKi9cbiAgICB5OiBudW1iZXI7XG59XG5cbi8qKlxuICogQSByZWNvcmQgZGVzY3JpYmluZyB0aGUgc2l6ZSBvZiBhIHdpbmRvdy5cbiAqL1xuaW50ZXJmYWNlIFNpemUge1xuICAgIC8qKiBUaGUgd2lkdGggb2YgdGhlIHdpbmRvdy4gKi9cbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIC8qKiBUaGUgaGVpZ2h0IG9mIHRoZSB3aW5kb3cuICovXG4gICAgaGVpZ2h0OiBudW1iZXI7XG59XG5cbi8vIFByaXZhdGUgZmllbGQgbmFtZXMuXG5jb25zdCBjYWxsZXJTeW0gPSBTeW1ib2woXCJjYWxsZXJcIik7XG5cbmNsYXNzIFdpbmRvdyB7XG4gICAgLy8gUHJpdmF0ZSBmaWVsZHMuXG4gICAgcHJpdmF0ZSBbY2FsbGVyU3ltXTogKG1lc3NhZ2U6IG51bWJlciwgYXJncz86IGFueSkgPT4gUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGlzZXMgYSB3aW5kb3cgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgd2luZG93LlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZyA9ICcnKSB7XG4gICAgICAgIHRoaXNbY2FsbGVyU3ltXSA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuV2luZG93LCBuYW1lKVxuXG4gICAgICAgIC8vIGJpbmQgaW5zdGFuY2UgbWV0aG9kIHRvIG1ha2UgdGhlbSBlYXNpbHkgdXNhYmxlIGluIGV2ZW50IGhhbmRsZXJzXG4gICAgICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFdpbmRvdy5wcm90b3R5cGUpKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgbWV0aG9kICE9PSBcImNvbnN0cnVjdG9yXCJcbiAgICAgICAgICAgICAgICAmJiB0eXBlb2YgKHRoaXMgYXMgYW55KVttZXRob2RdID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICh0aGlzIGFzIGFueSlbbWV0aG9kXSA9ICh0aGlzIGFzIGFueSlbbWV0aG9kXS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc3BlY2lmaWVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHdpbmRvdyB0byBnZXQuXG4gICAgICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgd2luZG93IG9iamVjdC5cbiAgICAgKi9cbiAgICBHZXQobmFtZTogc3RyaW5nKTogV2luZG93IHtcbiAgICAgICAgcmV0dXJuIG5ldyBXaW5kb3cobmFtZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBjdXJyZW50IGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuXG4gICAgICovXG4gICAgUG9zaXRpb24oKTogUHJvbWlzZTxQb3NpdGlvbj4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFBvc2l0aW9uTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDZW50ZXJzIHRoZSB3aW5kb3cgb24gdGhlIHNjcmVlbi5cbiAgICAgKi9cbiAgICBDZW50ZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oQ2VudGVyTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBDbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShDbG9zZU1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzYWJsZXMgbWluL21heCBzaXplIGNvbnN0cmFpbnRzLlxuICAgICAqL1xuICAgIERpc2FibGVTaXplQ29uc3RyYWludHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oRGlzYWJsZVNpemVDb25zdHJhaW50c01ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5hYmxlcyBtaW4vbWF4IHNpemUgY29uc3RyYWludHMuXG4gICAgICovXG4gICAgRW5hYmxlU2l6ZUNvbnN0cmFpbnRzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEVuYWJsZVNpemVDb25zdHJhaW50c01ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9jdXNlcyB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIEZvY3VzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEZvY3VzTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgdGhlIHdpbmRvdyB0byByZWxvYWQgdGhlIHBhZ2UgYXNzZXRzLlxuICAgICAqL1xuICAgIEZvcmNlUmVsb2FkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEZvcmNlUmVsb2FkTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTd2l0Y2hlcyB0aGUgd2luZG93IHRvIGZ1bGxzY3JlZW4gbW9kZS5cbiAgICAgKi9cbiAgICBGdWxsc2NyZWVuKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEZ1bGxzY3JlZW5NZXRob2QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNjcmVlbiB0aGF0IHRoZSB3aW5kb3cgaXMgb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgc2NyZWVuIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IG9uLlxuICAgICAqL1xuICAgIEdldFNjcmVlbigpOiBQcm9taXNlPFNjcmVlbj4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEdldFNjcmVlbk1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCB6b29tIGxldmVsIG9mIHRoZSB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3VycmVudCB6b29tIGxldmVsLlxuICAgICAqL1xuICAgIEdldFpvb20oKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShHZXRab29tTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBoZWlnaHQgb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBjdXJyZW50IGhlaWdodCBvZiB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIEhlaWdodCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEhlaWdodE1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGlkZXMgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBIaWRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEhpZGVNZXRob2QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgd2luZG93IGlzIGZvY3VzZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IGZvY3VzZWQuXG4gICAgICovXG4gICAgSXNGb2N1c2VkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKElzRm9jdXNlZE1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB3aW5kb3cgaXMgZnVsbHNjcmVlbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHdpbmRvdyBpcyBjdXJyZW50bHkgZnVsbHNjcmVlbi5cbiAgICAgKi9cbiAgICBJc0Z1bGxzY3JlZW4oKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oSXNGdWxsc2NyZWVuTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHdpbmRvdyBpcyBtYXhpbWlzZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IG1heGltaXNlZC5cbiAgICAgKi9cbiAgICBJc01heGltaXNlZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShJc01heGltaXNlZE1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB3aW5kb3cgaXMgbWluaW1pc2VkLlxuICAgICAqXG4gICAgICogQHJldHVybnMgV2hldGhlciB0aGUgd2luZG93IGlzIGN1cnJlbnRseSBtaW5pbWlzZWQuXG4gICAgICovXG4gICAgSXNNaW5pbWlzZWQoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oSXNNaW5pbWlzZWRNZXRob2QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1heGltaXNlcyB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIE1heGltaXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKE1heGltaXNlTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNaW5pbWlzZXMgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBNaW5pbWlzZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShNaW5pbWlzZU1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgd2luZG93LlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG5hbWUgb2YgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBOYW1lKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oTmFtZU1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIGRldmVsb3BtZW50IHRvb2xzIHBhbmUuXG4gICAgICovXG4gICAgT3BlbkRldlRvb2xzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKE9wZW5EZXZUb29sc01ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcmVsYXRpdmUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdyB0byB0aGUgc2NyZWVuLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgcmVsYXRpdmUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBSZWxhdGl2ZVBvc2l0aW9uKCk6IFByb21pc2U8UG9zaXRpb24+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShSZWxhdGl2ZVBvc2l0aW9uTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWxvYWRzIHRoZSBwYWdlIGFzc2V0cy5cbiAgICAgKi9cbiAgICBSZWxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oUmVsb2FkTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHdpbmRvdyBpcyByZXNpemFibGUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IHJlc2l6YWJsZS5cbiAgICAgKi9cbiAgICBSZXNpemFibGUoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oUmVzaXphYmxlTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXN0b3JlcyB0aGUgd2luZG93IHRvIGl0cyBwcmV2aW91cyBzdGF0ZSBpZiBpdCB3YXMgcHJldmlvdXNseSBtaW5pbWlzZWQsIG1heGltaXNlZCBvciBmdWxsc2NyZWVuLlxuICAgICAqL1xuICAgIFJlc3RvcmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oUmVzdG9yZU1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYWJzb2x1dGUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB4IC0gVGhlIGRlc2lyZWQgaG9yaXpvbnRhbCBhYnNvbHV0ZSBwb3NpdGlvbiBvZiB0aGUgd2luZG93LlxuICAgICAqIEBwYXJhbSB5IC0gVGhlIGRlc2lyZWQgdmVydGljYWwgYWJzb2x1dGUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBTZXRQb3NpdGlvbih4OiBudW1iZXIsIHk6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldFBvc2l0aW9uTWV0aG9kLCB7IHgsIHkgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgd2luZG93IHRvIGJlIGFsd2F5cyBvbiB0b3AuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWx3YXlzT25Ub3AgLSBXaGV0aGVyIHRoZSB3aW5kb3cgc2hvdWxkIHN0YXkgb24gdG9wLlxuICAgICAqL1xuICAgIFNldEFsd2F5c09uVG9wKGFsd2F5c09uVG9wOiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2V0QWx3YXlzT25Ub3BNZXRob2QsIHsgYWx3YXlzT25Ub3AgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvdXIgb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByIC0gVGhlIGRlc2lyZWQgcmVkIGNvbXBvbmVudCBvZiB0aGUgd2luZG93IGJhY2tncm91bmQuXG4gICAgICogQHBhcmFtIGcgLSBUaGUgZGVzaXJlZCBncmVlbiBjb21wb25lbnQgb2YgdGhlIHdpbmRvdyBiYWNrZ3JvdW5kLlxuICAgICAqIEBwYXJhbSBiIC0gVGhlIGRlc2lyZWQgYmx1ZSBjb21wb25lbnQgb2YgdGhlIHdpbmRvdyBiYWNrZ3JvdW5kLlxuICAgICAqIEBwYXJhbSBhIC0gVGhlIGRlc2lyZWQgYWxwaGEgY29tcG9uZW50IG9mIHRoZSB3aW5kb3cgYmFja2dyb3VuZC5cbiAgICAgKi9cbiAgICBTZXRCYWNrZ3JvdW5kQ29sb3VyKHI6IG51bWJlciwgZzogbnVtYmVyLCBiOiBudW1iZXIsIGE6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldEJhY2tncm91bmRDb2xvdXJNZXRob2QsIHsgciwgZywgYiwgYSB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRoZSB3aW5kb3cgZnJhbWUgYW5kIHRpdGxlIGJhci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBmcmFtZWxlc3MgLSBXaGV0aGVyIHRoZSB3aW5kb3cgc2hvdWxkIGJlIGZyYW1lbGVzcy5cbiAgICAgKi9cbiAgICBTZXRGcmFtZWxlc3MoZnJhbWVsZXNzOiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2V0RnJhbWVsZXNzTWV0aG9kLCB7IGZyYW1lbGVzcyB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEaXNhYmxlcyB0aGUgc3lzdGVtIGZ1bGxzY3JlZW4gYnV0dG9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVuYWJsZWQgLSBXaGV0aGVyIHRoZSBmdWxsc2NyZWVuIGJ1dHRvbiBzaG91bGQgYmUgZW5hYmxlZC5cbiAgICAgKi9cbiAgICBTZXRGdWxsc2NyZWVuQnV0dG9uRW5hYmxlZChlbmFibGVkOiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2V0RnVsbHNjcmVlbkJ1dHRvbkVuYWJsZWRNZXRob2QsIHsgZW5hYmxlZCB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB3aWR0aCAtIFRoZSBkZXNpcmVkIG1heGltdW0gd2lkdGggb2YgdGhlIHdpbmRvdy5cbiAgICAgKiBAcGFyYW0gaGVpZ2h0IC0gVGhlIGRlc2lyZWQgbWF4aW11bSBoZWlnaHQgb2YgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBTZXRNYXhTaXplKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2V0TWF4U2l6ZU1ldGhvZCwgeyB3aWR0aCwgaGVpZ2h0IH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIG1pbmltdW0gc2l6ZSBvZiB0aGUgd2luZG93LlxuICAgICAqXG4gICAgICogQHBhcmFtIHdpZHRoIC0gVGhlIGRlc2lyZWQgbWluaW11bSB3aWR0aCBvZiB0aGUgd2luZG93LlxuICAgICAqIEBwYXJhbSBoZWlnaHQgLSBUaGUgZGVzaXJlZCBtaW5pbXVtIGhlaWdodCBvZiB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIFNldE1pblNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTZXRNaW5TaXplTWV0aG9kLCB7IHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcmVsYXRpdmUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdyB0byB0aGUgc2NyZWVuLlxuICAgICAqXG4gICAgICogQHBhcmFtIHggLSBUaGUgZGVzaXJlZCBob3Jpem9udGFsIHJlbGF0aXZlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuXG4gICAgICogQHBhcmFtIHkgLSBUaGUgZGVzaXJlZCB2ZXJ0aWNhbCByZWxhdGl2ZSBwb3NpdGlvbiBvZiB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIFNldFJlbGF0aXZlUG9zaXRpb24oeDogbnVtYmVyLCB5OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTZXRSZWxhdGl2ZVBvc2l0aW9uTWV0aG9kLCB7IHgsIHkgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgcmVzaXphYmxlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHJlc2l6YWJsZSAtIFdoZXRoZXIgdGhlIHdpbmRvdyBzaG91bGQgYmUgcmVzaXphYmxlLlxuICAgICAqL1xuICAgIFNldFJlc2l6YWJsZShyZXNpemFibGU6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTZXRSZXNpemFibGVNZXRob2QsIHsgcmVzaXphYmxlIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHNpemUgb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB3aWR0aCAtIFRoZSBkZXNpcmVkIHdpZHRoIG9mIHRoZSB3aW5kb3cuXG4gICAgICogQHBhcmFtIGhlaWdodCAtIFRoZSBkZXNpcmVkIGhlaWdodCBvZiB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIFNldFNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTZXRTaXplTWV0aG9kLCB7IHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgdGl0bGUgb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0aXRsZSAtIFRoZSBkZXNpcmVkIHRpdGxlIG9mIHRoZSB3aW5kb3cuXG4gICAgICovXG4gICAgU2V0VGl0bGUodGl0bGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldFRpdGxlTWV0aG9kLCB7IHRpdGxlIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHpvb20gbGV2ZWwgb2YgdGhlIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB6b29tIC0gVGhlIGRlc2lyZWQgem9vbSBsZXZlbC5cbiAgICAgKi9cbiAgICBTZXRab29tKHpvb206IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldFpvb21NZXRob2QsIHsgem9vbSB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIFNob3coKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2hvd01ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgd2luZG93LlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIFNpemUoKTogUHJvbWlzZTxTaXplPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2l6ZU1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyB0aGUgd2luZG93IGJldHdlZW4gZnVsbHNjcmVlbiBhbmQgbm9ybWFsLlxuICAgICAqL1xuICAgIFRvZ2dsZUZ1bGxzY3JlZW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oVG9nZ2xlRnVsbHNjcmVlbk1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyB0aGUgd2luZG93IGJldHdlZW4gbWF4aW1pc2VkIGFuZCBub3JtYWwuXG4gICAgICovXG4gICAgVG9nZ2xlTWF4aW1pc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oVG9nZ2xlTWF4aW1pc2VNZXRob2QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVuLWZ1bGxzY3JlZW5zIHRoZSB3aW5kb3cuXG4gICAgICovXG4gICAgVW5GdWxsc2NyZWVuKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFVuRnVsbHNjcmVlbk1ldGhvZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW4tbWF4aW1pc2VzIHRoZSB3aW5kb3cuXG4gICAgICovXG4gICAgVW5NYXhpbWlzZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShVbk1heGltaXNlTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVbi1taW5pbWlzZXMgdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBVbk1pbmltaXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFVuTWluaW1pc2VNZXRob2QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHdpZHRoIG9mIHRoZSB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3VycmVudCB3aWR0aCBvZiB0aGUgd2luZG93LlxuICAgICAqL1xuICAgIFdpZHRoKCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oV2lkdGhNZXRob2QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFpvb21zIHRoZSB3aW5kb3cuXG4gICAgICovXG4gICAgWm9vbSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShab29tTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbmNyZWFzZXMgdGhlIHpvb20gbGV2ZWwgb2YgdGhlIHdlYnZpZXcgY29udGVudC5cbiAgICAgKi9cbiAgICBab29tSW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oWm9vbUluTWV0aG9kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWNyZWFzZXMgdGhlIHpvb20gbGV2ZWwgb2YgdGhlIHdlYnZpZXcgY29udGVudC5cbiAgICAgKi9cbiAgICBab29tT3V0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFpvb21PdXRNZXRob2QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2V0cyB0aGUgem9vbSBsZXZlbCBvZiB0aGUgd2VidmlldyBjb250ZW50LlxuICAgICAqL1xuICAgIFpvb21SZXNldCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShab29tUmVzZXRNZXRob2QpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGUgd2luZG93IHdpdGhpbiB3aGljaCB0aGUgc2NyaXB0IGlzIHJ1bm5pbmcuXG4gKi9cbmNvbnN0IHRoaXNXaW5kb3cgPSBuZXcgV2luZG93KCcnKTtcblxuZXhwb3J0IGRlZmF1bHQgdGhpc1dpbmRvdztcbiIsICIvKlxuIF9cdCAgIF9fXHQgIF8gX19cbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuaW1wb3J0ICogYXMgUnVudGltZSBmcm9tIFwiLi4vQHdhaWxzaW8vcnVudGltZS9zcmNcIjtcblxuLy8gTk9URTogdGhlIGZvbGxvd2luZyBtZXRob2RzIE1VU1QgYmUgaW1wb3J0ZWQgZXhwbGljaXRseSBiZWNhdXNlIG9mIGhvdyBlc2J1aWxkIGluamVjdGlvbiB3b3Jrc1xuaW1wb3J0IHsgRW5hYmxlIGFzIEVuYWJsZVdNTCB9IGZyb20gXCIuLi9Ad2FpbHNpby9ydW50aW1lL3NyYy93bWxcIjtcbmltcG9ydCB7IGRlYnVnTG9nIH0gZnJvbSBcIi4uL0B3YWlsc2lvL3J1bnRpbWUvc3JjL3V0aWxzXCI7XG5cbndpbmRvdy53YWlscyA9IFJ1bnRpbWU7XG5FbmFibGVXTUwoKTtcblxuaWYgKERFQlVHKSB7XG4gICAgZGVidWdMb2coXCJXYWlscyBSdW50aW1lIExvYWRlZFwiKVxufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG5pbXBvcnQgeyBuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lcyB9IGZyb20gXCIuL3J1bnRpbWUuanNcIjtcblxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuU3lzdGVtKTtcblxuY29uc3QgU3lzdGVtSXNEYXJrTW9kZSA9IDA7XG5jb25zdCBTeXN0ZW1FbnZpcm9ubWVudCA9IDE7XG5cbmNvbnN0IF9pbnZva2UgPSAoZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICgod2luZG93IGFzIGFueSkuY2hyb21lPy53ZWJ2aWV3Py5wb3N0TWVzc2FnZSkge1xuICAgICAgICAgICAgcmV0dXJuICh3aW5kb3cgYXMgYW55KS5jaHJvbWUud2Vidmlldy5wb3N0TWVzc2FnZS5iaW5kKCh3aW5kb3cgYXMgYW55KS5jaHJvbWUud2Vidmlldyk7XG4gICAgICAgIH0gZWxzZSBpZiAoKHdpbmRvdyBhcyBhbnkpLndlYmtpdD8ubWVzc2FnZUhhbmRsZXJzPy5bJ2V4dGVybmFsJ10/LnBvc3RNZXNzYWdlKSB7XG4gICAgICAgICAgICByZXR1cm4gKHdpbmRvdyBhcyBhbnkpLndlYmtpdC5tZXNzYWdlSGFuZGxlcnNbJ2V4dGVybmFsJ10ucG9zdE1lc3NhZ2UuYmluZCgod2luZG93IGFzIGFueSkud2Via2l0Lm1lc3NhZ2VIYW5kbGVyc1snZXh0ZXJuYWwnXSk7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoKGUpIHt9XG5cbiAgICBjb25zb2xlLndhcm4oJ1xcbiVjXHUyNkEwXHVGRTBGIEJyb3dzZXIgRW52aXJvbm1lbnQgRGV0ZWN0ZWQgJWNcXG5cXG4lY09ubHkgVUkgcHJldmlld3MgYXJlIGF2YWlsYWJsZSBpbiB0aGUgYnJvd3Nlci4gRm9yIGZ1bGwgZnVuY3Rpb25hbGl0eSwgcGxlYXNlIHJ1biB0aGUgYXBwbGljYXRpb24gaW4gZGVza3RvcCBtb2RlLlxcbk1vcmUgaW5mb3JtYXRpb24gYXQ6IGh0dHBzOi8vdjMud2FpbHMuaW8vbGVhcm4vYnVpbGQvI3VzaW5nLWEtYnJvd3Nlci1mb3ItZGV2ZWxvcG1lbnRcXG4nLFxuICAgICAgICAnYmFja2dyb3VuZDogI2ZmZmZmZjsgY29sb3I6ICMwMDAwMDA7IGZvbnQtd2VpZ2h0OiBib2xkOyBwYWRkaW5nOiA0cHggOHB4OyBib3JkZXItcmFkaXVzOiA0cHg7IGJvcmRlcjogMnB4IHNvbGlkICMwMDAwMDA7JyxcbiAgICAgICAgJ2JhY2tncm91bmQ6IHRyYW5zcGFyZW50OycsXG4gICAgICAgICdjb2xvcjogI2ZmZmZmZjsgZm9udC1zdHlsZTogaXRhbGljOyBmb250LXdlaWdodDogYm9sZDsnKTtcbiAgICByZXR1cm4gbnVsbDtcbn0pKCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnZva2UobXNnOiBhbnkpOiB2b2lkIHtcbiAgICBfaW52b2tlPy4obXNnKTtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIHN5c3RlbSBkYXJrIG1vZGUgc3RhdHVzLlxuICpcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIGlmIHRoZSBzeXN0ZW0gaXMgaW4gZGFyayBtb2RlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gSXNEYXJrTW9kZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gY2FsbChTeXN0ZW1Jc0RhcmtNb2RlKTtcbn1cblxuLyoqXG4gKiBGZXRjaGVzIHRoZSBjYXBhYmlsaXRpZXMgb2YgdGhlIGFwcGxpY2F0aW9uIGZyb20gdGhlIHNlcnZlci5cbiAqXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgY2FwYWJpbGl0aWVzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gQ2FwYWJpbGl0aWVzKCk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGxldCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFwiL3dhaWxzL2NhcGFiaWxpdGllc1wiKTtcbiAgICBpZiAocmVzcG9uc2Uub2spIHtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjb3VsZCBub3QgZmV0Y2ggY2FwYWJpbGl0aWVzOiBcIiArIHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBPU0luZm8ge1xuICAgIC8qKiBUaGUgYnJhbmRpbmcgb2YgdGhlIE9TLiAqL1xuICAgIEJyYW5kaW5nOiBzdHJpbmc7XG4gICAgLyoqIFRoZSBJRCBvZiB0aGUgT1MuICovXG4gICAgSUQ6IHN0cmluZztcbiAgICAvKiogVGhlIG5hbWUgb2YgdGhlIE9TLiAqL1xuICAgIE5hbWU6IHN0cmluZztcbiAgICAvKiogVGhlIHZlcnNpb24gb2YgdGhlIE9TLiAqL1xuICAgIFZlcnNpb246IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFbnZpcm9ubWVudEluZm8ge1xuICAgIC8qKiBUaGUgYXJjaGl0ZWN0dXJlIG9mIHRoZSBzeXN0ZW0uICovXG4gICAgQXJjaDogc3RyaW5nO1xuICAgIC8qKiBUcnVlIGlmIHRoZSBhcHBsaWNhdGlvbiBpcyBydW5uaW5nIGluIGRlYnVnIG1vZGUsIG90aGVyd2lzZSBmYWxzZS4gKi9cbiAgICBEZWJ1ZzogYm9vbGVhbjtcbiAgICAvKiogVGhlIG9wZXJhdGluZyBzeXN0ZW0gaW4gdXNlLiAqL1xuICAgIE9TOiBzdHJpbmc7XG4gICAgLyoqIERldGFpbHMgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uICovXG4gICAgT1NJbmZvOiBPU0luZm87XG4gICAgLyoqIEFkZGl0aW9uYWwgcGxhdGZvcm0gaW5mb3JtYXRpb24uICovXG4gICAgUGxhdGZvcm1JbmZvOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyBlbnZpcm9ubWVudCBkZXRhaWxzLlxuICpcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIG9iamVjdCBjb250YWluaW5nIE9TIGFuZCBzeXN0ZW0gYXJjaGl0ZWN0dXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gRW52aXJvbm1lbnQoKTogUHJvbWlzZTxFbnZpcm9ubWVudEluZm8+IHtcbiAgICByZXR1cm4gY2FsbChTeXN0ZW1FbnZpcm9ubWVudCk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IG9wZXJhdGluZyBzeXN0ZW0gaXMgV2luZG93cy5cbiAqXG4gKiBAcmV0dXJuIFRydWUgaWYgdGhlIG9wZXJhdGluZyBzeXN0ZW0gaXMgV2luZG93cywgb3RoZXJ3aXNlIGZhbHNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gSXNXaW5kb3dzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB3aW5kb3cuX3dhaWxzLmVudmlyb25tZW50Lk9TID09PSBcIndpbmRvd3NcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgb3BlcmF0aW5nIHN5c3RlbSBpcyBMaW51eC5cbiAqXG4gKiBAcmV0dXJucyBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgb3BlcmF0aW5nIHN5c3RlbSBpcyBMaW51eCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gSXNMaW51eCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gd2luZG93Ll93YWlscy5lbnZpcm9ubWVudC5PUyA9PT0gXCJsaW51eFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBpcyBhIG1hY09TIG9wZXJhdGluZyBzeXN0ZW0uXG4gKlxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgbWFjT1MsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIElzTWFjKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB3aW5kb3cuX3dhaWxzLmVudmlyb25tZW50Lk9TID09PSBcImRhcndpblwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBhcmNoaXRlY3R1cmUgaXMgQU1ENjQuXG4gKlxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBhcmNoaXRlY3R1cmUgaXMgQU1ENjQsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIElzQU1ENjQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHdpbmRvdy5fd2FpbHMuZW52aXJvbm1lbnQuQXJjaCA9PT0gXCJhbWQ2NFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBhcmNoaXRlY3R1cmUgaXMgQVJNLlxuICpcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGN1cnJlbnQgYXJjaGl0ZWN0dXJlIGlzIEFSTSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gSXNBUk0oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHdpbmRvdy5fd2FpbHMuZW52aXJvbm1lbnQuQXJjaCA9PT0gXCJhcm1cIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgaXMgQVJNNjQgYXJjaGl0ZWN0dXJlLlxuICpcbiAqIEByZXR1cm5zIFJldHVybnMgdHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgQVJNNjQgYXJjaGl0ZWN0dXJlLCBvdGhlcndpc2UgcmV0dXJucyBmYWxzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIElzQVJNNjQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHdpbmRvdy5fd2FpbHMuZW52aXJvbm1lbnQuQXJjaCA9PT0gXCJhcm02NFwiO1xufVxuXG4vKipcbiAqIFJlcG9ydHMgd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIHJ1biBpbiBkZWJ1ZyBtb2RlLlxuICpcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGFwcCBpcyBiZWluZyBydW4gaW4gZGVidWcgbW9kZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIElzRGVidWcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEJvb2xlYW4od2luZG93Ll93YWlscy5lbnZpcm9ubWVudC5EZWJ1Zyk7XG59XG5cbiIsICIvKlxuIF9cdCAgIF9fXHQgIF8gX19cbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuaW1wb3J0IHsgbmV3UnVudGltZUNhbGxlciwgb2JqZWN0TmFtZXMgfSBmcm9tIFwiLi9ydW50aW1lLmpzXCI7XG5pbXBvcnQgeyBJc0RlYnVnIH0gZnJvbSBcIi4vc3lzdGVtLmpzXCI7XG5pbXBvcnQgeyBldmVudFRhcmdldCB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbi8vIHNldHVwXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBjb250ZXh0TWVudUhhbmRsZXIpO1xuXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcihvYmplY3ROYW1lcy5Db250ZXh0TWVudSk7XG5cbmNvbnN0IENvbnRleHRNZW51T3BlbiA9IDA7XG5cbmZ1bmN0aW9uIG9wZW5Db250ZXh0TWVudShpZDogc3RyaW5nLCB4OiBudW1iZXIsIHk6IG51bWJlciwgZGF0YTogYW55KTogdm9pZCB7XG4gICAgdm9pZCBjYWxsKENvbnRleHRNZW51T3Blbiwge2lkLCB4LCB5LCBkYXRhfSk7XG59XG5cbmZ1bmN0aW9uIGNvbnRleHRNZW51SGFuZGxlcihldmVudDogTW91c2VFdmVudCkge1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50VGFyZ2V0KGV2ZW50KTtcblxuICAgIC8vIENoZWNrIGZvciBjdXN0b20gY29udGV4dCBtZW51XG4gICAgY29uc3QgY3VzdG9tQ29udGV4dE1lbnUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpLmdldFByb3BlcnR5VmFsdWUoXCItLWN1c3RvbS1jb250ZXh0bWVudVwiKS50cmltKCk7XG5cbiAgICBpZiAoY3VzdG9tQ29udGV4dE1lbnUpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRhcmdldCkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY3VzdG9tLWNvbnRleHRtZW51LWRhdGFcIik7XG4gICAgICAgIG9wZW5Db250ZXh0TWVudShjdXN0b21Db250ZXh0TWVudSwgZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgZGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcHJvY2Vzc0RlZmF1bHRDb250ZXh0TWVudShldmVudCwgdGFyZ2V0KTtcbiAgICB9XG59XG5cblxuLypcbi0tZGVmYXVsdC1jb250ZXh0bWVudTogYXV0bzsgKGRlZmF1bHQpIHdpbGwgc2hvdyB0aGUgZGVmYXVsdCBjb250ZXh0IG1lbnUgaWYgY29udGVudEVkaXRhYmxlIGlzIHRydWUgT1IgdGV4dCBoYXMgYmVlbiBzZWxlY3RlZCBPUiBlbGVtZW50IGlzIGlucHV0IG9yIHRleHRhcmVhXG4tLWRlZmF1bHQtY29udGV4dG1lbnU6IHNob3c7IHdpbGwgYWx3YXlzIHNob3cgdGhlIGRlZmF1bHQgY29udGV4dCBtZW51XG4tLWRlZmF1bHQtY29udGV4dG1lbnU6IGhpZGU7IHdpbGwgYWx3YXlzIGhpZGUgdGhlIGRlZmF1bHQgY29udGV4dCBtZW51XG5cblRoaXMgcnVsZSBpcyBpbmhlcml0ZWQgbGlrZSBub3JtYWwgQ1NTIHJ1bGVzLCBzbyBuZXN0aW5nIHdvcmtzIGFzIGV4cGVjdGVkXG4qL1xuZnVuY3Rpb24gcHJvY2Vzc0RlZmF1bHRDb250ZXh0TWVudShldmVudDogTW91c2VFdmVudCwgdGFyZ2V0OiBIVE1MRWxlbWVudCkge1xuICAgIC8vIERlYnVnIGJ1aWxkcyBhbHdheXMgc2hvdyB0aGUgbWVudVxuICAgIGlmIChJc0RlYnVnKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFByb2Nlc3MgZGVmYXVsdCBjb250ZXh0IG1lbnVcbiAgICBzd2l0Y2ggKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRhcmdldCkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tZGVmYXVsdC1jb250ZXh0bWVudVwiKS50cmltKCkpIHtcbiAgICAgICAgY2FzZSAnc2hvdyc6XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNhc2UgJ2hpZGUnOlxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZVxuICAgIGlmICh0YXJnZXQuaXNDb250ZW50RWRpdGFibGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRleHQgaGFzIGJlZW4gc2VsZWN0ZWRcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgY29uc3QgaGFzU2VsZWN0aW9uID0gc2VsZWN0aW9uICYmIHNlbGVjdGlvbi50b1N0cmluZygpLmxlbmd0aCA+IDA7XG4gICAgaWYgKGhhc1NlbGVjdGlvbikge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGVjdGlvbi5yYW5nZUNvdW50OyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoaSk7XG4gICAgICAgICAgICBjb25zdCByZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IHJlY3RzW2pdO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KHJlY3QubGVmdCwgcmVjdC50b3ApID09PSB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRhZyBpcyBpbnB1dCBvciB0ZXh0YXJlYS5cbiAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fCB0YXJnZXQgaW5zdGFuY2VvZiBIVE1MVGV4dEFyZWFFbGVtZW50KSB7XG4gICAgICAgIGlmIChoYXNTZWxlY3Rpb24gfHwgKCF0YXJnZXQucmVhZE9ubHkgJiYgIXRhcmdldC5kaXNhYmxlZCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGhpZGUgZGVmYXVsdCBjb250ZXh0IG1lbnVcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGZyb20gdGhlIGZsYWcgbWFwLlxuICpcbiAqIEBwYXJhbSBrZXkgLSBUaGUga2V5IHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmb3IuXG4gKiBAcmV0dXJuIFRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHZXRGbGFnKGtleTogc3RyaW5nKTogYW55IHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gd2luZG93Ll93YWlscy5mbGFnc1trZXldO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5hYmxlIHRvIHJldHJpZXZlIGZsYWcgJ1wiICsga2V5ICsgXCInOiBcIiArIGUsIHsgY2F1c2U6IGUgfSk7XG4gICAgfVxufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG5pbXBvcnQgeyBpbnZva2UsIElzV2luZG93cyB9IGZyb20gXCIuL3N5c3RlbS5qc1wiO1xuaW1wb3J0IHsgR2V0RmxhZyB9IGZyb20gXCIuL2ZsYWdzLmpzXCI7XG5pbXBvcnQgeyBjYW5UcmFja0J1dHRvbnMsIGV2ZW50VGFyZ2V0IH0gZnJvbSBcIi4vdXRpbHMuanNcIjtcblxuLy8gU2V0dXBcbmxldCBjYW5EcmFnID0gZmFsc2U7XG5sZXQgZHJhZ2dpbmcgPSBmYWxzZTtcblxubGV0IHJlc2l6YWJsZSA9IGZhbHNlO1xubGV0IGNhblJlc2l6ZSA9IGZhbHNlO1xubGV0IHJlc2l6aW5nID0gZmFsc2U7XG5sZXQgcmVzaXplRWRnZTogc3RyaW5nID0gXCJcIjtcbmxldCBkZWZhdWx0Q3Vyc29yID0gXCJhdXRvXCI7XG5cbmxldCBidXR0b25zID0gMDtcbmNvbnN0IGJ1dHRvbnNUcmFja2VkID0gY2FuVHJhY2tCdXR0b25zKCk7XG5cbndpbmRvdy5fd2FpbHMgPSB3aW5kb3cuX3dhaWxzIHx8IHt9O1xud2luZG93Ll93YWlscy5zZXRSZXNpemFibGUgPSAodmFsdWU6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICByZXNpemFibGUgPSB2YWx1ZTtcbiAgICBpZiAoIXJlc2l6YWJsZSkge1xuICAgICAgICAvLyBTdG9wIHJlc2l6aW5nIGlmIGluIHByb2dyZXNzLlxuICAgICAgICBjYW5SZXNpemUgPSByZXNpemluZyA9IGZhbHNlO1xuICAgICAgICBzZXRSZXNpemUoKTtcbiAgICB9XG59O1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdXBkYXRlLCB7IGNhcHR1cmU6IHRydWUgfSk7XG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdXBkYXRlLCB7IGNhcHR1cmU6IHRydWUgfSk7XG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHVwZGF0ZSwgeyBjYXB0dXJlOiB0cnVlIH0pO1xuZm9yIChjb25zdCBldiBvZiBbJ2NsaWNrJywgJ2NvbnRleHRtZW51JywgJ2RibGNsaWNrJ10pIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihldiwgc3VwcHJlc3NFdmVudCwgeyBjYXB0dXJlOiB0cnVlIH0pO1xufVxuXG5mdW5jdGlvbiBzdXBwcmVzc0V2ZW50KGV2ZW50OiBFdmVudCkge1xuICAgIC8vIFN1cHByZXNzIGNsaWNrIGV2ZW50cyB3aGlsZSByZXNpemluZyBvciBkcmFnZ2luZy5cbiAgICBpZiAoZHJhZ2dpbmcgfHwgcmVzaXppbmcpIHtcbiAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn1cblxuLy8gVXNlIGNvbnN0YW50cyB0byBhdm9pZCBjb21wYXJpbmcgc3RyaW5ncyBtdWx0aXBsZSB0aW1lcy5cbmNvbnN0IE1vdXNlRG93biA9IDA7XG5jb25zdCBNb3VzZVVwICAgPSAxO1xuY29uc3QgTW91c2VNb3ZlID0gMjtcblxuZnVuY3Rpb24gdXBkYXRlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgLy8gV2luZG93cyBzdXBwcmVzc2VzIG1vdXNlIGV2ZW50cyBhdCB0aGUgZW5kIG9mIGRyYWdnaW5nIG9yIHJlc2l6aW5nLFxuICAgIC8vIHNvIHdlIG5lZWQgdG8gYmUgc21hcnQgYW5kIHN5bnRoZXNpemUgYnV0dG9uIGV2ZW50cy5cblxuICAgIGxldCBldmVudFR5cGU6IG51bWJlciwgZXZlbnRCdXR0b25zID0gZXZlbnQuYnV0dG9ucztcbiAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgY2FzZSAnbW91c2Vkb3duJzpcbiAgICAgICAgICAgIGV2ZW50VHlwZSA9IE1vdXNlRG93bjtcbiAgICAgICAgICAgIGlmICghYnV0dG9uc1RyYWNrZWQpIHsgZXZlbnRCdXR0b25zID0gYnV0dG9ucyB8ICgxIDw8IGV2ZW50LmJ1dHRvbik7IH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdtb3VzZXVwJzpcbiAgICAgICAgICAgIGV2ZW50VHlwZSA9IE1vdXNlVXA7XG4gICAgICAgICAgICBpZiAoIWJ1dHRvbnNUcmFja2VkKSB7IGV2ZW50QnV0dG9ucyA9IGJ1dHRvbnMgJiB+KDEgPDwgZXZlbnQuYnV0dG9uKTsgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBldmVudFR5cGUgPSBNb3VzZU1vdmU7XG4gICAgICAgICAgICBpZiAoIWJ1dHRvbnNUcmFja2VkKSB7IGV2ZW50QnV0dG9ucyA9IGJ1dHRvbnM7IH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGxldCByZWxlYXNlZCA9IGJ1dHRvbnMgJiB+ZXZlbnRCdXR0b25zO1xuICAgIGxldCBwcmVzc2VkID0gZXZlbnRCdXR0b25zICYgfmJ1dHRvbnM7XG5cbiAgICBidXR0b25zID0gZXZlbnRCdXR0b25zO1xuXG4gICAgLy8gU3ludGhlc2l6ZSBhIHJlbGVhc2UtcHJlc3Mgc2VxdWVuY2UgaWYgd2UgZGV0ZWN0IGEgcHJlc3Mgb2YgYW4gYWxyZWFkeSBwcmVzc2VkIGJ1dHRvbi5cbiAgICBpZiAoZXZlbnRUeXBlID09PSBNb3VzZURvd24gJiYgIShwcmVzc2VkICYgZXZlbnQuYnV0dG9uKSkge1xuICAgICAgICByZWxlYXNlZCB8PSAoMSA8PCBldmVudC5idXR0b24pO1xuICAgICAgICBwcmVzc2VkIHw9ICgxIDw8IGV2ZW50LmJ1dHRvbik7XG4gICAgfVxuXG4gICAgLy8gU3VwcHJlc3MgYWxsIGJ1dHRvbiBldmVudHMgZHVyaW5nIGRyYWdnaW5nIGFuZCByZXNpemluZyxcbiAgICAvLyB1bmxlc3MgdGhpcyBpcyBhIG1vdXNldXAgZXZlbnQgdGhhdCBpcyBlbmRpbmcgYSBkcmFnIGFjdGlvbi5cbiAgICBpZiAoXG4gICAgICAgIGV2ZW50VHlwZSAhPT0gTW91c2VNb3ZlIC8vIEZhc3QgcGF0aCBmb3IgbW91c2Vtb3ZlXG4gICAgICAgICYmIHJlc2l6aW5nXG4gICAgICAgIHx8IChcbiAgICAgICAgICAgIGRyYWdnaW5nXG4gICAgICAgICAgICAmJiAoXG4gICAgICAgICAgICAgICAgZXZlbnRUeXBlID09PSBNb3VzZURvd25cbiAgICAgICAgICAgICAgICB8fCBldmVudC5idXR0b24gIT09IDBcbiAgICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICkge1xuICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHJlbGVhc2VzXG4gICAgaWYgKHJlbGVhc2VkICYgMSkgeyBwcmltYXJ5VXAoZXZlbnQpOyB9XG4gICAgLy8gSGFuZGxlIHByZXNzZXNcbiAgICBpZiAocHJlc3NlZCAmIDEpIHsgcHJpbWFyeURvd24oZXZlbnQpOyB9XG5cbiAgICAvLyBIYW5kbGUgbW91c2Vtb3ZlXG4gICAgaWYgKGV2ZW50VHlwZSA9PT0gTW91c2VNb3ZlKSB7IG9uTW91c2VNb3ZlKGV2ZW50KTsgfTtcbn1cblxuZnVuY3Rpb24gcHJpbWFyeURvd24oZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBSZXNldCByZWFkaW5lc3Mgc3RhdGUuXG4gICAgY2FuRHJhZyA9IGZhbHNlO1xuICAgIGNhblJlc2l6ZSA9IGZhbHNlO1xuXG4gICAgLy8gSWdub3JlIHJlcGVhdGVkIGNsaWNrcyBvbiBtYWNPUyBhbmQgTGludXguXG4gICAgaWYgKCFJc1dpbmRvd3MoKSkge1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicgJiYgZXZlbnQuYnV0dG9uID09PSAwICYmIGV2ZW50LmRldGFpbCAhPT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlc2l6ZUVkZ2UpIHtcbiAgICAgICAgLy8gUmVhZHkgdG8gcmVzaXplIGlmIHRoZSBwcmltYXJ5IGJ1dHRvbiB3YXMgcHJlc3NlZCBmb3IgdGhlIGZpcnN0IHRpbWUuXG4gICAgICAgIGNhblJlc2l6ZSA9IHRydWU7XG4gICAgICAgIC8vIERvIG5vdCBzdGFydCBkcmFnIG9wZXJhdGlvbnMgd2hlbiBvbiByZXNpemUgZWRnZXMuXG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBSZXRyaWV2ZSB0YXJnZXQgZWxlbWVudFxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50VGFyZ2V0KGV2ZW50KTtcblxuICAgIC8vIFJlYWR5IHRvIGRyYWcgaWYgdGhlIHByaW1hcnkgYnV0dG9uIHdhcyBwcmVzc2VkIGZvciB0aGUgZmlyc3QgdGltZSBvbiBhIGRyYWdnYWJsZSBlbGVtZW50LlxuICAgIC8vIElnbm9yZSBjbGlja3Mgb24gdGhlIHNjcm9sbGJhci5cbiAgICBjb25zdCBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRhcmdldCk7XG4gICAgY2FuRHJhZyA9IChcbiAgICAgICAgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0td2FpbHMtZHJhZ2dhYmxlXCIpLnRyaW0oKSA9PT0gXCJkcmFnXCJcbiAgICAgICAgJiYgKFxuICAgICAgICAgICAgZXZlbnQub2Zmc2V0WCAtIHBhcnNlRmxvYXQoc3R5bGUucGFkZGluZ0xlZnQpIDwgdGFyZ2V0LmNsaWVudFdpZHRoXG4gICAgICAgICAgICAmJiBldmVudC5vZmZzZXRZIC0gcGFyc2VGbG9hdChzdHlsZS5wYWRkaW5nVG9wKSA8IHRhcmdldC5jbGllbnRIZWlnaHRcbiAgICAgICAgKVxuICAgICk7XG59XG5cbmZ1bmN0aW9uIHByaW1hcnlVcChldmVudDogTW91c2VFdmVudCkge1xuICAgIC8vIFN0b3AgZHJhZ2dpbmcgYW5kIHJlc2l6aW5nLlxuICAgIGNhbkRyYWcgPSBmYWxzZTtcbiAgICBkcmFnZ2luZyA9IGZhbHNlO1xuICAgIGNhblJlc2l6ZSA9IGZhbHNlO1xuICAgIHJlc2l6aW5nID0gZmFsc2U7XG59XG5cbmNvbnN0IGN1cnNvckZvckVkZ2UgPSBPYmplY3QuZnJlZXplKHtcbiAgICBcInNlLXJlc2l6ZVwiOiBcIm53c2UtcmVzaXplXCIsXG4gICAgXCJzdy1yZXNpemVcIjogXCJuZXN3LXJlc2l6ZVwiLFxuICAgIFwibnctcmVzaXplXCI6IFwibndzZS1yZXNpemVcIixcbiAgICBcIm5lLXJlc2l6ZVwiOiBcIm5lc3ctcmVzaXplXCIsXG4gICAgXCJ3LXJlc2l6ZVwiOiBcImV3LXJlc2l6ZVwiLFxuICAgIFwibi1yZXNpemVcIjogXCJucy1yZXNpemVcIixcbiAgICBcInMtcmVzaXplXCI6IFwibnMtcmVzaXplXCIsXG4gICAgXCJlLXJlc2l6ZVwiOiBcImV3LXJlc2l6ZVwiLFxufSlcblxuZnVuY3Rpb24gc2V0UmVzaXplKGVkZ2U/OiBrZXlvZiB0eXBlb2YgY3Vyc29yRm9yRWRnZSk6IHZvaWQge1xuICAgIGlmIChlZGdlKSB7XG4gICAgICAgIGlmICghcmVzaXplRWRnZSkgeyBkZWZhdWx0Q3Vyc29yID0gZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3I7IH1cbiAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSBjdXJzb3JGb3JFZGdlW2VkZ2VdO1xuICAgIH0gZWxzZSBpZiAoIWVkZ2UgJiYgcmVzaXplRWRnZSkge1xuICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9IGRlZmF1bHRDdXJzb3I7XG4gICAgfVxuXG4gICAgcmVzaXplRWRnZSA9IGVkZ2UgfHwgXCJcIjtcbn1cblxuZnVuY3Rpb24gb25Nb3VzZU1vdmUoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoY2FuUmVzaXplICYmIHJlc2l6ZUVkZ2UpIHtcbiAgICAgICAgLy8gU3RhcnQgcmVzaXppbmcuXG4gICAgICAgIHJlc2l6aW5nID0gdHJ1ZTtcbiAgICAgICAgaW52b2tlKFwid2FpbHM6cmVzaXplOlwiICsgcmVzaXplRWRnZSk7XG4gICAgfSBlbHNlIGlmIChjYW5EcmFnKSB7XG4gICAgICAgIC8vIFN0YXJ0IGRyYWdnaW5nLlxuICAgICAgICBkcmFnZ2luZyA9IHRydWU7XG4gICAgICAgIGludm9rZShcIndhaWxzOmRyYWdcIik7XG4gICAgfVxuXG4gICAgaWYgKGRyYWdnaW5nIHx8IHJlc2l6aW5nKSB7XG4gICAgICAgIC8vIEVpdGhlciBkcmFnIG9yIHJlc2l6ZSBpcyBvbmdvaW5nLFxuICAgICAgICAvLyByZXNldCByZWFkaW5lc3MgYW5kIHN0b3AgcHJvY2Vzc2luZy5cbiAgICAgICAgY2FuRHJhZyA9IGNhblJlc2l6ZSA9IGZhbHNlO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFyZXNpemFibGUgfHwgIUlzV2luZG93cygpKSB7XG4gICAgICAgIGlmIChyZXNpemVFZGdlKSB7IHNldFJlc2l6ZSgpOyB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXNpemVIYW5kbGVIZWlnaHQgPSBHZXRGbGFnKFwic3lzdGVtLnJlc2l6ZUhhbmRsZUhlaWdodFwiKSB8fCA1O1xuICAgIGNvbnN0IHJlc2l6ZUhhbmRsZVdpZHRoID0gR2V0RmxhZyhcInN5c3RlbS5yZXNpemVIYW5kbGVXaWR0aFwiKSB8fCA1O1xuXG4gICAgLy8gRXh0cmEgcGl4ZWxzIGZvciB0aGUgY29ybmVyIGFyZWFzLlxuICAgIGNvbnN0IGNvcm5lckV4dHJhID0gR2V0RmxhZyhcInJlc2l6ZUNvcm5lckV4dHJhXCIpIHx8IDEwO1xuXG4gICAgY29uc3QgcmlnaHRCb3JkZXIgPSAod2luZG93Lm91dGVyV2lkdGggLSBldmVudC5jbGllbnRYKSA8IHJlc2l6ZUhhbmRsZVdpZHRoO1xuICAgIGNvbnN0IGxlZnRCb3JkZXIgPSBldmVudC5jbGllbnRYIDwgcmVzaXplSGFuZGxlV2lkdGg7XG4gICAgY29uc3QgdG9wQm9yZGVyID0gZXZlbnQuY2xpZW50WSA8IHJlc2l6ZUhhbmRsZUhlaWdodDtcbiAgICBjb25zdCBib3R0b21Cb3JkZXIgPSAod2luZG93Lm91dGVySGVpZ2h0IC0gZXZlbnQuY2xpZW50WSkgPCByZXNpemVIYW5kbGVIZWlnaHQ7XG5cbiAgICAvLyBBZGp1c3QgZm9yIGNvcm5lciBhcmVhcy5cbiAgICBjb25zdCByaWdodENvcm5lciA9ICh3aW5kb3cub3V0ZXJXaWR0aCAtIGV2ZW50LmNsaWVudFgpIDwgKHJlc2l6ZUhhbmRsZVdpZHRoICsgY29ybmVyRXh0cmEpO1xuICAgIGNvbnN0IGxlZnRDb3JuZXIgPSBldmVudC5jbGllbnRYIDwgKHJlc2l6ZUhhbmRsZVdpZHRoICsgY29ybmVyRXh0cmEpO1xuICAgIGNvbnN0IHRvcENvcm5lciA9IGV2ZW50LmNsaWVudFkgPCAocmVzaXplSGFuZGxlSGVpZ2h0ICsgY29ybmVyRXh0cmEpO1xuICAgIGNvbnN0IGJvdHRvbUNvcm5lciA9ICh3aW5kb3cub3V0ZXJIZWlnaHQgLSBldmVudC5jbGllbnRZKSA8IChyZXNpemVIYW5kbGVIZWlnaHQgKyBjb3JuZXJFeHRyYSk7XG5cbiAgICBpZiAoIWxlZnRDb3JuZXIgJiYgIXRvcENvcm5lciAmJiAhYm90dG9tQ29ybmVyICYmICFyaWdodENvcm5lcikge1xuICAgICAgICAvLyBPcHRpbWlzYXRpb246IG91dCBvZiBhbGwgY29ybmVyIGFyZWFzIGltcGxpZXMgb3V0IG9mIGJvcmRlcnMuXG4gICAgICAgIHNldFJlc2l6ZSgpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgY29ybmVycy5cbiAgICBlbHNlIGlmIChyaWdodENvcm5lciAmJiBib3R0b21Db3JuZXIpIHNldFJlc2l6ZShcInNlLXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChsZWZ0Q29ybmVyICYmIGJvdHRvbUNvcm5lcikgc2V0UmVzaXplKFwic3ctcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKGxlZnRDb3JuZXIgJiYgdG9wQ29ybmVyKSBzZXRSZXNpemUoXCJudy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAodG9wQ29ybmVyICYmIHJpZ2h0Q29ybmVyKSBzZXRSZXNpemUoXCJuZS1yZXNpemVcIik7XG4gICAgLy8gRGV0ZWN0IGJvcmRlcnMuXG4gICAgZWxzZSBpZiAobGVmdEJvcmRlcikgc2V0UmVzaXplKFwidy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAodG9wQm9yZGVyKSBzZXRSZXNpemUoXCJuLXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInMtcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKHJpZ2h0Qm9yZGVyKSBzZXRSZXNpemUoXCJlLXJlc2l6ZVwiKTtcbiAgICAvLyBPdXQgb2YgYm9yZGVyIGFyZWEuXG4gICAgZWxzZSBzZXRSZXNpemUoKTtcbn1cbiIsICIvKlxuIF9cdCAgIF9fXHQgIF8gX19cbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuaW1wb3J0IHsgbmV3UnVudGltZUNhbGxlciwgb2JqZWN0TmFtZXMgfSBmcm9tIFwiLi9ydW50aW1lLmpzXCI7XG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcihvYmplY3ROYW1lcy5BcHBsaWNhdGlvbik7XG5cbmNvbnN0IEhpZGVNZXRob2QgPSAwO1xuY29uc3QgU2hvd01ldGhvZCA9IDE7XG5jb25zdCBRdWl0TWV0aG9kID0gMjtcblxuLyoqXG4gKiBIaWRlcyBhIGNlcnRhaW4gbWV0aG9kIGJ5IGNhbGxpbmcgdGhlIEhpZGVNZXRob2QgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBIaWRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBjYWxsKEhpZGVNZXRob2QpO1xufVxuXG4vKipcbiAqIENhbGxzIHRoZSBTaG93TWV0aG9kIGFuZCByZXR1cm5zIHRoZSByZXN1bHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTaG93KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBjYWxsKFNob3dNZXRob2QpO1xufVxuXG4vKipcbiAqIENhbGxzIHRoZSBRdWl0TWV0aG9kIHRvIHRlcm1pbmF0ZSB0aGUgcHJvZ3JhbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFF1aXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGNhbGwoUXVpdE1ldGhvZCk7XG59XG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbmltcG9ydCB7IENhbmNlbGxhYmxlUHJvbWlzZSwgdHlwZSBDYW5jZWxsYWJsZVByb21pc2VXaXRoUmVzb2x2ZXJzIH0gZnJvbSBcIi4vY2FuY2VsbGFibGUuanNcIjtcbmltcG9ydCB7IG5ld1J1bnRpbWVDYWxsZXIsIG9iamVjdE5hbWVzIH0gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSBcIi4vbmFub2lkLmpzXCI7XG5cbi8vIFNldHVwXG53aW5kb3cuX3dhaWxzID0gd2luZG93Ll93YWlscyB8fCB7fTtcbndpbmRvdy5fd2FpbHMuY2FsbFJlc3VsdEhhbmRsZXIgPSByZXN1bHRIYW5kbGVyO1xud2luZG93Ll93YWlscy5jYWxsRXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuXG50eXBlIFByb21pc2VSZXNvbHZlcnMgPSBPbWl0PENhbmNlbGxhYmxlUHJvbWlzZVdpdGhSZXNvbHZlcnM8YW55PiwgXCJwcm9taXNlXCIgfCBcIm9uY2FuY2VsbGVkXCI+XG5cbmNvbnN0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyKG9iamVjdE5hbWVzLkNhbGwpO1xuY29uc3QgY2FuY2VsQ2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuQ2FuY2VsQ2FsbCk7XG5jb25zdCBjYWxsUmVzcG9uc2VzID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2VSZXNvbHZlcnM+KCk7XG5cbmNvbnN0IENhbGxCaW5kaW5nID0gMDtcbmNvbnN0IENhbmNlbE1ldGhvZCA9IDBcblxuLyoqXG4gKiBIb2xkcyBhbGwgcmVxdWlyZWQgaW5mb3JtYXRpb24gZm9yIGEgYmluZGluZyBjYWxsLlxuICogTWF5IHByb3ZpZGUgZWl0aGVyIGEgbWV0aG9kIElEIG9yIGEgbWV0aG9kIG5hbWUsIGJ1dCBub3QgYm90aC5cbiAqL1xuZXhwb3J0IHR5cGUgQ2FsbE9wdGlvbnMgPSB7XG4gICAgLyoqIFRoZSBudW1lcmljIElEIG9mIHRoZSBib3VuZCBtZXRob2QgdG8gY2FsbC4gKi9cbiAgICBtZXRob2RJRDogbnVtYmVyO1xuICAgIC8qKiBUaGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGJvdW5kIG1ldGhvZCB0byBjYWxsLiAqL1xuICAgIG1ldGhvZE5hbWU/OiBuZXZlcjtcbiAgICAvKiogQXJndW1lbnRzIHRvIGJlIHBhc3NlZCBpbnRvIHRoZSBib3VuZCBtZXRob2QuICovXG4gICAgYXJnczogYW55W107XG59IHwge1xuICAgIC8qKiBUaGUgbnVtZXJpYyBJRCBvZiB0aGUgYm91bmQgbWV0aG9kIHRvIGNhbGwuICovXG4gICAgbWV0aG9kSUQ/OiBuZXZlcjtcbiAgICAvKiogVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBib3VuZCBtZXRob2QgdG8gY2FsbC4gKi9cbiAgICBtZXRob2ROYW1lOiBzdHJpbmc7XG4gICAgLyoqIEFyZ3VtZW50cyB0byBiZSBwYXNzZWQgaW50byB0aGUgYm91bmQgbWV0aG9kLiAqL1xuICAgIGFyZ3M6IGFueVtdO1xufTtcblxuLyoqXG4gKiBFeGNlcHRpb24gY2xhc3MgdGhhdCB3aWxsIGJlIHRocm93biBpbiBjYXNlIHRoZSBib3VuZCBtZXRob2QgcmV0dXJucyBhbiBlcnJvci5cbiAqIFRoZSB2YWx1ZSBvZiB0aGUge0BsaW5rIFJ1bnRpbWVFcnJvciNuYW1lfSBwcm9wZXJ0eSBpcyBcIlJ1bnRpbWVFcnJvclwiLlxuICovXG5leHBvcnQgY2xhc3MgUnVudGltZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgUnVudGltZUVycm9yIGluc3RhbmNlLlxuICAgICAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIGVycm9yIG1lc3NhZ2UuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25zIHRvIGJlIGZvcndhcmRlZCB0byB0aGUgRXJyb3IgY29uc3RydWN0b3IuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobWVzc2FnZT86IHN0cmluZywgb3B0aW9ucz86IEVycm9yT3B0aW9ucykge1xuICAgICAgICBzdXBlcihtZXNzYWdlLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJSdW50aW1lRXJyb3JcIjtcbiAgICB9XG59XG5cbi8qKlxuICogSGFuZGxlcyB0aGUgcmVzdWx0IG9mIGEgY2FsbCByZXF1ZXN0LlxuICpcbiAqIEBwYXJhbSBpZCAtIFRoZSBpZCBvZiB0aGUgcmVxdWVzdCB0byBoYW5kbGUgdGhlIHJlc3VsdCBmb3IuXG4gKiBAcGFyYW0gZGF0YSAtIFRoZSByZXN1bHQgZGF0YSBvZiB0aGUgcmVxdWVzdC5cbiAqIEBwYXJhbSBpc0pTT04gLSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZGF0YSBpcyBKU09OIG9yIG5vdC5cbiAqL1xuZnVuY3Rpb24gcmVzdWx0SGFuZGxlcihpZDogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGlzSlNPTjogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHJlc29sdmVycyA9IGdldEFuZERlbGV0ZVJlc3BvbnNlKGlkKTtcbiAgICBpZiAoIXJlc29sdmVycykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFkYXRhKSB7XG4gICAgICAgIHJlc29sdmVycy5yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgfSBlbHNlIGlmICghaXNKU09OKSB7XG4gICAgICAgIHJlc29sdmVycy5yZXNvbHZlKGRhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNvbHZlcnMucmVzb2x2ZShKU09OLnBhcnNlKGRhdGEpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICAgIHJlc29sdmVycy5yZWplY3QobmV3IFR5cGVFcnJvcihcImNvdWxkIG5vdCBwYXJzZSByZXN1bHQ6IFwiICsgZXJyLm1lc3NhZ2UsIHsgY2F1c2U6IGVyciB9KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogSGFuZGxlcyB0aGUgZXJyb3IgZnJvbSBhIGNhbGwgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gaWQgLSBUaGUgaWQgb2YgdGhlIHByb21pc2UgaGFuZGxlci5cbiAqIEBwYXJhbSBkYXRhIC0gVGhlIGVycm9yIGRhdGEgdG8gcmVqZWN0IHRoZSBwcm9taXNlIGhhbmRsZXIgd2l0aC5cbiAqIEBwYXJhbSBpc0pTT04gLSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZGF0YSBpcyBKU09OIG9yIG5vdC5cbiAqL1xuZnVuY3Rpb24gZXJyb3JIYW5kbGVyKGlkOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgaXNKU09OOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgcmVzb2x2ZXJzID0gZ2V0QW5kRGVsZXRlUmVzcG9uc2UoaWQpO1xuICAgIGlmICghcmVzb2x2ZXJzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlzSlNPTikge1xuICAgICAgICByZXNvbHZlcnMucmVqZWN0KG5ldyBFcnJvcihkYXRhKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IGVycm9yOiBhbnk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBlcnJvciA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICByZXNvbHZlcnMucmVqZWN0KG5ldyBUeXBlRXJyb3IoXCJjb3VsZCBub3QgcGFyc2UgZXJyb3I6IFwiICsgZXJyLm1lc3NhZ2UsIHsgY2F1c2U6IGVyciB9KSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgb3B0aW9uczogRXJyb3JPcHRpb25zID0ge307XG4gICAgICAgIGlmIChlcnJvci5jYXVzZSkge1xuICAgICAgICAgICAgb3B0aW9ucy5jYXVzZSA9IGVycm9yLmNhdXNlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGV4Y2VwdGlvbjtcbiAgICAgICAgc3dpdGNoIChlcnJvci5raW5kKSB7XG4gICAgICAgICAgICBjYXNlIFwiUmVmZXJlbmNlRXJyb3JcIjpcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBuZXcgUmVmZXJlbmNlRXJyb3IoZXJyb3IubWVzc2FnZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiVHlwZUVycm9yXCI6XG4gICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gbmV3IFR5cGVFcnJvcihlcnJvci5tZXNzYWdlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJSdW50aW1lRXJyb3JcIjpcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBuZXcgUnVudGltZUVycm9yKGVycm9yLm1lc3NhZ2UsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBuZXcgRXJyb3IoZXJyb3IubWVzc2FnZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXNvbHZlcnMucmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgfVxufVxuXG4vKipcbiAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgcmVzcG9uc2UgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBJRCBmcm9tIHRoZSBjYWxsUmVzcG9uc2VzIG1hcC5cbiAqXG4gKiBAcGFyYW0gaWQgLSBUaGUgSUQgb2YgdGhlIHJlc3BvbnNlIHRvIGJlIHJldHJpZXZlZCBhbmQgcmVtb3ZlZC5cbiAqIEByZXR1cm5zIFRoZSByZXNwb25zZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBJRCwgaWYgYW55LlxuICovXG5mdW5jdGlvbiBnZXRBbmREZWxldGVSZXNwb25zZShpZDogc3RyaW5nKTogUHJvbWlzZVJlc29sdmVycyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBjYWxsUmVzcG9uc2VzLmdldChpZCk7XG4gICAgY2FsbFJlc3BvbnNlcy5kZWxldGUoaWQpO1xuICAgIHJldHVybiByZXNwb25zZTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSB1bmlxdWUgSUQgdXNpbmcgdGhlIG5hbm9pZCBsaWJyYXJ5LlxuICpcbiAqIEByZXR1cm5zIEEgdW5pcXVlIElEIHRoYXQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGNhbGxSZXNwb25zZXMgc2V0LlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUlEKCk6IHN0cmluZyB7XG4gICAgbGV0IHJlc3VsdDtcbiAgICBkbyB7XG4gICAgICAgIHJlc3VsdCA9IG5hbm9pZCgpO1xuICAgIH0gd2hpbGUgKGNhbGxSZXNwb25zZXMuaGFzKHJlc3VsdCkpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQ2FsbCBhIGJvdW5kIG1ldGhvZCBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGNhbGwgb3B0aW9ucy5cbiAqXG4gKiBJbiBjYXNlIG9mIGZhaWx1cmUsIHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgcmVqZWN0IHdpdGggYW4gZXhjZXB0aW9uXG4gKiBhbW9uZyBSZWZlcmVuY2VFcnJvciAodW5rbm93biBtZXRob2QpLCBUeXBlRXJyb3IgKHdyb25nIGFyZ3VtZW50IGNvdW50IG9yIHR5cGUpLFxuICoge0BsaW5rIFJ1bnRpbWVFcnJvcn0gKG1ldGhvZCByZXR1cm5lZCBhbiBlcnJvciksIG9yIG90aGVyIChuZXR3b3JrIG9yIGludGVybmFsIGVycm9ycykuXG4gKiBUaGUgZXhjZXB0aW9uIG1pZ2h0IGhhdmUgYSBcImNhdXNlXCIgZmllbGQgd2l0aCB0aGUgdmFsdWUgcmV0dXJuZWRcbiAqIGJ5IHRoZSBhcHBsaWNhdGlvbi0gb3Igc2VydmljZS1sZXZlbCBlcnJvciBtYXJzaGFsaW5nIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEEgbWV0aG9kIGNhbGwgZGVzY3JpcHRvci5cbiAqIEByZXR1cm5zIFRoZSByZXN1bHQgb2YgdGhlIGNhbGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDYWxsKG9wdGlvbnM6IENhbGxPcHRpb25zKTogQ2FuY2VsbGFibGVQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGlkID0gZ2VuZXJhdGVJRCgpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gQ2FuY2VsbGFibGVQcm9taXNlLndpdGhSZXNvbHZlcnM8YW55PigpO1xuICAgIGNhbGxSZXNwb25zZXMuc2V0KGlkLCB7IHJlc29sdmU6IHJlc3VsdC5yZXNvbHZlLCByZWplY3Q6IHJlc3VsdC5yZWplY3QgfSk7XG5cbiAgICBjb25zdCByZXF1ZXN0ID0gY2FsbChDYWxsQmluZGluZywgT2JqZWN0LmFzc2lnbih7IFwiY2FsbC1pZFwiOiBpZCB9LCBvcHRpb25zKSk7XG4gICAgbGV0IHJ1bm5pbmcgPSBmYWxzZTtcblxuICAgIHJlcXVlc3QudGhlbigoKSA9PiB7XG4gICAgICAgIHJ1bm5pbmcgPSB0cnVlO1xuICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgY2FsbFJlc3BvbnNlcy5kZWxldGUoaWQpO1xuICAgICAgICByZXN1bHQucmVqZWN0KGVycik7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjYW5jZWwgPSAoKSA9PiB7XG4gICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcbiAgICAgICAgcmV0dXJuIGNhbmNlbENhbGwoQ2FuY2VsTWV0aG9kLCB7XCJjYWxsLWlkXCI6IGlkfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHdoaWxlIHJlcXVlc3RpbmcgYmluZGluZyBjYWxsIGNhbmNlbGxhdGlvbjpcIiwgZXJyKTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHJlc3VsdC5vbmNhbmNlbGxlZCA9ICgpID0+IHtcbiAgICAgICAgaWYgKHJ1bm5pbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBjYW5jZWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXF1ZXN0LnRoZW4oY2FuY2VsKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gcmVzdWx0LnByb21pc2U7XG59XG5cbi8qKlxuICogQ2FsbHMgYSBib3VuZCBtZXRob2QgYnkgbmFtZSB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzLlxuICogU2VlIHtAbGluayBDYWxsfSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAcGFyYW0gbWV0aG9kTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBtZXRob2QgaW4gdGhlIGZvcm1hdCAncGFja2FnZS5zdHJ1Y3QubWV0aG9kJy5cbiAqIEBwYXJhbSBhcmdzIC0gVGhlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2QuXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0IG9mIHRoZSBtZXRob2QgY2FsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEJ5TmFtZShtZXRob2ROYW1lOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogQ2FuY2VsbGFibGVQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBDYWxsKHsgbWV0aG9kTmFtZSwgYXJncyB9KTtcbn1cblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBieSBpdHMgbnVtZXJpYyBJRCB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzLlxuICogU2VlIHtAbGluayBDYWxsfSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAcGFyYW0gbWV0aG9kSUQgLSBUaGUgSUQgb2YgdGhlIG1ldGhvZCB0byBjYWxsLlxuICogQHBhcmFtIGFyZ3MgLSBUaGUgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZC5cbiAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgbWV0aG9kIGNhbGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBCeUlEKG1ldGhvZElEOiBudW1iZXIsIC4uLmFyZ3M6IGFueVtdKTogQ2FuY2VsbGFibGVQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBDYWxsKHsgbWV0aG9kSUQsIGFyZ3MgfSk7XG59XG4iLCAiLy8gU291cmNlOiBodHRwczovL2dpdGh1Yi5jb20vaW5zcGVjdC1qcy9pcy1jYWxsYWJsZVxuXG4vLyBUaGUgTUlUIExpY2Vuc2UgKE1JVClcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTUgSm9yZGFuIEhhcmJhbmRcbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4vLyBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbi8vIFNPRlRXQVJFLlxuXG52YXIgZm5Ub1N0ciA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZztcbnZhciByZWZsZWN0QXBwbHk6IHR5cGVvZiBSZWZsZWN0LmFwcGx5IHwgZmFsc2UgfCBudWxsID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U6IGFueTtcbnZhciBpc0NhbGxhYmxlTWFya2VyOiBhbnk7XG5pZiAodHlwZW9mIHJlZmxlY3RBcHBseSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgT2JqZWN0LmRlZmluZVByb3BlcnR5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgYmFkQXJyYXlMaWtlID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnbGVuZ3RoJywge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlzQ2FsbGFibGVNYXJrZXIgPSB7fTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcbiAgICAgICAgcmVmbGVjdEFwcGx5KGZ1bmN0aW9uICgpIHsgdGhyb3cgNDI7IH0sIG51bGwsIGJhZEFycmF5TGlrZSk7XG4gICAgfSBjYXRjaCAoXykge1xuICAgICAgICBpZiAoXyAhPT0gaXNDYWxsYWJsZU1hcmtlcikge1xuICAgICAgICAgICAgcmVmbGVjdEFwcGx5ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbn0gZWxzZSB7XG4gICAgcmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgICB2YXIgZm5TdHIgPSBmblRvU3RyLmNhbGwodmFsdWUpO1xuICAgICAgICByZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cbiAgICB9XG59O1xuXG52YXIgdHJ5RnVuY3Rpb25PYmplY3QgPSBmdW5jdGlvbiB0cnlGdW5jdGlvblRvU3RyKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAoaXNFUzZDbGFzc0ZuKHZhbHVlKSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgZm5Ub1N0ci5jYWxsKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufTtcbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgb2JqZWN0Q2xhc3MgPSAnW29iamVjdCBPYmplY3RdJztcbnZhciBmbkNsYXNzID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbnZhciBnZW5DbGFzcyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXSc7XG52YXIgZGRhQ2xhc3MgPSAnW29iamVjdCBIVE1MQWxsQ29sbGVjdGlvbl0nOyAvLyBJRSAxMVxudmFyIGRkYUNsYXNzMiA9ICdbb2JqZWN0IEhUTUwgZG9jdW1lbnQuYWxsIGNsYXNzXSc7XG52YXIgZGRhQ2xhc3MzID0gJ1tvYmplY3QgSFRNTENvbGxlY3Rpb25dJzsgLy8gSUUgOS0xMFxudmFyIGhhc1RvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiAhIVN5bWJvbC50b1N0cmluZ1RhZzsgLy8gYmV0dGVyOiB1c2UgYGhhcy10b3N0cmluZ3RhZ2BcblxudmFyIGlzSUU2OCA9ICEoMCBpbiBbLF0pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNwYXJzZS1hcnJheXMsIGNvbW1hLXNwYWNpbmdcblxudmFyIGlzRERBOiAodmFsdWU6IGFueSkgPT4gYm9vbGVhbiA9IGZ1bmN0aW9uIGlzRG9jdW1lbnREb3RBbGwoKSB7IHJldHVybiBmYWxzZTsgfTtcbmlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICdvYmplY3QnKSB7XG4gICAgLy8gRmlyZWZveCAzIGNhbm9uaWNhbGl6ZXMgRERBIHRvIHVuZGVmaW5lZCB3aGVuIGl0J3Mgbm90IGFjY2Vzc2VkIGRpcmVjdGx5XG4gICAgdmFyIGFsbCA9IGRvY3VtZW50LmFsbDtcbiAgICBpZiAodG9TdHIuY2FsbChhbGwpID09PSB0b1N0ci5jYWxsKGRvY3VtZW50LmFsbCkpIHtcbiAgICAgICAgaXNEREEgPSBmdW5jdGlvbiBpc0RvY3VtZW50RG90QWxsKHZhbHVlKSB7XG4gICAgICAgICAgICAvKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xuICAgICAgICAgICAgLy8gaW4gSUUgNi04LCB0eXBlb2YgZG9jdW1lbnQuYWxsIGlzIFwib2JqZWN0XCIgYW5kIGl0J3MgdHJ1dGh5XG4gICAgICAgICAgICBpZiAoKGlzSUU2OCB8fCAhdmFsdWUpICYmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyID09PSBkZGFDbGFzc1xuICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3RyID09PSBkZGFDbGFzczJcbiAgICAgICAgICAgICAgICAgICAgICAgIHx8IHN0ciA9PT0gZGRhQ2xhc3MzIC8vIG9wZXJhIDEyLjE2XG4gICAgICAgICAgICAgICAgICAgICAgICB8fCBzdHIgPT09IG9iamVjdENsYXNzIC8vIElFIDYtOFxuICAgICAgICAgICAgICAgICAgICApICYmIHZhbHVlKCcnKSA9PSBudWxsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgLyoqLyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0NhbGxhYmxlUmVmQXBwbHk8VD4odmFsdWU6IFQgfCB1bmtub3duKTogdmFsdWUgaXMgKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkgIHtcbiAgICBpZiAoaXNEREEodmFsdWUpKSB7IHJldHVybiB0cnVlOyB9XG4gICAgaWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgdHJ5IHtcbiAgICAgICAgKHJlZmxlY3RBcHBseSBhcyBhbnkpKHZhbHVlLCBudWxsLCBiYWRBcnJheUxpa2UpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGUgIT09IGlzQ2FsbGFibGVNYXJrZXIpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgfVxuICAgIHJldHVybiAhaXNFUzZDbGFzc0ZuKHZhbHVlKSAmJiB0cnlGdW5jdGlvbk9iamVjdCh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGlzQ2FsbGFibGVOb1JlZkFwcGx5PFQ+KHZhbHVlOiBUIHwgdW5rbm93bik6IHZhbHVlIGlzICguLi5hcmdzOiBhbnlbXSkgPT4gYW55IHtcbiAgICBpZiAoaXNEREEodmFsdWUpKSB7IHJldHVybiB0cnVlOyB9XG4gICAgaWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgaWYgKGhhc1RvU3RyaW5nVGFnKSB7IHJldHVybiB0cnlGdW5jdGlvbk9iamVjdCh2YWx1ZSk7IH1cbiAgICBpZiAoaXNFUzZDbGFzc0ZuKHZhbHVlKSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICB2YXIgc3RyQ2xhc3MgPSB0b1N0ci5jYWxsKHZhbHVlKTtcbiAgICBpZiAoc3RyQ2xhc3MgIT09IGZuQ2xhc3MgJiYgc3RyQ2xhc3MgIT09IGdlbkNsYXNzICYmICEoL15cXFtvYmplY3QgSFRNTC8pLnRlc3Qoc3RyQ2xhc3MpKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIHJldHVybiB0cnlGdW5jdGlvbk9iamVjdCh2YWx1ZSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCByZWZsZWN0QXBwbHkgPyBpc0NhbGxhYmxlUmVmQXBwbHkgOiBpc0NhbGxhYmxlTm9SZWZBcHBseTtcbiIsICIvKlxuIF9cdCAgIF9fXHQgIF8gX19cbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuaW1wb3J0IGlzQ2FsbGFibGUgZnJvbSBcIi4vY2FsbGFibGUuanNcIjtcblxuLyoqXG4gKiBFeGNlcHRpb24gY2xhc3MgdGhhdCB3aWxsIGJlIHVzZWQgYXMgcmVqZWN0aW9uIHJlYXNvblxuICogaW4gY2FzZSBhIHtAbGluayBDYW5jZWxsYWJsZVByb21pc2V9IGlzIGNhbmNlbGxlZCBzdWNjZXNzZnVsbHkuXG4gKlxuICogVGhlIHZhbHVlIG9mIHRoZSB7QGxpbmsgbmFtZX0gcHJvcGVydHkgaXMgdGhlIHN0cmluZyBgXCJDYW5jZWxFcnJvclwiYC5cbiAqIFRoZSB2YWx1ZSBvZiB0aGUge0BsaW5rIGNhdXNlfSBwcm9wZXJ0eSBpcyB0aGUgY2F1c2UgcGFzc2VkIHRvIHRoZSBjYW5jZWwgbWV0aG9kLCBpZiBhbnkuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYW5jZWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGBDYW5jZWxFcnJvcmAgaW5zdGFuY2UuXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgZXJyb3IgbWVzc2FnZS5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbnMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBFcnJvciBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlPzogc3RyaW5nLCBvcHRpb25zPzogRXJyb3JPcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UsIG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNhbmNlbEVycm9yXCI7XG4gICAgfVxufVxuXG4vKipcbiAqIEV4Y2VwdGlvbiBjbGFzcyB0aGF0IHdpbGwgYmUgcmVwb3J0ZWQgYXMgYW4gdW5oYW5kbGVkIHJlamVjdGlvblxuICogaW4gY2FzZSBhIHtAbGluayBDYW5jZWxsYWJsZVByb21pc2V9IHJlamVjdHMgYWZ0ZXIgYmVpbmcgY2FuY2VsbGVkLFxuICogb3Igd2hlbiB0aGUgYG9uY2FuY2VsbGVkYCBjYWxsYmFjayB0aHJvd3Mgb3IgcmVqZWN0cy5cbiAqXG4gKiBUaGUgdmFsdWUgb2YgdGhlIHtAbGluayBuYW1lfSBwcm9wZXJ0eSBpcyB0aGUgc3RyaW5nIGBcIkNhbmNlbGxlZFJlamVjdGlvbkVycm9yXCJgLlxuICogVGhlIHZhbHVlIG9mIHRoZSB7QGxpbmsgY2F1c2V9IHByb3BlcnR5IGlzIHRoZSByZWFzb24gdGhlIHByb21pc2UgcmVqZWN0ZWQgd2l0aC5cbiAqXG4gKiBCZWNhdXNlIHRoZSBvcmlnaW5hbCBwcm9taXNlIHdhcyBjYW5jZWxsZWQsXG4gKiBhIHdyYXBwZXIgcHJvbWlzZSB3aWxsIGJlIHBhc3NlZCB0byB0aGUgdW5oYW5kbGVkIHJlamVjdGlvbiBsaXN0ZW5lciBpbnN0ZWFkLlxuICogVGhlIHtAbGluayBwcm9taXNlfSBwcm9wZXJ0eSBob2xkcyBhIHJlZmVyZW5jZSB0byB0aGUgb3JpZ2luYWwgcHJvbWlzZS5cbiAqL1xuZXhwb3J0IGNsYXNzIENhbmNlbGxlZFJlamVjdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIC8qKlxuICAgICAqIEhvbGRzIGEgcmVmZXJlbmNlIHRvIHRoZSBwcm9taXNlIHRoYXQgd2FzIGNhbmNlbGxlZCBhbmQgdGhlbiByZWplY3RlZC5cbiAgICAgKi9cbiAgICBwcm9taXNlOiBDYW5jZWxsYWJsZVByb21pc2U8dW5rbm93bj47XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGBDYW5jZWxsZWRSZWplY3Rpb25FcnJvcmAgaW5zdGFuY2UuXG4gICAgICogQHBhcmFtIHByb21pc2UgLSBUaGUgcHJvbWlzZSB0aGF0IGNhdXNlZCB0aGUgZXJyb3Igb3JpZ2luYWxseS5cbiAgICAgKiBAcGFyYW0gcmVhc29uIC0gVGhlIHJlamVjdGlvbiByZWFzb24uXG4gICAgICogQHBhcmFtIGluZm8gLSBBbiBvcHRpb25hbCBpbmZvcm1hdGl2ZSBtZXNzYWdlIHNwZWNpZnlpbmcgdGhlIGNpcmN1bXN0YW5jZXMgaW4gd2hpY2ggdGhlIGVycm9yIHdhcyB0aHJvd24uXG4gICAgICogICAgICAgICAgICAgICBEZWZhdWx0cyB0byB0aGUgc3RyaW5nIGBcIlVuaGFuZGxlZCByZWplY3Rpb24gaW4gY2FuY2VsbGVkIHByb21pc2UuXCJgLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByb21pc2U6IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPiwgcmVhc29uPzogYW55LCBpbmZvPzogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKChpbmZvID8/IFwiVW5oYW5kbGVkIHJlamVjdGlvbiBpbiBjYW5jZWxsZWQgcHJvbWlzZS5cIikgKyBcIiBSZWFzb246IFwiICsgZXJyb3JNZXNzYWdlKHJlYXNvbiksIHsgY2F1c2U6IHJlYXNvbiB9KTtcbiAgICAgICAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDYW5jZWxsZWRSZWplY3Rpb25FcnJvclwiO1xuICAgIH1cbn1cblxudHlwZSBDYW5jZWxsYWJsZVByb21pc2VSZXNvbHZlcjxUPiA9ICh2YWx1ZTogVCB8IFByb21pc2VMaWtlPFQ+IHwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUPikgPT4gdm9pZDtcbnR5cGUgQ2FuY2VsbGFibGVQcm9taXNlUmVqZWN0b3IgPSAocmVhc29uPzogYW55KSA9PiB2b2lkO1xudHlwZSBDYW5jZWxsYWJsZVByb21pc2VDYW5jZWxsZXIgPSAoY2F1c2U/OiBhbnkpID0+IHZvaWQgfCBQcm9taXNlTGlrZTx2b2lkPjtcbnR5cGUgQ2FuY2VsbGFibGVQcm9taXNlRXhlY3V0b3I8VD4gPSAocmVzb2x2ZTogQ2FuY2VsbGFibGVQcm9taXNlUmVzb2x2ZXI8VD4sIHJlamVjdDogQ2FuY2VsbGFibGVQcm9taXNlUmVqZWN0b3IpID0+IHZvaWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUPiB7XG4gICAgdGhlbjxUUmVzdWx0MSA9IFQsIFRSZXN1bHQyID0gbmV2ZXI+KG9uZnVsZmlsbGVkPzogKCh2YWx1ZTogVCkgPT4gVFJlc3VsdDEgfCBQcm9taXNlTGlrZTxUUmVzdWx0MT4gfCBDYW5jZWxsYWJsZVByb21pc2VMaWtlPFRSZXN1bHQxPikgfCB1bmRlZmluZWQgfCBudWxsLCBvbnJlamVjdGVkPzogKChyZWFzb246IGFueSkgPT4gVFJlc3VsdDIgfCBQcm9taXNlTGlrZTxUUmVzdWx0Mj4gfCBDYW5jZWxsYWJsZVByb21pc2VMaWtlPFRSZXN1bHQyPikgfCB1bmRlZmluZWQgfCBudWxsKTogQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUUmVzdWx0MSB8IFRSZXN1bHQyPjtcbiAgICBjYW5jZWwoY2F1c2U/OiBhbnkpOiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD47XG59XG5cbi8qKlxuICogV3JhcHMgYSBjYW5jZWxsYWJsZSBwcm9taXNlIGFsb25nIHdpdGggaXRzIHJlc29sdXRpb24gbWV0aG9kcy5cbiAqIFRoZSBgb25jYW5jZWxsZWRgIGZpZWxkIHdpbGwgYmUgbnVsbCBpbml0aWFsbHkgYnV0IG1heSBiZSBzZXQgdG8gcHJvdmlkZSBhIGN1c3RvbSBjYW5jZWxsYXRpb24gZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FuY2VsbGFibGVQcm9taXNlV2l0aFJlc29sdmVyczxUPiB7XG4gICAgcHJvbWlzZTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+O1xuICAgIHJlc29sdmU6IENhbmNlbGxhYmxlUHJvbWlzZVJlc29sdmVyPFQ+O1xuICAgIHJlamVjdDogQ2FuY2VsbGFibGVQcm9taXNlUmVqZWN0b3I7XG4gICAgb25jYW5jZWxsZWQ6IENhbmNlbGxhYmxlUHJvbWlzZUNhbmNlbGxlciB8IG51bGw7XG59XG5cbmludGVyZmFjZSBDYW5jZWxsYWJsZVByb21pc2VTdGF0ZSB7XG4gICAgcmVhZG9ubHkgcm9vdDogQ2FuY2VsbGFibGVQcm9taXNlU3RhdGU7XG4gICAgcmVzb2x2aW5nOiBib29sZWFuO1xuICAgIHNldHRsZWQ6IGJvb2xlYW47XG4gICAgcmVhc29uPzogQ2FuY2VsRXJyb3I7XG59XG5cbi8vIFByaXZhdGUgZmllbGQgbmFtZXMuXG5jb25zdCBiYXJyaWVyU3ltID0gU3ltYm9sKFwiYmFycmllclwiKTtcbmNvbnN0IGNhbmNlbEltcGxTeW0gPSBTeW1ib2woXCJjYW5jZWxJbXBsXCIpO1xuY29uc3Qgc3BlY2llcyA9IFN5bWJvbC5zcGVjaWVzID8/IFN5bWJvbChcInNwZWNpZXNQb2x5ZmlsbFwiKTtcblxuLyoqXG4gKiBBIHByb21pc2Ugd2l0aCBhbiBhdHRhY2hlZCBtZXRob2QgZm9yIGNhbmNlbGxpbmcgbG9uZy1ydW5uaW5nIG9wZXJhdGlvbnMgKHNlZSB7QGxpbmsgQ2FuY2VsbGFibGVQcm9taXNlI2NhbmNlbH0pLlxuICogQ2FuY2VsbGF0aW9uIGNhbiBvcHRpb25hbGx5IGJlIGJvdW5kIHRvIGFuIHtAbGluayBBYm9ydFNpZ25hbH1cbiAqIGZvciBiZXR0ZXIgY29tcG9zYWJpbGl0eSAoc2VlIHtAbGluayBDYW5jZWxsYWJsZVByb21pc2UjY2FuY2VsT259KS5cbiAqXG4gKiBDYW5jZWxsaW5nIGEgcGVuZGluZyBwcm9taXNlIHdpbGwgcmVzdWx0IGluIGFuIGltbWVkaWF0ZSByZWplY3Rpb25cbiAqIHdpdGggYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIENhbmNlbEVycm9yfSBhcyByZWFzb24sXG4gKiBidXQgd2hvZXZlciBzdGFydGVkIHRoZSBwcm9taXNlIHdpbGwgYmUgcmVzcG9uc2libGVcbiAqIGZvciBhY3R1YWxseSBhYm9ydGluZyB0aGUgdW5kZXJseWluZyBvcGVyYXRpb24uXG4gKiBUbyB0aGlzIHB1cnBvc2UsIHRoZSBjb25zdHJ1Y3RvciBhbmQgYWxsIGNoYWluaW5nIG1ldGhvZHNcbiAqIGFjY2VwdCBvcHRpb25hbCBjYW5jZWxsYXRpb24gY2FsbGJhY2tzLlxuICpcbiAqIElmIGEgYENhbmNlbGxhYmxlUHJvbWlzZWAgc3RpbGwgcmVzb2x2ZXMgYWZ0ZXIgaGF2aW5nIGJlZW4gY2FuY2VsbGVkLFxuICogdGhlIHJlc3VsdCB3aWxsIGJlIGRpc2NhcmRlZC4gSWYgaXQgcmVqZWN0cywgdGhlIHJlYXNvblxuICogd2lsbCBiZSByZXBvcnRlZCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLFxuICogd3JhcHBlZCBpbiBhIHtAbGluayBDYW5jZWxsZWRSZWplY3Rpb25FcnJvcn0gaW5zdGFuY2UuXG4gKiBUbyBmYWNpbGl0YXRlIHRoZSBoYW5kbGluZyBvZiBjYW5jZWxsYXRpb24gcmVxdWVzdHMsXG4gKiBjYW5jZWxsZWQgYENhbmNlbGxhYmxlUHJvbWlzZWBzIHdpbGwgX25vdF8gcmVwb3J0IHVuaGFuZGxlZCBgQ2FuY2VsRXJyb3Jgc1xuICogd2hvc2UgYGNhdXNlYCBmaWVsZCBpcyB0aGUgc2FtZSBhcyB0aGUgb25lIHdpdGggd2hpY2ggdGhlIGN1cnJlbnQgcHJvbWlzZSB3YXMgY2FuY2VsbGVkLlxuICpcbiAqIEFsbCB1c3VhbCBwcm9taXNlIG1ldGhvZHMgYXJlIGRlZmluZWQgYW5kIHJldHVybiBhIGBDYW5jZWxsYWJsZVByb21pc2VgXG4gKiB3aG9zZSBjYW5jZWwgbWV0aG9kIHdpbGwgY2FuY2VsIHRoZSBwYXJlbnQgb3BlcmF0aW9uIGFzIHdlbGwsIHByb3BhZ2F0aW5nIHRoZSBjYW5jZWxsYXRpb24gcmVhc29uXG4gKiB1cHdhcmRzIHRocm91Z2ggcHJvbWlzZSBjaGFpbnMuXG4gKiBDb252ZXJzZWx5LCBjYW5jZWxsaW5nIGEgcHJvbWlzZSB3aWxsIG5vdCBhdXRvbWF0aWNhbGx5IGNhbmNlbCBkZXBlbmRlbnQgcHJvbWlzZXMgZG93bnN0cmVhbTpcbiAqIGBgYHRzXG4gKiBsZXQgcm9vdCA9IG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4geyAuLi4gfSk7XG4gKiBsZXQgY2hpbGQxID0gcm9vdC50aGVuKCgpID0+IHsgLi4uIH0pO1xuICogbGV0IGNoaWxkMiA9IGNoaWxkMS50aGVuKCgpID0+IHsgLi4uIH0pO1xuICogbGV0IGNoaWxkMyA9IHJvb3QuY2F0Y2goKCkgPT4geyAuLi4gfSk7XG4gKiBjaGlsZDEuY2FuY2VsKCk7IC8vIENhbmNlbHMgY2hpbGQxIGFuZCByb290LCBidXQgbm90IGNoaWxkMiBvciBjaGlsZDNcbiAqIGBgYFxuICogQ2FuY2VsbGluZyBhIHByb21pc2UgdGhhdCBoYXMgYWxyZWFkeSBzZXR0bGVkIGlzIHNhZmUgYW5kIGhhcyBubyBjb25zZXF1ZW5jZS5cbiAqXG4gKiBUaGUgYGNhbmNlbGAgbWV0aG9kIHJldHVybnMgYSBwcm9taXNlIHRoYXQgX2Fsd2F5cyBmdWxmaWxsc19cbiAqIGFmdGVyIHRoZSB3aG9sZSBjaGFpbiBoYXMgcHJvY2Vzc2VkIHRoZSBjYW5jZWwgcmVxdWVzdFxuICogYW5kIGFsbCBhdHRhY2hlZCBjYWxsYmFja3MgdXAgdG8gdGhhdCBtb21lbnQgaGF2ZSBydW4uXG4gKlxuICogQWxsIEVTMjAyNCBwcm9taXNlIG1ldGhvZHMgKHN0YXRpYyBhbmQgaW5zdGFuY2UpIGFyZSBkZWZpbmVkIG9uIENhbmNlbGxhYmxlUHJvbWlzZSxcbiAqIGJ1dCBhY3R1YWwgYXZhaWxhYmlsaXR5IG1heSB2YXJ5IHdpdGggT1Mvd2VidmlldyB2ZXJzaW9uLlxuICpcbiAqIEluIGxpbmUgd2l0aCB0aGUgcHJvcG9zYWwgYXQgaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcm0tYnVpbHRpbi1zdWJjbGFzc2luZyxcbiAqIGBDYW5jZWxsYWJsZVByb21pc2VgIGRvZXMgbm90IHN1cHBvcnQgdHJhbnNwYXJlbnQgc3ViY2xhc3NpbmcuXG4gKiBFeHRlbmRlcnMgc2hvdWxkIHRha2UgY2FyZSB0byBwcm92aWRlIHRoZWlyIG93biBtZXRob2QgaW1wbGVtZW50YXRpb25zLlxuICogVGhpcyBtaWdodCBiZSByZWNvbnNpZGVyZWQgaW4gY2FzZSB0aGUgcHJvcG9zYWwgaXMgcmV0aXJlZC5cbiAqXG4gKiBDYW5jZWxsYWJsZVByb21pc2UgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgRE9NIFByb21pc2Ugb2JqZWN0XG4gKiBhbmQgaXMgY29tcGxpYW50IHdpdGggdGhlIFtQcm9taXNlcy9BKyBzcGVjaWZpY2F0aW9uXShodHRwczovL3Byb21pc2VzYXBsdXMuY29tLylcbiAqIChpdCBwYXNzZXMgdGhlIFtjb21wbGlhbmNlIHN1aXRlXShodHRwczovL2dpdGh1Yi5jb20vcHJvbWlzZXMtYXBsdXMvcHJvbWlzZXMtdGVzdHMpKVxuICogaWYgc28gaXMgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBDYW5jZWxsYWJsZVByb21pc2U8VD4gZXh0ZW5kcyBQcm9taXNlPFQ+IGltcGxlbWVudHMgUHJvbWlzZUxpa2U8VD4sIENhbmNlbGxhYmxlUHJvbWlzZUxpa2U8VD4ge1xuICAgIC8vIFByaXZhdGUgZmllbGRzLlxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBwcml2YXRlIFtiYXJyaWVyU3ltXSE6IFBhcnRpYWw8UHJvbWlzZVdpdGhSZXNvbHZlcnM8dm9pZD4+IHwgbnVsbDtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBbY2FuY2VsSW1wbFN5bV0hOiAocmVhc29uOiBDYW5jZWxFcnJvcikgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBgQ2FuY2VsbGFibGVQcm9taXNlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBleGVjdXRvciAtIEEgY2FsbGJhY2sgdXNlZCB0byBpbml0aWFsaXplIHRoZSBwcm9taXNlLiBUaGlzIGNhbGxiYWNrIGlzIHBhc3NlZCB0d28gYXJndW1lbnRzOlxuICAgICAqICAgICAgICAgICAgICAgICAgIGEgYHJlc29sdmVgIGNhbGxiYWNrIHVzZWQgdG8gcmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoIGEgdmFsdWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICBvciB0aGUgcmVzdWx0IG9mIGFub3RoZXIgcHJvbWlzZSAocG9zc2libHkgY2FuY2VsbGFibGUpLFxuICAgICAqICAgICAgICAgICAgICAgICAgIGFuZCBhIGByZWplY3RgIGNhbGxiYWNrIHVzZWQgdG8gcmVqZWN0IHRoZSBwcm9taXNlIHdpdGggYSBwcm92aWRlZCByZWFzb24gb3IgZXJyb3IuXG4gICAgICogICAgICAgICAgICAgICAgICAgSWYgdGhlIHZhbHVlIHByb3ZpZGVkIHRvIHRoZSBgcmVzb2x2ZWAgY2FsbGJhY2sgaXMgYSB0aGVuYWJsZSBfYW5kXyBjYW5jZWxsYWJsZSBvYmplY3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAoaXQgaGFzIGEgYHRoZW5gIF9hbmRfIGEgYGNhbmNlbGAgbWV0aG9kKSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICBjYW5jZWxsYXRpb24gcmVxdWVzdHMgd2lsbCBiZSBmb3J3YXJkZWQgdG8gdGhhdCBvYmplY3QgYW5kIHRoZSBvbmNhbmNlbGxlZCB3aWxsIG5vdCBiZSBpbnZva2VkIGFueW1vcmUuXG4gICAgICogICAgICAgICAgICAgICAgICAgSWYgYW55IG9uZSBvZiB0aGUgdHdvIGNhbGxiYWNrcyBpcyBjYWxsZWQgX2FmdGVyXyB0aGUgcHJvbWlzZSBoYXMgYmVlbiBjYW5jZWxsZWQsXG4gICAgICogICAgICAgICAgICAgICAgICAgdGhlIHByb3ZpZGVkIHZhbHVlcyB3aWxsIGJlIGNhbmNlbGxlZCBhbmQgcmVzb2x2ZWQgYXMgdXN1YWwsXG4gICAgICogICAgICAgICAgICAgICAgICAgYnV0IHRoZWlyIHJlc3VsdHMgd2lsbCBiZSBkaXNjYXJkZWQuXG4gICAgICogICAgICAgICAgICAgICAgICAgSG93ZXZlciwgaWYgdGhlIHJlc29sdXRpb24gcHJvY2VzcyB1bHRpbWF0ZWx5IGVuZHMgdXAgaW4gYSByZWplY3Rpb25cbiAgICAgKiAgICAgICAgICAgICAgICAgICB0aGF0IGlzIG5vdCBkdWUgdG8gY2FuY2VsbGF0aW9uLCB0aGUgcmVqZWN0aW9uIHJlYXNvblxuICAgICAqICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgd3JhcHBlZCBpbiBhIHtAbGluayBDYW5jZWxsZWRSZWplY3Rpb25FcnJvcn1cbiAgICAgKiAgICAgICAgICAgICAgICAgICBhbmQgYnViYmxlZCB1cCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLlxuICAgICAqIEBwYXJhbSBvbmNhbmNlbGxlZCAtIEl0IGlzIHRoZSBjYWxsZXIncyByZXNwb25zaWJpbGl0eSB0byBlbnN1cmUgdGhhdCBhbnkgb3BlcmF0aW9uXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc3RhcnRlZCBieSB0aGUgZXhlY3V0b3IgaXMgcHJvcGVybHkgaGFsdGVkIHVwb24gY2FuY2VsbGF0aW9uLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIFRoaXMgb3B0aW9uYWwgY2FsbGJhY2sgY2FuIGJlIHVzZWQgdG8gdGhhdCBwdXJwb3NlLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIEl0IHdpbGwgYmUgY2FsbGVkIF9zeW5jaHJvbm91c2x5XyB3aXRoIGEgY2FuY2VsbGF0aW9uIGNhdXNlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgd2hlbiBjYW5jZWxsYXRpb24gaXMgcmVxdWVzdGVkLCBfYWZ0ZXJfIHRoZSBwcm9taXNlIGhhcyBhbHJlYWR5IHJlamVjdGVkXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgd2l0aCBhIHtAbGluayBDYW5jZWxFcnJvcn0sIGJ1dCBfYmVmb3JlX1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGFueSB7QGxpbmsgdGhlbn0ve0BsaW5rIGNhdGNofS97QGxpbmsgZmluYWxseX0gY2FsbGJhY2sgcnVucy5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyBhIHRoZW5hYmxlLCB0aGUgcHJvbWlzZSByZXR1cm5lZCBmcm9tIHtAbGluayBjYW5jZWx9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgd2lsbCBvbmx5IGZ1bGZpbGwgYWZ0ZXIgdGhlIGZvcm1lciBoYXMgc2V0dGxlZC5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBVbmhhbmRsZWQgZXhjZXB0aW9ucyBvciByZWplY3Rpb25zIGZyb20gdGhlIGNhbGxiYWNrIHdpbGwgYmUgd3JhcHBlZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGluIGEge0BsaW5rIENhbmNlbGxlZFJlamVjdGlvbkVycm9yfSBhbmQgYnViYmxlZCB1cCBhcyB1bmhhbmRsZWQgcmVqZWN0aW9ucy5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBJZiB0aGUgYHJlc29sdmVgIGNhbGxiYWNrIGlzIGNhbGxlZCBiZWZvcmUgY2FuY2VsbGF0aW9uIHdpdGggYSBjYW5jZWxsYWJsZSBwcm9taXNlLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNhbmNlbGxhdGlvbiByZXF1ZXN0cyBvbiB0aGlzIHByb21pc2Ugd2lsbCBiZSBkaXZlcnRlZCB0byB0aGF0IHByb21pc2UsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgYW5kIHRoZSBvcmlnaW5hbCBgb25jYW5jZWxsZWRgIGNhbGxiYWNrIHdpbGwgYmUgZGlzY2FyZGVkLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGV4ZWN1dG9yOiBDYW5jZWxsYWJsZVByb21pc2VFeGVjdXRvcjxUPiwgb25jYW5jZWxsZWQ/OiBDYW5jZWxsYWJsZVByb21pc2VDYW5jZWxsZXIpIHtcbiAgICAgICAgbGV0IHJlc29sdmUhOiAodmFsdWU6IFQgfCBQcm9taXNlTGlrZTxUPikgPT4gdm9pZDtcbiAgICAgICAgbGV0IHJlamVjdCE6IChyZWFzb24/OiBhbnkpID0+IHZvaWQ7XG4gICAgICAgIHN1cGVyKChyZXMsIHJlaikgPT4geyByZXNvbHZlID0gcmVzOyByZWplY3QgPSByZWo7IH0pO1xuXG4gICAgICAgIGlmICgodGhpcy5jb25zdHJ1Y3RvciBhcyBhbnkpW3NwZWNpZXNdICE9PSBQcm9taXNlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2FuY2VsbGFibGVQcm9taXNlIGRvZXMgbm90IHN1cHBvcnQgdHJhbnNwYXJlbnQgc3ViY2xhc3NpbmcuIFBsZWFzZSByZWZyYWluIGZyb20gb3ZlcnJpZGluZyB0aGUgW1N5bWJvbC5zcGVjaWVzXSBzdGF0aWMgcHJvcGVydHkuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHByb21pc2U6IENhbmNlbGxhYmxlUHJvbWlzZVdpdGhSZXNvbHZlcnM8VD4gPSB7XG4gICAgICAgICAgICBwcm9taXNlOiB0aGlzLFxuICAgICAgICAgICAgcmVzb2x2ZSxcbiAgICAgICAgICAgIHJlamVjdCxcbiAgICAgICAgICAgIGdldCBvbmNhbmNlbGxlZCgpIHsgcmV0dXJuIG9uY2FuY2VsbGVkID8/IG51bGw7IH0sXG4gICAgICAgICAgICBzZXQgb25jYW5jZWxsZWQoY2IpIHsgb25jYW5jZWxsZWQgPSBjYiA/PyB1bmRlZmluZWQ7IH1cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzdGF0ZTogQ2FuY2VsbGFibGVQcm9taXNlU3RhdGUgPSB7XG4gICAgICAgICAgICBnZXQgcm9vdCgpIHsgcmV0dXJuIHN0YXRlOyB9LFxuICAgICAgICAgICAgcmVzb2x2aW5nOiBmYWxzZSxcbiAgICAgICAgICAgIHNldHRsZWQ6IGZhbHNlXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0dXAgY2FuY2VsbGF0aW9uIHN5c3RlbS5cbiAgICAgICAgdm9pZCBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgICAgICBbYmFycmllclN5bV06IHtcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBudWxsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgW2NhbmNlbEltcGxTeW1dOiB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGNhbmNlbGxlckZvcihwcm9taXNlLCBzdGF0ZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUnVuIHRoZSBhY3R1YWwgZXhlY3V0b3IuXG4gICAgICAgIGNvbnN0IHJlamVjdG9yID0gcmVqZWN0b3JGb3IocHJvbWlzZSwgc3RhdGUpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZXhlY3V0b3IocmVzb2x2ZXJGb3IocHJvbWlzZSwgc3RhdGUpLCByZWplY3Rvcik7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKHN0YXRlLnJlc29sdmluZykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiVW5oYW5kbGVkIGV4Y2VwdGlvbiBpbiBDYW5jZWxsYWJsZVByb21pc2UgZXhlY3V0b3IuXCIsIGVycik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdG9yKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIGltbWVkaWF0ZWx5IHRoZSBleGVjdXRpb24gb2YgdGhlIG9wZXJhdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcm9taXNlLlxuICAgICAqIFRoZSBwcm9taXNlIHJlamVjdHMgd2l0aCBhIHtAbGluayBDYW5jZWxFcnJvcn0gaW5zdGFuY2UgYXMgcmVhc29uLFxuICAgICAqIHdpdGggdGhlIHtAbGluayBDYW5jZWxFcnJvciNjYXVzZX0gcHJvcGVydHkgc2V0IHRvIHRoZSBnaXZlbiBhcmd1bWVudCwgaWYgYW55LlxuICAgICAqXG4gICAgICogSGFzIG5vIGVmZmVjdCBpZiBjYWxsZWQgYWZ0ZXIgdGhlIHByb21pc2UgaGFzIGFscmVhZHkgc2V0dGxlZDtcbiAgICAgKiByZXBlYXRlZCBjYWxscyBpbiBwYXJ0aWN1bGFyIGFyZSBzYWZlLCBidXQgb25seSB0aGUgZmlyc3Qgb25lXG4gICAgICogd2lsbCBzZXQgdGhlIGNhbmNlbGxhdGlvbiBjYXVzZS5cbiAgICAgKlxuICAgICAqIFRoZSBgQ2FuY2VsRXJyb3JgIGV4Y2VwdGlvbiBfbmVlZCBub3RfIGJlIGhhbmRsZWQgZXhwbGljaXRseSBfb24gdGhlIHByb21pc2VzIHRoYXQgYXJlIGJlaW5nIGNhbmNlbGxlZDpfXG4gICAgICogY2FuY2VsbGluZyBhIHByb21pc2Ugd2l0aCBubyBhdHRhY2hlZCByZWplY3Rpb24gaGFuZGxlciBkb2VzIG5vdCB0cmlnZ2VyIGFuIHVuaGFuZGxlZCByZWplY3Rpb24gZXZlbnQuXG4gICAgICogVGhlcmVmb3JlLCB0aGUgZm9sbG93aW5nIGlkaW9tcyBhcmUgYWxsIGVxdWFsbHkgY29ycmVjdDpcbiAgICAgKiBgYGB0c1xuICAgICAqIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4geyAuLi4gfSkuY2FuY2VsKCk7XG4gICAgICogbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7IC4uLiB9KS50aGVuKC4uLikuY2FuY2VsKCk7XG4gICAgICogbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7IC4uLiB9KS50aGVuKC4uLikuY2F0Y2goLi4uKS5jYW5jZWwoKTtcbiAgICAgKiBgYGBcbiAgICAgKiBXaGVuZXZlciBzb21lIGNhbmNlbGxlZCBwcm9taXNlIGluIGEgY2hhaW4gcmVqZWN0cyB3aXRoIGEgYENhbmNlbEVycm9yYFxuICAgICAqIHdpdGggdGhlIHNhbWUgY2FuY2VsbGF0aW9uIGNhdXNlIGFzIGl0c2VsZiwgdGhlIGVycm9yIHdpbGwgYmUgZGlzY2FyZGVkIHNpbGVudGx5LlxuICAgICAqIEhvd2V2ZXIsIHRoZSBgQ2FuY2VsRXJyb3JgIF93aWxsIHN0aWxsIGJlIGRlbGl2ZXJlZF8gdG8gYWxsIGF0dGFjaGVkIHJlamVjdGlvbiBoYW5kbGVyc1xuICAgICAqIGFkZGVkIGJ5IHtAbGluayB0aGVufSBhbmQgcmVsYXRlZCBtZXRob2RzOlxuICAgICAqIGBgYHRzXG4gICAgICogbGV0IGNhbmNlbGxhYmxlID0gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7IC4uLiB9KTtcbiAgICAgKiBjYW5jZWxsYWJsZS50aGVuKCgpID0+IHsgLi4uIH0pLmNhdGNoKGNvbnNvbGUubG9nKTtcbiAgICAgKiBjYW5jZWxsYWJsZS5jYW5jZWwoKTsgLy8gQSBDYW5jZWxFcnJvciBpcyBwcmludGVkIHRvIHRoZSBjb25zb2xlLlxuICAgICAqIGBgYFxuICAgICAqIElmIHRoZSBgQ2FuY2VsRXJyb3JgIGlzIG5vdCBoYW5kbGVkIGRvd25zdHJlYW0gYnkgdGhlIHRpbWUgaXQgcmVhY2hlc1xuICAgICAqIGEgX25vbi1jYW5jZWxsZWRfIHByb21pc2UsIGl0IF93aWxsXyB0cmlnZ2VyIGFuIHVuaGFuZGxlZCByZWplY3Rpb24gZXZlbnQsXG4gICAgICoganVzdCBsaWtlIG5vcm1hbCByZWplY3Rpb25zIHdvdWxkOlxuICAgICAqIGBgYHRzXG4gICAgICogbGV0IGNhbmNlbGxhYmxlID0gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7IC4uLiB9KTtcbiAgICAgKiBsZXQgY2hhaW5lZCA9IGNhbmNlbGxhYmxlLnRoZW4oKCkgPT4geyAuLi4gfSkudGhlbigoKSA9PiB7IC4uLiB9KTsgLy8gTm8gY2F0Y2guLi5cbiAgICAgKiBjYW5jZWxsYWJsZS5jYW5jZWwoKTsgLy8gVW5oYW5kbGVkIHJlamVjdGlvbiBldmVudCBvbiBjaGFpbmVkIVxuICAgICAqIGBgYFxuICAgICAqIFRoZXJlZm9yZSwgaXQgaXMgaW1wb3J0YW50IHRvIGVpdGhlciBjYW5jZWwgd2hvbGUgcHJvbWlzZSBjaGFpbnMgZnJvbSB0aGVpciB0YWlsLFxuICAgICAqIGFzIHNob3duIGluIHRoZSBjb3JyZWN0IGlkaW9tcyBhYm92ZSwgb3IgdGFrZSBjYXJlIG9mIGhhbmRsaW5nIGVycm9ycyBldmVyeXdoZXJlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBjYW5jZWxsYWJsZSBwcm9taXNlIHRoYXQgX2Z1bGZpbGxzXyBhZnRlciB0aGUgY2FuY2VsIGNhbGxiYWNrIChpZiBhbnkpXG4gICAgICogYW5kIGFsbCBoYW5kbGVycyBhdHRhY2hlZCB1cCB0byB0aGUgY2FsbCB0byBjYW5jZWwgaGF2ZSBydW4uXG4gICAgICogSWYgdGhlIGNhbmNlbCBjYWxsYmFjayByZXR1cm5zIGEgdGhlbmFibGUsIHRoZSBwcm9taXNlIHJldHVybmVkIGJ5IGBjYW5jZWxgXG4gICAgICogd2lsbCBhbHNvIHdhaXQgZm9yIHRoYXQgdGhlbmFibGUgdG8gc2V0dGxlLlxuICAgICAqIFRoaXMgZW5hYmxlcyBjYWxsZXJzIHRvIHdhaXQgZm9yIHRoZSBjYW5jZWxsZWQgb3BlcmF0aW9uIHRvIHRlcm1pbmF0ZVxuICAgICAqIHdpdGhvdXQgYmVpbmcgZm9yY2VkIHRvIGhhbmRsZSBwb3RlbnRpYWwgZXJyb3JzIGF0IHRoZSBjYWxsIHNpdGUuXG4gICAgICogYGBgdHNcbiAgICAgKiBjYW5jZWxsYWJsZS5jYW5jZWwoKS50aGVuKCgpID0+IHtcbiAgICAgKiAgICAgLy8gQ2xlYW51cCBmaW5pc2hlZCwgaXQncyBzYWZlIHRvIGRvIHNvbWV0aGluZyBlbHNlLlxuICAgICAqIH0sIChlcnIpID0+IHtcbiAgICAgKiAgICAgLy8gVW5yZWFjaGFibGU6IHRoZSBwcm9taXNlIHJldHVybmVkIGZyb20gY2FuY2VsIHdpbGwgbmV2ZXIgcmVqZWN0LlxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqIE5vdGUgdGhhdCB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIF9ub3RfIGhhbmRsZSBpbXBsaWNpdGx5IGFueSByZWplY3Rpb25cbiAgICAgKiB0aGF0IG1pZ2h0IGhhdmUgb2NjdXJyZWQgYWxyZWFkeSBpbiB0aGUgY2FuY2VsbGVkIGNoYWluLlxuICAgICAqIEl0IHdpbGwganVzdCB0cmFjayB3aGV0aGVyIHJlZ2lzdGVyZWQgaGFuZGxlcnMgaGF2ZSBiZWVuIGV4ZWN1dGVkIG9yIG5vdC5cbiAgICAgKiBUaGVyZWZvcmUsIHVuaGFuZGxlZCByZWplY3Rpb25zIHdpbGwgbmV2ZXIgYmUgc2lsZW50bHkgaGFuZGxlZCBieSBjYWxsaW5nIGNhbmNlbC5cbiAgICAgKi9cbiAgICBjYW5jZWwoY2F1c2U/OiBhbnkpOiBDYW5jZWxsYWJsZVByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgLy8gSU5WQVJJQU5UOiB0aGUgcmVzdWx0IG9mIHRoaXNbY2FuY2VsSW1wbFN5bV0gYW5kIHRoZSBiYXJyaWVyIGRvIG5vdCBldmVyIHJlamVjdC5cbiAgICAgICAgICAgIC8vIFVuZm9ydHVuYXRlbHkgbWFjT1MgSGlnaCBTaWVycmEgZG9lcyBub3Qgc3VwcG9ydCBQcm9taXNlLmFsbFNldHRsZWQuXG4gICAgICAgICAgICBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgdGhpc1tjYW5jZWxJbXBsU3ltXShuZXcgQ2FuY2VsRXJyb3IoXCJQcm9taXNlIGNhbmNlbGxlZC5cIiwgeyBjYXVzZSB9KSksXG4gICAgICAgICAgICAgICAgY3VycmVudEJhcnJpZXIodGhpcylcbiAgICAgICAgICAgIF0pLnRoZW4oKCkgPT4gcmVzb2x2ZSgpLCAoKSA9PiByZXNvbHZlKCkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBCaW5kcyBwcm9taXNlIGNhbmNlbGxhdGlvbiB0byB0aGUgYWJvcnQgZXZlbnQgb2YgdGhlIGdpdmVuIHtAbGluayBBYm9ydFNpZ25hbH0uXG4gICAgICogSWYgdGhlIHNpZ25hbCBoYXMgYWxyZWFkeSBhYm9ydGVkLCB0aGUgcHJvbWlzZSB3aWxsIGJlIGNhbmNlbGxlZCBpbW1lZGlhdGVseS5cbiAgICAgKiBXaGVuIGVpdGhlciBjb25kaXRpb24gaXMgdmVyaWZpZWQsIHRoZSBjYW5jZWxsYXRpb24gY2F1c2Ugd2lsbCBiZSBzZXRcbiAgICAgKiB0byB0aGUgc2lnbmFsJ3MgYWJvcnQgcmVhc29uIChzZWUge0BsaW5rIEFib3J0U2lnbmFsI3JlYXNvbn0pLlxuICAgICAqXG4gICAgICogSGFzIG5vIGVmZmVjdCBpZiBjYWxsZWQgKG9yIGlmIHRoZSBzaWduYWwgYWJvcnRzKSBfYWZ0ZXJfIHRoZSBwcm9taXNlIGhhcyBhbHJlYWR5IHNldHRsZWQuXG4gICAgICogT25seSB0aGUgZmlyc3Qgc2lnbmFsIHRvIGFib3J0IHdpbGwgc2V0IHRoZSBjYW5jZWxsYXRpb24gY2F1c2UuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBkZXRhaWxzIGFib3V0IHRoZSBjYW5jZWxsYXRpb24gcHJvY2VzcyxcbiAgICAgKiBzZWUge0BsaW5rIGNhbmNlbH0gYW5kIHRoZSBgQ2FuY2VsbGFibGVQcm9taXNlYCBjb25zdHJ1Y3Rvci5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIGVuYWJsZXMgYGF3YWl0YGluZyBjYW5jZWxsYWJsZSBwcm9taXNlcyB3aXRob3V0IGhhdmluZ1xuICAgICAqIHRvIHN0b3JlIHRoZW0gZm9yIGZ1dHVyZSBjYW5jZWxsYXRpb24sIGUuZy46XG4gICAgICogYGBgdHNcbiAgICAgKiBhd2FpdCBsb25nUnVubmluZ09wZXJhdGlvbigpLmNhbmNlbE9uKHNpZ25hbCk7XG4gICAgICogYGBgXG4gICAgICogaW5zdGVhZCBvZjpcbiAgICAgKiBgYGB0c1xuICAgICAqIGxldCBwcm9taXNlVG9CZUNhbmNlbGxlZCA9IGxvbmdSdW5uaW5nT3BlcmF0aW9uKCk7XG4gICAgICogYXdhaXQgcHJvbWlzZVRvQmVDYW5jZWxsZWQ7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGlzIHByb21pc2UsIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICovXG4gICAgY2FuY2VsT24oc2lnbmFsOiBBYm9ydFNpZ25hbCk6IENhbmNlbGxhYmxlUHJvbWlzZTxUPiB7XG4gICAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgICAgdm9pZCB0aGlzLmNhbmNlbChzaWduYWwucmVhc29uKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgKCkgPT4gdm9pZCB0aGlzLmNhbmNlbChzaWduYWwucmVhc29uKSwge2NhcHR1cmU6IHRydWV9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEF0dGFjaGVzIGNhbGxiYWNrcyBmb3IgdGhlIHJlc29sdXRpb24gYW5kL29yIHJlamVjdGlvbiBvZiB0aGUgYENhbmNlbGxhYmxlUHJvbWlzZWAuXG4gICAgICpcbiAgICAgKiBUaGUgb3B0aW9uYWwgYG9uY2FuY2VsbGVkYCBhcmd1bWVudCB3aWxsIGJlIGludm9rZWQgd2hlbiB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBjYW5jZWxsZWQsXG4gICAgICogd2l0aCB0aGUgc2FtZSBzZW1hbnRpY3MgYXMgdGhlIGBvbmNhbmNlbGxlZGAgYXJndW1lbnQgb2YgdGhlIGNvbnN0cnVjdG9yLlxuICAgICAqIFdoZW4gdGhlIHBhcmVudCBwcm9taXNlIHJlamVjdHMgb3IgaXMgY2FuY2VsbGVkLCB0aGUgYG9ucmVqZWN0ZWRgIGNhbGxiYWNrIHdpbGwgcnVuLFxuICAgICAqIF9ldmVuIGFmdGVyIHRoZSByZXR1cm5lZCBwcm9taXNlIGhhcyBiZWVuIGNhbmNlbGxlZDpfXG4gICAgICogaW4gdGhhdCBjYXNlLCBzaG91bGQgaXQgcmVqZWN0IG9yIHRocm93LCB0aGUgcmVhc29uIHdpbGwgYmUgd3JhcHBlZFxuICAgICAqIGluIGEge0BsaW5rIENhbmNlbGxlZFJlamVjdGlvbkVycm9yfSBhbmQgYnViYmxlZCB1cCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIG9uZnVsZmlsbGVkIFRoZSBjYWxsYmFjayB0byBleGVjdXRlIHdoZW4gdGhlIFByb21pc2UgaXMgcmVzb2x2ZWQuXG4gICAgICogQHBhcmFtIG9ucmVqZWN0ZWQgVGhlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgd2hlbiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZC5cbiAgICAgKiBAcmV0dXJucyBBIGBDYW5jZWxsYWJsZVByb21pc2VgIGZvciB0aGUgY29tcGxldGlvbiBvZiB3aGljaGV2ZXIgY2FsbGJhY2sgaXMgZXhlY3V0ZWQuXG4gICAgICogVGhlIHJldHVybmVkIHByb21pc2UgaXMgaG9va2VkIHVwIHRvIHByb3BhZ2F0ZSBjYW5jZWxsYXRpb24gcmVxdWVzdHMgdXAgdGhlIGNoYWluLCBidXQgbm90IGRvd246XG4gICAgICpcbiAgICAgKiAgIC0gaWYgdGhlIHBhcmVudCBwcm9taXNlIGlzIGNhbmNlbGxlZCwgdGhlIGBvbnJlamVjdGVkYCBoYW5kbGVyIHdpbGwgYmUgaW52b2tlZCB3aXRoIGEgYENhbmNlbEVycm9yYFxuICAgICAqICAgICBhbmQgdGhlIHJldHVybmVkIHByb21pc2UgX3dpbGwgcmVzb2x2ZSByZWd1bGFybHlfIHdpdGggaXRzIHJlc3VsdDtcbiAgICAgKiAgIC0gY29udmVyc2VseSwgaWYgdGhlIHJldHVybmVkIHByb21pc2UgaXMgY2FuY2VsbGVkLCBfdGhlIHBhcmVudCBwcm9taXNlIGlzIGNhbmNlbGxlZCB0b287X1xuICAgICAqICAgICB0aGUgYG9ucmVqZWN0ZWRgIGhhbmRsZXIgd2lsbCBzdGlsbCBiZSBpbnZva2VkIHdpdGggdGhlIHBhcmVudCdzIGBDYW5jZWxFcnJvcmAsXG4gICAgICogICAgIGJ1dCBpdHMgcmVzdWx0IHdpbGwgYmUgZGlzY2FyZGVkXG4gICAgICogICAgIGFuZCB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIHJlamVjdCB3aXRoIGEgYENhbmNlbEVycm9yYCBhcyB3ZWxsLlxuICAgICAqXG4gICAgICogVGhlIHByb21pc2UgcmV0dXJuZWQgZnJvbSB7QGxpbmsgY2FuY2VsfSB3aWxsIGZ1bGZpbGwgb25seSBhZnRlciBhbGwgYXR0YWNoZWQgaGFuZGxlcnNcbiAgICAgKiB1cCB0aGUgZW50aXJlIHByb21pc2UgY2hhaW4gaGF2ZSBiZWVuIHJ1bi5cbiAgICAgKlxuICAgICAqIElmIGVpdGhlciBjYWxsYmFjayByZXR1cm5zIGEgY2FuY2VsbGFibGUgcHJvbWlzZSxcbiAgICAgKiBjYW5jZWxsYXRpb24gcmVxdWVzdHMgd2lsbCBiZSBkaXZlcnRlZCB0byBpdCxcbiAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBgb25jYW5jZWxsZWRgIGNhbGxiYWNrIHdpbGwgYmUgZGlzY2FyZGVkLlxuICAgICAqL1xuICAgIHRoZW48VFJlc3VsdDEgPSBULCBUUmVzdWx0MiA9IG5ldmVyPihvbmZ1bGZpbGxlZD86ICgodmFsdWU6IFQpID0+IFRSZXN1bHQxIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDE+IHwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUUmVzdWx0MT4pIHwgdW5kZWZpbmVkIHwgbnVsbCwgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+IHwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUUmVzdWx0Mj4pIHwgdW5kZWZpbmVkIHwgbnVsbCwgb25jYW5jZWxsZWQ/OiBDYW5jZWxsYWJsZVByb21pc2VDYW5jZWxsZXIpOiBDYW5jZWxsYWJsZVByb21pc2U8VFJlc3VsdDEgfCBUUmVzdWx0Mj4ge1xuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2FuY2VsbGFibGVQcm9taXNlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbiBjYWxsZWQgb24gYW4gaW52YWxpZCBvYmplY3QuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTk9URTogVHlwZVNjcmlwdCdzIGJ1aWx0LWluIHR5cGUgZm9yIHRoZW4gaXMgYnJva2VuLFxuICAgICAgICAvLyBhcyBpdCBhbGxvd3Mgc3BlY2lmeWluZyBhbiBhcmJpdHJhcnkgVFJlc3VsdDEgIT0gVCBldmVuIHdoZW4gb25mdWxmaWxsZWQgaXMgbm90IGEgZnVuY3Rpb24uXG4gICAgICAgIC8vIFdlIGNhbm5vdCBmaXggaXQgaWYgd2Ugd2FudCB0byBDYW5jZWxsYWJsZVByb21pc2UgdG8gaW1wbGVtZW50IFByb21pc2VMaWtlPFQ+LlxuXG4gICAgICAgIGlmICghaXNDYWxsYWJsZShvbmZ1bGZpbGxlZCkpIHsgb25mdWxmaWxsZWQgPSBpZGVudGl0eSBhcyBhbnk7IH1cbiAgICAgICAgaWYgKCFpc0NhbGxhYmxlKG9ucmVqZWN0ZWQpKSB7IG9ucmVqZWN0ZWQgPSB0aHJvd2VyOyB9XG5cbiAgICAgICAgaWYgKG9uZnVsZmlsbGVkID09PSBpZGVudGl0eSAmJiBvbnJlamVjdGVkID09IHRocm93ZXIpIHtcbiAgICAgICAgICAgIC8vIFNob3J0Y3V0IGZvciB0cml2aWFsIGFyZ3VtZW50cy5cbiAgICAgICAgICAgIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiByZXNvbHZlKHRoaXMgYXMgYW55KSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBiYXJyaWVyOiBQYXJ0aWFsPFByb21pc2VXaXRoUmVzb2x2ZXJzPHZvaWQ+PiA9IHt9O1xuICAgICAgICB0aGlzW2JhcnJpZXJTeW1dID0gYmFycmllcjtcblxuICAgICAgICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTxUUmVzdWx0MSB8IFRSZXN1bHQyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB2b2lkIHN1cGVyLnRoZW4oXG4gICAgICAgICAgICAgICAgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2JhcnJpZXJTeW1dID09PSBiYXJyaWVyKSB7IHRoaXNbYmFycmllclN5bV0gPSBudWxsOyB9XG4gICAgICAgICAgICAgICAgICAgIGJhcnJpZXIucmVzb2x2ZT8uKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob25mdWxmaWxsZWQhKHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChyZWFzb24/KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2JhcnJpZXJTeW1dID09PSBiYXJyaWVyKSB7IHRoaXNbYmFycmllclN5bV0gPSBudWxsOyB9XG4gICAgICAgICAgICAgICAgICAgIGJhcnJpZXIucmVzb2x2ZT8uKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob25yZWplY3RlZCEocmVhc29uKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9LCBhc3luYyAoY2F1c2U/KSA9PiB7XG4gICAgICAgICAgICAvL2NhbmNlbGxlZCA9IHRydWU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvbmNhbmNlbGxlZD8uKGNhdXNlKTtcbiAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jYW5jZWwoY2F1c2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdHRhY2hlcyBhIGNhbGxiYWNrIGZvciBvbmx5IHRoZSByZWplY3Rpb24gb2YgdGhlIFByb21pc2UuXG4gICAgICpcbiAgICAgKiBUaGUgb3B0aW9uYWwgYG9uY2FuY2VsbGVkYCBhcmd1bWVudCB3aWxsIGJlIGludm9rZWQgd2hlbiB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBjYW5jZWxsZWQsXG4gICAgICogd2l0aCB0aGUgc2FtZSBzZW1hbnRpY3MgYXMgdGhlIGBvbmNhbmNlbGxlZGAgYXJndW1lbnQgb2YgdGhlIGNvbnN0cnVjdG9yLlxuICAgICAqIFdoZW4gdGhlIHBhcmVudCBwcm9taXNlIHJlamVjdHMgb3IgaXMgY2FuY2VsbGVkLCB0aGUgYG9ucmVqZWN0ZWRgIGNhbGxiYWNrIHdpbGwgcnVuLFxuICAgICAqIF9ldmVuIGFmdGVyIHRoZSByZXR1cm5lZCBwcm9taXNlIGhhcyBiZWVuIGNhbmNlbGxlZDpfXG4gICAgICogaW4gdGhhdCBjYXNlLCBzaG91bGQgaXQgcmVqZWN0IG9yIHRocm93LCB0aGUgcmVhc29uIHdpbGwgYmUgd3JhcHBlZFxuICAgICAqIGluIGEge0BsaW5rIENhbmNlbGxlZFJlamVjdGlvbkVycm9yfSBhbmQgYnViYmxlZCB1cCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLlxuICAgICAqXG4gICAgICogSXQgaXMgZXF1aXZhbGVudCB0b1xuICAgICAqIGBgYHRzXG4gICAgICogY2FuY2VsbGFibGVQcm9taXNlLnRoZW4odW5kZWZpbmVkLCBvbnJlamVjdGVkLCBvbmNhbmNlbGxlZCk7XG4gICAgICogYGBgXG4gICAgICogYW5kIHRoZSBzYW1lIGNhdmVhdHMgYXBwbHkuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgZm9yIHRoZSBjb21wbGV0aW9uIG9mIHRoZSBjYWxsYmFjay5cbiAgICAgKiBDYW5jZWxsYXRpb24gcmVxdWVzdHMgb24gdGhlIHJldHVybmVkIHByb21pc2VcbiAgICAgKiB3aWxsIHByb3BhZ2F0ZSB1cCB0aGUgY2hhaW4gdG8gdGhlIHBhcmVudCBwcm9taXNlLFxuICAgICAqIGJ1dCBub3QgaW4gdGhlIG90aGVyIGRpcmVjdGlvbi5cbiAgICAgKlxuICAgICAqIFRoZSBwcm9taXNlIHJldHVybmVkIGZyb20ge0BsaW5rIGNhbmNlbH0gd2lsbCBmdWxmaWxsIG9ubHkgYWZ0ZXIgYWxsIGF0dGFjaGVkIGhhbmRsZXJzXG4gICAgICogdXAgdGhlIGVudGlyZSBwcm9taXNlIGNoYWluIGhhdmUgYmVlbiBydW4uXG4gICAgICpcbiAgICAgKiBJZiBgb25yZWplY3RlZGAgcmV0dXJucyBhIGNhbmNlbGxhYmxlIHByb21pc2UsXG4gICAgICogY2FuY2VsbGF0aW9uIHJlcXVlc3RzIHdpbGwgYmUgZGl2ZXJ0ZWQgdG8gaXQsXG4gICAgICogYW5kIHRoZSBzcGVjaWZpZWQgYG9uY2FuY2VsbGVkYCBjYWxsYmFjayB3aWxsIGJlIGRpc2NhcmRlZC5cbiAgICAgKiBTZWUge0BsaW5rIHRoZW59IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICovXG4gICAgY2F0Y2g8VFJlc3VsdCA9IG5ldmVyPihvbnJlamVjdGVkPzogKChyZWFzb246IGFueSkgPT4gKFByb21pc2VMaWtlPFRSZXN1bHQ+IHwgVFJlc3VsdCkpIHwgdW5kZWZpbmVkIHwgbnVsbCwgb25jYW5jZWxsZWQ/OiBDYW5jZWxsYWJsZVByb21pc2VDYW5jZWxsZXIpOiBDYW5jZWxsYWJsZVByb21pc2U8VCB8IFRSZXN1bHQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIG9ucmVqZWN0ZWQsIG9uY2FuY2VsbGVkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdHRhY2hlcyBhIGNhbGxiYWNrIHRoYXQgaXMgaW52b2tlZCB3aGVuIHRoZSBDYW5jZWxsYWJsZVByb21pc2UgaXMgc2V0dGxlZCAoZnVsZmlsbGVkIG9yIHJlamVjdGVkKS4gVGhlXG4gICAgICogcmVzb2x2ZWQgdmFsdWUgY2Fubm90IGJlIGFjY2Vzc2VkIG9yIG1vZGlmaWVkIGZyb20gdGhlIGNhbGxiYWNrLlxuICAgICAqIFRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgc2V0dGxlIGluIHRoZSBzYW1lIHN0YXRlIGFzIHRoZSBvcmlnaW5hbCBvbmVcbiAgICAgKiBhZnRlciB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgaGFzIGNvbXBsZXRlZCBleGVjdXRpb24sXG4gICAgICogdW5sZXNzIHRoZSBjYWxsYmFjayB0aHJvd3Mgb3IgcmV0dXJucyBhIHJlamVjdGluZyBwcm9taXNlLFxuICAgICAqIGluIHdoaWNoIGNhc2UgdGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCByZWplY3QgYXMgd2VsbC5cbiAgICAgKlxuICAgICAqIFRoZSBvcHRpb25hbCBgb25jYW5jZWxsZWRgIGFyZ3VtZW50IHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSByZXR1cm5lZCBwcm9taXNlIGlzIGNhbmNlbGxlZCxcbiAgICAgKiB3aXRoIHRoZSBzYW1lIHNlbWFudGljcyBhcyB0aGUgYG9uY2FuY2VsbGVkYCBhcmd1bWVudCBvZiB0aGUgY29uc3RydWN0b3IuXG4gICAgICogT25jZSB0aGUgcGFyZW50IHByb21pc2Ugc2V0dGxlcywgdGhlIGBvbmZpbmFsbHlgIGNhbGxiYWNrIHdpbGwgcnVuLFxuICAgICAqIF9ldmVuIGFmdGVyIHRoZSByZXR1cm5lZCBwcm9taXNlIGhhcyBiZWVuIGNhbmNlbGxlZDpfXG4gICAgICogaW4gdGhhdCBjYXNlLCBzaG91bGQgaXQgcmVqZWN0IG9yIHRocm93LCB0aGUgcmVhc29uIHdpbGwgYmUgd3JhcHBlZFxuICAgICAqIGluIGEge0BsaW5rIENhbmNlbGxlZFJlamVjdGlvbkVycm9yfSBhbmQgYnViYmxlZCB1cCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgaXMgaW1wbGVtZW50ZWQgaW4gdGVybXMgb2Yge0BsaW5rIHRoZW59IGFuZCB0aGUgc2FtZSBjYXZlYXRzIGFwcGx5LlxuICAgICAqIEl0IGlzIHBvbHlmaWxsZWQsIGhlbmNlIGF2YWlsYWJsZSBpbiBldmVyeSBPUy93ZWJ2aWV3IHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgZm9yIHRoZSBjb21wbGV0aW9uIG9mIHRoZSBjYWxsYmFjay5cbiAgICAgKiBDYW5jZWxsYXRpb24gcmVxdWVzdHMgb24gdGhlIHJldHVybmVkIHByb21pc2VcbiAgICAgKiB3aWxsIHByb3BhZ2F0ZSB1cCB0aGUgY2hhaW4gdG8gdGhlIHBhcmVudCBwcm9taXNlLFxuICAgICAqIGJ1dCBub3QgaW4gdGhlIG90aGVyIGRpcmVjdGlvbi5cbiAgICAgKlxuICAgICAqIFRoZSBwcm9taXNlIHJldHVybmVkIGZyb20ge0BsaW5rIGNhbmNlbH0gd2lsbCBmdWxmaWxsIG9ubHkgYWZ0ZXIgYWxsIGF0dGFjaGVkIGhhbmRsZXJzXG4gICAgICogdXAgdGhlIGVudGlyZSBwcm9taXNlIGNoYWluIGhhdmUgYmVlbiBydW4uXG4gICAgICpcbiAgICAgKiBJZiBgb25maW5hbGx5YCByZXR1cm5zIGEgY2FuY2VsbGFibGUgcHJvbWlzZSxcbiAgICAgKiBjYW5jZWxsYXRpb24gcmVxdWVzdHMgd2lsbCBiZSBkaXZlcnRlZCB0byBpdCxcbiAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBgb25jYW5jZWxsZWRgIGNhbGxiYWNrIHdpbGwgYmUgZGlzY2FyZGVkLlxuICAgICAqIFNlZSB7QGxpbmsgdGhlbn0gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKi9cbiAgICBmaW5hbGx5KG9uZmluYWxseT86ICgoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCB8IG51bGwsIG9uY2FuY2VsbGVkPzogQ2FuY2VsbGFibGVQcm9taXNlQ2FuY2VsbGVyKTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+IHtcbiAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENhbmNlbGxhYmxlUHJvbWlzZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmZpbmFsbHkgY2FsbGVkIG9uIGFuIGludmFsaWQgb2JqZWN0LlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNDYWxsYWJsZShvbmZpbmFsbHkpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50aGVuKG9uZmluYWxseSwgb25maW5hbGx5LCBvbmNhbmNlbGxlZCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy50aGVuKFxuICAgICAgICAgICAgKHZhbHVlKSA9PiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZShvbmZpbmFsbHkoKSkudGhlbigoKSA9PiB2YWx1ZSksXG4gICAgICAgICAgICAocmVhc29uPykgPT4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUob25maW5hbGx5KCkpLnRoZW4oKCkgPT4geyB0aHJvdyByZWFzb247IH0pLFxuICAgICAgICAgICAgb25jYW5jZWxsZWQsXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2UgdXNlIHRoZSBgW1N5bWJvbC5zcGVjaWVzXWAgc3RhdGljIHByb3BlcnR5LCBpZiBhdmFpbGFibGUsXG4gICAgICogdG8gZGlzYWJsZSB0aGUgYnVpbHQtaW4gYXV0b21hdGljIHN1YmNsYXNzaW5nIGZlYXR1cmVzIGZyb20ge0BsaW5rIFByb21pc2V9LlxuICAgICAqIEl0IGlzIGNyaXRpY2FsIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIHRoYXQgZXh0ZW5kZXJzIGRvIG5vdCBvdmVycmlkZSB0aGlzLlxuICAgICAqIE9uY2UgdGhlIHByb3Bvc2FsIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXJtLWJ1aWx0aW4tc3ViY2xhc3NpbmdcbiAgICAgKiBpcyBlaXRoZXIgYWNjZXB0ZWQgb3IgcmV0aXJlZCwgdGhpcyBpbXBsZW1lbnRhdGlvbiB3aWxsIGhhdmUgdG8gYmUgcmV2aXNlZCBhY2NvcmRpbmdseS5cbiAgICAgKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtzcGVjaWVzXSgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIENhbmNlbGxhYmxlUHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdpdGggYW4gYXJyYXkgb2YgcmVzdWx0c1xuICAgICAqIHdoZW4gYWxsIG9mIHRoZSBwcm92aWRlZCBQcm9taXNlcyByZXNvbHZlLCBvciByZWplY3RlZCB3aGVuIGFueSBQcm9taXNlIGlzIHJlamVjdGVkLlxuICAgICAqXG4gICAgICogRXZlcnkgb25lIG9mIHRoZSBwcm92aWRlZCBvYmplY3RzIHRoYXQgaXMgYSB0aGVuYWJsZSBfYW5kXyBjYW5jZWxsYWJsZSBvYmplY3RcbiAgICAgKiB3aWxsIGJlIGNhbmNlbGxlZCB3aGVuIHRoZSByZXR1cm5lZCBwcm9taXNlIGlzIGNhbmNlbGxlZCwgd2l0aCB0aGUgc2FtZSBjYXVzZS5cbiAgICAgKlxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xuICAgICAqL1xuICAgIHN0YXRpYyBhbGw8VD4odmFsdWVzOiBJdGVyYWJsZTxUIHwgUHJvbWlzZUxpa2U8VD4+KTogQ2FuY2VsbGFibGVQcm9taXNlPEF3YWl0ZWQ8VD5bXT47XG4gICAgc3RhdGljIGFsbDxUIGV4dGVuZHMgcmVhZG9ubHkgdW5rbm93bltdIHwgW10+KHZhbHVlczogVCk6IENhbmNlbGxhYmxlUHJvbWlzZTx7IC1yZWFkb25seSBbUCBpbiBrZXlvZiBUXTogQXdhaXRlZDxUW1BdPjsgfT47XG4gICAgc3RhdGljIGFsbDxUIGV4dGVuZHMgSXRlcmFibGU8dW5rbm93bj4gfCBBcnJheUxpa2U8dW5rbm93bj4+KHZhbHVlczogVCk6IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGxldCBjb2xsZWN0ZWQgPSBBcnJheS5mcm9tKHZhbHVlcyk7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBjb2xsZWN0ZWQubGVuZ3RoID09PSAwXG4gICAgICAgICAgICA/IENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKGNvbGxlY3RlZClcbiAgICAgICAgICAgIDogbmV3IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgdm9pZCBQcm9taXNlLmFsbChjb2xsZWN0ZWQpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgIH0sIChjYXVzZT8pOiBQcm9taXNlPHZvaWQ+ID0+IGNhbmNlbEFsbChwcm9taXNlLCBjb2xsZWN0ZWQsIGNhdXNlKSk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBDYW5jZWxsYWJsZVByb21pc2UgdGhhdCBpcyByZXNvbHZlZCB3aXRoIGFuIGFycmF5IG9mIHJlc3VsdHNcbiAgICAgKiB3aGVuIGFsbCBvZiB0aGUgcHJvdmlkZWQgUHJvbWlzZXMgcmVzb2x2ZSBvciByZWplY3QuXG4gICAgICpcbiAgICAgKiBFdmVyeSBvbmUgb2YgdGhlIHByb3ZpZGVkIG9iamVjdHMgdGhhdCBpcyBhIHRoZW5hYmxlIF9hbmRfIGNhbmNlbGxhYmxlIG9iamVjdFxuICAgICAqIHdpbGwgYmUgY2FuY2VsbGVkIHdoZW4gdGhlIHJldHVybmVkIHByb21pc2UgaXMgY2FuY2VsbGVkLCB3aXRoIHRoZSBzYW1lIGNhdXNlLlxuICAgICAqXG4gICAgICogQGdyb3VwIFN0YXRpYyBNZXRob2RzXG4gICAgICovXG4gICAgc3RhdGljIGFsbFNldHRsZWQ8VD4odmFsdWVzOiBJdGVyYWJsZTxUIHwgUHJvbWlzZUxpa2U8VD4+KTogQ2FuY2VsbGFibGVQcm9taXNlPFByb21pc2VTZXR0bGVkUmVzdWx0PEF3YWl0ZWQ8VD4+W10+O1xuICAgIHN0YXRpYyBhbGxTZXR0bGVkPFQgZXh0ZW5kcyByZWFkb25seSB1bmtub3duW10gfCBbXT4odmFsdWVzOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPHsgLXJlYWRvbmx5IFtQIGluIGtleW9mIFRdOiBQcm9taXNlU2V0dGxlZFJlc3VsdDxBd2FpdGVkPFRbUF0+PjsgfT47XG4gICAgc3RhdGljIGFsbFNldHRsZWQ8VCBleHRlbmRzIEl0ZXJhYmxlPHVua25vd24+IHwgQXJyYXlMaWtlPHVua25vd24+Pih2YWx1ZXM6IFQpOiBDYW5jZWxsYWJsZVByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICBsZXQgY29sbGVjdGVkID0gQXJyYXkuZnJvbSh2YWx1ZXMpO1xuICAgICAgICBjb25zdCBwcm9taXNlID0gY29sbGVjdGVkLmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgPyBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZShjb2xsZWN0ZWQpXG4gICAgICAgICAgICA6IG5ldyBDYW5jZWxsYWJsZVByb21pc2U8dW5rbm93bj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIHZvaWQgUHJvbWlzZS5hbGxTZXR0bGVkKGNvbGxlY3RlZCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgfSwgKGNhdXNlPyk6IFByb21pc2U8dm9pZD4gPT4gY2FuY2VsQWxsKHByb21pc2UsIGNvbGxlY3RlZCwgY2F1c2UpKTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGFueSBmdW5jdGlvbiByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCBieSB0aGUgZmlyc3QgZ2l2ZW4gcHJvbWlzZSB0byBiZSBmdWxmaWxsZWQsXG4gICAgICogb3IgcmVqZWN0ZWQgd2l0aCBhbiBBZ2dyZWdhdGVFcnJvciBjb250YWluaW5nIGFuIGFycmF5IG9mIHJlamVjdGlvbiByZWFzb25zXG4gICAgICogaWYgYWxsIG9mIHRoZSBnaXZlbiBwcm9taXNlcyBhcmUgcmVqZWN0ZWQuXG4gICAgICogSXQgcmVzb2x2ZXMgYWxsIGVsZW1lbnRzIG9mIHRoZSBwYXNzZWQgaXRlcmFibGUgdG8gcHJvbWlzZXMgYXMgaXQgcnVucyB0aGlzIGFsZ29yaXRobS5cbiAgICAgKlxuICAgICAqIEV2ZXJ5IG9uZSBvZiB0aGUgcHJvdmlkZWQgb2JqZWN0cyB0aGF0IGlzIGEgdGhlbmFibGUgX2FuZF8gY2FuY2VsbGFibGUgb2JqZWN0XG4gICAgICogd2lsbCBiZSBjYW5jZWxsZWQgd2hlbiB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBjYW5jZWxsZWQsIHdpdGggdGhlIHNhbWUgY2F1c2UuXG4gICAgICpcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcbiAgICAgKi9cbiAgICBzdGF0aWMgYW55PFQ+KHZhbHVlczogSXRlcmFibGU8VCB8IFByb21pc2VMaWtlPFQ+Pik6IENhbmNlbGxhYmxlUHJvbWlzZTxBd2FpdGVkPFQ+PjtcbiAgICBzdGF0aWMgYW55PFQgZXh0ZW5kcyByZWFkb25seSB1bmtub3duW10gfCBbXT4odmFsdWVzOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPEF3YWl0ZWQ8VFtudW1iZXJdPj47XG4gICAgc3RhdGljIGFueTxUIGV4dGVuZHMgSXRlcmFibGU8dW5rbm93bj4gfCBBcnJheUxpa2U8dW5rbm93bj4+KHZhbHVlczogVCk6IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGxldCBjb2xsZWN0ZWQgPSBBcnJheS5mcm9tKHZhbHVlcyk7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBjb2xsZWN0ZWQubGVuZ3RoID09PSAwXG4gICAgICAgICAgICA/IENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKGNvbGxlY3RlZClcbiAgICAgICAgICAgIDogbmV3IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgdm9pZCBQcm9taXNlLmFueShjb2xsZWN0ZWQpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgIH0sIChjYXVzZT8pOiBQcm9taXNlPHZvaWQ+ID0+IGNhbmNlbEFsbChwcm9taXNlLCBjb2xsZWN0ZWQsIGNhdXNlKSk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBQcm9taXNlIHRoYXQgaXMgcmVzb2x2ZWQgb3IgcmVqZWN0ZWQgd2hlbiBhbnkgb2YgdGhlIHByb3ZpZGVkIFByb21pc2VzIGFyZSByZXNvbHZlZCBvciByZWplY3RlZC5cbiAgICAgKlxuICAgICAqIEV2ZXJ5IG9uZSBvZiB0aGUgcHJvdmlkZWQgb2JqZWN0cyB0aGF0IGlzIGEgdGhlbmFibGUgX2FuZF8gY2FuY2VsbGFibGUgb2JqZWN0XG4gICAgICogd2lsbCBiZSBjYW5jZWxsZWQgd2hlbiB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBjYW5jZWxsZWQsIHdpdGggdGhlIHNhbWUgY2F1c2UuXG4gICAgICpcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcbiAgICAgKi9cbiAgICBzdGF0aWMgcmFjZTxUPih2YWx1ZXM6IEl0ZXJhYmxlPFQgfCBQcm9taXNlTGlrZTxUPj4pOiBDYW5jZWxsYWJsZVByb21pc2U8QXdhaXRlZDxUPj47XG4gICAgc3RhdGljIHJhY2U8VCBleHRlbmRzIHJlYWRvbmx5IHVua25vd25bXSB8IFtdPih2YWx1ZXM6IFQpOiBDYW5jZWxsYWJsZVByb21pc2U8QXdhaXRlZDxUW251bWJlcl0+PjtcbiAgICBzdGF0aWMgcmFjZTxUIGV4dGVuZHMgSXRlcmFibGU8dW5rbm93bj4gfCBBcnJheUxpa2U8dW5rbm93bj4+KHZhbHVlczogVCk6IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGxldCBjb2xsZWN0ZWQgPSBBcnJheS5mcm9tKHZhbHVlcyk7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPHVua25vd24+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHZvaWQgUHJvbWlzZS5yYWNlKGNvbGxlY3RlZCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9LCAoY2F1c2U/KTogUHJvbWlzZTx2b2lkPiA9PiBjYW5jZWxBbGwocHJvbWlzZSwgY29sbGVjdGVkLCBjYXVzZSkpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGNhbmNlbGxlZCBDYW5jZWxsYWJsZVByb21pc2UgZm9yIHRoZSBwcm92aWRlZCBjYXVzZS5cbiAgICAgKlxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xuICAgICAqL1xuICAgIHN0YXRpYyBjYW5jZWw8VCA9IG5ldmVyPihjYXVzZT86IGFueSk6IENhbmNlbGxhYmxlUHJvbWlzZTxUPiB7XG4gICAgICAgIGNvbnN0IHAgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPFQ+KCgpID0+IHt9KTtcbiAgICAgICAgcC5jYW5jZWwoY2F1c2UpO1xuICAgICAgICByZXR1cm4gcDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IENhbmNlbGxhYmxlUHJvbWlzZSB0aGF0IGNhbmNlbHNcbiAgICAgKiBhZnRlciB0aGUgc3BlY2lmaWVkIHRpbWVvdXQsIHdpdGggdGhlIHByb3ZpZGVkIGNhdXNlLlxuICAgICAqXG4gICAgICogSWYgdGhlIHtAbGluayBBYm9ydFNpZ25hbC50aW1lb3V0fSBmYWN0b3J5IG1ldGhvZCBpcyBhdmFpbGFibGUsXG4gICAgICogaXQgaXMgdXNlZCB0byBiYXNlIHRoZSB0aW1lb3V0IG9uIF9hY3RpdmVfIHRpbWUgcmF0aGVyIHRoYW4gX2VsYXBzZWRfIHRpbWUuXG4gICAgICogT3RoZXJ3aXNlLCBgdGltZW91dGAgZmFsbHMgYmFjayB0byB7QGxpbmsgc2V0VGltZW91dH0uXG4gICAgICpcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcbiAgICAgKi9cbiAgICBzdGF0aWMgdGltZW91dDxUID0gbmV2ZXI+KG1pbGxpc2Vjb25kczogbnVtYmVyLCBjYXVzZT86IGFueSk6IENhbmNlbGxhYmxlUHJvbWlzZTxUPiB7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPFQ+KCgpID0+IHt9KTtcbiAgICAgICAgaWYgKEFib3J0U2lnbmFsICYmIHR5cGVvZiBBYm9ydFNpZ25hbCA9PT0gJ2Z1bmN0aW9uJyAmJiBBYm9ydFNpZ25hbC50aW1lb3V0ICYmIHR5cGVvZiBBYm9ydFNpZ25hbC50aW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBBYm9ydFNpZ25hbC50aW1lb3V0KG1pbGxpc2Vjb25kcykuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCAoKSA9PiB2b2lkIHByb21pc2UuY2FuY2VsKGNhdXNlKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHZvaWQgcHJvbWlzZS5jYW5jZWwoY2F1c2UpLCBtaWxsaXNlY29uZHMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCB0aW1lb3V0LlxuICAgICAqIFRoZSByZXR1cm5lZCBwcm9taXNlIGNhbiBiZSBjYW5jZWxsZWQgd2l0aG91dCBjb25zZXF1ZW5jZXMuXG4gICAgICpcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcbiAgICAgKi9cbiAgICBzdGF0aWMgc2xlZXAobWlsbGlzZWNvbmRzOiBudW1iZXIpOiBDYW5jZWxsYWJsZVByb21pc2U8dm9pZD47XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBDYW5jZWxsYWJsZVByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlclxuICAgICAqIHRoZSBzcGVjaWZpZWQgdGltZW91dCwgd2l0aCB0aGUgcHJvdmlkZWQgdmFsdWUuXG4gICAgICogVGhlIHJldHVybmVkIHByb21pc2UgY2FuIGJlIGNhbmNlbGxlZCB3aXRob3V0IGNvbnNlcXVlbmNlcy5cbiAgICAgKlxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xuICAgICAqL1xuICAgIHN0YXRpYyBzbGVlcDxUPihtaWxsaXNlY29uZHM6IG51bWJlciwgdmFsdWU6IFQpOiBDYW5jZWxsYWJsZVByb21pc2U8VD47XG4gICAgc3RhdGljIHNsZWVwPFQgPSB2b2lkPihtaWxsaXNlY29uZHM6IG51bWJlciwgdmFsdWU/OiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2U8VD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZSh2YWx1ZSEpLCBtaWxsaXNlY29uZHMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHJlamVjdGVkIENhbmNlbGxhYmxlUHJvbWlzZSBmb3IgdGhlIHByb3ZpZGVkIHJlYXNvbi5cbiAgICAgKlxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xuICAgICAqL1xuICAgIHN0YXRpYyByZWplY3Q8VCA9IG5ldmVyPihyZWFzb24/OiBhbnkpOiBDYW5jZWxsYWJsZVByb21pc2U8VD4ge1xuICAgICAgICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTxUPigoXywgcmVqZWN0KSA9PiByZWplY3QocmVhc29uKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyByZXNvbHZlZCBDYW5jZWxsYWJsZVByb21pc2UuXG4gICAgICpcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcbiAgICAgKi9cbiAgICBzdGF0aWMgcmVzb2x2ZSgpOiBDYW5jZWxsYWJsZVByb21pc2U8dm9pZD47XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyByZXNvbHZlZCBDYW5jZWxsYWJsZVByb21pc2UgZm9yIHRoZSBwcm92aWRlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xuICAgICAqL1xuICAgIHN0YXRpYyByZXNvbHZlPFQ+KHZhbHVlOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPEF3YWl0ZWQ8VD4+O1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgcmVzb2x2ZWQgQ2FuY2VsbGFibGVQcm9taXNlIGZvciB0aGUgcHJvdmlkZWQgdmFsdWUuXG4gICAgICpcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcbiAgICAgKi9cbiAgICBzdGF0aWMgcmVzb2x2ZTxUPih2YWx1ZTogVCB8IFByb21pc2VMaWtlPFQ+KTogQ2FuY2VsbGFibGVQcm9taXNlPEF3YWl0ZWQ8VD4+O1xuICAgIHN0YXRpYyByZXNvbHZlPFQgPSB2b2lkPih2YWx1ZT86IFQgfCBQcm9taXNlTGlrZTxUPik6IENhbmNlbGxhYmxlUHJvbWlzZTxBd2FpdGVkPFQ+PiB7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIENhbmNlbGxhYmxlUHJvbWlzZSkge1xuICAgICAgICAgICAgLy8gT3B0aW1pc2UgZm9yIGNhbmNlbGxhYmxlIHByb21pc2VzLlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPGFueT4oKHJlc29sdmUpID0+IHJlc29sdmUodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IENhbmNlbGxhYmxlUHJvbWlzZSBhbmQgcmV0dXJucyBpdCBpbiBhbiBvYmplY3QsIGFsb25nIHdpdGggaXRzIHJlc29sdmUgYW5kIHJlamVjdCBmdW5jdGlvbnNcbiAgICAgKiBhbmQgYSBnZXR0ZXIvc2V0dGVyIGZvciB0aGUgY2FuY2VsbGF0aW9uIGNhbGxiYWNrLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgaXMgcG9seWZpbGxlZCwgaGVuY2UgYXZhaWxhYmxlIGluIGV2ZXJ5IE9TL3dlYnZpZXcgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xuICAgICAqL1xuICAgIHN0YXRpYyB3aXRoUmVzb2x2ZXJzPFQ+KCk6IENhbmNlbGxhYmxlUHJvbWlzZVdpdGhSZXNvbHZlcnM8VD4ge1xuICAgICAgICBsZXQgcmVzdWx0OiBDYW5jZWxsYWJsZVByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+ID0geyBvbmNhbmNlbGxlZDogbnVsbCB9IGFzIGFueTtcbiAgICAgICAgcmVzdWx0LnByb21pc2UgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc3VsdC5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlc3VsdC5yZWplY3QgPSByZWplY3Q7XG4gICAgICAgIH0sIChjYXVzZT86IGFueSkgPT4geyByZXN1bHQub25jYW5jZWxsZWQ/LihjYXVzZSk7IH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgY2FsbGJhY2sgdGhhdCBpbXBsZW1lbnRzIHRoZSBjYW5jZWxsYXRpb24gYWxnb3JpdGhtIGZvciB0aGUgZ2l2ZW4gY2FuY2VsbGFibGUgcHJvbWlzZS5cbiAqIFRoZSBwcm9taXNlIHJldHVybmVkIGZyb20gdGhlIHJlc3VsdGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZWplY3QuXG4gKi9cbmZ1bmN0aW9uIGNhbmNlbGxlckZvcjxUPihwcm9taXNlOiBDYW5jZWxsYWJsZVByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+LCBzdGF0ZTogQ2FuY2VsbGFibGVQcm9taXNlU3RhdGUpIHtcbiAgICBsZXQgY2FuY2VsbGF0aW9uUHJvbWlzZTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+ID0gdW5kZWZpbmVkO1xuXG4gICAgcmV0dXJuIChyZWFzb246IENhbmNlbEVycm9yKTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+ID0+IHtcbiAgICAgICAgaWYgKCFzdGF0ZS5zZXR0bGVkKSB7XG4gICAgICAgICAgICBzdGF0ZS5zZXR0bGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHN0YXRlLnJlYXNvbiA9IHJlYXNvbjtcbiAgICAgICAgICAgIHByb21pc2UucmVqZWN0KHJlYXNvbik7XG5cbiAgICAgICAgICAgIC8vIEF0dGFjaCBhbiBlcnJvciBoYW5kbGVyIHRoYXQgaWdub3JlcyB0aGlzIHNwZWNpZmljIHJlamVjdGlvbiByZWFzb24gYW5kIG5vdGhpbmcgZWxzZS5cbiAgICAgICAgICAgIC8vIEluIHRoZW9yeSwgYSBzYW5lIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gYXQgdGhpcyBwb2ludFxuICAgICAgICAgICAgLy8gc2hvdWxkIGFsd2F5cyByZWplY3Qgd2l0aCBvdXIgY2FuY2VsbGF0aW9uIHJlYXNvbixcbiAgICAgICAgICAgIC8vIGhlbmNlIHRoZSBoYW5kbGVyIHdpbGwgbmV2ZXIgdGhyb3cuXG4gICAgICAgICAgICB2b2lkIFByb21pc2UucHJvdG90eXBlLnRoZW4uY2FsbChwcm9taXNlLnByb21pc2UsIHVuZGVmaW5lZCwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnIgIT09IHJlYXNvbikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiByZWFzb24gaXMgbm90IHNldCwgdGhlIHByb21pc2UgcmVzb2x2ZWQgcmVndWxhcmx5LCBoZW5jZSB3ZSBtdXN0IG5vdCBjYWxsIG9uY2FuY2VsbGVkLlxuICAgICAgICAvLyBJZiBvbmNhbmNlbGxlZCBpcyB1bnNldCwgbm8gbmVlZCB0byBnbyBhbnkgZnVydGhlci5cbiAgICAgICAgaWYgKCFzdGF0ZS5yZWFzb24gfHwgIXByb21pc2Uub25jYW5jZWxsZWQpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgY2FuY2VsbGF0aW9uUHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc29sdmUocHJvbWlzZS5vbmNhbmNlbGxlZCEoc3RhdGUucmVhc29uIS5jYXVzZSkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxlZFJlamVjdGlvbkVycm9yKHByb21pc2UucHJvbWlzZSwgZXJyLCBcIlVuaGFuZGxlZCBleGNlcHRpb24gaW4gb25jYW5jZWxsZWQgY2FsbGJhY2suXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkuY2F0Y2goKHJlYXNvbj8pID0+IHtcbiAgICAgICAgICAgIFByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsZWRSZWplY3Rpb25FcnJvcihwcm9taXNlLnByb21pc2UsIHJlYXNvbiwgXCJVbmhhbmRsZWQgcmVqZWN0aW9uIGluIG9uY2FuY2VsbGVkIGNhbGxiYWNrLlwiKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFVuc2V0IG9uY2FuY2VsbGVkIHRvIHByZXZlbnQgcmVwZWF0ZWQgY2FsbHMuXG4gICAgICAgIHByb21pc2Uub25jYW5jZWxsZWQgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiBjYW5jZWxsYXRpb25Qcm9taXNlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgY2FsbGJhY2sgdGhhdCBpbXBsZW1lbnRzIHRoZSByZXNvbHV0aW9uIGFsZ29yaXRobSBmb3IgdGhlIGdpdmVuIGNhbmNlbGxhYmxlIHByb21pc2UuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVyRm9yPFQ+KHByb21pc2U6IENhbmNlbGxhYmxlUHJvbWlzZVdpdGhSZXNvbHZlcnM8VD4sIHN0YXRlOiBDYW5jZWxsYWJsZVByb21pc2VTdGF0ZSk6IENhbmNlbGxhYmxlUHJvbWlzZVJlc29sdmVyPFQ+IHtcbiAgICByZXR1cm4gKHZhbHVlKSA9PiB7XG4gICAgICAgIGlmIChzdGF0ZS5yZXNvbHZpbmcpIHsgcmV0dXJuOyB9XG4gICAgICAgIHN0YXRlLnJlc29sdmluZyA9IHRydWU7XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSBwcm9taXNlLnByb21pc2UpIHtcbiAgICAgICAgICAgIGlmIChzdGF0ZS5zZXR0bGVkKSB7IHJldHVybjsgfVxuICAgICAgICAgICAgc3RhdGUuc2V0dGxlZCA9IHRydWU7XG4gICAgICAgICAgICBwcm9taXNlLnJlamVjdChuZXcgVHlwZUVycm9yKFwiQSBwcm9taXNlIGNhbm5vdCBiZSByZXNvbHZlZCB3aXRoIGl0c2VsZi5cIikpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgICAgICAgbGV0IHRoZW46IGFueTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhlbiA9ICh2YWx1ZSBhcyBhbnkpLnRoZW47XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBzdGF0ZS5zZXR0bGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzQ2FsbGFibGUodGhlbikpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY2FuY2VsID0gKHZhbHVlIGFzIGFueSkuY2FuY2VsO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNDYWxsYWJsZShjYW5jZWwpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbmNhbmNlbGxlZCA9IChjYXVzZT86IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmxlY3QuYXBwbHkoY2FuY2VsLCB2YWx1ZSwgW2NhdXNlXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlLnJlYXNvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGFscmVhZHkgY2FuY2VsbGVkLCBwcm9wYWdhdGUgY2FuY2VsbGF0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBwcm9taXNlIHJldHVybmVkIGZyb20gdGhlIGNhbmNlbGxlciBhbGdvcml0aG0gZG9lcyBub3QgcmVqZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gaXQgY2FuIGJlIGRpc2NhcmRlZCBzYWZlbHkuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCBjYW5jZWxsZXJGb3IoeyAuLi5wcm9taXNlLCBvbmNhbmNlbGxlZCB9LCBzdGF0ZSkoc3RhdGUucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZS5vbmNhbmNlbGxlZCA9IG9uY2FuY2VsbGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCB7fVxuXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U3RhdGU6IENhbmNlbGxhYmxlUHJvbWlzZVN0YXRlID0ge1xuICAgICAgICAgICAgICAgICAgICByb290OiBzdGF0ZS5yb290LFxuICAgICAgICAgICAgICAgICAgICByZXNvbHZpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBnZXQgc2V0dGxlZCgpIHsgcmV0dXJuIHRoaXMucm9vdC5zZXR0bGVkIH0sXG4gICAgICAgICAgICAgICAgICAgIHNldCBzZXR0bGVkKHZhbHVlKSB7IHRoaXMucm9vdC5zZXR0bGVkID0gdmFsdWU7IH0sXG4gICAgICAgICAgICAgICAgICAgIGdldCByZWFzb24oKSB7IHJldHVybiB0aGlzLnJvb3QucmVhc29uIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcmVqZWN0b3IgPSByZWplY3RvckZvcihwcm9taXNlLCBuZXdTdGF0ZSk7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgUmVmbGVjdC5hcHBseSh0aGVuLCB2YWx1ZSwgW3Jlc29sdmVyRm9yKHByb21pc2UsIG5ld1N0YXRlKSwgcmVqZWN0b3JdKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0b3IoZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBJTVBPUlRBTlQhXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdGUuc2V0dGxlZCkgeyByZXR1cm47IH1cbiAgICAgICAgc3RhdGUuc2V0dGxlZCA9IHRydWU7XG4gICAgICAgIHByb21pc2UucmVzb2x2ZSh2YWx1ZSk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgY2FsbGJhY2sgdGhhdCBpbXBsZW1lbnRzIHRoZSByZWplY3Rpb24gYWxnb3JpdGhtIGZvciB0aGUgZ2l2ZW4gY2FuY2VsbGFibGUgcHJvbWlzZS5cbiAqL1xuZnVuY3Rpb24gcmVqZWN0b3JGb3I8VD4ocHJvbWlzZTogQ2FuY2VsbGFibGVQcm9taXNlV2l0aFJlc29sdmVyczxUPiwgc3RhdGU6IENhbmNlbGxhYmxlUHJvbWlzZVN0YXRlKTogQ2FuY2VsbGFibGVQcm9taXNlUmVqZWN0b3Ige1xuICAgIHJldHVybiAocmVhc29uPykgPT4ge1xuICAgICAgICBpZiAoc3RhdGUucmVzb2x2aW5nKSB7IHJldHVybjsgfVxuICAgICAgICBzdGF0ZS5yZXNvbHZpbmcgPSB0cnVlO1xuXG4gICAgICAgIGlmIChzdGF0ZS5zZXR0bGVkKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChyZWFzb24gaW5zdGFuY2VvZiBDYW5jZWxFcnJvciAmJiBzdGF0ZS5yZWFzb24gaW5zdGFuY2VvZiBDYW5jZWxFcnJvciAmJiBPYmplY3QuaXMocmVhc29uLmNhdXNlLCBzdGF0ZS5yZWFzb24uY2F1c2UpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN3YWxsb3cgbGF0ZSByZWplY3Rpb25zIHRoYXQgYXJlIENhbmNlbEVycm9ycyB3aG9zZSBjYW5jZWxsYXRpb24gY2F1c2UgaXMgdGhlIHNhbWUgYXMgb3Vycy5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2gge31cblxuICAgICAgICAgICAgdm9pZCBQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGVkUmVqZWN0aW9uRXJyb3IocHJvbWlzZS5wcm9taXNlLCByZWFzb24pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0YXRlLnNldHRsZWQgPSB0cnVlO1xuICAgICAgICAgICAgcHJvbWlzZS5yZWplY3QocmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBDYW5jZWxzIGFsbCB2YWx1ZXMgaW4gYW4gYXJyYXkgdGhhdCBsb29rIGxpa2UgY2FuY2VsbGFibGUgdGhlbmFibGVzLlxuICogUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBvbmNlIGFsbCBjYW5jZWxsYXRpb24gcHJvY2VkdXJlcyBmb3IgdGhlIGdpdmVuIHZhbHVlcyBoYXZlIHNldHRsZWQuXG4gKi9cbmZ1bmN0aW9uIGNhbmNlbEFsbChwYXJlbnQ6IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPiwgdmFsdWVzOiBhbnlbXSwgY2F1c2U/OiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXN1bHRzID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykge1xuICAgICAgICBsZXQgY2FuY2VsOiBDYW5jZWxsYWJsZVByb21pc2VDYW5jZWxsZXI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUodmFsdWUudGhlbikpIHsgY29udGludWU7IH1cbiAgICAgICAgICAgIGNhbmNlbCA9IHZhbHVlLmNhbmNlbDtcbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYW5jZWwpKSB7IGNvbnRpbnVlOyB9XG4gICAgICAgIH0gY2F0Y2ggeyBjb250aW51ZTsgfVxuXG4gICAgICAgIGxldCByZXN1bHQ6IHZvaWQgfCBQcm9taXNlTGlrZTx2b2lkPjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoY2FuY2VsLCB2YWx1ZSwgW2NhdXNlXSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxlZFJlamVjdGlvbkVycm9yKHBhcmVudCwgZXJyLCBcIlVuaGFuZGxlZCBleGNlcHRpb24gaW4gY2FuY2VsIG1ldGhvZC5cIikpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXJlc3VsdCkgeyBjb250aW51ZTsgfVxuICAgICAgICByZXN1bHRzLnB1c2goXG4gICAgICAgICAgICAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSAgPyByZXN1bHQgOiBQcm9taXNlLnJlc29sdmUocmVzdWx0KSkuY2F0Y2goKHJlYXNvbj8pID0+IHtcbiAgICAgICAgICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGVkUmVqZWN0aW9uRXJyb3IocGFyZW50LCByZWFzb24sIFwiVW5oYW5kbGVkIHJlamVjdGlvbiBpbiBjYW5jZWwgbWV0aG9kLlwiKSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLmFsbChyZXN1bHRzKSBhcyBhbnk7XG59XG5cbi8qKlxuICogUmV0dXJucyBpdHMgYXJndW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5PFQ+KHg6IFQpOiBUIHtcbiAgICByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBUaHJvd3MgaXRzIGFyZ3VtZW50LlxuICovXG5mdW5jdGlvbiB0aHJvd2VyKHJlYXNvbj86IGFueSk6IG5ldmVyIHtcbiAgICB0aHJvdyByZWFzb247XG59XG5cbi8qKlxuICogQXR0ZW1wdHMgdmFyaW91cyBzdHJhdGVnaWVzIHRvIGNvbnZlcnQgYW4gZXJyb3IgdG8gYSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGVycm9yTWVzc2FnZShlcnI6IGFueSk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yIHx8IHR5cGVvZiBlcnIgIT09ICdvYmplY3QnIHx8IGVyci50b1N0cmluZyAhPT0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZykge1xuICAgICAgICAgICAgcmV0dXJuIFwiXCIgKyBlcnI7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIHt9XG5cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZXJyKTtcbiAgICB9IGNhdGNoIHt9XG5cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGVycik7XG4gICAgfSBjYXRjaCB7fVxuXG4gICAgcmV0dXJuIFwiPGNvdWxkIG5vdCBjb252ZXJ0IGVycm9yIHRvIHN0cmluZz5cIjtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBjdXJyZW50IGJhcnJpZXIgcHJvbWlzZSBmb3IgdGhlIGdpdmVuIGNhbmNlbGxhYmxlIHByb21pc2UuIElmIG5lY2Vzc2FyeSwgaW5pdGlhbGlzZXMgdGhlIGJhcnJpZXIuXG4gKi9cbmZ1bmN0aW9uIGN1cnJlbnRCYXJyaWVyPFQ+KHByb21pc2U6IENhbmNlbGxhYmxlUHJvbWlzZTxUPik6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCBwd3I6IFBhcnRpYWw8UHJvbWlzZVdpdGhSZXNvbHZlcnM8dm9pZD4+ID0gcHJvbWlzZVtiYXJyaWVyU3ltXSA/PyB7fTtcbiAgICBpZiAoISgncHJvbWlzZScgaW4gcHdyKSkge1xuICAgICAgICBPYmplY3QuYXNzaWduKHB3ciwgcHJvbWlzZVdpdGhSZXNvbHZlcnM8dm9pZD4oKSk7XG4gICAgfVxuICAgIGlmIChwcm9taXNlW2JhcnJpZXJTeW1dID09IG51bGwpIHtcbiAgICAgICAgcHdyLnJlc29sdmUhKCk7XG4gICAgICAgIHByb21pc2VbYmFycmllclN5bV0gPSBwd3I7XG4gICAgfVxuICAgIHJldHVybiBwd3IucHJvbWlzZSE7XG59XG5cbi8vIFBvbHlmaWxsIFByb21pc2Uud2l0aFJlc29sdmVycy5cbmxldCBwcm9taXNlV2l0aFJlc29sdmVycyA9IFByb21pc2Uud2l0aFJlc29sdmVycztcbmlmIChwcm9taXNlV2l0aFJlc29sdmVycyAmJiB0eXBlb2YgcHJvbWlzZVdpdGhSZXNvbHZlcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBwcm9taXNlV2l0aFJlc29sdmVycyA9IHByb21pc2VXaXRoUmVzb2x2ZXJzLmJpbmQoUHJvbWlzZSk7XG59IGVsc2Uge1xuICAgIHByb21pc2VXaXRoUmVzb2x2ZXJzID0gZnVuY3Rpb24gPFQ+KCk6IFByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+IHtcbiAgICAgICAgbGV0IHJlc29sdmUhOiAodmFsdWU6IFQgfCBQcm9taXNlTGlrZTxUPikgPT4gdm9pZDtcbiAgICAgICAgbGV0IHJlamVjdCE6IChyZWFzb24/OiBhbnkpID0+IHZvaWQ7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZTxUPigocmVzLCByZWopID0+IHsgcmVzb2x2ZSA9IHJlczsgcmVqZWN0ID0gcmVqOyB9KTtcbiAgICAgICAgcmV0dXJuIHsgcHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0IH07XG4gICAgfVxufSIsICIvKlxuIF9cdCAgIF9fXHQgIF8gX19cbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xuXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcihvYmplY3ROYW1lcy5DbGlwYm9hcmQpO1xuXG5jb25zdCBDbGlwYm9hcmRTZXRUZXh0ID0gMDtcbmNvbnN0IENsaXBib2FyZFRleHQgPSAxO1xuXG4vKipcbiAqIFNldHMgdGhlIHRleHQgdG8gdGhlIENsaXBib2FyZC5cbiAqXG4gKiBAcGFyYW0gdGV4dCAtIFRoZSB0ZXh0IHRvIGJlIHNldCB0byB0aGUgQ2xpcGJvYXJkLlxuICogQHJldHVybiBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgc3VjY2Vzc2Z1bC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNldFRleHQodGV4dDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGNhbGwoQ2xpcGJvYXJkU2V0VGV4dCwge3RleHR9KTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIENsaXBib2FyZCB0ZXh0XG4gKlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgdGV4dCBmcm9tIHRoZSBDbGlwYm9hcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUZXh0KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIGNhbGwoQ2xpcGJvYXJkVGV4dCk7XG59XG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbi8qKlxuICogQW55IGlzIGEgZHVtbXkgY3JlYXRpb24gZnVuY3Rpb24gZm9yIHNpbXBsZSBvciB1bmtub3duIHR5cGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gQW55PFQgPSBhbnk+KHNvdXJjZTogYW55KTogVCB7XG4gICAgcmV0dXJuIHNvdXJjZTtcbn1cblxuLyoqXG4gKiBCeXRlU2xpY2UgaXMgYSBjcmVhdGlvbiBmdW5jdGlvbiB0aGF0IHJlcGxhY2VzXG4gKiBudWxsIHN0cmluZ3Mgd2l0aCBlbXB0eSBzdHJpbmdzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gQnl0ZVNsaWNlKHNvdXJjZTogYW55KTogc3RyaW5nIHtcbiAgICByZXR1cm4gKChzb3VyY2UgPT0gbnVsbCkgPyBcIlwiIDogc291cmNlKTtcbn1cblxuLyoqXG4gKiBBcnJheSB0YWtlcyBhIGNyZWF0aW9uIGZ1bmN0aW9uIGZvciBhbiBhcmJpdHJhcnkgdHlwZVxuICogYW5kIHJldHVybnMgYW4gaW4tcGxhY2UgY3JlYXRpb24gZnVuY3Rpb24gZm9yIGFuIGFycmF5XG4gKiB3aG9zZSBlbGVtZW50cyBhcmUgb2YgdGhhdCB0eXBlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gQXJyYXk8VCA9IGFueT4oZWxlbWVudDogKHNvdXJjZTogYW55KSA9PiBUKTogKHNvdXJjZTogYW55KSA9PiBUW10ge1xuICAgIGlmIChlbGVtZW50ID09PSBBbnkpIHtcbiAgICAgICAgcmV0dXJuIChzb3VyY2UpID0+IChzb3VyY2UgPT09IG51bGwgPyBbXSA6IHNvdXJjZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIChzb3VyY2UpID0+IHtcbiAgICAgICAgaWYgKHNvdXJjZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzb3VyY2VbaV0gPSBlbGVtZW50KHNvdXJjZVtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9O1xufVxuXG4vKipcbiAqIE1hcCB0YWtlcyBjcmVhdGlvbiBmdW5jdGlvbnMgZm9yIHR3byBhcmJpdHJhcnkgdHlwZXNcbiAqIGFuZCByZXR1cm5zIGFuIGluLXBsYWNlIGNyZWF0aW9uIGZ1bmN0aW9uIGZvciBhbiBvYmplY3RcbiAqIHdob3NlIGtleXMgYW5kIHZhbHVlcyBhcmUgb2YgdGhvc2UgdHlwZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBNYXA8ViA9IGFueT4oa2V5OiAoc291cmNlOiBhbnkpID0+IHN0cmluZywgdmFsdWU6IChzb3VyY2U6IGFueSkgPT4gVik6IChzb3VyY2U6IGFueSkgPT4gUmVjb3JkPHN0cmluZywgVj4ge1xuICAgIGlmICh2YWx1ZSA9PT0gQW55KSB7XG4gICAgICAgIHJldHVybiAoc291cmNlKSA9PiAoc291cmNlID09PSBudWxsID8ge30gOiBzb3VyY2UpO1xuICAgIH1cblxuICAgIHJldHVybiAoc291cmNlKSA9PiB7XG4gICAgICAgIGlmIChzb3VyY2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIHNvdXJjZVtrZXldID0gdmFsdWUoc291cmNlW2tleV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBOdWxsYWJsZSB0YWtlcyBhIGNyZWF0aW9uIGZ1bmN0aW9uIGZvciBhbiBhcmJpdHJhcnkgdHlwZVxuICogYW5kIHJldHVybnMgYSBjcmVhdGlvbiBmdW5jdGlvbiBmb3IgYSBudWxsYWJsZSB2YWx1ZSBvZiB0aGF0IHR5cGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBOdWxsYWJsZTxUID0gYW55PihlbGVtZW50OiAoc291cmNlOiBhbnkpID0+IFQpOiAoc291cmNlOiBhbnkpID0+IChUIHwgbnVsbCkge1xuICAgIGlmIChlbGVtZW50ID09PSBBbnkpIHtcbiAgICAgICAgcmV0dXJuIEFueTtcbiAgICB9XG5cbiAgICByZXR1cm4gKHNvdXJjZSkgPT4gKHNvdXJjZSA9PT0gbnVsbCA/IG51bGwgOiBlbGVtZW50KHNvdXJjZSkpO1xufVxuXG4vKipcbiAqIFN0cnVjdCB0YWtlcyBhbiBvYmplY3QgbWFwcGluZyBmaWVsZCBuYW1lcyB0byBjcmVhdGlvbiBmdW5jdGlvbnNcbiAqIGFuZCByZXR1cm5zIGFuIGluLXBsYWNlIGNyZWF0aW9uIGZ1bmN0aW9uIGZvciBhIHN0cnVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFN0cnVjdChjcmVhdGVGaWVsZDogUmVjb3JkPHN0cmluZywgKHNvdXJjZTogYW55KSA9PiBhbnk+KTpcbiAgICA8VSBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBhbnk+KHNvdXJjZTogYW55KSA9PiBVXG57XG4gICAgbGV0IGFsbEFueSA9IHRydWU7XG4gICAgZm9yIChjb25zdCBuYW1lIGluIGNyZWF0ZUZpZWxkKSB7XG4gICAgICAgIGlmIChjcmVhdGVGaWVsZFtuYW1lXSAhPT0gQW55KSB7XG4gICAgICAgICAgICBhbGxBbnkgPSBmYWxzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChhbGxBbnkpIHtcbiAgICAgICAgcmV0dXJuIEFueTtcbiAgICB9XG5cbiAgICByZXR1cm4gKHNvdXJjZSkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gY3JlYXRlRmllbGQpIHtcbiAgICAgICAgICAgIGlmIChuYW1lIGluIHNvdXJjZSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZVtuYW1lXSA9IGNyZWF0ZUZpZWxkW25hbWVdKHNvdXJjZVtuYW1lXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9O1xufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG5leHBvcnQgaW50ZXJmYWNlIFNpemUge1xuICAgIC8qKiBUaGUgd2lkdGggb2YgYSByZWN0YW5ndWxhciBhcmVhLiAqL1xuICAgIFdpZHRoOiBudW1iZXI7XG4gICAgLyoqIFRoZSBoZWlnaHQgb2YgYSByZWN0YW5ndWxhciBhcmVhLiAqL1xuICAgIEhlaWdodDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY3Qge1xuICAgIC8qKiBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBvcmlnaW4uICovXG4gICAgWDogbnVtYmVyO1xuICAgIC8qKiBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBvcmlnaW4uICovXG4gICAgWTogbnVtYmVyO1xuICAgIC8qKiBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4gKi9cbiAgICBXaWR0aDogbnVtYmVyO1xuICAgIC8qKiBUaGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUuICovXG4gICAgSGVpZ2h0OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2NyZWVuIHtcbiAgICAvKiogVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBzY3JlZW4uICovXG4gICAgSUQ6IHN0cmluZztcbiAgICAvKiogSHVtYW4tcmVhZGFibGUgbmFtZSBvZiB0aGUgc2NyZWVuLiAqL1xuICAgIE5hbWU6IHN0cmluZztcbiAgICAvKiogVGhlIHNjYWxlIGZhY3RvciBvZiB0aGUgc2NyZWVuIChEUEkvOTYpLiAxID0gc3RhbmRhcmQgRFBJLCAyID0gSGlEUEkgKFJldGluYSksIGV0Yy4gKi9cbiAgICBTY2FsZUZhY3RvcjogbnVtYmVyO1xuICAgIC8qKiBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBzY3JlZW4uICovXG4gICAgWDogbnVtYmVyO1xuICAgIC8qKiBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBzY3JlZW4uICovXG4gICAgWTogbnVtYmVyO1xuICAgIC8qKiBDb250YWlucyB0aGUgd2lkdGggYW5kIGhlaWdodCBvZiB0aGUgc2NyZWVuLiAqL1xuICAgIFNpemU6IFNpemU7XG4gICAgLyoqIENvbnRhaW5zIHRoZSBib3VuZHMgb2YgdGhlIHNjcmVlbiBpbiB0ZXJtcyBvZiBYLCBZLCBXaWR0aCwgYW5kIEhlaWdodC4gKi9cbiAgICBCb3VuZHM6IFJlY3Q7XG4gICAgLyoqIENvbnRhaW5zIHRoZSBwaHlzaWNhbCBib3VuZHMgb2YgdGhlIHNjcmVlbiBpbiB0ZXJtcyBvZiBYLCBZLCBXaWR0aCwgYW5kIEhlaWdodCAoYmVmb3JlIHNjYWxpbmcpLiAqL1xuICAgIFBoeXNpY2FsQm91bmRzOiBSZWN0O1xuICAgIC8qKiBDb250YWlucyB0aGUgYXJlYSBvZiB0aGUgc2NyZWVuIHRoYXQgaXMgYWN0dWFsbHkgdXNhYmxlIChleGNsdWRpbmcgdGFza2JhciBhbmQgb3RoZXIgc3lzdGVtIFVJKS4gKi9cbiAgICBXb3JrQXJlYTogUmVjdDtcbiAgICAvKiogQ29udGFpbnMgdGhlIHBoeXNpY2FsIFdvcmtBcmVhIG9mIHRoZSBzY3JlZW4gKGJlZm9yZSBzY2FsaW5nKS4gKi9cbiAgICBQaHlzaWNhbFdvcmtBcmVhOiBSZWN0O1xuICAgIC8qKiBUcnVlIGlmIHRoaXMgaXMgdGhlIHByaW1hcnkgbW9uaXRvciBzZWxlY3RlZCBieSB0aGUgdXNlciBpbiB0aGUgb3BlcmF0aW5nIHN5c3RlbS4gKi9cbiAgICBJc1ByaW1hcnk6IGJvb2xlYW47XG4gICAgLyoqIFRoZSByb3RhdGlvbiBvZiB0aGUgc2NyZWVuLiAqL1xuICAgIFJvdGF0aW9uOiBudW1iZXI7XG59XG5cbmltcG9ydCB7IG5ld1J1bnRpbWVDYWxsZXIsIG9iamVjdE5hbWVzIH0gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuU2NyZWVucyk7XG5cbmNvbnN0IGdldEFsbCA9IDA7XG5jb25zdCBnZXRQcmltYXJ5ID0gMTtcbmNvbnN0IGdldEN1cnJlbnQgPSAyO1xuXG4vKipcbiAqIEdldHMgYWxsIHNjcmVlbnMuXG4gKlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgb2YgU2NyZWVuIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHZXRBbGwoKTogUHJvbWlzZTxTY3JlZW5bXT4ge1xuICAgIHJldHVybiBjYWxsKGdldEFsbCk7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgcHJpbWFyeSBzY3JlZW4uXG4gKlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHByaW1hcnkgc2NyZWVuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gR2V0UHJpbWFyeSgpOiBQcm9taXNlPFNjcmVlbj4ge1xuICAgIHJldHVybiBjYWxsKGdldFByaW1hcnkpO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIGN1cnJlbnQgYWN0aXZlIHNjcmVlbi5cbiAqXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBjdXJyZW50IGFjdGl2ZSBzY3JlZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHZXRDdXJyZW50KCk6IFByb21pc2U8U2NyZWVuPiB7XG4gICAgcmV0dXJuIGNhbGwoZ2V0Q3VycmVudCk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7QUNBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7QUNBQTtBQUFBO0FBQUE7QUFBQTs7O0FDNkJBLElBQU0sY0FDRjtBQUVHLFNBQVMsT0FBTyxPQUFlLElBQVk7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MkJBQTJCO0FBQUEsSUFDM0IsK0JBQStCO0FBQUEsSUFDL0Isb0JBQW9CO0FBQUEsSUFDcEIsNEJBQTRCO0FBQUEsSUFDNUIsc0JBQXNCO0FBQUEsSUFDdEIsc0JBQXNCO0FBQUEsSUFDdEIsK0JBQStCO0FBQUEsSUFDL0IsNkJBQTZCO0FBQUEsSUFDN0IsZ0NBQWdDO0FBQUEsSUFDaEMscUJBQXFCO0FBQUEsSUFDckIsNkJBQTZCO0FBQUEsSUFDN0IsMEJBQTBCO0FBQUEsSUFDMUIsdUJBQXVCO0FBQUEsSUFDdkIsdUJBQXVCO0FBQUEsSUFDdkIsZ0JBQWdCO0FBQUEsSUFDaEIsc0JBQXNCO0FBQUEsSUFDdEIsY0FBYztBQUFBLElBQ2Qsb0JBQW9CO0FBQUEsSUFDcEIsb0JBQW9CO0FBQUEsSUFDcEIsc0JBQXNCO0FBQUEsSUFDdEIsYUFBYTtBQUFBLElBQ2IsY0FBYztBQUFBLElBQ2QsbUJBQW1CO0FBQUEsSUFDbkIsbUJBQW1CO0FBQUEsSUFDbkIseUJBQXlCO0FBQUEsSUFDekIsZUFBZTtBQUFBLElBQ2YsaUJBQWlCO0FBQUEsSUFDakIsdUJBQXVCO0FBQUEsSUFDdkIscUJBQXFCO0FBQUEsSUFDckIscUJBQXFCO0FBQUEsSUFDckIsdUJBQXVCO0FBQUEsSUFDdkIsY0FBYztBQUFBLElBQ2QsZUFBZTtBQUFBLElBQ2Ysb0JBQW9CO0FBQUEsSUFDcEIsb0JBQW9CO0FBQUEsSUFDcEIsMEJBQTBCO0FBQUEsSUFDMUIsZ0JBQWdCO0FBQUEsSUFDaEIsNEJBQTRCO0FBQUEsSUFDNUIsNEJBQTRCO0FBQUEsSUFDNUIseURBQXlEO0FBQUEsSUFDekQsc0NBQXNDO0FBQUEsSUFDdEMsb0JBQW9CO0FBQUEsSUFDcEIscUJBQXFCO0FBQUEsSUFDckIscUJBQXFCO0FBQUEsSUFDckIsc0JBQXNCO0FBQUEsSUFDdEIsZ0NBQWdDO0FBQUEsSUFDaEMsa0NBQWtDO0FBQUEsSUFDbEMsbUNBQW1DO0FBQUEsSUFDbkMsb0NBQW9DO0FBQUEsSUFDcEMsK0JBQStCO0FBQUEsSUFDL0IsNkJBQTZCO0FBQUEsSUFDN0IsdUJBQXVCO0FBQUEsSUFDdkIsaUNBQWlDO0FBQUEsSUFDakMsOEJBQThCO0FBQUEsSUFDOUIsNEJBQTRCO0FBQUEsSUFDNUIsc0NBQXNDO0FBQUEsSUFDdEMsNEJBQTRCO0FBQUEsSUFDNUIsc0JBQXNCO0FBQUEsSUFDdEIsa0NBQWtDO0FBQUEsSUFDbEMsc0JBQXNCO0FBQUEsSUFDdEIsd0JBQXdCO0FBQUEsSUFDeEIsd0JBQXdCO0FBQUEsSUFDeEIsbUJBQW1CO0FBQUEsSUFDbkIsMEJBQTBCO0FBQUEsSUFDMUIsOEJBQThCO0FBQUEsSUFDOUIseUJBQXlCO0FBQUEsSUFDekIsNkJBQTZCO0FBQUEsSUFDN0IsaUJBQWlCO0FBQUEsSUFDakIsZ0JBQWdCO0FBQUEsSUFDaEIsc0JBQXNCO0FBQUEsSUFDdEIsZUFBZTtBQUFBLElBQ2YseUJBQXlCO0FBQUEsSUFDekIsd0JBQXdCO0FBQUEsSUFDeEIsb0JBQW9CO0FBQUEsSUFDcEIscUJBQXFCO0FBQUEsSUFDckIsaUJBQWlCO0FBQUEsSUFDakIsaUJBQWlCO0FBQUEsSUFDakIsc0JBQXNCO0FBQUEsSUFDdEIsbUNBQW1DO0FBQUEsSUFDbkMscUNBQXFDO0FBQUEsSUFDckMsdUJBQXVCO0FBQUEsSUFDdkIsc0JBQXNCO0FBQUEsSUFDdEIsd0JBQXdCO0FBQUEsSUFDeEIsZUFBZTtBQUFBLElBQ2YsMkJBQTJCO0FBQUEsSUFDM0IsMEJBQTBCO0FBQUEsSUFDMUIsNkJBQTZCO0FBQUEsSUFDN0IsWUFBWTtBQUFBLElBQ1osZ0JBQWdCO0FBQUEsSUFDaEIsa0JBQWtCO0FBQUEsSUFDbEIsZ0JBQWdCO0FBQUEsSUFDaEIsa0JBQWtCO0FBQUEsSUFDbEIsbUJBQW1CO0FBQUEsSUFDbkIsWUFBWTtBQUFBLElBQ1oscUJBQXFCO0FBQUEsSUFDckIsc0JBQXNCO0FBQUEsSUFDdEIsc0JBQXNCO0FBQUEsSUFDdEIsOEJBQThCO0FBQUEsSUFDOUIsaUJBQWlCO0FBQUEsSUFDakIseUJBQXlCO0FBQUEsSUFDekIsMkJBQTJCO0FBQUEsSUFDM0IsK0JBQStCO0FBQUEs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O0FBQ0EsV0FBTztBQUFBLEVBQ1g7QUFDSjs7O0FDekdBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQXdEQSxJQUFNQyxRQUFPLGlCQUFpQixZQUFZLE9BQU87QUFFakQsSUFBTSxTQUFTO0FBQ2YsSUFBTSxhQUFhO0FBQ25CLElBQU0sYUFBYTtBQU9aLFNBQVMsU0FBNEI7QUFDeEMsU0FBT0EsTUFBSyxNQUFNO0FBQ3RCO0FBT08sU0FBUyxhQUE4QjtBQUMxQyxTQUFPQSxNQUFLLFVBQVU7QUFDMUI7QUFPTyxTQUFTLGFBQThCO0FBQzFDLFNBQU9BLE1BQUssVUFBVTtBQUMxQjs7O0F0QjVFQSxPQUFPLFNBQVMsT0FBTyxVQUFVLENBQUM7QUE0Q2xDLE9BQU8sT0FBTyxTQUFnQjtBQUN2QixPQUFPLHFCQUFxQjsiLAogICJuYW1lcyI6IFsiX2EiLCAiRXJyb3IiLCAiY2FsbCIsICJfYSIsICJFcnJvciIsICJjYWxsIiwgIl9hIiwgInJlc2l6YWJsZSIsICJjYWxsIiwgIl9hIiwgImNhbGwiLCAiY2FsbCIsICJIaWRlTWV0aG9kIiwgIlNob3dNZXRob2QiLCAiaXNEb2N1bWVudERvdEFsbCIsICJfYSIsICJyZWFzb24iLCAidmFsdWUiLCAiY2FsbCIsICJnZXRBbmREZWxldGVSZXNwb25zZSIsICJnZW5lcmF0ZUlEIiwgImNhbGwiLCAiQXJyYXkiLCAiTWFwIiwgIkFycmF5IiwgIk1hcCIsICJrZXkiLCAiY2FsbCJdCn0K +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2luZGV4LnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy93bWwudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2Jyb3dzZXIudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL25hbm9pZC50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvcnVudGltZS50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvZGlhbG9ncy50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvZXZlbnRzLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9saXN0ZW5lci50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvZXZlbnRfdHlwZXMudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL3V0aWxzLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy93aW5kb3cudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL2NvbXBpbGVkL21haW4uanMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL3N5c3RlbS50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvY29udGV4dG1lbnUudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2ZsYWdzLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9kcmFnLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9hcHBsaWNhdGlvbi50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvY2FsbHMudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL2NhbGxhYmxlLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9jYW5jZWxsYWJsZS50cyIsICIuLi8uLi9ydW50aW1lL2Rlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zcmMvY2xpcGJvYXJkLnRzIiwgIi4uLy4uL3J1bnRpbWUvZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3NyYy9jcmVhdGUudHMiLCAiLi4vLi4vcnVudGltZS9kZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvc3JjL3NjcmVlbnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8vIFNldHVwXHJcbndpbmRvdy5fd2FpbHMgPSB3aW5kb3cuX3dhaWxzIHx8IHt9O1xyXG5cclxuaW1wb3J0IFwiLi9jb250ZXh0bWVudS5qc1wiO1xyXG5pbXBvcnQgXCIuL2RyYWcuanNcIjtcclxuXHJcbi8vIFJlLWV4cG9ydCBwdWJsaWMgQVBJXHJcbmltcG9ydCAqIGFzIEFwcGxpY2F0aW9uIGZyb20gXCIuL2FwcGxpY2F0aW9uLmpzXCI7XHJcbmltcG9ydCAqIGFzIEJyb3dzZXIgZnJvbSBcIi4vYnJvd3Nlci5qc1wiO1xyXG5pbXBvcnQgKiBhcyBDYWxsIGZyb20gXCIuL2NhbGxzLmpzXCI7XHJcbmltcG9ydCAqIGFzIENsaXBib2FyZCBmcm9tIFwiLi9jbGlwYm9hcmQuanNcIjtcclxuaW1wb3J0ICogYXMgQ3JlYXRlIGZyb20gXCIuL2NyZWF0ZS5qc1wiO1xyXG5pbXBvcnQgKiBhcyBEaWFsb2dzIGZyb20gXCIuL2RpYWxvZ3MuanNcIjtcclxuaW1wb3J0ICogYXMgRXZlbnRzIGZyb20gXCIuL2V2ZW50cy5qc1wiO1xyXG5pbXBvcnQgKiBhcyBGbGFncyBmcm9tIFwiLi9mbGFncy5qc1wiO1xyXG5pbXBvcnQgKiBhcyBTY3JlZW5zIGZyb20gXCIuL3NjcmVlbnMuanNcIjtcclxuaW1wb3J0ICogYXMgU3lzdGVtIGZyb20gXCIuL3N5c3RlbS5qc1wiO1xyXG5pbXBvcnQgV2luZG93IGZyb20gXCIuL3dpbmRvdy5qc1wiO1xyXG5pbXBvcnQgKiBhcyBXTUwgZnJvbSBcIi4vd21sLmpzXCI7XHJcblxyXG5leHBvcnQge1xyXG4gICAgQXBwbGljYXRpb24sXHJcbiAgICBCcm93c2VyLFxyXG4gICAgQ2FsbCxcclxuICAgIENsaXBib2FyZCxcclxuICAgIERpYWxvZ3MsXHJcbiAgICBFdmVudHMsXHJcbiAgICBGbGFncyxcclxuICAgIFNjcmVlbnMsXHJcbiAgICBTeXN0ZW0sXHJcbiAgICBXaW5kb3csXHJcbiAgICBXTUxcclxufTtcclxuXHJcbi8qKlxyXG4gKiBBbiBpbnRlcm5hbCB1dGlsaXR5IGNvbnN1bWVkIGJ5IHRoZSBiaW5kaW5nIGdlbmVyYXRvci5cclxuICpcclxuICogQGlnbm9yZVxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmV4cG9ydCB7IENyZWF0ZSB9O1xyXG5cclxuZXhwb3J0ICogZnJvbSBcIi4vY2FuY2VsbGFibGUuanNcIjtcclxuXHJcbi8vIE5vdGlmeSBiYWNrZW5kXHJcbndpbmRvdy5fd2FpbHMuaW52b2tlID0gU3lzdGVtLmludm9rZTtcclxuU3lzdGVtLmludm9rZShcIndhaWxzOnJ1bnRpbWU6cmVhZHlcIik7XHJcbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG5pbXBvcnQgeyBPcGVuVVJMIH0gZnJvbSBcIi4vYnJvd3Nlci5qc1wiO1xyXG5pbXBvcnQgeyBRdWVzdGlvbiB9IGZyb20gXCIuL2RpYWxvZ3MuanNcIjtcclxuaW1wb3J0IHsgRW1pdCwgV2FpbHNFdmVudCB9IGZyb20gXCIuL2V2ZW50cy5qc1wiO1xyXG5pbXBvcnQgeyBjYW5BYm9ydExpc3RlbmVycywgd2hlblJlYWR5IH0gZnJvbSBcIi4vdXRpbHMuanNcIjtcclxuaW1wb3J0IFdpbmRvdyBmcm9tIFwiLi93aW5kb3cuanNcIjtcclxuXHJcbi8qKlxyXG4gKiBTZW5kcyBhbiBldmVudCB3aXRoIHRoZSBnaXZlbiBuYW1lIGFuZCBvcHRpb25hbCBkYXRhLlxyXG4gKlxyXG4gKiBAcGFyYW0gZXZlbnROYW1lIC0gLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gc2VuZC5cclxuICogQHBhcmFtIFtkYXRhPW51bGxdIC0gLSBPcHRpb25hbCBkYXRhIHRvIHNlbmQgYWxvbmcgd2l0aCB0aGUgZXZlbnQuXHJcbiAqL1xyXG5mdW5jdGlvbiBzZW5kRXZlbnQoZXZlbnROYW1lOiBzdHJpbmcsIGRhdGE6IGFueSA9IG51bGwpOiB2b2lkIHtcclxuICAgIEVtaXQobmV3IFdhaWxzRXZlbnQoZXZlbnROYW1lLCBkYXRhKSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDYWxscyBhIG1ldGhvZCBvbiBhIHNwZWNpZmllZCB3aW5kb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSB3aW5kb3dOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHdpbmRvdyB0byBjYWxsIHRoZSBtZXRob2Qgb24uXHJcbiAqIEBwYXJhbSBtZXRob2ROYW1lIC0gVGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0byBjYWxsLlxyXG4gKi9cclxuZnVuY3Rpb24gY2FsbFdpbmRvd01ldGhvZCh3aW5kb3dOYW1lOiBzdHJpbmcsIG1ldGhvZE5hbWU6IHN0cmluZykge1xyXG4gICAgY29uc3QgdGFyZ2V0V2luZG93ID0gV2luZG93LkdldCh3aW5kb3dOYW1lKTtcclxuICAgIGNvbnN0IG1ldGhvZCA9ICh0YXJnZXRXaW5kb3cgYXMgYW55KVttZXRob2ROYW1lXTtcclxuXHJcbiAgICBpZiAodHlwZW9mIG1ldGhvZCAhPT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihgV2luZG93IG1ldGhvZCAnJHttZXRob2ROYW1lfScgbm90IGZvdW5kYCk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgICAgbWV0aG9kLmNhbGwodGFyZ2V0V2luZG93KTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBjYWxsaW5nIHdpbmRvdyBtZXRob2QgJyR7bWV0aG9kTmFtZX0nOiBgLCBlKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJlc3BvbmRzIHRvIGEgdHJpZ2dlcmluZyBldmVudCBieSBydW5uaW5nIGFwcHJvcHJpYXRlIFdNTCBhY3Rpb25zIGZvciB0aGUgY3VycmVudCB0YXJnZXQuXHJcbiAqL1xyXG5mdW5jdGlvbiBvbldNTFRyaWdnZXJlZChldjogRXZlbnQpOiB2b2lkIHtcclxuICAgIGNvbnN0IGVsZW1lbnQgPSBldi5jdXJyZW50VGFyZ2V0IGFzIEVsZW1lbnQ7XHJcblxyXG4gICAgZnVuY3Rpb24gcnVuRWZmZWN0KGNob2ljZSA9IFwiWWVzXCIpIHtcclxuICAgICAgICBpZiAoY2hvaWNlICE9PSBcIlllc1wiKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGNvbnN0IGV2ZW50VHlwZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtZXZlbnQnKSB8fCBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS13bWwtZXZlbnQnKTtcclxuICAgICAgICBjb25zdCB0YXJnZXRXaW5kb3cgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXRhcmdldC13aW5kb3cnKSB8fCBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS13bWwtdGFyZ2V0LXdpbmRvdycpIHx8IFwiXCI7XHJcbiAgICAgICAgY29uc3Qgd2luZG93TWV0aG9kID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC13aW5kb3cnKSB8fCBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS13bWwtd2luZG93Jyk7XHJcbiAgICAgICAgY29uc3QgdXJsID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC1vcGVudXJsJykgfHwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtd21sLW9wZW51cmwnKTtcclxuXHJcbiAgICAgICAgaWYgKGV2ZW50VHlwZSAhPT0gbnVsbClcclxuICAgICAgICAgICAgc2VuZEV2ZW50KGV2ZW50VHlwZSk7XHJcbiAgICAgICAgaWYgKHdpbmRvd01ldGhvZCAhPT0gbnVsbClcclxuICAgICAgICAgICAgY2FsbFdpbmRvd01ldGhvZCh0YXJnZXRXaW5kb3csIHdpbmRvd01ldGhvZCk7XHJcbiAgICAgICAgaWYgKHVybCAhPT0gbnVsbClcclxuICAgICAgICAgICAgdm9pZCBPcGVuVVJMKHVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY29uZmlybSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtY29uZmlybScpIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXdtbC1jb25maXJtJyk7XHJcblxyXG4gICAgaWYgKGNvbmZpcm0pIHtcclxuICAgICAgICBRdWVzdGlvbih7XHJcbiAgICAgICAgICAgIFRpdGxlOiBcIkNvbmZpcm1cIixcclxuICAgICAgICAgICAgTWVzc2FnZTogY29uZmlybSxcclxuICAgICAgICAgICAgRGV0YWNoZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICBCdXR0b25zOiBbXHJcbiAgICAgICAgICAgICAgICB7IExhYmVsOiBcIlllc1wiIH0sXHJcbiAgICAgICAgICAgICAgICB7IExhYmVsOiBcIk5vXCIsIElzRGVmYXVsdDogdHJ1ZSB9XHJcbiAgICAgICAgICAgIF1cclxuICAgICAgICB9KS50aGVuKHJ1bkVmZmVjdCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJ1bkVmZmVjdCgpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vLyBQcml2YXRlIGZpZWxkIG5hbWVzLlxyXG5jb25zdCBjb250cm9sbGVyU3ltID0gU3ltYm9sKFwiY29udHJvbGxlclwiKTtcclxuY29uc3QgdHJpZ2dlck1hcFN5bSA9IFN5bWJvbChcInRyaWdnZXJNYXBcIik7XHJcbmNvbnN0IGVsZW1lbnRDb3VudFN5bSA9IFN5bWJvbChcImVsZW1lbnRDb3VudFwiKTtcclxuXHJcbi8qKlxyXG4gKiBBYm9ydENvbnRyb2xsZXJSZWdpc3RyeSBkb2VzIG5vdCBhY3R1YWxseSByZW1lbWJlciBhY3RpdmUgZXZlbnQgbGlzdGVuZXJzOiBpbnN0ZWFkXHJcbiAqIGl0IHRpZXMgdGhlbSB0byBhbiBBYm9ydFNpZ25hbCBhbmQgdXNlcyBhbiBBYm9ydENvbnRyb2xsZXIgdG8gcmVtb3ZlIHRoZW0gYWxsIGF0IG9uY2UuXHJcbiAqL1xyXG5jbGFzcyBBYm9ydENvbnRyb2xsZXJSZWdpc3RyeSB7XHJcbiAgICAvLyBQcml2YXRlIGZpZWxkcy5cclxuICAgIFtjb250cm9sbGVyU3ltXTogQWJvcnRDb250cm9sbGVyO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXNbY29udHJvbGxlclN5bV0gPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGFuIG9wdGlvbnMgb2JqZWN0IGZvciBhZGRFdmVudExpc3RlbmVyIHRoYXQgdGllcyB0aGUgbGlzdGVuZXJcclxuICAgICAqIHRvIHRoZSBBYm9ydFNpZ25hbCBmcm9tIHRoZSBjdXJyZW50IEFib3J0Q29udHJvbGxlci5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZWxlbWVudCAtIEFuIEhUTUwgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHRyaWdnZXJzIC0gVGhlIGxpc3Qgb2YgYWN0aXZlIFdNTCB0cmlnZ2VyIGV2ZW50cyBmb3IgdGhlIHNwZWNpZmllZCBlbGVtZW50c1xyXG4gICAgICovXHJcbiAgICBzZXQoZWxlbWVudDogRWxlbWVudCwgdHJpZ2dlcnM6IHN0cmluZ1tdKTogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnMge1xyXG4gICAgICAgIHJldHVybiB7IHNpZ25hbDogdGhpc1tjb250cm9sbGVyU3ltXS5zaWduYWwgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYWxsIHJlZ2lzdGVyZWQgZXZlbnQgbGlzdGVuZXJzIGFuZCByZXNldHMgdGhlIHJlZ2lzdHJ5LlxyXG4gICAgICovXHJcbiAgICByZXNldCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzW2NvbnRyb2xsZXJTeW1dLmFib3J0KCk7XHJcbiAgICAgICAgdGhpc1tjb250cm9sbGVyU3ltXSA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFdlYWtNYXBSZWdpc3RyeSBtYXBzIGFjdGl2ZSB0cmlnZ2VyIGV2ZW50cyB0byBlYWNoIERPTSBlbGVtZW50IHRocm91Z2ggYSBXZWFrTWFwLlxyXG4gKiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgbWFwcGluZyByZW1haW5zIHByaXZhdGUgdG8gdGhpcyBtb2R1bGUsIHdoaWxlIHN0aWxsIGFsbG93aW5nIGdhcmJhZ2VcclxuICogY29sbGVjdGlvbiBvZiB0aGUgaW52b2x2ZWQgZWxlbWVudHMuXHJcbiAqL1xyXG5jbGFzcyBXZWFrTWFwUmVnaXN0cnkge1xyXG4gICAgLyoqIFN0b3JlcyB0aGUgY3VycmVudCBlbGVtZW50LXRvLXRyaWdnZXIgbWFwcGluZy4gKi9cclxuICAgIFt0cmlnZ2VyTWFwU3ltXTogV2Vha01hcDxFbGVtZW50LCBzdHJpbmdbXT47XHJcbiAgICAvKiogQ291bnRzIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgd2l0aCBhY3RpdmUgV01MIHRyaWdnZXJzLiAqL1xyXG4gICAgW2VsZW1lbnRDb3VudFN5bV06IG51bWJlcjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzW3RyaWdnZXJNYXBTeW1dID0gbmV3IFdlYWtNYXAoKTtcclxuICAgICAgICB0aGlzW2VsZW1lbnRDb3VudFN5bV0gPSAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyBhY3RpdmUgdHJpZ2dlcnMgZm9yIHRoZSBzcGVjaWZpZWQgZWxlbWVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZWxlbWVudCAtIEFuIEhUTUwgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHRyaWdnZXJzIC0gVGhlIGxpc3Qgb2YgYWN0aXZlIFdNTCB0cmlnZ2VyIGV2ZW50cyBmb3IgdGhlIHNwZWNpZmllZCBlbGVtZW50XHJcbiAgICAgKi9cclxuICAgIHNldChlbGVtZW50OiBFbGVtZW50LCB0cmlnZ2Vyczogc3RyaW5nW10pOiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucyB7XHJcbiAgICAgICAgaWYgKCF0aGlzW3RyaWdnZXJNYXBTeW1dLmhhcyhlbGVtZW50KSkgeyB0aGlzW2VsZW1lbnRDb3VudFN5bV0rKzsgfVxyXG4gICAgICAgIHRoaXNbdHJpZ2dlck1hcFN5bV0uc2V0KGVsZW1lbnQsIHRyaWdnZXJzKTtcclxuICAgICAgICByZXR1cm4ge307XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFsbCByZWdpc3RlcmVkIGV2ZW50IGxpc3RlbmVycy5cclxuICAgICAqL1xyXG4gICAgcmVzZXQoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXNbZWxlbWVudENvdW50U3ltXSA8PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBkb2N1bWVudC5ib2R5LnF1ZXJ5U2VsZWN0b3JBbGwoJyonKSkge1xyXG4gICAgICAgICAgICBpZiAodGhpc1tlbGVtZW50Q291bnRTeW1dIDw9IDApXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXJzID0gdGhpc1t0cmlnZ2VyTWFwU3ltXS5nZXQoZWxlbWVudCk7XHJcbiAgICAgICAgICAgIGlmICh0cmlnZ2VycyAhPSBudWxsKSB7IHRoaXNbZWxlbWVudENvdW50U3ltXS0tOyB9XHJcblxyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRyaWdnZXIgb2YgdHJpZ2dlcnMgfHwgW10pXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHJpZ2dlciwgb25XTUxUcmlnZ2VyZWQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpc1t0cmlnZ2VyTWFwU3ltXSA9IG5ldyBXZWFrTWFwKCk7XHJcbiAgICAgICAgdGhpc1tlbGVtZW50Q291bnRTeW1dID0gMDtcclxuICAgIH1cclxufVxyXG5cclxuY29uc3QgdHJpZ2dlclJlZ2lzdHJ5ID0gY2FuQWJvcnRMaXN0ZW5lcnMoKSA/IG5ldyBBYm9ydENvbnRyb2xsZXJSZWdpc3RyeSgpIDogbmV3IFdlYWtNYXBSZWdpc3RyeSgpO1xyXG5cclxuLyoqXHJcbiAqIEFkZHMgZXZlbnQgbGlzdGVuZXJzIHRvIHRoZSBzcGVjaWZpZWQgZWxlbWVudC5cclxuICovXHJcbmZ1bmN0aW9uIGFkZFdNTExpc3RlbmVycyhlbGVtZW50OiBFbGVtZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCB0cmlnZ2VyUmVnRXhwID0gL1xcUysvZztcclxuICAgIGNvbnN0IHRyaWdnZXJBdHRyID0gKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtdHJpZ2dlcicpIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXdtbC10cmlnZ2VyJykgfHwgXCJjbGlja1wiKTtcclxuICAgIGNvbnN0IHRyaWdnZXJzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgIGxldCBtYXRjaDtcclxuICAgIHdoaWxlICgobWF0Y2ggPSB0cmlnZ2VyUmVnRXhwLmV4ZWModHJpZ2dlckF0dHIpKSAhPT0gbnVsbClcclxuICAgICAgICB0cmlnZ2Vycy5wdXNoKG1hdGNoWzBdKTtcclxuXHJcbiAgICBjb25zdCBvcHRpb25zID0gdHJpZ2dlclJlZ2lzdHJ5LnNldChlbGVtZW50LCB0cmlnZ2Vycyk7XHJcbiAgICBmb3IgKGNvbnN0IHRyaWdnZXIgb2YgdHJpZ2dlcnMpXHJcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHRyaWdnZXIsIG9uV01MVHJpZ2dlcmVkLCBvcHRpb25zKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNjaGVkdWxlcyBhbiBhdXRvbWF0aWMgcmVsb2FkIG9mIFdNTCB0byBiZSBwZXJmb3JtZWQgYXMgc29vbiBhcyB0aGUgZG9jdW1lbnQgaXMgZnVsbHkgbG9hZGVkLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEVuYWJsZSgpOiB2b2lkIHtcclxuICAgIHdoZW5SZWFkeShSZWxvYWQpO1xyXG59XHJcblxyXG4vKipcclxuICogUmVsb2FkcyB0aGUgV01MIHBhZ2UgYnkgYWRkaW5nIG5lY2Vzc2FyeSBldmVudCBsaXN0ZW5lcnMgYW5kIGJyb3dzZXIgbGlzdGVuZXJzLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFJlbG9hZCgpOiB2b2lkIHtcclxuICAgIHRyaWdnZXJSZWdpc3RyeS5yZXNldCgpO1xyXG4gICAgZG9jdW1lbnQuYm9keS5xdWVyeVNlbGVjdG9yQWxsKCdbd21sLWV2ZW50XSwgW3dtbC13aW5kb3ddLCBbd21sLW9wZW51cmxdLCBbZGF0YS13bWwtZXZlbnRdLCBbZGF0YS13bWwtd2luZG93XSwgW2RhdGEtd21sLW9wZW51cmxdJykuZm9yRWFjaChhZGRXTUxMaXN0ZW5lcnMpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG5pbXBvcnQgeyBuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lcyB9IGZyb20gXCIuL3J1bnRpbWUuanNcIjtcclxuXHJcbmNvbnN0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyKG9iamVjdE5hbWVzLkJyb3dzZXIpO1xyXG5cclxuY29uc3QgQnJvd3Nlck9wZW5VUkwgPSAwO1xyXG5cclxuLyoqXHJcbiAqIE9wZW4gYSBicm93c2VyIHdpbmRvdyB0byB0aGUgZ2l2ZW4gVVJMLlxyXG4gKlxyXG4gKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCB0byBvcGVuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT3BlblVSTCh1cmw6IHN0cmluZyB8IFVSTCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgcmV0dXJuIGNhbGwoQnJvd3Nlck9wZW5VUkwsIHt1cmw6IHVybC50b1N0cmluZygpfSk7XHJcbn1cclxuIiwgIi8vIFNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tL2FpL25hbm9pZFxyXG5cclxuLy8gVGhlIE1JVCBMaWNlbnNlIChNSVQpXHJcbi8vXHJcbi8vIENvcHlyaWdodCAyMDE3IEFuZHJleSBTaXRuaWsgPGFuZHJleUBzaXRuaWsucnU+XHJcbi8vXHJcbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2ZcclxuLy8gdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpblxyXG4vLyB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvXHJcbi8vIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mXHJcbi8vIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbyxcclxuLy8gICAgIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxyXG4vL1xyXG4vLyAgICAgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXHJcbi8vIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXHJcbi8vXHJcbi8vICAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXHJcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTXHJcbi8vIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUlxyXG4vLyBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVJcclxuLy8gSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU5cclxuLy8gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cclxuXHJcbi8vIFRoaXMgYWxwaGFiZXQgdXNlcyBgQS1aYS16MC05Xy1gIHN5bWJvbHMuXHJcbi8vIFRoZSBvcmRlciBvZiBjaGFyYWN0ZXJzIGlzIG9wdGltaXplZCBmb3IgYmV0dGVyIGd6aXAgYW5kIGJyb3RsaSBjb21wcmVzc2lvbi5cclxuLy8gUmVmZXJlbmNlcyB0byB0aGUgc2FtZSBmaWxlICh3b3JrcyBib3RoIGZvciBnemlwIGFuZCBicm90bGkpOlxyXG4vLyBgJ3VzZWAsIGBhbmRvbWAsIGFuZCBgcmljdCdgXHJcbi8vIFJlZmVyZW5jZXMgdG8gdGhlIGJyb3RsaSBkZWZhdWx0IGRpY3Rpb25hcnk6XHJcbi8vIGAtMjZUYCwgYDE5ODNgLCBgNDBweGAsIGA3NXB4YCwgYGJ1c2hgLCBgamFja2AsIGBtaW5kYCwgYHZlcnlgLCBhbmQgYHdvbGZgXHJcbmNvbnN0IHVybEFscGhhYmV0ID1cclxuICAgICd1c2VhbmRvbS0yNlQxOTgzNDBQWDc1cHhKQUNLVkVSWU1JTkRCVVNIV09MRl9HUVpiZmdoamtscXZ3eXpyaWN0J1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5hbm9pZChzaXplOiBudW1iZXIgPSAyMSk6IHN0cmluZyB7XHJcbiAgICBsZXQgaWQgPSAnJ1xyXG4gICAgLy8gQSBjb21wYWN0IGFsdGVybmF0aXZlIGZvciBgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGVwOyBpKyspYC5cclxuICAgIGxldCBpID0gc2l6ZSB8IDBcclxuICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICAvLyBgfCAwYCBpcyBtb3JlIGNvbXBhY3QgYW5kIGZhc3RlciB0aGFuIGBNYXRoLmZsb29yKClgLlxyXG4gICAgICAgIGlkICs9IHVybEFscGhhYmV0WyhNYXRoLnJhbmRvbSgpICogNjQpIHwgMF1cclxuICAgIH1cclxuICAgIHJldHVybiBpZFxyXG59XHJcbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tICcuL25hbm9pZC5qcyc7XHJcblxyXG5jb25zdCBydW50aW1lVVJMID0gd2luZG93LmxvY2F0aW9uLm9yaWdpbiArIFwiL3dhaWxzL3J1bnRpbWVcIjtcclxuXHJcbi8vIE9iamVjdCBOYW1lc1xyXG5leHBvcnQgY29uc3Qgb2JqZWN0TmFtZXMgPSBPYmplY3QuZnJlZXplKHtcclxuICAgIENhbGw6IDAsXHJcbiAgICBDbGlwYm9hcmQ6IDEsXHJcbiAgICBBcHBsaWNhdGlvbjogMixcclxuICAgIEV2ZW50czogMyxcclxuICAgIENvbnRleHRNZW51OiA0LFxyXG4gICAgRGlhbG9nOiA1LFxyXG4gICAgV2luZG93OiA2LFxyXG4gICAgU2NyZWVuczogNyxcclxuICAgIFN5c3RlbTogOCxcclxuICAgIEJyb3dzZXI6IDksXHJcbiAgICBDYW5jZWxDYWxsOiAxMCxcclxufSk7XHJcbmV4cG9ydCBsZXQgY2xpZW50SWQgPSBuYW5vaWQoKTtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IHJ1bnRpbWUgY2FsbGVyIHdpdGggc3BlY2lmaWVkIElELlxyXG4gKlxyXG4gKiBAcGFyYW0gb2JqZWN0IC0gVGhlIG9iamVjdCB0byBpbnZva2UgdGhlIG1ldGhvZCBvbi5cclxuICogQHBhcmFtIHdpbmRvd05hbWUgLSBUaGUgbmFtZSBvZiB0aGUgd2luZG93LlxyXG4gKiBAcmV0dXJuIFRoZSBuZXcgcnVudGltZSBjYWxsZXIgZnVuY3Rpb24uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbmV3UnVudGltZUNhbGxlcihvYmplY3Q6IG51bWJlciwgd2luZG93TmFtZTogc3RyaW5nID0gJycpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAobWV0aG9kOiBudW1iZXIsIGFyZ3M6IGFueSA9IG51bGwpIHtcclxuICAgICAgICByZXR1cm4gcnVudGltZUNhbGxXaXRoSUQob2JqZWN0LCBtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpO1xyXG4gICAgfTtcclxufVxyXG5cclxuYXN5bmMgZnVuY3Rpb24gcnVudGltZUNhbGxXaXRoSUQob2JqZWN0SUQ6IG51bWJlciwgbWV0aG9kOiBudW1iZXIsIHdpbmRvd05hbWU6IHN0cmluZywgYXJnczogYW55KTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJvYmplY3RcIiwgb2JqZWN0SUQudG9TdHJpbmcoKSk7XHJcbiAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm1ldGhvZFwiLCBtZXRob2QudG9TdHJpbmcoKSk7XHJcbiAgICBpZiAoYXJncykgeyB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcImFyZ3NcIiwgSlNPTi5zdHJpbmdpZnkoYXJncykpOyB9XHJcblxyXG4gICAgbGV0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XHJcbiAgICAgICAgW1wieC13YWlscy1jbGllbnQtaWRcIl06IGNsaWVudElkXHJcbiAgICB9XHJcbiAgICBpZiAod2luZG93TmFtZSkge1xyXG4gICAgICAgIGhlYWRlcnNbXCJ4LXdhaWxzLXdpbmRvdy1uYW1lXCJdID0gd2luZG93TmFtZTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHsgaGVhZGVycyB9KTtcclxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYXdhaXQgcmVzcG9uc2UudGV4dCgpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpPy5pbmRleE9mKFwiYXBwbGljYXRpb24vanNvblwiKSA/PyAtMSkgIT09IC0xKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKTtcclxuICAgIH1cclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xyXG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tICcuL25hbm9pZC5qcyc7XHJcblxyXG4vLyBzZXR1cFxyXG53aW5kb3cuX3dhaWxzID0gd2luZG93Ll93YWlscyB8fCB7fTtcclxud2luZG93Ll93YWlscy5kaWFsb2dFcnJvckNhbGxiYWNrID0gZGlhbG9nRXJyb3JDYWxsYmFjaztcclxud2luZG93Ll93YWlscy5kaWFsb2dSZXN1bHRDYWxsYmFjayA9IGRpYWxvZ1Jlc3VsdENhbGxiYWNrO1xyXG5cclxudHlwZSBQcm9taXNlUmVzb2x2ZXJzID0gT21pdDxQcm9taXNlV2l0aFJlc29sdmVyczxhbnk+LCBcInByb21pc2VcIj47XHJcblxyXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcihvYmplY3ROYW1lcy5EaWFsb2cpO1xyXG5jb25zdCBkaWFsb2dSZXNwb25zZXMgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZVJlc29sdmVycz4oKTtcclxuXHJcbi8vIERlZmluZSBjb25zdGFudHMgZnJvbSB0aGUgYG1ldGhvZHNgIG9iamVjdCBpbiBUaXRsZSBDYXNlXHJcbmNvbnN0IERpYWxvZ0luZm8gPSAwO1xyXG5jb25zdCBEaWFsb2dXYXJuaW5nID0gMTtcclxuY29uc3QgRGlhbG9nRXJyb3IgPSAyO1xyXG5jb25zdCBEaWFsb2dRdWVzdGlvbiA9IDM7XHJcbmNvbnN0IERpYWxvZ09wZW5GaWxlID0gNDtcclxuY29uc3QgRGlhbG9nU2F2ZUZpbGUgPSA1O1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBPcGVuRmlsZURpYWxvZ09wdGlvbnMge1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiBkaXJlY3RvcmllcyBjYW4gYmUgY2hvc2VuLiAqL1xyXG4gICAgQ2FuQ2hvb3NlRGlyZWN0b3JpZXM/OiBib29sZWFuO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiBmaWxlcyBjYW4gYmUgY2hvc2VuLiAqL1xyXG4gICAgQ2FuQ2hvb3NlRmlsZXM/OiBib29sZWFuO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiBkaXJlY3RvcmllcyBjYW4gYmUgY3JlYXRlZC4gKi9cclxuICAgIENhbkNyZWF0ZURpcmVjdG9yaWVzPzogYm9vbGVhbjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgaWYgaGlkZGVuIGZpbGVzIHNob3VsZCBiZSBzaG93bi4gKi9cclxuICAgIFNob3dIaWRkZW5GaWxlcz86IGJvb2xlYW47XHJcbiAgICAvKiogSW5kaWNhdGVzIGlmIGFsaWFzZXMgc2hvdWxkIGJlIHJlc29sdmVkLiAqL1xyXG4gICAgUmVzb2x2ZXNBbGlhc2VzPzogYm9vbGVhbjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgaWYgbXVsdGlwbGUgc2VsZWN0aW9uIGlzIGFsbG93ZWQuICovXHJcbiAgICBBbGxvd3NNdWx0aXBsZVNlbGVjdGlvbj86IGJvb2xlYW47XHJcbiAgICAvKiogSW5kaWNhdGVzIGlmIHRoZSBleHRlbnNpb24gc2hvdWxkIGJlIGhpZGRlbi4gKi9cclxuICAgIEhpZGVFeHRlbnNpb24/OiBib29sZWFuO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiBoaWRkZW4gZXh0ZW5zaW9ucyBjYW4gYmUgc2VsZWN0ZWQuICovXHJcbiAgICBDYW5TZWxlY3RIaWRkZW5FeHRlbnNpb24/OiBib29sZWFuO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiBmaWxlIHBhY2thZ2VzIHNob3VsZCBiZSB0cmVhdGVkIGFzIGRpcmVjdG9yaWVzLiAqL1xyXG4gICAgVHJlYXRzRmlsZVBhY2thZ2VzQXNEaXJlY3Rvcmllcz86IGJvb2xlYW47XHJcbiAgICAvKiogSW5kaWNhdGVzIGlmIG90aGVyIGZpbGUgdHlwZXMgYXJlIGFsbG93ZWQuICovXHJcbiAgICBBbGxvd3NPdGhlckZpbGV0eXBlcz86IGJvb2xlYW47XHJcbiAgICAvKiogQXJyYXkgb2YgZmlsZSBmaWx0ZXJzLiAqL1xyXG4gICAgRmlsdGVycz86IEZpbGVGaWx0ZXJbXTtcclxuICAgIC8qKiBUaXRsZSBvZiB0aGUgZGlhbG9nLiAqL1xyXG4gICAgVGl0bGU/OiBzdHJpbmc7XHJcbiAgICAvKiogTWVzc2FnZSB0byBzaG93IGluIHRoZSBkaWFsb2cuICovXHJcbiAgICBNZXNzYWdlPzogc3RyaW5nO1xyXG4gICAgLyoqIFRleHQgdG8gZGlzcGxheSBvbiB0aGUgYnV0dG9uLiAqL1xyXG4gICAgQnV0dG9uVGV4dD86IHN0cmluZztcclxuICAgIC8qKiBEaXJlY3RvcnkgdG8gb3BlbiBpbiB0aGUgZGlhbG9nLiAqL1xyXG4gICAgRGlyZWN0b3J5Pzogc3RyaW5nO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiB0aGUgZGlhbG9nIHNob3VsZCBhcHBlYXIgZGV0YWNoZWQgZnJvbSB0aGUgbWFpbiB3aW5kb3cuICovXHJcbiAgICBEZXRhY2hlZD86IGJvb2xlYW47XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgU2F2ZUZpbGVEaWFsb2dPcHRpb25zIHtcclxuICAgIC8qKiBEZWZhdWx0IGZpbGVuYW1lIHRvIHVzZSBpbiB0aGUgZGlhbG9nLiAqL1xyXG4gICAgRmlsZW5hbWU/OiBzdHJpbmc7XHJcbiAgICAvKiogSW5kaWNhdGVzIGlmIGRpcmVjdG9yaWVzIGNhbiBiZSBjaG9zZW4uICovXHJcbiAgICBDYW5DaG9vc2VEaXJlY3Rvcmllcz86IGJvb2xlYW47XHJcbiAgICAvKiogSW5kaWNhdGVzIGlmIGZpbGVzIGNhbiBiZSBjaG9zZW4uICovXHJcbiAgICBDYW5DaG9vc2VGaWxlcz86IGJvb2xlYW47XHJcbiAgICAvKiogSW5kaWNhdGVzIGlmIGRpcmVjdG9yaWVzIGNhbiBiZSBjcmVhdGVkLiAqL1xyXG4gICAgQ2FuQ3JlYXRlRGlyZWN0b3JpZXM/OiBib29sZWFuO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiBoaWRkZW4gZmlsZXMgc2hvdWxkIGJlIHNob3duLiAqL1xyXG4gICAgU2hvd0hpZGRlbkZpbGVzPzogYm9vbGVhbjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgaWYgYWxpYXNlcyBzaG91bGQgYmUgcmVzb2x2ZWQuICovXHJcbiAgICBSZXNvbHZlc0FsaWFzZXM/OiBib29sZWFuO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiB0aGUgZXh0ZW5zaW9uIHNob3VsZCBiZSBoaWRkZW4uICovXHJcbiAgICBIaWRlRXh0ZW5zaW9uPzogYm9vbGVhbjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgaWYgaGlkZGVuIGV4dGVuc2lvbnMgY2FuIGJlIHNlbGVjdGVkLiAqL1xyXG4gICAgQ2FuU2VsZWN0SGlkZGVuRXh0ZW5zaW9uPzogYm9vbGVhbjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgaWYgZmlsZSBwYWNrYWdlcyBzaG91bGQgYmUgdHJlYXRlZCBhcyBkaXJlY3Rvcmllcy4gKi9cclxuICAgIFRyZWF0c0ZpbGVQYWNrYWdlc0FzRGlyZWN0b3JpZXM/OiBib29sZWFuO1xyXG4gICAgLyoqIEluZGljYXRlcyBpZiBvdGhlciBmaWxlIHR5cGVzIGFyZSBhbGxvd2VkLiAqL1xyXG4gICAgQWxsb3dzT3RoZXJGaWxldHlwZXM/OiBib29sZWFuO1xyXG4gICAgLyoqIEFycmF5IG9mIGZpbGUgZmlsdGVycy4gKi9cclxuICAgIEZpbHRlcnM/OiBGaWxlRmlsdGVyW107XHJcbiAgICAvKiogVGl0bGUgb2YgdGhlIGRpYWxvZy4gKi9cclxuICAgIFRpdGxlPzogc3RyaW5nO1xyXG4gICAgLyoqIE1lc3NhZ2UgdG8gc2hvdyBpbiB0aGUgZGlhbG9nLiAqL1xyXG4gICAgTWVzc2FnZT86IHN0cmluZztcclxuICAgIC8qKiBUZXh0IHRvIGRpc3BsYXkgb24gdGhlIGJ1dHRvbi4gKi9cclxuICAgIEJ1dHRvblRleHQ/OiBzdHJpbmc7XHJcbiAgICAvKiogRGlyZWN0b3J5IHRvIG9wZW4gaW4gdGhlIGRpYWxvZy4gKi9cclxuICAgIERpcmVjdG9yeT86IHN0cmluZztcclxuICAgIC8qKiBJbmRpY2F0ZXMgaWYgdGhlIGRpYWxvZyBzaG91bGQgYXBwZWFyIGRldGFjaGVkIGZyb20gdGhlIG1haW4gd2luZG93LiAqL1xyXG4gICAgRGV0YWNoZWQ/OiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE1lc3NhZ2VEaWFsb2dPcHRpb25zIHtcclxuICAgIC8qKiBUaGUgdGl0bGUgb2YgdGhlIGRpYWxvZyB3aW5kb3cuICovXHJcbiAgICBUaXRsZT86IHN0cmluZztcclxuICAgIC8qKiBUaGUgbWFpbiBtZXNzYWdlIHRvIHNob3cgaW4gdGhlIGRpYWxvZy4gKi9cclxuICAgIE1lc3NhZ2U/OiBzdHJpbmc7XHJcbiAgICAvKiogQXJyYXkgb2YgYnV0dG9uIG9wdGlvbnMgdG8gc2hvdyBpbiB0aGUgZGlhbG9nLiAqL1xyXG4gICAgQnV0dG9ucz86IEJ1dHRvbltdO1xyXG4gICAgLyoqIFRydWUgaWYgdGhlIGRpYWxvZyBzaG91bGQgYXBwZWFyIGRldGFjaGVkIGZyb20gdGhlIG1haW4gd2luZG93IChpZiBhcHBsaWNhYmxlKS4gKi9cclxuICAgIERldGFjaGVkPzogYm9vbGVhbjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBCdXR0b24ge1xyXG4gICAgLyoqIFRleHQgdGhhdCBhcHBlYXJzIHdpdGhpbiB0aGUgYnV0dG9uLiAqL1xyXG4gICAgTGFiZWw/OiBzdHJpbmc7XHJcbiAgICAvKiogVHJ1ZSBpZiB0aGUgYnV0dG9uIHNob3VsZCBjYW5jZWwgYW4gb3BlcmF0aW9uIHdoZW4gY2xpY2tlZC4gKi9cclxuICAgIElzQ2FuY2VsPzogYm9vbGVhbjtcclxuICAgIC8qKiBUcnVlIGlmIHRoZSBidXR0b24gc2hvdWxkIGJlIHRoZSBkZWZhdWx0IGFjdGlvbiB3aGVuIHRoZSB1c2VyIHByZXNzZXMgZW50ZXIuICovXHJcbiAgICBJc0RlZmF1bHQ/OiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVGaWx0ZXIge1xyXG4gICAgLyoqIERpc3BsYXkgbmFtZSBmb3IgdGhlIGZpbHRlciwgaXQgY291bGQgYmUgXCJUZXh0IEZpbGVzXCIsIFwiSW1hZ2VzXCIgZXRjLiAqL1xyXG4gICAgRGlzcGxheU5hbWU/OiBzdHJpbmc7XHJcbiAgICAvKiogUGF0dGVybiB0byBtYXRjaCBmb3IgdGhlIGZpbHRlciwgZS5nLiBcIioudHh0OyoubWRcIiBmb3IgdGV4dCBtYXJrZG93biBmaWxlcy4gKi9cclxuICAgIFBhdHRlcm4/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIYW5kbGVzIHRoZSByZXN1bHQgb2YgYSBkaWFsb2cgcmVxdWVzdC5cclxuICpcclxuICogQHBhcmFtIGlkIC0gVGhlIGlkIG9mIHRoZSByZXF1ZXN0IHRvIGhhbmRsZSB0aGUgcmVzdWx0IGZvci5cclxuICogQHBhcmFtIGRhdGEgLSBUaGUgcmVzdWx0IGRhdGEgb2YgdGhlIHJlcXVlc3QuXHJcbiAqIEBwYXJhbSBpc0pTT04gLSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZGF0YSBpcyBKU09OIG9yIG5vdC5cclxuICovXHJcbmZ1bmN0aW9uIGRpYWxvZ1Jlc3VsdENhbGxiYWNrKGlkOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgaXNKU09OOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICBsZXQgcmVzb2x2ZXJzID0gZ2V0QW5kRGVsZXRlUmVzcG9uc2UoaWQpO1xyXG4gICAgaWYgKCFyZXNvbHZlcnMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzSlNPTikge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHJlc29sdmVycy5yZXNvbHZlKEpTT04ucGFyc2UoZGF0YSkpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XHJcbiAgICAgICAgICAgIHJlc29sdmVycy5yZWplY3QobmV3IFR5cGVFcnJvcihcImNvdWxkIG5vdCBwYXJzZSByZXN1bHQ6IFwiICsgZXJyLm1lc3NhZ2UsIHsgY2F1c2U6IGVyciB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICByZXNvbHZlcnMucmVzb2x2ZShkYXRhKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEhhbmRsZXMgdGhlIGVycm9yIGZyb20gYSBkaWFsb2cgcmVxdWVzdC5cclxuICpcclxuICogQHBhcmFtIGlkIC0gVGhlIGlkIG9mIHRoZSBwcm9taXNlIGhhbmRsZXIuXHJcbiAqIEBwYXJhbSBtZXNzYWdlIC0gQW4gZXJyb3IgbWVzc2FnZS5cclxuICovXHJcbmZ1bmN0aW9uIGRpYWxvZ0Vycm9yQ2FsbGJhY2soaWQ6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBnZXRBbmREZWxldGVSZXNwb25zZShpZCk/LnJlamVjdChuZXcgd2luZG93LkVycm9yKG1lc3NhZ2UpKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgcmVzcG9uc2UgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBJRCBmcm9tIHRoZSBkaWFsb2dSZXNwb25zZXMgbWFwLlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgLSBUaGUgSUQgb2YgdGhlIHJlc3BvbnNlIHRvIGJlIHJldHJpZXZlZCBhbmQgcmVtb3ZlZC5cclxuICogQHJldHVybnMgVGhlIHJlc3BvbnNlIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIElELCBpZiBhbnkuXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRBbmREZWxldGVSZXNwb25zZShpZDogc3RyaW5nKTogUHJvbWlzZVJlc29sdmVycyB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCByZXNwb25zZSA9IGRpYWxvZ1Jlc3BvbnNlcy5nZXQoaWQpO1xyXG4gICAgZGlhbG9nUmVzcG9uc2VzLmRlbGV0ZShpZCk7XHJcbiAgICByZXR1cm4gcmVzcG9uc2U7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSB1bmlxdWUgSUQgdXNpbmcgdGhlIG5hbm9pZCBsaWJyYXJ5LlxyXG4gKlxyXG4gKiBAcmV0dXJucyBBIHVuaXF1ZSBJRCB0aGF0IGRvZXMgbm90IGV4aXN0IGluIHRoZSBkaWFsb2dSZXNwb25zZXMgc2V0LlxyXG4gKi9cclxuZnVuY3Rpb24gZ2VuZXJhdGVJRCgpOiBzdHJpbmcge1xyXG4gICAgbGV0IHJlc3VsdDtcclxuICAgIGRvIHtcclxuICAgICAgICByZXN1bHQgPSBuYW5vaWQoKTtcclxuICAgIH0gd2hpbGUgKGRpYWxvZ1Jlc3BvbnNlcy5oYXMocmVzdWx0KSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG4vKipcclxuICogUHJlc2VudHMgYSBkaWFsb2cgb2Ygc3BlY2lmaWVkIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy5cclxuICpcclxuICogQHBhcmFtIHR5cGUgLSBEaWFsb2cgdHlwZS5cclxuICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25zIGZvciB0aGUgZGlhbG9nLlxyXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHJlc3VsdCBvZiBkaWFsb2cuXHJcbiAqL1xyXG5mdW5jdGlvbiBkaWFsb2codHlwZTogbnVtYmVyLCBvcHRpb25zOiBNZXNzYWdlRGlhbG9nT3B0aW9ucyB8IE9wZW5GaWxlRGlhbG9nT3B0aW9ucyB8IFNhdmVGaWxlRGlhbG9nT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGNvbnN0IGlkID0gZ2VuZXJhdGVJRCgpO1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBkaWFsb2dSZXNwb25zZXMuc2V0KGlkLCB7IHJlc29sdmUsIHJlamVjdCB9KTtcclxuICAgICAgICBjYWxsKHR5cGUsIE9iamVjdC5hc3NpZ24oeyBcImRpYWxvZy1pZFwiOiBpZCB9LCBvcHRpb25zKSkuY2F0Y2goKGVycjogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogUHJlc2VudHMgYW4gaW5mbyBkaWFsb2cuXHJcbiAqXHJcbiAqIEBwYXJhbSBvcHRpb25zIC0gRGlhbG9nIG9wdGlvbnNcclxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbGFiZWwgb2YgdGhlIGNob3NlbiBidXR0b24uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSW5mbyhvcHRpb25zOiBNZXNzYWdlRGlhbG9nT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7IHJldHVybiBkaWFsb2coRGlhbG9nSW5mbywgb3B0aW9ucyk7IH1cclxuXHJcbi8qKlxyXG4gKiBQcmVzZW50cyBhIHdhcm5pbmcgZGlhbG9nLlxyXG4gKlxyXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zLlxyXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsYWJlbCBvZiB0aGUgY2hvc2VuIGJ1dHRvbi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBXYXJuaW5nKG9wdGlvbnM6IE1lc3NhZ2VEaWFsb2dPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHsgcmV0dXJuIGRpYWxvZyhEaWFsb2dXYXJuaW5nLCBvcHRpb25zKTsgfVxyXG5cclxuLyoqXHJcbiAqIFByZXNlbnRzIGFuIGVycm9yIGRpYWxvZy5cclxuICpcclxuICogQHBhcmFtIG9wdGlvbnMgLSBEaWFsb2cgb3B0aW9ucy5cclxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbGFiZWwgb2YgdGhlIGNob3NlbiBidXR0b24uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gRXJyb3Iob3B0aW9uczogTWVzc2FnZURpYWxvZ09wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4geyByZXR1cm4gZGlhbG9nKERpYWxvZ0Vycm9yLCBvcHRpb25zKTsgfVxyXG5cclxuLyoqXHJcbiAqIFByZXNlbnRzIGEgcXVlc3Rpb24gZGlhbG9nLlxyXG4gKlxyXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zLlxyXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsYWJlbCBvZiB0aGUgY2hvc2VuIGJ1dHRvbi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBRdWVzdGlvbihvcHRpb25zOiBNZXNzYWdlRGlhbG9nT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7IHJldHVybiBkaWFsb2coRGlhbG9nUXVlc3Rpb24sIG9wdGlvbnMpOyB9XHJcblxyXG4vKipcclxuICogUHJlc2VudHMgYSBmaWxlIHNlbGVjdGlvbiBkaWFsb2cgdG8gcGljayBvbmUgb3IgbW9yZSBmaWxlcyB0byBvcGVuLlxyXG4gKlxyXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zLlxyXG4gKiBAcmV0dXJucyBTZWxlY3RlZCBmaWxlIG9yIGxpc3Qgb2YgZmlsZXMsIG9yIGEgYmxhbmsgc3RyaW5nL2VtcHR5IGxpc3QgaWYgbm8gZmlsZSBoYXMgYmVlbiBzZWxlY3RlZC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPcGVuRmlsZShvcHRpb25zOiBPcGVuRmlsZURpYWxvZ09wdGlvbnMgJiB7IEFsbG93c011bHRpcGxlU2VsZWN0aW9uOiB0cnVlIH0pOiBQcm9taXNlPHN0cmluZ1tdPjtcclxuZXhwb3J0IGZ1bmN0aW9uIE9wZW5GaWxlKG9wdGlvbnM6IE9wZW5GaWxlRGlhbG9nT3B0aW9ucyAmIHsgQWxsb3dzTXVsdGlwbGVTZWxlY3Rpb24/OiBmYWxzZSB8IHVuZGVmaW5lZCB9KTogUHJvbWlzZTxzdHJpbmc+O1xyXG5leHBvcnQgZnVuY3Rpb24gT3BlbkZpbGUob3B0aW9uczogT3BlbkZpbGVEaWFsb2dPcHRpb25zKTogUHJvbWlzZTxzdHJpbmcgfCBzdHJpbmdbXT47XHJcbmV4cG9ydCBmdW5jdGlvbiBPcGVuRmlsZShvcHRpb25zOiBPcGVuRmlsZURpYWxvZ09wdGlvbnMpOiBQcm9taXNlPHN0cmluZyB8IHN0cmluZ1tdPiB7IHJldHVybiBkaWFsb2coRGlhbG9nT3BlbkZpbGUsIG9wdGlvbnMpID8/IFtdOyB9XHJcblxyXG4vKipcclxuICogUHJlc2VudHMgYSBmaWxlIHNlbGVjdGlvbiBkaWFsb2cgdG8gcGljayBhIGZpbGUgdG8gc2F2ZS5cclxuICpcclxuICogQHBhcmFtIG9wdGlvbnMgLSBEaWFsb2cgb3B0aW9ucy5cclxuICogQHJldHVybnMgU2VsZWN0ZWQgZmlsZSwgb3IgYSBibGFuayBzdHJpbmcgaWYgbm8gZmlsZSBoYXMgYmVlbiBzZWxlY3RlZC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBTYXZlRmlsZShvcHRpb25zOiBTYXZlRmlsZURpYWxvZ09wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4geyByZXR1cm4gZGlhbG9nKERpYWxvZ1NhdmVGaWxlLCBvcHRpb25zKTsgfVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuaW1wb3J0IHsgbmV3UnVudGltZUNhbGxlciwgb2JqZWN0TmFtZXMgfSBmcm9tIFwiLi9ydW50aW1lLmpzXCI7XHJcbmltcG9ydCB7IGV2ZW50TGlzdGVuZXJzLCBMaXN0ZW5lciwgbGlzdGVuZXJPZmYgfSBmcm9tIFwiLi9saXN0ZW5lci5qc1wiO1xyXG5cclxuLy8gU2V0dXBcclxud2luZG93Ll93YWlscyA9IHdpbmRvdy5fd2FpbHMgfHwge307XHJcbndpbmRvdy5fd2FpbHMuZGlzcGF0Y2hXYWlsc0V2ZW50ID0gZGlzcGF0Y2hXYWlsc0V2ZW50O1xyXG5cclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuRXZlbnRzKTtcclxuY29uc3QgRW1pdE1ldGhvZCA9IDA7XHJcblxyXG5leHBvcnQgeyBUeXBlcyB9IGZyb20gXCIuL2V2ZW50X3R5cGVzLmpzXCI7XHJcblxyXG4vKipcclxuICogVGhlIHR5cGUgb2YgaGFuZGxlcnMgZm9yIGEgZ2l2ZW4gZXZlbnQuXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBDYWxsYmFjayA9IChldjogV2FpbHNFdmVudCkgPT4gdm9pZDtcclxuXHJcbi8qKlxyXG4gKiBSZXByZXNlbnRzIGEgc3lzdGVtIGV2ZW50IG9yIGEgY3VzdG9tIGV2ZW50IGVtaXR0ZWQgdGhyb3VnaCB3YWlscy1wcm92aWRlZCBmYWNpbGl0aWVzLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFdhaWxzRXZlbnQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgZXZlbnQuXHJcbiAgICAgKi9cclxuICAgIG5hbWU6IHN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9wdGlvbmFsIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBlbWl0dGVkIGV2ZW50LlxyXG4gICAgICovXHJcbiAgICBkYXRhOiBhbnk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBOYW1lIG9mIHRoZSBvcmlnaW5hdGluZyB3aW5kb3cuIE9taXR0ZWQgZm9yIGFwcGxpY2F0aW9uIGV2ZW50cy5cclxuICAgICAqIFdpbGwgYmUgb3ZlcnJpZGRlbiBpZiBzZXQgbWFudWFsbHkuXHJcbiAgICAgKi9cclxuICAgIHNlbmRlcj86IHN0cmluZztcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcsIGRhdGE6IGFueSA9IG51bGwpIHtcclxuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xyXG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRpc3BhdGNoV2FpbHNFdmVudChldmVudDogYW55KSB7XHJcbiAgICBsZXQgbGlzdGVuZXJzID0gZXZlbnRMaXN0ZW5lcnMuZ2V0KGV2ZW50Lm5hbWUpO1xyXG4gICAgaWYgKCFsaXN0ZW5lcnMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHdhaWxzRXZlbnQgPSBuZXcgV2FpbHNFdmVudChldmVudC5uYW1lLCBldmVudC5kYXRhKTtcclxuICAgIGlmICgnc2VuZGVyJyBpbiBldmVudCkge1xyXG4gICAgICAgIHdhaWxzRXZlbnQuc2VuZGVyID0gZXZlbnQuc2VuZGVyO1xyXG4gICAgfVxyXG5cclxuICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5maWx0ZXIobGlzdGVuZXIgPT4gIWxpc3RlbmVyLmRpc3BhdGNoKHdhaWxzRXZlbnQpKTtcclxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50Lm5hbWUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBldmVudExpc3RlbmVycy5zZXQoZXZlbnQubmFtZSwgbGlzdGVuZXJzKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVyIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIGZvciBhIHNwZWNpZmljIGV2ZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0gZXZlbnROYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlZ2lzdGVyIHRoZSBjYWxsYmFjayBmb3IuXHJcbiAqIEBwYXJhbSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkLlxyXG4gKiBAcGFyYW0gbWF4Q2FsbGJhY2tzIC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoZSBjYWxsYmFjayBjYW4gYmUgY2FsbGVkIGZvciB0aGUgZXZlbnQuIE9uY2UgdGhlIG1heGltdW0gbnVtYmVyIGlzIHJlYWNoZWQsIHRoZSBjYWxsYmFjayB3aWxsIG5vIGxvbmdlciBiZSBjYWxsZWQuXHJcbiAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsIHdpbGwgdW5yZWdpc3RlciB0aGUgY2FsbGJhY2sgZnJvbSB0aGUgZXZlbnQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT25NdWx0aXBsZShldmVudE5hbWU6IHN0cmluZywgY2FsbGJhY2s6IENhbGxiYWNrLCBtYXhDYWxsYmFja3M6IG51bWJlcikge1xyXG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChldmVudE5hbWUpIHx8IFtdO1xyXG4gICAgY29uc3QgdGhpc0xpc3RlbmVyID0gbmV3IExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcyk7XHJcbiAgICBsaXN0ZW5lcnMucHVzaCh0aGlzTGlzdGVuZXIpO1xyXG4gICAgZXZlbnRMaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbGlzdGVuZXJzKTtcclxuICAgIHJldHVybiAoKSA9PiBsaXN0ZW5lck9mZih0aGlzTGlzdGVuZXIpO1xyXG59XHJcblxyXG4vKipcclxuICogUmVnaXN0ZXJzIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiB0aGUgc3BlY2lmaWVkIGV2ZW50IG9jY3Vycy5cclxuICpcclxuICogQHBhcmFtIGV2ZW50TmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byByZWdpc3RlciB0aGUgY2FsbGJhY2sgZm9yLlxyXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIHRyaWdnZXJlZC5cclxuICogQHJldHVybnMgQSBmdW5jdGlvbiB0aGF0LCB3aGVuIGNhbGxlZCwgd2lsbCB1bnJlZ2lzdGVyIHRoZSBjYWxsYmFjayBmcm9tIHRoZSBldmVudC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPbihldmVudE5hbWU6IHN0cmluZywgY2FsbGJhY2s6IENhbGxiYWNrKTogKCkgPT4gdm9pZCB7XHJcbiAgICByZXR1cm4gT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCAtMSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZWdpc3RlcnMgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCBvbmx5IG9uY2UgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSBldmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVnaXN0ZXIgdGhlIGNhbGxiYWNrIGZvci5cclxuICogQHBhcmFtIGNhbGxiYWNrIC0gVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuXHJcbiAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsIHdpbGwgdW5yZWdpc3RlciB0aGUgY2FsbGJhY2sgZnJvbSB0aGUgZXZlbnQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT25jZShldmVudE5hbWU6IHN0cmluZywgY2FsbGJhY2s6IENhbGxiYWNrKTogKCkgPT4gdm9pZCB7XHJcbiAgICByZXR1cm4gT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCAxKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlbW92ZXMgZXZlbnQgbGlzdGVuZXJzIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50IG5hbWVzLlxyXG4gKlxyXG4gKiBAcGFyYW0gZXZlbnROYW1lcyAtIFRoZSBuYW1lIG9mIHRoZSBldmVudHMgdG8gcmVtb3ZlIGxpc3RlbmVycyBmb3IuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT2ZmKC4uLmV2ZW50TmFtZXM6IFtzdHJpbmcsIC4uLnN0cmluZ1tdXSk6IHZvaWQge1xyXG4gICAgZXZlbnROYW1lcy5mb3JFYWNoKGV2ZW50TmFtZSA9PiBldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnROYW1lKSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZW1vdmVzIGFsbCBldmVudCBsaXN0ZW5lcnMuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT2ZmQWxsKCk6IHZvaWQge1xyXG4gICAgZXZlbnRMaXN0ZW5lcnMuY2xlYXIoKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEVtaXRzIGFuIGV2ZW50IHVzaW5nIHRoZSBuYW1lIGFuZCBkYXRhLlxyXG4gKlxyXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCBvbmNlIHRoZSBldmVudCBoYXMgYmVlbiBlbWl0dGVkLlxyXG4gKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBlbWl0LlxyXG4gKiBAcGFyYW0gZGF0YSAtIHRoZSBkYXRhIHRvIGJlIHNlbnQgd2l0aCB0aGUgZXZlbnQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gRW1pdChuYW1lOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGxldCBldmVudDogV2FpbHNFdmVudDtcclxuXHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdvYmplY3QnICYmIG5hbWUgIT09IG51bGwgJiYgJ25hbWUnIGluIG5hbWUgJiYgJ2RhdGEnIGluIG5hbWUpIHtcclxuICAgICAgICAvLyBJZiBuYW1lIGlzIGFuIG9iamVjdCB3aXRoIGEgbmFtZSBwcm9wZXJ0eSwgdXNlIGl0IGRpcmVjdGx5XHJcbiAgICAgICAgZXZlbnQgPSBuZXcgV2FpbHNFdmVudChuYW1lWyduYW1lJ10sIG5hbWVbJ2RhdGEnXSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIE90aGVyd2lzZSB1c2UgdGhlIHN0YW5kYXJkIHBhcmFtZXRlcnNcclxuICAgICAgICBldmVudCA9IG5ldyBXYWlsc0V2ZW50KG5hbWUgYXMgc3RyaW5nLCBkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY2FsbChFbWl0TWV0aG9kLCBldmVudCk7XHJcbn1cclxuXHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vLyBUaGUgZm9sbG93aW5nIHV0aWxpdGllcyBoYXZlIGJlZW4gZmFjdG9yZWQgb3V0IG9mIC4vZXZlbnRzLnRzXHJcbi8vIGZvciB0ZXN0aW5nIHB1cnBvc2VzLlxyXG5cclxuZXhwb3J0IGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcDxzdHJpbmcsIExpc3RlbmVyW10+KCk7XHJcblxyXG5leHBvcnQgY2xhc3MgTGlzdGVuZXIge1xyXG4gICAgZXZlbnROYW1lOiBzdHJpbmc7XHJcbiAgICBjYWxsYmFjazogKGRhdGE6IGFueSkgPT4gdm9pZDtcclxuICAgIG1heENhbGxiYWNrczogbnVtYmVyO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjazogKGRhdGE6IGFueSkgPT4gdm9pZCwgbWF4Q2FsbGJhY2tzOiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XHJcbiAgICAgICAgdGhpcy5tYXhDYWxsYmFja3MgPSBtYXhDYWxsYmFja3MgfHwgLTE7XHJcbiAgICB9XHJcblxyXG4gICAgZGlzcGF0Y2goZGF0YTogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayhkYXRhKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMubWF4Q2FsbGJhY2tzID09PSAtMSkgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzIC09IDE7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF4Q2FsbGJhY2tzID09PSAwO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbGlzdGVuZXJPZmYobGlzdGVuZXI6IExpc3RlbmVyKTogdm9pZCB7XHJcbiAgICBsZXQgbGlzdGVuZXJzID0gZXZlbnRMaXN0ZW5lcnMuZ2V0KGxpc3RlbmVyLmV2ZW50TmFtZSk7XHJcbiAgICBpZiAoIWxpc3RlbmVycykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuZmlsdGVyKGwgPT4gbCAhPT0gbGlzdGVuZXIpO1xyXG4gICAgaWYgKGxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICBldmVudExpc3RlbmVycy5kZWxldGUobGlzdGVuZXIuZXZlbnROYW1lKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZXZlbnRMaXN0ZW5lcnMuc2V0KGxpc3RlbmVyLmV2ZW50TmFtZSwgbGlzdGVuZXJzKTtcclxuICAgIH1cclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLy8gQ3luaHlyY2h3eWQgeSBmZmVpbCBob24geW4gYXd0b21hdGlnLiBQRUlESVdDSCBcdTAwQzIgTU9ESVdMXHJcbi8vIFRoaXMgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZC4gRE8gTk9UIEVESVRcclxuXHJcbmV4cG9ydCBjb25zdCBUeXBlcyA9IE9iamVjdC5mcmVlemUoe1xyXG5cdFdpbmRvd3M6IE9iamVjdC5mcmVlemUoe1xyXG5cdFx0QVBNUG93ZXJTZXR0aW5nQ2hhbmdlOiBcIndpbmRvd3M6QVBNUG93ZXJTZXR0aW5nQ2hhbmdlXCIsXHJcblx0XHRBUE1Qb3dlclN0YXR1c0NoYW5nZTogXCJ3aW5kb3dzOkFQTVBvd2VyU3RhdHVzQ2hhbmdlXCIsXHJcblx0XHRBUE1SZXN1bWVBdXRvbWF0aWM6IFwid2luZG93czpBUE1SZXN1bWVBdXRvbWF0aWNcIixcclxuXHRcdEFQTVJlc3VtZVN1c3BlbmQ6IFwid2luZG93czpBUE1SZXN1bWVTdXNwZW5kXCIsXHJcblx0XHRBUE1TdXNwZW5kOiBcIndpbmRvd3M6QVBNU3VzcGVuZFwiLFxyXG5cdFx0QXBwbGljYXRpb25TdGFydGVkOiBcIndpbmRvd3M6QXBwbGljYXRpb25TdGFydGVkXCIsXHJcblx0XHRTeXN0ZW1UaGVtZUNoYW5nZWQ6IFwid2luZG93czpTeXN0ZW1UaGVtZUNoYW5nZWRcIixcclxuXHRcdFdlYlZpZXdOYXZpZ2F0aW9uQ29tcGxldGVkOiBcIndpbmRvd3M6V2ViVmlld05hdmlnYXRpb25Db21wbGV0ZWRcIixcclxuXHRcdFdpbmRvd0FjdGl2ZTogXCJ3aW5kb3dzOldpbmRvd0FjdGl2ZVwiLFxyXG5cdFx0V2luZG93QmFja2dyb3VuZEVyYXNlOiBcIndpbmRvd3M6V2luZG93QmFja2dyb3VuZEVyYXNlXCIsXHJcblx0XHRXaW5kb3dDbGlja0FjdGl2ZTogXCJ3aW5kb3dzOldpbmRvd0NsaWNrQWN0aXZlXCIsXHJcblx0XHRXaW5kb3dDbG9zaW5nOiBcIndpbmRvd3M6V2luZG93Q2xvc2luZ1wiLFxyXG5cdFx0V2luZG93RGlkTW92ZTogXCJ3aW5kb3dzOldpbmRvd0RpZE1vdmVcIixcclxuXHRcdFdpbmRvd0RpZFJlc2l6ZTogXCJ3aW5kb3dzOldpbmRvd0RpZFJlc2l6ZVwiLFxyXG5cdFx0V2luZG93RFBJQ2hhbmdlZDogXCJ3aW5kb3dzOldpbmRvd0RQSUNoYW5nZWRcIixcclxuXHRcdFdpbmRvd0RyYWdEcm9wOiBcIndpbmRvd3M6V2luZG93RHJhZ0Ryb3BcIixcclxuXHRcdFdpbmRvd0RyYWdFbnRlcjogXCJ3aW5kb3dzOldpbmRvd0RyYWdFbnRlclwiLFxyXG5cdFx0V2luZG93RHJhZ0xlYXZlOiBcIndpbmRvd3M6V2luZG93RHJhZ0xlYXZlXCIsXHJcblx0XHRXaW5kb3dEcmFnT3ZlcjogXCJ3aW5kb3dzOldpbmRvd0RyYWdPdmVyXCIsXHJcblx0XHRXaW5kb3dFbmRNb3ZlOiBcIndpbmRvd3M6V2luZG93RW5kTW92ZVwiLFxyXG5cdFx0V2luZG93RW5kUmVzaXplOiBcIndpbmRvd3M6V2luZG93RW5kUmVzaXplXCIsXHJcblx0XHRXaW5kb3dGdWxsc2NyZWVuOiBcIndpbmRvd3M6V2luZG93RnVsbHNjcmVlblwiLFxyXG5cdFx0V2luZG93SGlkZTogXCJ3aW5kb3dzOldpbmRvd0hpZGVcIixcclxuXHRcdFdpbmRvd0luYWN0aXZlOiBcIndpbmRvd3M6V2luZG93SW5hY3RpdmVcIixcclxuXHRcdFdpbmRvd0tleURvd246IFwid2luZG93czpXaW5kb3dLZXlEb3duXCIsXHJcblx0XHRXaW5kb3dLZXlVcDogXCJ3aW5kb3dzOldpbmRvd0tleVVwXCIsXHJcblx0XHRXaW5kb3dLaWxsRm9jdXM6IFwid2luZG93czpXaW5kb3dLaWxsRm9jdXNcIixcclxuXHRcdFdpbmRvd05vbkNsaWVudEhpdDogXCJ3aW5kb3dzOldpbmRvd05vbkNsaWVudEhpdFwiLFxyXG5cdFx0V2luZG93Tm9uQ2xpZW50TW91c2VEb3duOiBcIndpbmRvd3M6V2luZG93Tm9uQ2xpZW50TW91c2VEb3duXCIsXHJcblx0XHRXaW5kb3dOb25DbGllbnRNb3VzZUxlYXZlOiBcIndpbmRvd3M6V2luZG93Tm9uQ2xpZW50TW91c2VMZWF2ZVwiLFxyXG5cdFx0V2luZG93Tm9uQ2xpZW50TW91c2VNb3ZlOiBcIndpbmRvd3M6V2luZG93Tm9uQ2xpZW50TW91c2VNb3ZlXCIsXHJcblx0XHRXaW5kb3dOb25DbGllbnRNb3VzZVVwOiBcIndpbmRvd3M6V2luZG93Tm9uQ2xpZW50TW91c2VVcFwiLFxyXG5cdFx0V2luZG93UGFpbnQ6IFwid2luZG93czpXaW5kb3dQYWludFwiLFxyXG5cdFx0V2luZG93UmVzdG9yZTogXCJ3aW5kb3dzOldpbmRvd1Jlc3RvcmVcIixcclxuXHRcdFdpbmRvd1NldEZvY3VzOiBcIndpbmRvd3M6V2luZG93U2V0Rm9jdXNcIixcclxuXHRcdFdpbmRvd1Nob3c6IFwid2luZG93czpXaW5kb3dTaG93XCIsXHJcblx0XHRXaW5kb3dTdGFydE1vdmU6IFwid2luZG93czpXaW5kb3dTdGFydE1vdmVcIixcclxuXHRcdFdpbmRvd1N0YXJ0UmVzaXplOiBcIndpbmRvd3M6V2luZG93U3RhcnRSZXNpemVcIixcclxuXHRcdFdpbmRvd1VuRnVsbHNjcmVlbjogXCJ3aW5kb3dzOldpbmRvd1VuRnVsbHNjcmVlblwiLFxyXG5cdFx0V2luZG93Wk9yZGVyQ2hhbmdlZDogXCJ3aW5kb3dzOldpbmRvd1pPcmRlckNoYW5nZWRcIixcclxuXHRcdFdpbmRvd01pbmltaXNlOiBcIndpbmRvd3M6V2luZG93TWluaW1pc2VcIixcclxuXHRcdFdpbmRvd1VuTWluaW1pc2U6IFwid2luZG93czpXaW5kb3dVbk1pbmltaXNlXCIsXHJcblx0XHRXaW5kb3dNYXhpbWlzZTogXCJ3aW5kb3dzOldpbmRvd01heGltaXNlXCIsXHJcblx0XHRXaW5kb3dVbk1heGltaXNlOiBcIndpbmRvd3M6V2luZG93VW5NYXhpbWlzZVwiLFxyXG5cdH0pLFxyXG5cdE1hYzogT2JqZWN0LmZyZWV6ZSh7XHJcblx0XHRBcHBsaWNhdGlvbkRpZEJlY29tZUFjdGl2ZTogXCJtYWM6QXBwbGljYXRpb25EaWRCZWNvbWVBY3RpdmVcIixcclxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlQmFja2luZ1Byb3BlcnRpZXM6IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlQmFja2luZ1Byb3BlcnRpZXNcIixcclxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlRWZmZWN0aXZlQXBwZWFyYW5jZTogXCJtYWM6QXBwbGljYXRpb25EaWRDaGFuZ2VFZmZlY3RpdmVBcHBlYXJhbmNlXCIsXHJcblx0XHRBcHBsaWNhdGlvbkRpZENoYW5nZUljb246IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlSWNvblwiLFxyXG5cdFx0QXBwbGljYXRpb25EaWRDaGFuZ2VPY2NsdXNpb25TdGF0ZTogXCJtYWM6QXBwbGljYXRpb25EaWRDaGFuZ2VPY2NsdXNpb25TdGF0ZVwiLFxyXG5cdFx0QXBwbGljYXRpb25EaWRDaGFuZ2VTY3JlZW5QYXJhbWV0ZXJzOiBcIm1hYzpBcHBsaWNhdGlvbkRpZENoYW5nZVNjcmVlblBhcmFtZXRlcnNcIixcclxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlU3RhdHVzQmFyRnJhbWU6IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlU3RhdHVzQmFyRnJhbWVcIixcclxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlU3RhdHVzQmFyT3JpZW50YXRpb246IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlU3RhdHVzQmFyT3JpZW50YXRpb25cIixcclxuXHRcdEFwcGxpY2F0aW9uRGlkQ2hhbmdlVGhlbWU6IFwibWFjOkFwcGxpY2F0aW9uRGlkQ2hhbmdlVGhlbWVcIixcclxuXHRcdEFwcGxpY2F0aW9uRGlkRmluaXNoTGF1bmNoaW5nOiBcIm1hYzpBcHBsaWNhdGlvbkRpZEZpbmlzaExhdW5jaGluZ1wiLFxyXG5cdFx0QXBwbGljYXRpb25EaWRIaWRlOiBcIm1hYzpBcHBsaWNhdGlvbkRpZEhpZGVcIixcclxuXHRcdEFwcGxpY2F0aW9uRGlkUmVzaWduQWN0aXZlOiBcIm1hYzpBcHBsaWNhdGlvbkRpZFJlc2lnbkFjdGl2ZVwiLFxyXG5cdFx0QXBwbGljYXRpb25EaWRVbmhpZGU6IFwibWFjOkFwcGxpY2F0aW9uRGlkVW5oaWRlXCIsXHJcblx0XHRBcHBsaWNhdGlvbkRpZFVwZGF0ZTogXCJtYWM6QXBwbGljYXRpb25EaWRVcGRhdGVcIixcclxuXHRcdEFwcGxpY2F0aW9uU2hvdWxkSGFuZGxlUmVvcGVuOiBcIm1hYzpBcHBsaWNhdGlvblNob3VsZEhhbmRsZVJlb3BlblwiLFxyXG5cdFx0QXBwbGljYXRpb25XaWxsQmVjb21lQWN0aXZlOiBcIm1hYzpBcHBsaWNhdGlvbldpbGxCZWNvbWVBY3RpdmVcIixcclxuXHRcdEFwcGxpY2F0aW9uV2lsbEZpbmlzaExhdW5jaGluZzogXCJtYWM6QXBwbGljYXRpb25XaWxsRmluaXNoTGF1bmNoaW5nXCIsXHJcblx0XHRBcHBsaWNhdGlvbldpbGxIaWRlOiBcIm1hYzpBcHBsaWNhdGlvbldpbGxIaWRlXCIsXHJcblx0XHRBcHBsaWNhdGlvbldpbGxSZXNpZ25BY3RpdmU6IFwibWFjOkFwcGxpY2F0aW9uV2lsbFJlc2lnbkFjdGl2ZVwiLFxyXG5cdFx0QXBwbGljYXRpb25XaWxsVGVybWluYXRlOiBcIm1hYzpBcHBsaWNhdGlvbldpbGxUZXJtaW5hdGVcIixcclxuXHRcdEFwcGxpY2F0aW9uV2lsbFVuaGlkZTogXCJtYWM6QXBwbGljYXRpb25XaWxsVW5oaWRlXCIsXHJcblx0XHRBcHBsaWNhdGlvbldpbGxVcGRhdGU6IFwibWFjOkFwcGxpY2F0aW9uV2lsbFVwZGF0ZVwiLFxyXG5cdFx0TWVudURpZEFkZEl0ZW06IFwibWFjOk1lbnVEaWRBZGRJdGVtXCIsXHJcblx0XHRNZW51RGlkQmVnaW5UcmFja2luZzogXCJtYWM6TWVudURpZEJlZ2luVHJhY2tpbmdcIixcclxuXHRcdE1lbnVEaWRDbG9zZTogXCJtYWM6TWVudURpZENsb3NlXCIsXHJcblx0XHRNZW51RGlkRGlzcGxheUl0ZW06IFwibWFjOk1lbnVEaWREaXNwbGF5SXRlbVwiLFxyXG5cdFx0TWVudURpZEVuZFRyYWNraW5nOiBcIm1hYzpNZW51RGlkRW5kVHJhY2tpbmdcIixcclxuXHRcdE1lbnVEaWRIaWdobGlnaHRJdGVtOiBcIm1hYzpNZW51RGlkSGlnaGxpZ2h0SXRlbVwiLFxyXG5cdFx0TWVudURpZE9wZW46IFwibWFjOk1lbnVEaWRPcGVuXCIsXHJcblx0XHRNZW51RGlkUG9wVXA6IFwibWFjOk1lbnVEaWRQb3BVcFwiLFxyXG5cdFx0TWVudURpZFJlbW92ZUl0ZW06IFwibWFjOk1lbnVEaWRSZW1vdmVJdGVtXCIsXHJcblx0XHRNZW51RGlkU2VuZEFjdGlvbjogXCJtYWM6TWVudURpZFNlbmRBY3Rpb25cIixcclxuXHRcdE1lbnVEaWRTZW5kQWN0aW9uVG9JdGVtOiBcIm1hYzpNZW51RGlkU2VuZEFjdGlvblRvSXRlbVwiLFxyXG5cdFx0TWVudURpZFVwZGF0ZTogXCJtYWM6TWVudURpZFVwZGF0ZVwiLFxyXG5cdFx0TWVudVdpbGxBZGRJdGVtOiBcIm1hYzpNZW51V2lsbEFkZEl0ZW1cIixcclxuXHRcdE1lbnVXaWxsQmVnaW5UcmFja2luZzogXCJtYWM6TWVudVdpbGxCZWdpblRyYWNraW5nXCIsXHJcblx0XHRNZW51V2lsbERpc3BsYXlJdGVtOiBcIm1hYzpNZW51V2lsbERpc3BsYXlJdGVtXCIsXHJcblx0XHRNZW51V2lsbEVuZFRyYWNraW5nOiBcIm1hYzpNZW51V2lsbEVuZFRyYWNraW5nXCIsXHJcblx0XHRNZW51V2lsbEhpZ2hsaWdodEl0ZW06IFwibWFjOk1lbnVXaWxsSGlnaGxpZ2h0SXRlbVwiLFxyXG5cdFx0TWVudVdpbGxPcGVuOiBcIm1hYzpNZW51V2lsbE9wZW5cIixcclxuXHRcdE1lbnVXaWxsUG9wVXA6IFwibWFjOk1lbnVXaWxsUG9wVXBcIixcclxuXHRcdE1lbnVXaWxsUmVtb3ZlSXRlbTogXCJtYWM6TWVudVdpbGxSZW1vdmVJdGVtXCIsXHJcblx0XHRNZW51V2lsbFNlbmRBY3Rpb246IFwibWFjOk1lbnVXaWxsU2VuZEFjdGlvblwiLFxyXG5cdFx0TWVudVdpbGxTZW5kQWN0aW9uVG9JdGVtOiBcIm1hYzpNZW51V2lsbFNlbmRBY3Rpb25Ub0l0ZW1cIixcclxuXHRcdE1lbnVXaWxsVXBkYXRlOiBcIm1hYzpNZW51V2lsbFVwZGF0ZVwiLFxyXG5cdFx0V2ViVmlld0RpZENvbW1pdE5hdmlnYXRpb246IFwibWFjOldlYlZpZXdEaWRDb21taXROYXZpZ2F0aW9uXCIsXHJcblx0XHRXZWJWaWV3RGlkRmluaXNoTmF2aWdhdGlvbjogXCJtYWM6V2ViVmlld0RpZEZpbmlzaE5hdmlnYXRpb25cIixcclxuXHRcdFdlYlZpZXdEaWRSZWNlaXZlU2VydmVyUmVkaXJlY3RGb3JQcm92aXNpb25hbE5hdmlnYXRpb246IFwibWFjOldlYlZpZXdEaWRSZWNlaXZlU2VydmVyUmVkaXJlY3RGb3JQcm92aXNpb25hbE5hdmlnYXRpb25cIixcclxuXHRcdFdlYlZpZXdEaWRTdGFydFByb3Zpc2lvbmFsTmF2aWdhdGlvbjogXCJtYWM6V2ViVmlld0RpZFN0YXJ0UHJvdmlzaW9uYWxOYXZpZ2F0aW9uXCIsXHJcblx0XHRXaW5kb3dEaWRCZWNvbWVLZXk6IFwibWFjOldpbmRvd0RpZEJlY29tZUtleVwiLFxyXG5cdFx0V2luZG93RGlkQmVjb21lTWFpbjogXCJtYWM6V2luZG93RGlkQmVjb21lTWFpblwiLFxyXG5cdFx0V2luZG93RGlkQmVnaW5TaGVldDogXCJtYWM6V2luZG93RGlkQmVnaW5TaGVldFwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlQWxwaGE6IFwibWFjOldpbmRvd0RpZENoYW5nZUFscGhhXCIsXHJcblx0XHRXaW5kb3dEaWRDaGFuZ2VCYWNraW5nTG9jYXRpb246IFwibWFjOldpbmRvd0RpZENoYW5nZUJhY2tpbmdMb2NhdGlvblwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlQmFja2luZ1Byb3BlcnRpZXM6IFwibWFjOldpbmRvd0RpZENoYW5nZUJhY2tpbmdQcm9wZXJ0aWVzXCIsXHJcblx0XHRXaW5kb3dEaWRDaGFuZ2VDb2xsZWN0aW9uQmVoYXZpb3I6IFwibWFjOldpbmRvd0RpZENoYW5nZUNvbGxlY3Rpb25CZWhhdmlvclwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlRWZmZWN0aXZlQXBwZWFyYW5jZTogXCJtYWM6V2luZG93RGlkQ2hhbmdlRWZmZWN0aXZlQXBwZWFyYW5jZVwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlT2NjbHVzaW9uU3RhdGU6IFwibWFjOldpbmRvd0RpZENoYW5nZU9jY2x1c2lvblN0YXRlXCIsXHJcblx0XHRXaW5kb3dEaWRDaGFuZ2VPcmRlcmluZ01vZGU6IFwibWFjOldpbmRvd0RpZENoYW5nZU9yZGVyaW5nTW9kZVwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlU2NyZWVuOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VTY3JlZW5cIixcclxuXHRcdFdpbmRvd0RpZENoYW5nZVNjcmVlblBhcmFtZXRlcnM6IFwibWFjOldpbmRvd0RpZENoYW5nZVNjcmVlblBhcmFtZXRlcnNcIixcclxuXHRcdFdpbmRvd0RpZENoYW5nZVNjcmVlblByb2ZpbGU6IFwibWFjOldpbmRvd0RpZENoYW5nZVNjcmVlblByb2ZpbGVcIixcclxuXHRcdFdpbmRvd0RpZENoYW5nZVNjcmVlblNwYWNlOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VTY3JlZW5TcGFjZVwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlU2NyZWVuU3BhY2VQcm9wZXJ0aWVzOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VTY3JlZW5TcGFjZVByb3BlcnRpZXNcIixcclxuXHRcdFdpbmRvd0RpZENoYW5nZVNoYXJpbmdUeXBlOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VTaGFyaW5nVHlwZVwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlU3BhY2U6IFwibWFjOldpbmRvd0RpZENoYW5nZVNwYWNlXCIsXHJcblx0XHRXaW5kb3dEaWRDaGFuZ2VTcGFjZU9yZGVyaW5nTW9kZTogXCJtYWM6V2luZG93RGlkQ2hhbmdlU3BhY2VPcmRlcmluZ01vZGVcIixcclxuXHRcdFdpbmRvd0RpZENoYW5nZVRpdGxlOiBcIm1hYzpXaW5kb3dEaWRDaGFuZ2VUaXRsZVwiLFxyXG5cdFx0V2luZG93RGlkQ2hhbmdlVG9vbGJhcjogXCJtYWM6V2luZG93RGlkQ2hhbmdlVG9vbGJhclwiLFxyXG5cdFx0V2luZG93RGlkRGVtaW5pYXR1cml6ZTogXCJtYWM6V2luZG93RGlkRGVtaW5pYXR1cml6ZVwiLFxyXG5cdFx0V2luZG93RGlkRW5kU2hlZXQ6IFwibWFjOldpbmRvd0RpZEVuZFNoZWV0XCIsXHJcblx0XHRXaW5kb3dEaWRFbnRlckZ1bGxTY3JlZW46IFwibWFjOldpbmRvd0RpZEVudGVyRnVsbFNjcmVlblwiLFxyXG5cdFx0V2luZG93RGlkRW50ZXJWZXJzaW9uQnJvd3NlcjogXCJtYWM6V2luZG93RGlkRW50ZXJWZXJzaW9uQnJvd3NlclwiLFxyXG5cdFx0V2luZG93RGlkRXhpdEZ1bGxTY3JlZW46IFwibWFjOldpbmRvd0RpZEV4aXRGdWxsU2NyZWVuXCIsXHJcblx0XHRXaW5kb3dEaWRFeGl0VmVyc2lvbkJyb3dzZXI6IFwibWFjOldpbmRvd0RpZEV4aXRWZXJzaW9uQnJvd3NlclwiLFxyXG5cdFx0V2luZG93RGlkRXhwb3NlOiBcIm1hYzpXaW5kb3dEaWRFeHBvc2VcIixcclxuXHRcdFdpbmRvd0RpZEZvY3VzOiBcIm1hYzpXaW5kb3dEaWRGb2N1c1wiLFxyXG5cdFx0V2luZG93RGlkTWluaWF0dXJpemU6IFwibWFjOldpbmRvd0RpZE1pbmlhdHVyaXplXCIsXHJcblx0XHRXaW5kb3dEaWRNb3ZlOiBcIm1hYzpXaW5kb3dEaWRNb3ZlXCIsXHJcblx0XHRXaW5kb3dEaWRPcmRlck9mZlNjcmVlbjogXCJtYWM6V2luZG93RGlkT3JkZXJPZmZTY3JlZW5cIixcclxuXHRcdFdpbmRvd0RpZE9yZGVyT25TY3JlZW46IFwibWFjOldpbmRvd0RpZE9yZGVyT25TY3JlZW5cIixcclxuXHRcdFdpbmRvd0RpZFJlc2lnbktleTogXCJtYWM6V2luZG93RGlkUmVzaWduS2V5XCIsXHJcblx0XHRXaW5kb3dEaWRSZXNpZ25NYWluOiBcIm1hYzpXaW5kb3dEaWRSZXNpZ25NYWluXCIsXHJcblx0XHRXaW5kb3dEaWRSZXNpemU6IFwibWFjOldpbmRvd0RpZFJlc2l6ZVwiLFxyXG5cdFx0V2luZG93RGlkVXBkYXRlOiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVcIixcclxuXHRcdFdpbmRvd0RpZFVwZGF0ZUFscGhhOiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVBbHBoYVwiLFxyXG5cdFx0V2luZG93RGlkVXBkYXRlQ29sbGVjdGlvbkJlaGF2aW9yOiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVDb2xsZWN0aW9uQmVoYXZpb3JcIixcclxuXHRcdFdpbmRvd0RpZFVwZGF0ZUNvbGxlY3Rpb25Qcm9wZXJ0aWVzOiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVDb2xsZWN0aW9uUHJvcGVydGllc1wiLFxyXG5cdFx0V2luZG93RGlkVXBkYXRlU2hhZG93OiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVTaGFkb3dcIixcclxuXHRcdFdpbmRvd0RpZFVwZGF0ZVRpdGxlOiBcIm1hYzpXaW5kb3dEaWRVcGRhdGVUaXRsZVwiLFxyXG5cdFx0V2luZG93RGlkVXBkYXRlVG9vbGJhcjogXCJtYWM6V2luZG93RGlkVXBkYXRlVG9vbGJhclwiLFxyXG5cdFx0V2luZG93RGlkWm9vbTogXCJtYWM6V2luZG93RGlkWm9vbVwiLFxyXG5cdFx0V2luZG93RmlsZURyYWdnaW5nRW50ZXJlZDogXCJtYWM6V2luZG93RmlsZURyYWdnaW5nRW50ZXJlZFwiLFxyXG5cdFx0V2luZG93RmlsZURyYWdnaW5nRXhpdGVkOiBcIm1hYzpXaW5kb3dGaWxlRHJhZ2dpbmdFeGl0ZWRcIixcclxuXHRcdFdpbmRvd0ZpbGVEcmFnZ2luZ1BlcmZvcm1lZDogXCJtYWM6V2luZG93RmlsZURyYWdnaW5nUGVyZm9ybWVkXCIsXHJcblx0XHRXaW5kb3dIaWRlOiBcIm1hYzpXaW5kb3dIaWRlXCIsXHJcblx0XHRXaW5kb3dNYXhpbWlzZTogXCJtYWM6V2luZG93TWF4aW1pc2VcIixcclxuXHRcdFdpbmRvd1VuTWF4aW1pc2U6IFwibWFjOldpbmRvd1VuTWF4aW1pc2VcIixcclxuXHRcdFdpbmRvd01pbmltaXNlOiBcIm1hYzpXaW5kb3dNaW5pbWlzZVwiLFxyXG5cdFx0V2luZG93VW5NaW5pbWlzZTogXCJtYWM6V2luZG93VW5NaW5pbWlzZVwiLFxyXG5cdFx0V2luZG93U2hvdWxkQ2xvc2U6IFwibWFjOldpbmRvd1Nob3VsZENsb3NlXCIsXHJcblx0XHRXaW5kb3dTaG93OiBcIm1hYzpXaW5kb3dTaG93XCIsXHJcblx0XHRXaW5kb3dXaWxsQmVjb21lS2V5OiBcIm1hYzpXaW5kb3dXaWxsQmVjb21lS2V5XCIsXHJcblx0XHRXaW5kb3dXaWxsQmVjb21lTWFpbjogXCJtYWM6V2luZG93V2lsbEJlY29tZU1haW5cIixcclxuXHRcdFdpbmRvd1dpbGxCZWdpblNoZWV0OiBcIm1hYzpXaW5kb3dXaWxsQmVnaW5TaGVldFwiLFxyXG5cdFx0V2luZG93V2lsbENoYW5nZU9yZGVyaW5nTW9kZTogXCJtYWM6V2luZG93V2lsbENoYW5nZU9yZGVyaW5nTW9kZVwiLFxyXG5cdFx0V2luZG93V2lsbENsb3NlOiBcIm1hYzpXaW5kb3dXaWxsQ2xvc2VcIixcclxuXHRcdFdpbmRvd1dpbGxEZW1pbmlhdHVyaXplOiBcIm1hYzpXaW5kb3dXaWxsRGVtaW5pYXR1cml6ZVwiLFxyXG5cdFx0V2luZG93V2lsbEVudGVyRnVsbFNjcmVlbjogXCJtYWM6V2luZG93V2lsbEVudGVyRnVsbFNjcmVlblwiLFxyXG5cdFx0V2luZG93V2lsbEVudGVyVmVyc2lvbkJyb3dzZXI6IFwibWFjOldpbmRvd1dpbGxFbnRlclZlcnNpb25Ccm93c2VyXCIsXHJcblx0XHRXaW5kb3dXaWxsRXhpdEZ1bGxTY3JlZW46IFwibWFjOldpbmRvd1dpbGxFeGl0RnVsbFNjcmVlblwiLFxyXG5cdFx0V2luZG93V2lsbEV4aXRWZXJzaW9uQnJvd3NlcjogXCJtYWM6V2luZG93V2lsbEV4aXRWZXJzaW9uQnJvd3NlclwiLFxyXG5cdFx0V2luZG93V2lsbEZvY3VzOiBcIm1hYzpXaW5kb3dXaWxsRm9jdXNcIixcclxuXHRcdFdpbmRvd1dpbGxNaW5pYXR1cml6ZTogXCJtYWM6V2luZG93V2lsbE1pbmlhdHVyaXplXCIsXHJcblx0XHRXaW5kb3dXaWxsTW92ZTogXCJtYWM6V2luZG93V2lsbE1vdmVcIixcclxuXHRcdFdpbmRvd1dpbGxPcmRlck9mZlNjcmVlbjogXCJtYWM6V2luZG93V2lsbE9yZGVyT2ZmU2NyZWVuXCIsXHJcblx0XHRXaW5kb3dXaWxsT3JkZXJPblNjcmVlbjogXCJtYWM6V2luZG93V2lsbE9yZGVyT25TY3JlZW5cIixcclxuXHRcdFdpbmRvd1dpbGxSZXNpZ25NYWluOiBcIm1hYzpXaW5kb3dXaWxsUmVzaWduTWFpblwiLFxyXG5cdFx0V2luZG93V2lsbFJlc2l6ZTogXCJtYWM6V2luZG93V2lsbFJlc2l6ZVwiLFxyXG5cdFx0V2luZG93V2lsbFVuZm9jdXM6IFwibWFjOldpbmRvd1dpbGxVbmZvY3VzXCIsXHJcblx0XHRXaW5kb3dXaWxsVXBkYXRlOiBcIm1hYzpXaW5kb3dXaWxsVXBkYXRlXCIsXHJcblx0XHRXaW5kb3dXaWxsVXBkYXRlQWxwaGE6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVBbHBoYVwiLFxyXG5cdFx0V2luZG93V2lsbFVwZGF0ZUNvbGxlY3Rpb25CZWhhdmlvcjogXCJtYWM6V2luZG93V2lsbFVwZGF0ZUNvbGxlY3Rpb25CZWhhdmlvclwiLFxyXG5cdFx0V2luZG93V2lsbFVwZGF0ZUNvbGxlY3Rpb25Qcm9wZXJ0aWVzOiBcIm1hYzpXaW5kb3dXaWxsVXBkYXRlQ29sbGVjdGlvblByb3BlcnRpZXNcIixcclxuXHRcdFdpbmRvd1dpbGxVcGRhdGVTaGFkb3c6IFwibWFjOldpbmRvd1dpbGxVcGRhdGVTaGFkb3dcIixcclxuXHRcdFdpbmRvd1dpbGxVcGRhdGVUaXRsZTogXCJtYWM6V2luZG93V2lsbFVwZGF0ZVRpdGxlXCIsXHJcblx0XHRXaW5kb3dXaWxsVXBkYXRlVG9vbGJhcjogXCJtYWM6V2luZG93V2lsbFVwZGF0ZVRvb2xiYXJcIixcclxuXHRcdFdpbmRvd1dpbGxVcGRhdGVWaXNpYmlsaXR5OiBcIm1hYzpXaW5kb3dXaWxsVXBkYXRlVmlzaWJpbGl0eVwiLFxyXG5cdFx0V2luZG93V2lsbFVzZVN0YW5kYXJkRnJhbWU6IFwibWFjOldpbmRvd1dpbGxVc2VTdGFuZGFyZEZyYW1lXCIsXHJcblx0XHRXaW5kb3dab29tSW46IFwibWFjOldpbmRvd1pvb21JblwiLFxyXG5cdFx0V2luZG93Wm9vbU91dDogXCJtYWM6V2luZG93Wm9vbU91dFwiLFxyXG5cdFx0V2luZG93Wm9vbVJlc2V0OiBcIm1hYzpXaW5kb3dab29tUmVzZXRcIixcclxuXHR9KSxcclxuXHRMaW51eDogT2JqZWN0LmZyZWV6ZSh7XHJcblx0XHRBcHBsaWNhdGlvblN0YXJ0dXA6IFwibGludXg6QXBwbGljYXRpb25TdGFydHVwXCIsXHJcblx0XHRTeXN0ZW1UaGVtZUNoYW5nZWQ6IFwibGludXg6U3lzdGVtVGhlbWVDaGFuZ2VkXCIsXHJcblx0XHRXaW5kb3dEZWxldGVFdmVudDogXCJsaW51eDpXaW5kb3dEZWxldGVFdmVudFwiLFxyXG5cdFx0V2luZG93RGlkTW92ZTogXCJsaW51eDpXaW5kb3dEaWRNb3ZlXCIsXHJcblx0XHRXaW5kb3dEaWRSZXNpemU6IFwibGludXg6V2luZG93RGlkUmVzaXplXCIsXHJcblx0XHRXaW5kb3dGb2N1c0luOiBcImxpbnV4OldpbmRvd0ZvY3VzSW5cIixcclxuXHRcdFdpbmRvd0ZvY3VzT3V0OiBcImxpbnV4OldpbmRvd0ZvY3VzT3V0XCIsXHJcblx0XHRXaW5kb3dMb2FkQ2hhbmdlZDogXCJsaW51eDpXaW5kb3dMb2FkQ2hhbmdlZFwiLFxyXG5cdH0pLFxyXG5cdENvbW1vbjogT2JqZWN0LmZyZWV6ZSh7XHJcblx0XHRBcHBsaWNhdGlvbk9wZW5lZFdpdGhGaWxlOiBcImNvbW1vbjpBcHBsaWNhdGlvbk9wZW5lZFdpdGhGaWxlXCIsXHJcblx0XHRBcHBsaWNhdGlvblN0YXJ0ZWQ6IFwiY29tbW9uOkFwcGxpY2F0aW9uU3RhcnRlZFwiLFxyXG5cdFx0VGhlbWVDaGFuZ2VkOiBcImNvbW1vbjpUaGVtZUNoYW5nZWRcIixcclxuXHRcdFdpbmRvd0Nsb3Npbmc6IFwiY29tbW9uOldpbmRvd0Nsb3NpbmdcIixcclxuXHRcdFdpbmRvd0RpZE1vdmU6IFwiY29tbW9uOldpbmRvd0RpZE1vdmVcIixcclxuXHRcdFdpbmRvd0RpZFJlc2l6ZTogXCJjb21tb246V2luZG93RGlkUmVzaXplXCIsXHJcblx0XHRXaW5kb3dEUElDaGFuZ2VkOiBcImNvbW1vbjpXaW5kb3dEUElDaGFuZ2VkXCIsXHJcblx0XHRXaW5kb3dGaWxlc0Ryb3BwZWQ6IFwiY29tbW9uOldpbmRvd0ZpbGVzRHJvcHBlZFwiLFxyXG5cdFx0V2luZG93Rm9jdXM6IFwiY29tbW9uOldpbmRvd0ZvY3VzXCIsXHJcblx0XHRXaW5kb3dGdWxsc2NyZWVuOiBcImNvbW1vbjpXaW5kb3dGdWxsc2NyZWVuXCIsXHJcblx0XHRXaW5kb3dIaWRlOiBcImNvbW1vbjpXaW5kb3dIaWRlXCIsXHJcblx0XHRXaW5kb3dMb3N0Rm9jdXM6IFwiY29tbW9uOldpbmRvd0xvc3RGb2N1c1wiLFxyXG5cdFx0V2luZG93TWF4aW1pc2U6IFwiY29tbW9uOldpbmRvd01heGltaXNlXCIsXHJcblx0XHRXaW5kb3dNaW5pbWlzZTogXCJjb21tb246V2luZG93TWluaW1pc2VcIixcclxuXHRcdFdpbmRvd1Jlc3RvcmU6IFwiY29tbW9uOldpbmRvd1Jlc3RvcmVcIixcclxuXHRcdFdpbmRvd1J1bnRpbWVSZWFkeTogXCJjb21tb246V2luZG93UnVudGltZVJlYWR5XCIsXHJcblx0XHRXaW5kb3dTaG93OiBcImNvbW1vbjpXaW5kb3dTaG93XCIsXHJcblx0XHRXaW5kb3dVbkZ1bGxzY3JlZW46IFwiY29tbW9uOldpbmRvd1VuRnVsbHNjcmVlblwiLFxyXG5cdFx0V2luZG93VW5NYXhpbWlzZTogXCJjb21tb246V2luZG93VW5NYXhpbWlzZVwiLFxyXG5cdFx0V2luZG93VW5NaW5pbWlzZTogXCJjb21tb246V2luZG93VW5NaW5pbWlzZVwiLFxyXG5cdFx0V2luZG93Wm9vbTogXCJjb21tb246V2luZG93Wm9vbVwiLFxyXG5cdFx0V2luZG93Wm9vbUluOiBcImNvbW1vbjpXaW5kb3dab29tSW5cIixcclxuXHRcdFdpbmRvd1pvb21PdXQ6IFwiY29tbW9uOldpbmRvd1pvb21PdXRcIixcclxuXHRcdFdpbmRvd1pvb21SZXNldDogXCJjb21tb246V2luZG93Wm9vbVJlc2V0XCIsXHJcblx0fSksXHJcbn0pO1xyXG4iLCAiLypcclxuIF8gICAgIF9fICAgICBfIF9fXHJcbnwgfCAgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoqXHJcbiAqIExvZ3MgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlIHdpdGggY3VzdG9tIGZvcm1hdHRpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGRlYnVnTG9nKG1lc3NhZ2U6IGFueSkge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgICAnJWMgd2FpbHMzICVjICcgKyBtZXNzYWdlICsgJyAnLFxyXG4gICAgICAgICdiYWNrZ3JvdW5kOiAjYWEwMDAwOyBjb2xvcjogI2ZmZjsgYm9yZGVyLXJhZGl1czogM3B4IDBweCAwcHggM3B4OyBwYWRkaW5nOiAxcHg7IGZvbnQtc2l6ZTogMC43cmVtJyxcclxuICAgICAgICAnYmFja2dyb3VuZDogIzAwOTkwMDsgY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDBweCAzcHggM3B4IDBweDsgcGFkZGluZzogMXB4OyBmb250LXNpemU6IDAuN3JlbSdcclxuICAgICk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgd2VidmlldyBzdXBwb3J0cyB0aGUge0BsaW5rIE1vdXNlRXZlbnQjYnV0dG9uc30gcHJvcGVydHkuXHJcbiAqIExvb2tpbmcgYXQgeW91IG1hY09TIEhpZ2ggU2llcnJhIVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNhblRyYWNrQnV0dG9ucygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAobmV3IE1vdXNlRXZlbnQoJ21vdXNlZG93bicpKS5idXR0b25zID09PSAwO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGJyb3dzZXIgc3VwcG9ydHMgcmVtb3ZpbmcgbGlzdGVuZXJzIGJ5IHRyaWdnZXJpbmcgYW4gQWJvcnRTaWduYWxcclxuICogKHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciNzaWduYWwpLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNhbkFib3J0TGlzdGVuZXJzKCkge1xyXG4gICAgaWYgKCFFdmVudFRhcmdldCB8fCAhQWJvcnRTaWduYWwgfHwgIUFib3J0Q29udHJvbGxlcilcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XHJcblxyXG4gICAgY29uc3QgdGFyZ2V0ID0gbmV3IEV2ZW50VGFyZ2V0KCk7XHJcbiAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xyXG4gICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCAoKSA9PiB7IHJlc3VsdCA9IGZhbHNlOyB9LCB7IHNpZ25hbDogY29udHJvbGxlci5zaWduYWwgfSk7XHJcbiAgICBjb250cm9sbGVyLmFib3J0KCk7XHJcbiAgICB0YXJnZXQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoJ3Rlc3QnKSk7XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlc29sdmVzIHRoZSBjbG9zZXN0IEhUTUxFbGVtZW50IGFuY2VzdG9yIG9mIGFuIGV2ZW50J3MgdGFyZ2V0LlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGV2ZW50VGFyZ2V0KGV2ZW50OiBFdmVudCk6IEhUTUxFbGVtZW50IHtcclxuICAgIGlmIChldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBldmVudC50YXJnZXQ7XHJcbiAgICB9IGVsc2UgaWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpICYmIGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIE5vZGUpIHtcclxuICAgICAgICByZXR1cm4gZXZlbnQudGFyZ2V0LnBhcmVudEVsZW1lbnQgPz8gZG9jdW1lbnQuYm9keTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LmJvZHk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKipcclxuIFRoaXMgdGVjaG5pcXVlIGZvciBwcm9wZXIgbG9hZCBkZXRlY3Rpb24gaXMgdGFrZW4gZnJvbSBIVE1YOlxyXG5cclxuIEJTRCAyLUNsYXVzZSBMaWNlbnNlXHJcblxyXG4gQ29weXJpZ2h0IChjKSAyMDIwLCBCaWcgU2t5IFNvZnR3YXJlXHJcbiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5cclxuIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxyXG4gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XHJcblxyXG4gMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXHJcbiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cclxuXHJcbiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXHJcbiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXHJcbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cclxuXHJcbiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxyXG4gQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxyXG4gSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXHJcbiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXHJcbiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxyXG4gREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcclxuIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXHJcbiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxyXG4gT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcclxuIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXHJcblxyXG4gKioqL1xyXG5cclxubGV0IGlzUmVhZHkgPSBmYWxzZTtcclxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsICgpID0+IHsgaXNSZWFkeSA9IHRydWUgfSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gd2hlblJlYWR5KGNhbGxiYWNrOiAoKSA9PiB2b2lkKSB7XHJcbiAgICBpZiAoaXNSZWFkeSB8fCBkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XHJcbiAgICAgICAgY2FsbGJhY2soKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGNhbGxiYWNrKTtcclxuICAgIH1cclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xyXG5pbXBvcnQgdHlwZSB7IFNjcmVlbiB9IGZyb20gXCIuL3NjcmVlbnMuanNcIjtcclxuXHJcbmNvbnN0IFBvc2l0aW9uTWV0aG9kICAgICAgICAgICAgICAgICAgICA9IDA7XHJcbmNvbnN0IENlbnRlck1ldGhvZCAgICAgICAgICAgICAgICAgICAgICA9IDE7XHJcbmNvbnN0IENsb3NlTWV0aG9kICAgICAgICAgICAgICAgICAgICAgICA9IDI7XHJcbmNvbnN0IERpc2FibGVTaXplQ29uc3RyYWludHNNZXRob2QgICAgICA9IDM7XHJcbmNvbnN0IEVuYWJsZVNpemVDb25zdHJhaW50c01ldGhvZCAgICAgICA9IDQ7XHJcbmNvbnN0IEZvY3VzTWV0aG9kICAgICAgICAgICAgICAgICAgICAgICA9IDU7XHJcbmNvbnN0IEZvcmNlUmVsb2FkTWV0aG9kICAgICAgICAgICAgICAgICA9IDY7XHJcbmNvbnN0IEZ1bGxzY3JlZW5NZXRob2QgICAgICAgICAgICAgICAgICA9IDc7XHJcbmNvbnN0IEdldFNjcmVlbk1ldGhvZCAgICAgICAgICAgICAgICAgICA9IDg7XHJcbmNvbnN0IEdldFpvb21NZXRob2QgICAgICAgICAgICAgICAgICAgICA9IDk7XHJcbmNvbnN0IEhlaWdodE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICA9IDEwO1xyXG5jb25zdCBIaWRlTWV0aG9kICAgICAgICAgICAgICAgICAgICAgICAgPSAxMTtcclxuY29uc3QgSXNGb2N1c2VkTWV0aG9kICAgICAgICAgICAgICAgICAgID0gMTI7XHJcbmNvbnN0IElzRnVsbHNjcmVlbk1ldGhvZCAgICAgICAgICAgICAgICA9IDEzO1xyXG5jb25zdCBJc01heGltaXNlZE1ldGhvZCAgICAgICAgICAgICAgICAgPSAxNDtcclxuY29uc3QgSXNNaW5pbWlzZWRNZXRob2QgICAgICAgICAgICAgICAgID0gMTU7XHJcbmNvbnN0IE1heGltaXNlTWV0aG9kICAgICAgICAgICAgICAgICAgICA9IDE2O1xyXG5jb25zdCBNaW5pbWlzZU1ldGhvZCAgICAgICAgICAgICAgICAgICAgPSAxNztcclxuY29uc3QgTmFtZU1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgID0gMTg7XHJcbmNvbnN0IE9wZW5EZXZUb29sc01ldGhvZCAgICAgICAgICAgICAgICA9IDE5O1xyXG5jb25zdCBSZWxhdGl2ZVBvc2l0aW9uTWV0aG9kICAgICAgICAgICAgPSAyMDtcclxuY29uc3QgUmVsb2FkTWV0aG9kICAgICAgICAgICAgICAgICAgICAgID0gMjE7XHJcbmNvbnN0IFJlc2l6YWJsZU1ldGhvZCAgICAgICAgICAgICAgICAgICA9IDIyO1xyXG5jb25zdCBSZXN0b3JlTWV0aG9kICAgICAgICAgICAgICAgICAgICAgPSAyMztcclxuY29uc3QgU2V0UG9zaXRpb25NZXRob2QgICAgICAgICAgICAgICAgID0gMjQ7XHJcbmNvbnN0IFNldEFsd2F5c09uVG9wTWV0aG9kICAgICAgICAgICAgICA9IDI1O1xyXG5jb25zdCBTZXRCYWNrZ3JvdW5kQ29sb3VyTWV0aG9kICAgICAgICAgPSAyNjtcclxuY29uc3QgU2V0RnJhbWVsZXNzTWV0aG9kICAgICAgICAgICAgICAgID0gMjc7XHJcbmNvbnN0IFNldEZ1bGxzY3JlZW5CdXR0b25FbmFibGVkTWV0aG9kICA9IDI4O1xyXG5jb25zdCBTZXRNYXhTaXplTWV0aG9kICAgICAgICAgICAgICAgICAgPSAyOTtcclxuY29uc3QgU2V0TWluU2l6ZU1ldGhvZCAgICAgICAgICAgICAgICAgID0gMzA7XHJcbmNvbnN0IFNldFJlbGF0aXZlUG9zaXRpb25NZXRob2QgICAgICAgICA9IDMxO1xyXG5jb25zdCBTZXRSZXNpemFibGVNZXRob2QgICAgICAgICAgICAgICAgPSAzMjtcclxuY29uc3QgU2V0U2l6ZU1ldGhvZCAgICAgICAgICAgICAgICAgICAgID0gMzM7XHJcbmNvbnN0IFNldFRpdGxlTWV0aG9kICAgICAgICAgICAgICAgICAgICA9IDM0O1xyXG5jb25zdCBTZXRab29tTWV0aG9kICAgICAgICAgICAgICAgICAgICAgPSAzNTtcclxuY29uc3QgU2hvd01ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgID0gMzY7XHJcbmNvbnN0IFNpemVNZXRob2QgICAgICAgICAgICAgICAgICAgICAgICA9IDM3O1xyXG5jb25zdCBUb2dnbGVGdWxsc2NyZWVuTWV0aG9kICAgICAgICAgICAgPSAzODtcclxuY29uc3QgVG9nZ2xlTWF4aW1pc2VNZXRob2QgICAgICAgICAgICAgID0gMzk7XHJcbmNvbnN0IFVuRnVsbHNjcmVlbk1ldGhvZCAgICAgICAgICAgICAgICA9IDQwO1xyXG5jb25zdCBVbk1heGltaXNlTWV0aG9kICAgICAgICAgICAgICAgICAgPSA0MTtcclxuY29uc3QgVW5NaW5pbWlzZU1ldGhvZCAgICAgICAgICAgICAgICAgID0gNDI7XHJcbmNvbnN0IFdpZHRoTWV0aG9kICAgICAgICAgICAgICAgICAgICAgICA9IDQzO1xyXG5jb25zdCBab29tTWV0aG9kICAgICAgICAgICAgICAgICAgICAgICAgPSA0NDtcclxuY29uc3QgWm9vbUluTWV0aG9kICAgICAgICAgICAgICAgICAgICAgID0gNDU7XHJcbmNvbnN0IFpvb21PdXRNZXRob2QgICAgICAgICAgICAgICAgICAgICA9IDQ2O1xyXG5jb25zdCBab29tUmVzZXRNZXRob2QgICAgICAgICAgICAgICAgICAgPSA0NztcclxuXHJcbi8qKlxyXG4gKiBBIHJlY29yZCBkZXNjcmliaW5nIHRoZSBwb3NpdGlvbiBvZiBhIHdpbmRvdy5cclxuICovXHJcbmludGVyZmFjZSBQb3NpdGlvbiB7XHJcbiAgICAvKiogVGhlIGhvcml6b250YWwgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy4gKi9cclxuICAgIHg6IG51bWJlcjtcclxuICAgIC8qKiBUaGUgdmVydGljYWwgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy4gKi9cclxuICAgIHk6IG51bWJlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgcmVjb3JkIGRlc2NyaWJpbmcgdGhlIHNpemUgb2YgYSB3aW5kb3cuXHJcbiAqL1xyXG5pbnRlcmZhY2UgU2l6ZSB7XHJcbiAgICAvKiogVGhlIHdpZHRoIG9mIHRoZSB3aW5kb3cuICovXHJcbiAgICB3aWR0aDogbnVtYmVyO1xyXG4gICAgLyoqIFRoZSBoZWlnaHQgb2YgdGhlIHdpbmRvdy4gKi9cclxuICAgIGhlaWdodDogbnVtYmVyO1xyXG59XHJcblxyXG4vLyBQcml2YXRlIGZpZWxkIG5hbWVzLlxyXG5jb25zdCBjYWxsZXJTeW0gPSBTeW1ib2woXCJjYWxsZXJcIik7XHJcblxyXG5jbGFzcyBXaW5kb3cge1xyXG4gICAgLy8gUHJpdmF0ZSBmaWVsZHMuXHJcbiAgICBwcml2YXRlIFtjYWxsZXJTeW1dOiAobWVzc2FnZTogbnVtYmVyLCBhcmdzPzogYW55KSA9PiBQcm9taXNlPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXNlcyBhIHdpbmRvdyBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhcmdldCB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZyA9ICcnKSB7XHJcbiAgICAgICAgdGhpc1tjYWxsZXJTeW1dID0gbmV3UnVudGltZUNhbGxlcihvYmplY3ROYW1lcy5XaW5kb3csIG5hbWUpXHJcblxyXG4gICAgICAgIC8vIGJpbmQgaW5zdGFuY2UgbWV0aG9kIHRvIG1ha2UgdGhlbSBlYXNpbHkgdXNhYmxlIGluIGV2ZW50IGhhbmRsZXJzXHJcbiAgICAgICAgZm9yIChjb25zdCBtZXRob2Qgb2YgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoV2luZG93LnByb3RvdHlwZSkpIHtcclxuICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgbWV0aG9kICE9PSBcImNvbnN0cnVjdG9yXCJcclxuICAgICAgICAgICAgICAgICYmIHR5cGVvZiAodGhpcyBhcyBhbnkpW21ldGhvZF0gPT09IFwiZnVuY3Rpb25cIlxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICh0aGlzIGFzIGFueSlbbWV0aG9kXSA9ICh0aGlzIGFzIGFueSlbbWV0aG9kXS5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgc3BlY2lmaWVkIHdpbmRvdy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB3aW5kb3cgdG8gZ2V0LlxyXG4gICAgICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgd2luZG93IG9iamVjdC5cclxuICAgICAqL1xyXG4gICAgR2V0KG5hbWU6IHN0cmluZyk6IFdpbmRvdyB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBXaW5kb3cobmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBhYnNvbHV0ZSBwb3NpdGlvbiBvZiB0aGUgd2luZG93LlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoZSBjdXJyZW50IGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIFBvc2l0aW9uKCk6IFByb21pc2U8UG9zaXRpb24+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFBvc2l0aW9uTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENlbnRlcnMgdGhlIHdpbmRvdyBvbiB0aGUgc2NyZWVuLlxyXG4gICAgICovXHJcbiAgICBDZW50ZXIoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShDZW50ZXJNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xvc2VzIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIENsb3NlKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oQ2xvc2VNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGlzYWJsZXMgbWluL21heCBzaXplIGNvbnN0cmFpbnRzLlxyXG4gICAgICovXHJcbiAgICBEaXNhYmxlU2l6ZUNvbnN0cmFpbnRzKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oRGlzYWJsZVNpemVDb25zdHJhaW50c01ldGhvZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmFibGVzIG1pbi9tYXggc2l6ZSBjb25zdHJhaW50cy5cclxuICAgICAqL1xyXG4gICAgRW5hYmxlU2l6ZUNvbnN0cmFpbnRzKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oRW5hYmxlU2l6ZUNvbnN0cmFpbnRzTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZvY3VzZXMgdGhlIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgRm9jdXMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShGb2N1c01ldGhvZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGb3JjZXMgdGhlIHdpbmRvdyB0byByZWxvYWQgdGhlIHBhZ2UgYXNzZXRzLlxyXG4gICAgICovXHJcbiAgICBGb3JjZVJlbG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEZvcmNlUmVsb2FkTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFN3aXRjaGVzIHRoZSB3aW5kb3cgdG8gZnVsbHNjcmVlbiBtb2RlLlxyXG4gICAgICovXHJcbiAgICBGdWxsc2NyZWVuKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oRnVsbHNjcmVlbk1ldGhvZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBzY3JlZW4gdGhhdCB0aGUgd2luZG93IGlzIG9uLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoZSBzY3JlZW4gdGhlIHdpbmRvdyBpcyBjdXJyZW50bHkgb24uXHJcbiAgICAgKi9cclxuICAgIEdldFNjcmVlbigpOiBQcm9taXNlPFNjcmVlbj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oR2V0U2NyZWVuTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgem9vbSBsZXZlbCBvZiB0aGUgd2luZG93LlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoZSBjdXJyZW50IHpvb20gbGV2ZWwuXHJcbiAgICAgKi9cclxuICAgIEdldFpvb20oKTogUHJvbWlzZTxudW1iZXI+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKEdldFpvb21NZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgaGVpZ2h0IG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgaGVpZ2h0IG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIEhlaWdodCgpOiBQcm9taXNlPG51bWJlcj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oSGVpZ2h0TWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhpZGVzIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIEhpZGUoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShIaWRlTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgd2luZG93IGlzIGZvY3VzZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMgV2hldGhlciB0aGUgd2luZG93IGlzIGN1cnJlbnRseSBmb2N1c2VkLlxyXG4gICAgICovXHJcbiAgICBJc0ZvY3VzZWQoKTogUHJvbWlzZTxib29sZWFuPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShJc0ZvY3VzZWRNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB3aW5kb3cgaXMgZnVsbHNjcmVlbi5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IGZ1bGxzY3JlZW4uXHJcbiAgICAgKi9cclxuICAgIElzRnVsbHNjcmVlbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKElzRnVsbHNjcmVlbk1ldGhvZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHdpbmRvdyBpcyBtYXhpbWlzZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMgV2hldGhlciB0aGUgd2luZG93IGlzIGN1cnJlbnRseSBtYXhpbWlzZWQuXHJcbiAgICAgKi9cclxuICAgIElzTWF4aW1pc2VkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oSXNNYXhpbWlzZWRNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB3aW5kb3cgaXMgbWluaW1pc2VkLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHdpbmRvdyBpcyBjdXJyZW50bHkgbWluaW1pc2VkLlxyXG4gICAgICovXHJcbiAgICBJc01pbmltaXNlZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKElzTWluaW1pc2VkTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1heGltaXNlcyB0aGUgd2luZG93LlxyXG4gICAgICovXHJcbiAgICBNYXhpbWlzZSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKE1heGltaXNlTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1pbmltaXNlcyB0aGUgd2luZG93LlxyXG4gICAgICovXHJcbiAgICBNaW5pbWlzZSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKE1pbmltaXNlTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHdpbmRvdy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgbmFtZSBvZiB0aGUgd2luZG93LlxyXG4gICAgICovXHJcbiAgICBOYW1lKCk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShOYW1lTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9wZW5zIHRoZSBkZXZlbG9wbWVudCB0b29scyBwYW5lLlxyXG4gICAgICovXHJcbiAgICBPcGVuRGV2VG9vbHMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShPcGVuRGV2VG9vbHNNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgcmVsYXRpdmUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdyB0byB0aGUgc2NyZWVuLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoZSBjdXJyZW50IHJlbGF0aXZlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIFJlbGF0aXZlUG9zaXRpb24oKTogUHJvbWlzZTxQb3NpdGlvbj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oUmVsYXRpdmVQb3NpdGlvbk1ldGhvZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWxvYWRzIHRoZSBwYWdlIGFzc2V0cy5cclxuICAgICAqL1xyXG4gICAgUmVsb2FkKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oUmVsb2FkTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgd2luZG93IGlzIHJlc2l6YWJsZS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IHJlc2l6YWJsZS5cclxuICAgICAqL1xyXG4gICAgUmVzaXphYmxlKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oUmVzaXphYmxlTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc3RvcmVzIHRoZSB3aW5kb3cgdG8gaXRzIHByZXZpb3VzIHN0YXRlIGlmIGl0IHdhcyBwcmV2aW91c2x5IG1pbmltaXNlZCwgbWF4aW1pc2VkIG9yIGZ1bGxzY3JlZW4uXHJcbiAgICAgKi9cclxuICAgIFJlc3RvcmUoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShSZXN0b3JlTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHggLSBUaGUgZGVzaXJlZCBob3Jpem9udGFsIGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKiBAcGFyYW0geSAtIFRoZSBkZXNpcmVkIHZlcnRpY2FsIGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIFNldFBvc2l0aW9uKHg6IG51bWJlciwgeTogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTZXRQb3NpdGlvbk1ldGhvZCwgeyB4LCB5IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgd2luZG93IHRvIGJlIGFsd2F5cyBvbiB0b3AuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGFsd2F5c09uVG9wIC0gV2hldGhlciB0aGUgd2luZG93IHNob3VsZCBzdGF5IG9uIHRvcC5cclxuICAgICAqL1xyXG4gICAgU2V0QWx3YXlzT25Ub3AoYWx3YXlzT25Ub3A6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldEFsd2F5c09uVG9wTWV0aG9kLCB7IGFsd2F5c09uVG9wIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvdXIgb2YgdGhlIHdpbmRvdy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gciAtIFRoZSBkZXNpcmVkIHJlZCBjb21wb25lbnQgb2YgdGhlIHdpbmRvdyBiYWNrZ3JvdW5kLlxyXG4gICAgICogQHBhcmFtIGcgLSBUaGUgZGVzaXJlZCBncmVlbiBjb21wb25lbnQgb2YgdGhlIHdpbmRvdyBiYWNrZ3JvdW5kLlxyXG4gICAgICogQHBhcmFtIGIgLSBUaGUgZGVzaXJlZCBibHVlIGNvbXBvbmVudCBvZiB0aGUgd2luZG93IGJhY2tncm91bmQuXHJcbiAgICAgKiBAcGFyYW0gYSAtIFRoZSBkZXNpcmVkIGFscGhhIGNvbXBvbmVudCBvZiB0aGUgd2luZG93IGJhY2tncm91bmQuXHJcbiAgICAgKi9cclxuICAgIFNldEJhY2tncm91bmRDb2xvdXIocjogbnVtYmVyLCBnOiBudW1iZXIsIGI6IG51bWJlciwgYTogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTZXRCYWNrZ3JvdW5kQ29sb3VyTWV0aG9kLCB7IHIsIGcsIGIsIGEgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIHRoZSB3aW5kb3cgZnJhbWUgYW5kIHRpdGxlIGJhci5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZnJhbWVsZXNzIC0gV2hldGhlciB0aGUgd2luZG93IHNob3VsZCBiZSBmcmFtZWxlc3MuXHJcbiAgICAgKi9cclxuICAgIFNldEZyYW1lbGVzcyhmcmFtZWxlc3M6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldEZyYW1lbGVzc01ldGhvZCwgeyBmcmFtZWxlc3MgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEaXNhYmxlcyB0aGUgc3lzdGVtIGZ1bGxzY3JlZW4gYnV0dG9uLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBlbmFibGVkIC0gV2hldGhlciB0aGUgZnVsbHNjcmVlbiBidXR0b24gc2hvdWxkIGJlIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIFNldEZ1bGxzY3JlZW5CdXR0b25FbmFibGVkKGVuYWJsZWQ6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldEZ1bGxzY3JlZW5CdXR0b25FbmFibGVkTWV0aG9kLCB7IGVuYWJsZWQgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIHdpbmRvdy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gd2lkdGggLSBUaGUgZGVzaXJlZCBtYXhpbXVtIHdpZHRoIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKiBAcGFyYW0gaGVpZ2h0IC0gVGhlIGRlc2lyZWQgbWF4aW11bSBoZWlnaHQgb2YgdGhlIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgU2V0TWF4U2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2V0TWF4U2l6ZU1ldGhvZCwgeyB3aWR0aCwgaGVpZ2h0IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgbWluaW11bSBzaXplIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHdpZHRoIC0gVGhlIGRlc2lyZWQgbWluaW11bSB3aWR0aCBvZiB0aGUgd2luZG93LlxyXG4gICAgICogQHBhcmFtIGhlaWdodCAtIFRoZSBkZXNpcmVkIG1pbmltdW0gaGVpZ2h0IG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIFNldE1pblNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldE1pblNpemVNZXRob2QsIHsgd2lkdGgsIGhlaWdodCB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHJlbGF0aXZlIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cgdG8gdGhlIHNjcmVlbi5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0geCAtIFRoZSBkZXNpcmVkIGhvcml6b250YWwgcmVsYXRpdmUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy5cclxuICAgICAqIEBwYXJhbSB5IC0gVGhlIGRlc2lyZWQgdmVydGljYWwgcmVsYXRpdmUgcG9zaXRpb24gb2YgdGhlIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgU2V0UmVsYXRpdmVQb3NpdGlvbih4OiBudW1iZXIsIHk6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2V0UmVsYXRpdmVQb3NpdGlvbk1ldGhvZCwgeyB4LCB5IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgcmVzaXphYmxlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSByZXNpemFibGUgLSBXaGV0aGVyIHRoZSB3aW5kb3cgc2hvdWxkIGJlIHJlc2l6YWJsZS5cclxuICAgICAqL1xyXG4gICAgU2V0UmVzaXphYmxlKHJlc2l6YWJsZTogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oU2V0UmVzaXphYmxlTWV0aG9kLCB7IHJlc2l6YWJsZSB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHNpemUgb2YgdGhlIHdpbmRvdy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gd2lkdGggLSBUaGUgZGVzaXJlZCB3aWR0aCBvZiB0aGUgd2luZG93LlxyXG4gICAgICogQHBhcmFtIGhlaWdodCAtIFRoZSBkZXNpcmVkIGhlaWdodCBvZiB0aGUgd2luZG93LlxyXG4gICAgICovXHJcbiAgICBTZXRTaXplKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTZXRTaXplTWV0aG9kLCB7IHdpZHRoLCBoZWlnaHQgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSB0aXRsZSBvZiB0aGUgd2luZG93LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB0aXRsZSAtIFRoZSBkZXNpcmVkIHRpdGxlIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIFNldFRpdGxlKHRpdGxlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldFRpdGxlTWV0aG9kLCB7IHRpdGxlIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgem9vbSBsZXZlbCBvZiB0aGUgd2luZG93LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB6b29tIC0gVGhlIGRlc2lyZWQgem9vbSBsZXZlbC5cclxuICAgICAqL1xyXG4gICAgU2V0Wm9vbSh6b29tOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFNldFpvb21NZXRob2QsIHsgem9vbSB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNob3dzIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIFNob3coKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTaG93TWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHNpemUgb2YgdGhlIHdpbmRvdy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgY3VycmVudCBzaXplIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgKi9cclxuICAgIFNpemUoKTogUHJvbWlzZTxTaXplPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXNbY2FsbGVyU3ltXShTaXplTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRvZ2dsZXMgdGhlIHdpbmRvdyBiZXR3ZWVuIGZ1bGxzY3JlZW4gYW5kIG5vcm1hbC5cclxuICAgICAqL1xyXG4gICAgVG9nZ2xlRnVsbHNjcmVlbigpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFRvZ2dsZUZ1bGxzY3JlZW5NZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVG9nZ2xlcyB0aGUgd2luZG93IGJldHdlZW4gbWF4aW1pc2VkIGFuZCBub3JtYWwuXHJcbiAgICAgKi9cclxuICAgIFRvZ2dsZU1heGltaXNlKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oVG9nZ2xlTWF4aW1pc2VNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW4tZnVsbHNjcmVlbnMgdGhlIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgVW5GdWxsc2NyZWVuKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oVW5GdWxsc2NyZWVuTWV0aG9kKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFVuLW1heGltaXNlcyB0aGUgd2luZG93LlxyXG4gICAgICovXHJcbiAgICBVbk1heGltaXNlKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oVW5NYXhpbWlzZU1ldGhvZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBVbi1taW5pbWlzZXMgdGhlIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgVW5NaW5pbWlzZSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFVuTWluaW1pc2VNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgd2lkdGggb2YgdGhlIHdpbmRvdy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgY3VycmVudCB3aWR0aCBvZiB0aGUgd2luZG93LlxyXG4gICAgICovXHJcbiAgICBXaWR0aCgpOiBQcm9taXNlPG51bWJlcj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzW2NhbGxlclN5bV0oV2lkdGhNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogWm9vbXMgdGhlIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgWm9vbSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFpvb21NZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5jcmVhc2VzIHRoZSB6b29tIGxldmVsIG9mIHRoZSB3ZWJ2aWV3IGNvbnRlbnQuXHJcbiAgICAgKi9cclxuICAgIFpvb21JbigpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFpvb21Jbk1ldGhvZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNyZWFzZXMgdGhlIHpvb20gbGV2ZWwgb2YgdGhlIHdlYnZpZXcgY29udGVudC5cclxuICAgICAqL1xyXG4gICAgWm9vbU91dCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFpvb21PdXRNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoZSB6b29tIGxldmVsIG9mIHRoZSB3ZWJ2aWV3IGNvbnRlbnQuXHJcbiAgICAgKi9cclxuICAgIFpvb21SZXNldCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpc1tjYWxsZXJTeW1dKFpvb21SZXNldE1ldGhvZCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGUgd2luZG93IHdpdGhpbiB3aGljaCB0aGUgc2NyaXB0IGlzIHJ1bm5pbmcuXHJcbiAqL1xyXG5jb25zdCB0aGlzV2luZG93ID0gbmV3IFdpbmRvdygnJyk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCB0aGlzV2luZG93O1xyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuaW1wb3J0ICogYXMgUnVudGltZSBmcm9tIFwiLi4vQHdhaWxzaW8vcnVudGltZS9zcmNcIjtcclxuXHJcbi8vIE5PVEU6IHRoZSBmb2xsb3dpbmcgbWV0aG9kcyBNVVNUIGJlIGltcG9ydGVkIGV4cGxpY2l0bHkgYmVjYXVzZSBvZiBob3cgZXNidWlsZCBpbmplY3Rpb24gd29ya3NcclxuaW1wb3J0IHsgRW5hYmxlIGFzIEVuYWJsZVdNTCB9IGZyb20gXCIuLi9Ad2FpbHNpby9ydW50aW1lL3NyYy93bWxcIjtcclxuaW1wb3J0IHsgZGVidWdMb2cgfSBmcm9tIFwiLi4vQHdhaWxzaW8vcnVudGltZS9zcmMvdXRpbHNcIjtcclxuXHJcbndpbmRvdy53YWlscyA9IFJ1bnRpbWU7XHJcbkVuYWJsZVdNTCgpO1xyXG5cclxuaWYgKERFQlVHKSB7XHJcbiAgICBkZWJ1Z0xvZyhcIldhaWxzIFJ1bnRpbWUgTG9hZGVkXCIpXHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbmltcG9ydCB7IG5ld1J1bnRpbWVDYWxsZXIsIG9iamVjdE5hbWVzIH0gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xyXG5cclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuU3lzdGVtKTtcclxuXHJcbmNvbnN0IFN5c3RlbUlzRGFya01vZGUgPSAwO1xyXG5jb25zdCBTeXN0ZW1FbnZpcm9ubWVudCA9IDE7XHJcblxyXG5jb25zdCBfaW52b2tlID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgaWYgKCh3aW5kb3cgYXMgYW55KS5jaHJvbWU/LndlYnZpZXc/LnBvc3RNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAod2luZG93IGFzIGFueSkuY2hyb21lLndlYnZpZXcucG9zdE1lc3NhZ2UuYmluZCgod2luZG93IGFzIGFueSkuY2hyb21lLndlYnZpZXcpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoKHdpbmRvdyBhcyBhbnkpLndlYmtpdD8ubWVzc2FnZUhhbmRsZXJzPy5bJ2V4dGVybmFsJ10/LnBvc3RNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAod2luZG93IGFzIGFueSkud2Via2l0Lm1lc3NhZ2VIYW5kbGVyc1snZXh0ZXJuYWwnXS5wb3N0TWVzc2FnZS5iaW5kKCh3aW5kb3cgYXMgYW55KS53ZWJraXQubWVzc2FnZUhhbmRsZXJzWydleHRlcm5hbCddKTtcclxuICAgICAgICB9XHJcbiAgICB9IGNhdGNoKGUpIHt9XHJcblxyXG4gICAgY29uc29sZS53YXJuKCdcXG4lY1x1MjZBMFx1RkUwRiBCcm93c2VyIEVudmlyb25tZW50IERldGVjdGVkICVjXFxuXFxuJWNPbmx5IFVJIHByZXZpZXdzIGFyZSBhdmFpbGFibGUgaW4gdGhlIGJyb3dzZXIuIEZvciBmdWxsIGZ1bmN0aW9uYWxpdHksIHBsZWFzZSBydW4gdGhlIGFwcGxpY2F0aW9uIGluIGRlc2t0b3AgbW9kZS5cXG5Nb3JlIGluZm9ybWF0aW9uIGF0OiBodHRwczovL3YzLndhaWxzLmlvL2xlYXJuL2J1aWxkLyN1c2luZy1hLWJyb3dzZXItZm9yLWRldmVsb3BtZW50XFxuJyxcclxuICAgICAgICAnYmFja2dyb3VuZDogI2ZmZmZmZjsgY29sb3I6ICMwMDAwMDA7IGZvbnQtd2VpZ2h0OiBib2xkOyBwYWRkaW5nOiA0cHggOHB4OyBib3JkZXItcmFkaXVzOiA0cHg7IGJvcmRlcjogMnB4IHNvbGlkICMwMDAwMDA7JyxcclxuICAgICAgICAnYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7JyxcclxuICAgICAgICAnY29sb3I6ICNmZmZmZmY7IGZvbnQtc3R5bGU6IGl0YWxpYzsgZm9udC13ZWlnaHQ6IGJvbGQ7Jyk7XHJcbiAgICByZXR1cm4gbnVsbDtcclxufSkoKTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbnZva2UobXNnOiBhbnkpOiB2b2lkIHtcclxuICAgIF9pbnZva2U/Lihtc2cpO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0cmlldmVzIHRoZSBzeXN0ZW0gZGFyayBtb2RlIHN0YXR1cy5cclxuICpcclxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIHN5c3RlbSBpcyBpbiBkYXJrIG1vZGUuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSXNEYXJrTW9kZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIHJldHVybiBjYWxsKFN5c3RlbUlzRGFya01vZGUpO1xyXG59XHJcblxyXG4vKipcclxuICogRmV0Y2hlcyB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSBhcHBsaWNhdGlvbiBmcm9tIHRoZSBzZXJ2ZXIuXHJcbiAqXHJcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjYXBhYmlsaXRpZXMuXHJcbiAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gQ2FwYWJpbGl0aWVzKCk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xyXG4gICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXCIvd2FpbHMvY2FwYWJpbGl0aWVzXCIpO1xyXG4gICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY291bGQgbm90IGZldGNoIGNhcGFiaWxpdGllczogXCIgKyByZXNwb25zZS5zdGF0dXNUZXh0KTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBPU0luZm8ge1xyXG4gICAgLyoqIFRoZSBicmFuZGluZyBvZiB0aGUgT1MuICovXHJcbiAgICBCcmFuZGluZzogc3RyaW5nO1xyXG4gICAgLyoqIFRoZSBJRCBvZiB0aGUgT1MuICovXHJcbiAgICBJRDogc3RyaW5nO1xyXG4gICAgLyoqIFRoZSBuYW1lIG9mIHRoZSBPUy4gKi9cclxuICAgIE5hbWU6IHN0cmluZztcclxuICAgIC8qKiBUaGUgdmVyc2lvbiBvZiB0aGUgT1MuICovXHJcbiAgICBWZXJzaW9uOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRW52aXJvbm1lbnRJbmZvIHtcclxuICAgIC8qKiBUaGUgYXJjaGl0ZWN0dXJlIG9mIHRoZSBzeXN0ZW0uICovXHJcbiAgICBBcmNoOiBzdHJpbmc7XHJcbiAgICAvKiogVHJ1ZSBpZiB0aGUgYXBwbGljYXRpb24gaXMgcnVubmluZyBpbiBkZWJ1ZyBtb2RlLCBvdGhlcndpc2UgZmFsc2UuICovXHJcbiAgICBEZWJ1ZzogYm9vbGVhbjtcclxuICAgIC8qKiBUaGUgb3BlcmF0aW5nIHN5c3RlbSBpbiB1c2UuICovXHJcbiAgICBPUzogc3RyaW5nO1xyXG4gICAgLyoqIERldGFpbHMgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uICovXHJcbiAgICBPU0luZm86IE9TSW5mbztcclxuICAgIC8qKiBBZGRpdGlvbmFsIHBsYXRmb3JtIGluZm9ybWF0aW9uLiAqL1xyXG4gICAgUGxhdGZvcm1JbmZvOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xyXG59XHJcblxyXG4vKipcclxuICogUmV0cmlldmVzIGVudmlyb25tZW50IGRldGFpbHMuXHJcbiAqXHJcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIG9iamVjdCBjb250YWluaW5nIE9TIGFuZCBzeXN0ZW0gYXJjaGl0ZWN0dXJlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEVudmlyb25tZW50KCk6IFByb21pc2U8RW52aXJvbm1lbnRJbmZvPiB7XHJcbiAgICByZXR1cm4gY2FsbChTeXN0ZW1FbnZpcm9ubWVudCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgb3BlcmF0aW5nIHN5c3RlbSBpcyBXaW5kb3dzLlxyXG4gKlxyXG4gKiBAcmV0dXJuIFRydWUgaWYgdGhlIG9wZXJhdGluZyBzeXN0ZW0gaXMgV2luZG93cywgb3RoZXJ3aXNlIGZhbHNlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzV2luZG93cygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB3aW5kb3cuX3dhaWxzLmVudmlyb25tZW50Lk9TID09PSBcIndpbmRvd3NcIjtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBvcGVyYXRpbmcgc3lzdGVtIGlzIExpbnV4LlxyXG4gKlxyXG4gKiBAcmV0dXJucyBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgb3BlcmF0aW5nIHN5c3RlbSBpcyBMaW51eCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzTGludXgoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gd2luZG93Ll93YWlscy5lbnZpcm9ubWVudC5PUyA9PT0gXCJsaW51eFwiO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGlzIGEgbWFjT1Mgb3BlcmF0aW5nIHN5c3RlbS5cclxuICpcclxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgbWFjT1MsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBJc01hYygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB3aW5kb3cuX3dhaWxzLmVudmlyb25tZW50Lk9TID09PSBcImRhcndpblwiO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGFyY2hpdGVjdHVyZSBpcyBBTUQ2NC5cclxuICpcclxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBhcmNoaXRlY3R1cmUgaXMgQU1ENjQsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBJc0FNRDY0KCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHdpbmRvdy5fd2FpbHMuZW52aXJvbm1lbnQuQXJjaCA9PT0gXCJhbWQ2NFwiO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IGFyY2hpdGVjdHVyZSBpcyBBUk0uXHJcbiAqXHJcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGN1cnJlbnQgYXJjaGl0ZWN0dXJlIGlzIEFSTSwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzQVJNKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHdpbmRvdy5fd2FpbHMuZW52aXJvbm1lbnQuQXJjaCA9PT0gXCJhcm1cIjtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBpcyBBUk02NCBhcmNoaXRlY3R1cmUuXHJcbiAqXHJcbiAqIEByZXR1cm5zIFJldHVybnMgdHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgQVJNNjQgYXJjaGl0ZWN0dXJlLCBvdGhlcndpc2UgcmV0dXJucyBmYWxzZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBJc0FSTTY0KCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHdpbmRvdy5fd2FpbHMuZW52aXJvbm1lbnQuQXJjaCA9PT0gXCJhcm02NFwiO1xyXG59XHJcblxyXG4vKipcclxuICogUmVwb3J0cyB3aGV0aGVyIHRoZSBhcHAgaXMgYmVpbmcgcnVuIGluIGRlYnVnIG1vZGUuXHJcbiAqXHJcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGFwcCBpcyBiZWluZyBydW4gaW4gZGVidWcgbW9kZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBJc0RlYnVnKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIEJvb2xlYW4od2luZG93Ll93YWlscy5lbnZpcm9ubWVudC5EZWJ1Zyk7XHJcbn1cclxuXHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG5pbXBvcnQgeyBuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lcyB9IGZyb20gXCIuL3J1bnRpbWUuanNcIjtcclxuaW1wb3J0IHsgSXNEZWJ1ZyB9IGZyb20gXCIuL3N5c3RlbS5qc1wiO1xyXG5pbXBvcnQgeyBldmVudFRhcmdldCB9IGZyb20gXCIuL3V0aWxzXCI7XHJcblxyXG4vLyBzZXR1cFxyXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBjb250ZXh0TWVudUhhbmRsZXIpO1xyXG5cclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuQ29udGV4dE1lbnUpO1xyXG5cclxuY29uc3QgQ29udGV4dE1lbnVPcGVuID0gMDtcclxuXHJcbmZ1bmN0aW9uIG9wZW5Db250ZXh0TWVudShpZDogc3RyaW5nLCB4OiBudW1iZXIsIHk6IG51bWJlciwgZGF0YTogYW55KTogdm9pZCB7XHJcbiAgICB2b2lkIGNhbGwoQ29udGV4dE1lbnVPcGVuLCB7aWQsIHgsIHksIGRhdGF9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY29udGV4dE1lbnVIYW5kbGVyKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudFRhcmdldChldmVudCk7XHJcblxyXG4gICAgLy8gQ2hlY2sgZm9yIGN1c3RvbSBjb250ZXh0IG1lbnVcclxuICAgIGNvbnN0IGN1c3RvbUNvbnRleHRNZW51ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1jdXN0b20tY29udGV4dG1lbnVcIikudHJpbSgpO1xyXG5cclxuICAgIGlmIChjdXN0b21Db250ZXh0TWVudSkge1xyXG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgY29uc3QgZGF0YSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRhcmdldCkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY3VzdG9tLWNvbnRleHRtZW51LWRhdGFcIik7XHJcbiAgICAgICAgb3BlbkNvbnRleHRNZW51KGN1c3RvbUNvbnRleHRNZW51LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBkYXRhKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcHJvY2Vzc0RlZmF1bHRDb250ZXh0TWVudShldmVudCwgdGFyZ2V0KTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbi8qXHJcbi0tZGVmYXVsdC1jb250ZXh0bWVudTogYXV0bzsgKGRlZmF1bHQpIHdpbGwgc2hvdyB0aGUgZGVmYXVsdCBjb250ZXh0IG1lbnUgaWYgY29udGVudEVkaXRhYmxlIGlzIHRydWUgT1IgdGV4dCBoYXMgYmVlbiBzZWxlY3RlZCBPUiBlbGVtZW50IGlzIGlucHV0IG9yIHRleHRhcmVhXHJcbi0tZGVmYXVsdC1jb250ZXh0bWVudTogc2hvdzsgd2lsbCBhbHdheXMgc2hvdyB0aGUgZGVmYXVsdCBjb250ZXh0IG1lbnVcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBoaWRlOyB3aWxsIGFsd2F5cyBoaWRlIHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudVxyXG5cclxuVGhpcyBydWxlIGlzIGluaGVyaXRlZCBsaWtlIG5vcm1hbCBDU1MgcnVsZXMsIHNvIG5lc3Rpbmcgd29ya3MgYXMgZXhwZWN0ZWRcclxuKi9cclxuZnVuY3Rpb24gcHJvY2Vzc0RlZmF1bHRDb250ZXh0TWVudShldmVudDogTW91c2VFdmVudCwgdGFyZ2V0OiBIVE1MRWxlbWVudCkge1xyXG4gICAgLy8gRGVidWcgYnVpbGRzIGFsd2F5cyBzaG93IHRoZSBtZW51XHJcbiAgICBpZiAoSXNEZWJ1ZygpKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFByb2Nlc3MgZGVmYXVsdCBjb250ZXh0IG1lbnVcclxuICAgIHN3aXRjaCAod2luZG93LmdldENvbXB1dGVkU3R5bGUodGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1kZWZhdWx0LWNvbnRleHRtZW51XCIpLnRyaW0oKSkge1xyXG4gICAgICAgIGNhc2UgJ3Nob3cnOlxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgY2FzZSAnaGlkZSc6XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZVxyXG4gICAgaWYgKHRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiB0ZXh0IGhhcyBiZWVuIHNlbGVjdGVkXHJcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcbiAgICBjb25zdCBoYXNTZWxlY3Rpb24gPSBzZWxlY3Rpb24gJiYgc2VsZWN0aW9uLnRvU3RyaW5nKCkubGVuZ3RoID4gMDtcclxuICAgIGlmIChoYXNTZWxlY3Rpb24pIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGVjdGlvbi5yYW5nZUNvdW50OyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdChpKTtcclxuICAgICAgICAgICAgY29uc3QgcmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWN0ID0gcmVjdHNbal07XHJcbiAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChyZWN0LmxlZnQsIHJlY3QudG9wKSA9PT0gdGFyZ2V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGlmIHRhZyBpcyBpbnB1dCBvciB0ZXh0YXJlYS5cclxuICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50IHx8IHRhcmdldCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQpIHtcclxuICAgICAgICBpZiAoaGFzU2VsZWN0aW9uIHx8ICghdGFyZ2V0LnJlYWRPbmx5ICYmICF0YXJnZXQuZGlzYWJsZWQpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGlkZSBkZWZhdWx0IGNvbnRleHQgbWVudVxyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoqXHJcbiAqIFJldHJpZXZlcyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGZyb20gdGhlIGZsYWcgbWFwLlxyXG4gKlxyXG4gKiBAcGFyYW0ga2V5IC0gVGhlIGtleSB0byByZXRyaWV2ZSB0aGUgdmFsdWUgZm9yLlxyXG4gKiBAcmV0dXJuIFRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gR2V0RmxhZyhrZXk6IHN0cmluZyk6IGFueSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cuX3dhaWxzLmZsYWdzW2tleV07XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5hYmxlIHRvIHJldHJpZXZlIGZsYWcgJ1wiICsga2V5ICsgXCInOiBcIiArIGUsIHsgY2F1c2U6IGUgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbmltcG9ydCB7IGludm9rZSwgSXNXaW5kb3dzIH0gZnJvbSBcIi4vc3lzdGVtLmpzXCI7XHJcbmltcG9ydCB7IEdldEZsYWcgfSBmcm9tIFwiLi9mbGFncy5qc1wiO1xyXG5pbXBvcnQgeyBjYW5UcmFja0J1dHRvbnMsIGV2ZW50VGFyZ2V0IH0gZnJvbSBcIi4vdXRpbHMuanNcIjtcclxuXHJcbi8vIFNldHVwXHJcbmxldCBjYW5EcmFnID0gZmFsc2U7XHJcbmxldCBkcmFnZ2luZyA9IGZhbHNlO1xyXG5cclxubGV0IHJlc2l6YWJsZSA9IGZhbHNlO1xyXG5sZXQgY2FuUmVzaXplID0gZmFsc2U7XHJcbmxldCByZXNpemluZyA9IGZhbHNlO1xyXG5sZXQgcmVzaXplRWRnZTogc3RyaW5nID0gXCJcIjtcclxubGV0IGRlZmF1bHRDdXJzb3IgPSBcImF1dG9cIjtcclxuXHJcbmxldCBidXR0b25zID0gMDtcclxuY29uc3QgYnV0dG9uc1RyYWNrZWQgPSBjYW5UcmFja0J1dHRvbnMoKTtcclxuXHJcbndpbmRvdy5fd2FpbHMgPSB3aW5kb3cuX3dhaWxzIHx8IHt9O1xyXG53aW5kb3cuX3dhaWxzLnNldFJlc2l6YWJsZSA9ICh2YWx1ZTogYm9vbGVhbik6IHZvaWQgPT4ge1xyXG4gICAgcmVzaXphYmxlID0gdmFsdWU7XHJcbiAgICBpZiAoIXJlc2l6YWJsZSkge1xyXG4gICAgICAgIC8vIFN0b3AgcmVzaXppbmcgaWYgaW4gcHJvZ3Jlc3MuXHJcbiAgICAgICAgY2FuUmVzaXplID0gcmVzaXppbmcgPSBmYWxzZTtcclxuICAgICAgICBzZXRSZXNpemUoKTtcclxuICAgIH1cclxufTtcclxuXHJcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB1cGRhdGUsIHsgY2FwdHVyZTogdHJ1ZSB9KTtcclxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHVwZGF0ZSwgeyBjYXB0dXJlOiB0cnVlIH0pO1xyXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHVwZGF0ZSwgeyBjYXB0dXJlOiB0cnVlIH0pO1xyXG5mb3IgKGNvbnN0IGV2IG9mIFsnY2xpY2snLCAnY29udGV4dG1lbnUnLCAnZGJsY2xpY2snXSkge1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoZXYsIHN1cHByZXNzRXZlbnQsIHsgY2FwdHVyZTogdHJ1ZSB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gc3VwcHJlc3NFdmVudChldmVudDogRXZlbnQpIHtcclxuICAgIC8vIFN1cHByZXNzIGNsaWNrIGV2ZW50cyB3aGlsZSByZXNpemluZyBvciBkcmFnZ2luZy5cclxuICAgIGlmIChkcmFnZ2luZyB8fCByZXNpemluZykge1xyXG4gICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8vIFVzZSBjb25zdGFudHMgdG8gYXZvaWQgY29tcGFyaW5nIHN0cmluZ3MgbXVsdGlwbGUgdGltZXMuXHJcbmNvbnN0IE1vdXNlRG93biA9IDA7XHJcbmNvbnN0IE1vdXNlVXAgICA9IDE7XHJcbmNvbnN0IE1vdXNlTW92ZSA9IDI7XHJcblxyXG5mdW5jdGlvbiB1cGRhdGUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIC8vIFdpbmRvd3Mgc3VwcHJlc3NlcyBtb3VzZSBldmVudHMgYXQgdGhlIGVuZCBvZiBkcmFnZ2luZyBvciByZXNpemluZyxcclxuICAgIC8vIHNvIHdlIG5lZWQgdG8gYmUgc21hcnQgYW5kIHN5bnRoZXNpemUgYnV0dG9uIGV2ZW50cy5cclxuXHJcbiAgICBsZXQgZXZlbnRUeXBlOiBudW1iZXIsIGV2ZW50QnV0dG9ucyA9IGV2ZW50LmJ1dHRvbnM7XHJcbiAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcclxuICAgICAgICBjYXNlICdtb3VzZWRvd24nOlxyXG4gICAgICAgICAgICBldmVudFR5cGUgPSBNb3VzZURvd247XHJcbiAgICAgICAgICAgIGlmICghYnV0dG9uc1RyYWNrZWQpIHsgZXZlbnRCdXR0b25zID0gYnV0dG9ucyB8ICgxIDw8IGV2ZW50LmJ1dHRvbik7IH1cclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSAnbW91c2V1cCc6XHJcbiAgICAgICAgICAgIGV2ZW50VHlwZSA9IE1vdXNlVXA7XHJcbiAgICAgICAgICAgIGlmICghYnV0dG9uc1RyYWNrZWQpIHsgZXZlbnRCdXR0b25zID0gYnV0dG9ucyAmIH4oMSA8PCBldmVudC5idXR0b24pOyB9XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgIGV2ZW50VHlwZSA9IE1vdXNlTW92ZTtcclxuICAgICAgICAgICAgaWYgKCFidXR0b25zVHJhY2tlZCkgeyBldmVudEJ1dHRvbnMgPSBidXR0b25zOyB9XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCByZWxlYXNlZCA9IGJ1dHRvbnMgJiB+ZXZlbnRCdXR0b25zO1xyXG4gICAgbGV0IHByZXNzZWQgPSBldmVudEJ1dHRvbnMgJiB+YnV0dG9ucztcclxuXHJcbiAgICBidXR0b25zID0gZXZlbnRCdXR0b25zO1xyXG5cclxuICAgIC8vIFN5bnRoZXNpemUgYSByZWxlYXNlLXByZXNzIHNlcXVlbmNlIGlmIHdlIGRldGVjdCBhIHByZXNzIG9mIGFuIGFscmVhZHkgcHJlc3NlZCBidXR0b24uXHJcbiAgICBpZiAoZXZlbnRUeXBlID09PSBNb3VzZURvd24gJiYgIShwcmVzc2VkICYgZXZlbnQuYnV0dG9uKSkge1xyXG4gICAgICAgIHJlbGVhc2VkIHw9ICgxIDw8IGV2ZW50LmJ1dHRvbik7XHJcbiAgICAgICAgcHJlc3NlZCB8PSAoMSA8PCBldmVudC5idXR0b24pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFN1cHByZXNzIGFsbCBidXR0b24gZXZlbnRzIGR1cmluZyBkcmFnZ2luZyBhbmQgcmVzaXppbmcsXHJcbiAgICAvLyB1bmxlc3MgdGhpcyBpcyBhIG1vdXNldXAgZXZlbnQgdGhhdCBpcyBlbmRpbmcgYSBkcmFnIGFjdGlvbi5cclxuICAgIGlmIChcclxuICAgICAgICBldmVudFR5cGUgIT09IE1vdXNlTW92ZSAvLyBGYXN0IHBhdGggZm9yIG1vdXNlbW92ZVxyXG4gICAgICAgICYmIHJlc2l6aW5nXHJcbiAgICAgICAgfHwgKFxyXG4gICAgICAgICAgICBkcmFnZ2luZ1xyXG4gICAgICAgICAgICAmJiAoXHJcbiAgICAgICAgICAgICAgICBldmVudFR5cGUgPT09IE1vdXNlRG93blxyXG4gICAgICAgICAgICAgICAgfHwgZXZlbnQuYnV0dG9uICE9PSAwXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICApXHJcbiAgICApIHtcclxuICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEhhbmRsZSByZWxlYXNlc1xyXG4gICAgaWYgKHJlbGVhc2VkICYgMSkgeyBwcmltYXJ5VXAoZXZlbnQpOyB9XHJcbiAgICAvLyBIYW5kbGUgcHJlc3Nlc1xyXG4gICAgaWYgKHByZXNzZWQgJiAxKSB7IHByaW1hcnlEb3duKGV2ZW50KTsgfVxyXG5cclxuICAgIC8vIEhhbmRsZSBtb3VzZW1vdmVcclxuICAgIGlmIChldmVudFR5cGUgPT09IE1vdXNlTW92ZSkgeyBvbk1vdXNlTW92ZShldmVudCk7IH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHByaW1hcnlEb3duKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICAvLyBSZXNldCByZWFkaW5lc3Mgc3RhdGUuXHJcbiAgICBjYW5EcmFnID0gZmFsc2U7XHJcbiAgICBjYW5SZXNpemUgPSBmYWxzZTtcclxuXHJcbiAgICAvLyBJZ25vcmUgcmVwZWF0ZWQgY2xpY2tzIG9uIG1hY09TIGFuZCBMaW51eC5cclxuICAgIGlmICghSXNXaW5kb3dzKCkpIHtcclxuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicgJiYgZXZlbnQuYnV0dG9uID09PSAwICYmIGV2ZW50LmRldGFpbCAhPT0gMSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChyZXNpemVFZGdlKSB7XHJcbiAgICAgICAgLy8gUmVhZHkgdG8gcmVzaXplIGlmIHRoZSBwcmltYXJ5IGJ1dHRvbiB3YXMgcHJlc3NlZCBmb3IgdGhlIGZpcnN0IHRpbWUuXHJcbiAgICAgICAgY2FuUmVzaXplID0gdHJ1ZTtcclxuICAgICAgICAvLyBEbyBub3Qgc3RhcnQgZHJhZyBvcGVyYXRpb25zIHdoZW4gb24gcmVzaXplIGVkZ2VzLlxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZXRyaWV2ZSB0YXJnZXQgZWxlbWVudFxyXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnRUYXJnZXQoZXZlbnQpO1xyXG5cclxuICAgIC8vIFJlYWR5IHRvIGRyYWcgaWYgdGhlIHByaW1hcnkgYnV0dG9uIHdhcyBwcmVzc2VkIGZvciB0aGUgZmlyc3QgdGltZSBvbiBhIGRyYWdnYWJsZSBlbGVtZW50LlxyXG4gICAgLy8gSWdub3JlIGNsaWNrcyBvbiB0aGUgc2Nyb2xsYmFyLlxyXG4gICAgY29uc3Qgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpO1xyXG4gICAgY2FuRHJhZyA9IChcclxuICAgICAgICBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS13YWlscy1kcmFnZ2FibGVcIikudHJpbSgpID09PSBcImRyYWdcIlxyXG4gICAgICAgICYmIChcclxuICAgICAgICAgICAgZXZlbnQub2Zmc2V0WCAtIHBhcnNlRmxvYXQoc3R5bGUucGFkZGluZ0xlZnQpIDwgdGFyZ2V0LmNsaWVudFdpZHRoXHJcbiAgICAgICAgICAgICYmIGV2ZW50Lm9mZnNldFkgLSBwYXJzZUZsb2F0KHN0eWxlLnBhZGRpbmdUb3ApIDwgdGFyZ2V0LmNsaWVudEhlaWdodFxyXG4gICAgICAgIClcclxuICAgICk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHByaW1hcnlVcChldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgLy8gU3RvcCBkcmFnZ2luZyBhbmQgcmVzaXppbmcuXHJcbiAgICBjYW5EcmFnID0gZmFsc2U7XHJcbiAgICBkcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgY2FuUmVzaXplID0gZmFsc2U7XHJcbiAgICByZXNpemluZyA9IGZhbHNlO1xyXG59XHJcblxyXG5jb25zdCBjdXJzb3JGb3JFZGdlID0gT2JqZWN0LmZyZWV6ZSh7XHJcbiAgICBcInNlLXJlc2l6ZVwiOiBcIm53c2UtcmVzaXplXCIsXHJcbiAgICBcInN3LXJlc2l6ZVwiOiBcIm5lc3ctcmVzaXplXCIsXHJcbiAgICBcIm53LXJlc2l6ZVwiOiBcIm53c2UtcmVzaXplXCIsXHJcbiAgICBcIm5lLXJlc2l6ZVwiOiBcIm5lc3ctcmVzaXplXCIsXHJcbiAgICBcInctcmVzaXplXCI6IFwiZXctcmVzaXplXCIsXHJcbiAgICBcIm4tcmVzaXplXCI6IFwibnMtcmVzaXplXCIsXHJcbiAgICBcInMtcmVzaXplXCI6IFwibnMtcmVzaXplXCIsXHJcbiAgICBcImUtcmVzaXplXCI6IFwiZXctcmVzaXplXCIsXHJcbn0pXHJcblxyXG5mdW5jdGlvbiBzZXRSZXNpemUoZWRnZT86IGtleW9mIHR5cGVvZiBjdXJzb3JGb3JFZGdlKTogdm9pZCB7XHJcbiAgICBpZiAoZWRnZSkge1xyXG4gICAgICAgIGlmICghcmVzaXplRWRnZSkgeyBkZWZhdWx0Q3Vyc29yID0gZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3I7IH1cclxuICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9IGN1cnNvckZvckVkZ2VbZWRnZV07XHJcbiAgICB9IGVsc2UgaWYgKCFlZGdlICYmIHJlc2l6ZUVkZ2UpIHtcclxuICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9IGRlZmF1bHRDdXJzb3I7XHJcbiAgICB9XHJcblxyXG4gICAgcmVzaXplRWRnZSA9IGVkZ2UgfHwgXCJcIjtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VzZU1vdmUoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcclxuICAgIGlmIChjYW5SZXNpemUgJiYgcmVzaXplRWRnZSkge1xyXG4gICAgICAgIC8vIFN0YXJ0IHJlc2l6aW5nLlxyXG4gICAgICAgIHJlc2l6aW5nID0gdHJ1ZTtcclxuICAgICAgICBpbnZva2UoXCJ3YWlsczpyZXNpemU6XCIgKyByZXNpemVFZGdlKTtcclxuICAgIH0gZWxzZSBpZiAoY2FuRHJhZykge1xyXG4gICAgICAgIC8vIFN0YXJ0IGRyYWdnaW5nLlxyXG4gICAgICAgIGRyYWdnaW5nID0gdHJ1ZTtcclxuICAgICAgICBpbnZva2UoXCJ3YWlsczpkcmFnXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkcmFnZ2luZyB8fCByZXNpemluZykge1xyXG4gICAgICAgIC8vIEVpdGhlciBkcmFnIG9yIHJlc2l6ZSBpcyBvbmdvaW5nLFxyXG4gICAgICAgIC8vIHJlc2V0IHJlYWRpbmVzcyBhbmQgc3RvcCBwcm9jZXNzaW5nLlxyXG4gICAgICAgIGNhbkRyYWcgPSBjYW5SZXNpemUgPSBmYWxzZTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFyZXNpemFibGUgfHwgIUlzV2luZG93cygpKSB7XHJcbiAgICAgICAgaWYgKHJlc2l6ZUVkZ2UpIHsgc2V0UmVzaXplKCk7IH1cclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcmVzaXplSGFuZGxlSGVpZ2h0ID0gR2V0RmxhZyhcInN5c3RlbS5yZXNpemVIYW5kbGVIZWlnaHRcIikgfHwgNTtcclxuICAgIGNvbnN0IHJlc2l6ZUhhbmRsZVdpZHRoID0gR2V0RmxhZyhcInN5c3RlbS5yZXNpemVIYW5kbGVXaWR0aFwiKSB8fCA1O1xyXG5cclxuICAgIC8vIEV4dHJhIHBpeGVscyBmb3IgdGhlIGNvcm5lciBhcmVhcy5cclxuICAgIGNvbnN0IGNvcm5lckV4dHJhID0gR2V0RmxhZyhcInJlc2l6ZUNvcm5lckV4dHJhXCIpIHx8IDEwO1xyXG5cclxuICAgIGNvbnN0IHJpZ2h0Qm9yZGVyID0gKHdpbmRvdy5vdXRlcldpZHRoIC0gZXZlbnQuY2xpZW50WCkgPCByZXNpemVIYW5kbGVXaWR0aDtcclxuICAgIGNvbnN0IGxlZnRCb3JkZXIgPSBldmVudC5jbGllbnRYIDwgcmVzaXplSGFuZGxlV2lkdGg7XHJcbiAgICBjb25zdCB0b3BCb3JkZXIgPSBldmVudC5jbGllbnRZIDwgcmVzaXplSGFuZGxlSGVpZ2h0O1xyXG4gICAgY29uc3QgYm90dG9tQm9yZGVyID0gKHdpbmRvdy5vdXRlckhlaWdodCAtIGV2ZW50LmNsaWVudFkpIDwgcmVzaXplSGFuZGxlSGVpZ2h0O1xyXG5cclxuICAgIC8vIEFkanVzdCBmb3IgY29ybmVyIGFyZWFzLlxyXG4gICAgY29uc3QgcmlnaHRDb3JuZXIgPSAod2luZG93Lm91dGVyV2lkdGggLSBldmVudC5jbGllbnRYKSA8IChyZXNpemVIYW5kbGVXaWR0aCArIGNvcm5lckV4dHJhKTtcclxuICAgIGNvbnN0IGxlZnRDb3JuZXIgPSBldmVudC5jbGllbnRYIDwgKHJlc2l6ZUhhbmRsZVdpZHRoICsgY29ybmVyRXh0cmEpO1xyXG4gICAgY29uc3QgdG9wQ29ybmVyID0gZXZlbnQuY2xpZW50WSA8IChyZXNpemVIYW5kbGVIZWlnaHQgKyBjb3JuZXJFeHRyYSk7XHJcbiAgICBjb25zdCBib3R0b21Db3JuZXIgPSAod2luZG93Lm91dGVySGVpZ2h0IC0gZXZlbnQuY2xpZW50WSkgPCAocmVzaXplSGFuZGxlSGVpZ2h0ICsgY29ybmVyRXh0cmEpO1xyXG5cclxuICAgIGlmICghbGVmdENvcm5lciAmJiAhdG9wQ29ybmVyICYmICFib3R0b21Db3JuZXIgJiYgIXJpZ2h0Q29ybmVyKSB7XHJcbiAgICAgICAgLy8gT3B0aW1pc2F0aW9uOiBvdXQgb2YgYWxsIGNvcm5lciBhcmVhcyBpbXBsaWVzIG91dCBvZiBib3JkZXJzLlxyXG4gICAgICAgIHNldFJlc2l6ZSgpO1xyXG4gICAgfVxyXG4gICAgLy8gRGV0ZWN0IGNvcm5lcnMuXHJcbiAgICBlbHNlIGlmIChyaWdodENvcm5lciAmJiBib3R0b21Db3JuZXIpIHNldFJlc2l6ZShcInNlLXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKGxlZnRDb3JuZXIgJiYgYm90dG9tQ29ybmVyKSBzZXRSZXNpemUoXCJzdy1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Q29ybmVyICYmIHRvcENvcm5lcikgc2V0UmVzaXplKFwibnctcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAodG9wQ29ybmVyICYmIHJpZ2h0Q29ybmVyKSBzZXRSZXNpemUoXCJuZS1yZXNpemVcIik7XHJcbiAgICAvLyBEZXRlY3QgYm9yZGVycy5cclxuICAgIGVsc2UgaWYgKGxlZnRCb3JkZXIpIHNldFJlc2l6ZShcInctcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAodG9wQm9yZGVyKSBzZXRSZXNpemUoXCJuLXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKGJvdHRvbUJvcmRlcikgc2V0UmVzaXplKFwicy1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChyaWdodEJvcmRlcikgc2V0UmVzaXplKFwiZS1yZXNpemVcIik7XHJcbiAgICAvLyBPdXQgb2YgYm9yZGVyIGFyZWEuXHJcbiAgICBlbHNlIHNldFJlc2l6ZSgpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG5pbXBvcnQgeyBuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lcyB9IGZyb20gXCIuL3J1bnRpbWUuanNcIjtcclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuQXBwbGljYXRpb24pO1xyXG5cclxuY29uc3QgSGlkZU1ldGhvZCA9IDA7XHJcbmNvbnN0IFNob3dNZXRob2QgPSAxO1xyXG5jb25zdCBRdWl0TWV0aG9kID0gMjtcclxuXHJcbi8qKlxyXG4gKiBIaWRlcyBhIGNlcnRhaW4gbWV0aG9kIGJ5IGNhbGxpbmcgdGhlIEhpZGVNZXRob2QgZnVuY3Rpb24uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSGlkZSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHJldHVybiBjYWxsKEhpZGVNZXRob2QpO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsbHMgdGhlIFNob3dNZXRob2QgYW5kIHJldHVybnMgdGhlIHJlc3VsdC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBTaG93KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgcmV0dXJuIGNhbGwoU2hvd01ldGhvZCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDYWxscyB0aGUgUXVpdE1ldGhvZCB0byB0ZXJtaW5hdGUgdGhlIHByb2dyYW0uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUXVpdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHJldHVybiBjYWxsKFF1aXRNZXRob2QpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG5pbXBvcnQgeyBDYW5jZWxsYWJsZVByb21pc2UsIHR5cGUgQ2FuY2VsbGFibGVQcm9taXNlV2l0aFJlc29sdmVycyB9IGZyb20gXCIuL2NhbmNlbGxhYmxlLmpzXCI7XHJcbmltcG9ydCB7IG5ld1J1bnRpbWVDYWxsZXIsIG9iamVjdE5hbWVzIH0gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xyXG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tIFwiLi9uYW5vaWQuanNcIjtcclxuXHJcbi8vIFNldHVwXHJcbndpbmRvdy5fd2FpbHMgPSB3aW5kb3cuX3dhaWxzIHx8IHt9O1xyXG53aW5kb3cuX3dhaWxzLmNhbGxSZXN1bHRIYW5kbGVyID0gcmVzdWx0SGFuZGxlcjtcclxud2luZG93Ll93YWlscy5jYWxsRXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xyXG5cclxudHlwZSBQcm9taXNlUmVzb2x2ZXJzID0gT21pdDxDYW5jZWxsYWJsZVByb21pc2VXaXRoUmVzb2x2ZXJzPGFueT4sIFwicHJvbWlzZVwiIHwgXCJvbmNhbmNlbGxlZFwiPlxyXG5cclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuQ2FsbCk7XHJcbmNvbnN0IGNhbmNlbENhbGwgPSBuZXdSdW50aW1lQ2FsbGVyKG9iamVjdE5hbWVzLkNhbmNlbENhbGwpO1xyXG5jb25zdCBjYWxsUmVzcG9uc2VzID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2VSZXNvbHZlcnM+KCk7XHJcblxyXG5jb25zdCBDYWxsQmluZGluZyA9IDA7XHJcbmNvbnN0IENhbmNlbE1ldGhvZCA9IDBcclxuXHJcbi8qKlxyXG4gKiBIb2xkcyBhbGwgcmVxdWlyZWQgaW5mb3JtYXRpb24gZm9yIGEgYmluZGluZyBjYWxsLlxyXG4gKiBNYXkgcHJvdmlkZSBlaXRoZXIgYSBtZXRob2QgSUQgb3IgYSBtZXRob2QgbmFtZSwgYnV0IG5vdCBib3RoLlxyXG4gKi9cclxuZXhwb3J0IHR5cGUgQ2FsbE9wdGlvbnMgPSB7XHJcbiAgICAvKiogVGhlIG51bWVyaWMgSUQgb2YgdGhlIGJvdW5kIG1ldGhvZCB0byBjYWxsLiAqL1xyXG4gICAgbWV0aG9kSUQ6IG51bWJlcjtcclxuICAgIC8qKiBUaGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGJvdW5kIG1ldGhvZCB0byBjYWxsLiAqL1xyXG4gICAgbWV0aG9kTmFtZT86IG5ldmVyO1xyXG4gICAgLyoqIEFyZ3VtZW50cyB0byBiZSBwYXNzZWQgaW50byB0aGUgYm91bmQgbWV0aG9kLiAqL1xyXG4gICAgYXJnczogYW55W107XHJcbn0gfCB7XHJcbiAgICAvKiogVGhlIG51bWVyaWMgSUQgb2YgdGhlIGJvdW5kIG1ldGhvZCB0byBjYWxsLiAqL1xyXG4gICAgbWV0aG9kSUQ/OiBuZXZlcjtcclxuICAgIC8qKiBUaGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGJvdW5kIG1ldGhvZCB0byBjYWxsLiAqL1xyXG4gICAgbWV0aG9kTmFtZTogc3RyaW5nO1xyXG4gICAgLyoqIEFyZ3VtZW50cyB0byBiZSBwYXNzZWQgaW50byB0aGUgYm91bmQgbWV0aG9kLiAqL1xyXG4gICAgYXJnczogYW55W107XHJcbn07XHJcblxyXG4vKipcclxuICogRXhjZXB0aW9uIGNsYXNzIHRoYXQgd2lsbCBiZSB0aHJvd24gaW4gY2FzZSB0aGUgYm91bmQgbWV0aG9kIHJldHVybnMgYW4gZXJyb3IuXHJcbiAqIFRoZSB2YWx1ZSBvZiB0aGUge0BsaW5rIFJ1bnRpbWVFcnJvciNuYW1lfSBwcm9wZXJ0eSBpcyBcIlJ1bnRpbWVFcnJvclwiLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFJ1bnRpbWVFcnJvciBleHRlbmRzIEVycm9yIHtcclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBSdW50aW1lRXJyb3IgaW5zdGFuY2UuXHJcbiAgICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBlcnJvciBtZXNzYWdlLlxyXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25zIHRvIGJlIGZvcndhcmRlZCB0byB0aGUgRXJyb3IgY29uc3RydWN0b3IuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U/OiBzdHJpbmcsIG9wdGlvbnM/OiBFcnJvck9wdGlvbnMpIHtcclxuICAgICAgICBzdXBlcihtZXNzYWdlLCBvcHRpb25zKTtcclxuICAgICAgICB0aGlzLm5hbWUgPSBcIlJ1bnRpbWVFcnJvclwiO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogSGFuZGxlcyB0aGUgcmVzdWx0IG9mIGEgY2FsbCByZXF1ZXN0LlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgLSBUaGUgaWQgb2YgdGhlIHJlcXVlc3QgdG8gaGFuZGxlIHRoZSByZXN1bHQgZm9yLlxyXG4gKiBAcGFyYW0gZGF0YSAtIFRoZSByZXN1bHQgZGF0YSBvZiB0aGUgcmVxdWVzdC5cclxuICogQHBhcmFtIGlzSlNPTiAtIEluZGljYXRlcyB3aGV0aGVyIHRoZSBkYXRhIGlzIEpTT04gb3Igbm90LlxyXG4gKi9cclxuZnVuY3Rpb24gcmVzdWx0SGFuZGxlcihpZDogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGlzSlNPTjogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgY29uc3QgcmVzb2x2ZXJzID0gZ2V0QW5kRGVsZXRlUmVzcG9uc2UoaWQpO1xyXG4gICAgaWYgKCFyZXNvbHZlcnMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFkYXRhKSB7XHJcbiAgICAgICAgcmVzb2x2ZXJzLnJlc29sdmUodW5kZWZpbmVkKTtcclxuICAgIH0gZWxzZSBpZiAoIWlzSlNPTikge1xyXG4gICAgICAgIHJlc29sdmVycy5yZXNvbHZlKGRhdGEpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICByZXNvbHZlcnMucmVzb2x2ZShKU09OLnBhcnNlKGRhdGEpKTtcclxuICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xyXG4gICAgICAgICAgICByZXNvbHZlcnMucmVqZWN0KG5ldyBUeXBlRXJyb3IoXCJjb3VsZCBub3QgcGFyc2UgcmVzdWx0OiBcIiArIGVyci5tZXNzYWdlLCB7IGNhdXNlOiBlcnIgfSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEhhbmRsZXMgdGhlIGVycm9yIGZyb20gYSBjYWxsIHJlcXVlc3QuXHJcbiAqXHJcbiAqIEBwYXJhbSBpZCAtIFRoZSBpZCBvZiB0aGUgcHJvbWlzZSBoYW5kbGVyLlxyXG4gKiBAcGFyYW0gZGF0YSAtIFRoZSBlcnJvciBkYXRhIHRvIHJlamVjdCB0aGUgcHJvbWlzZSBoYW5kbGVyIHdpdGguXHJcbiAqIEBwYXJhbSBpc0pTT04gLSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZGF0YSBpcyBKU09OIG9yIG5vdC5cclxuICovXHJcbmZ1bmN0aW9uIGVycm9ySGFuZGxlcihpZDogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIGlzSlNPTjogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgY29uc3QgcmVzb2x2ZXJzID0gZ2V0QW5kRGVsZXRlUmVzcG9uc2UoaWQpO1xyXG4gICAgaWYgKCFyZXNvbHZlcnMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFpc0pTT04pIHtcclxuICAgICAgICByZXNvbHZlcnMucmVqZWN0KG5ldyBFcnJvcihkYXRhKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBlcnJvcjogYW55O1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGVycm9yID0gSlNPTi5wYXJzZShkYXRhKTtcclxuICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xyXG4gICAgICAgICAgICByZXNvbHZlcnMucmVqZWN0KG5ldyBUeXBlRXJyb3IoXCJjb3VsZCBub3QgcGFyc2UgZXJyb3I6IFwiICsgZXJyLm1lc3NhZ2UsIHsgY2F1c2U6IGVyciB9KSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBvcHRpb25zOiBFcnJvck9wdGlvbnMgPSB7fTtcclxuICAgICAgICBpZiAoZXJyb3IuY2F1c2UpIHtcclxuICAgICAgICAgICAgb3B0aW9ucy5jYXVzZSA9IGVycm9yLmNhdXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGV4Y2VwdGlvbjtcclxuICAgICAgICBzd2l0Y2ggKGVycm9yLmtpbmQpIHtcclxuICAgICAgICAgICAgY2FzZSBcIlJlZmVyZW5jZUVycm9yXCI6XHJcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBuZXcgUmVmZXJlbmNlRXJyb3IoZXJyb3IubWVzc2FnZSwgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBcIlR5cGVFcnJvclwiOlxyXG4gICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gbmV3IFR5cGVFcnJvcihlcnJvci5tZXNzYWdlLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIFwiUnVudGltZUVycm9yXCI6XHJcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBuZXcgUnVudGltZUVycm9yKGVycm9yLm1lc3NhZ2UsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBuZXcgRXJyb3IoZXJyb3IubWVzc2FnZSwgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJlc29sdmVycy5yZWplY3QoZXhjZXB0aW9uKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgcmVzcG9uc2UgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBJRCBmcm9tIHRoZSBjYWxsUmVzcG9uc2VzIG1hcC5cclxuICpcclxuICogQHBhcmFtIGlkIC0gVGhlIElEIG9mIHRoZSByZXNwb25zZSB0byBiZSByZXRyaWV2ZWQgYW5kIHJlbW92ZWQuXHJcbiAqIEByZXR1cm5zIFRoZSByZXNwb25zZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBJRCwgaWYgYW55LlxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0QW5kRGVsZXRlUmVzcG9uc2UoaWQ6IHN0cmluZyk6IFByb21pc2VSZXNvbHZlcnMgfCB1bmRlZmluZWQge1xyXG4gICAgY29uc3QgcmVzcG9uc2UgPSBjYWxsUmVzcG9uc2VzLmdldChpZCk7XHJcbiAgICBjYWxsUmVzcG9uc2VzLmRlbGV0ZShpZCk7XHJcbiAgICByZXR1cm4gcmVzcG9uc2U7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSB1bmlxdWUgSUQgdXNpbmcgdGhlIG5hbm9pZCBsaWJyYXJ5LlxyXG4gKlxyXG4gKiBAcmV0dXJucyBBIHVuaXF1ZSBJRCB0aGF0IGRvZXMgbm90IGV4aXN0IGluIHRoZSBjYWxsUmVzcG9uc2VzIHNldC5cclxuICovXHJcbmZ1bmN0aW9uIGdlbmVyYXRlSUQoKTogc3RyaW5nIHtcclxuICAgIGxldCByZXN1bHQ7XHJcbiAgICBkbyB7XHJcbiAgICAgICAgcmVzdWx0ID0gbmFub2lkKCk7XHJcbiAgICB9IHdoaWxlIChjYWxsUmVzcG9uc2VzLmhhcyhyZXN1bHQpKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDYWxsIGEgYm91bmQgbWV0aG9kIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gY2FsbCBvcHRpb25zLlxyXG4gKlxyXG4gKiBJbiBjYXNlIG9mIGZhaWx1cmUsIHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgcmVqZWN0IHdpdGggYW4gZXhjZXB0aW9uXHJcbiAqIGFtb25nIFJlZmVyZW5jZUVycm9yICh1bmtub3duIG1ldGhvZCksIFR5cGVFcnJvciAod3JvbmcgYXJndW1lbnQgY291bnQgb3IgdHlwZSksXHJcbiAqIHtAbGluayBSdW50aW1lRXJyb3J9IChtZXRob2QgcmV0dXJuZWQgYW4gZXJyb3IpLCBvciBvdGhlciAobmV0d29yayBvciBpbnRlcm5hbCBlcnJvcnMpLlxyXG4gKiBUaGUgZXhjZXB0aW9uIG1pZ2h0IGhhdmUgYSBcImNhdXNlXCIgZmllbGQgd2l0aCB0aGUgdmFsdWUgcmV0dXJuZWRcclxuICogYnkgdGhlIGFwcGxpY2F0aW9uLSBvciBzZXJ2aWNlLWxldmVsIGVycm9yIG1hcnNoYWxpbmcgZnVuY3Rpb25zLlxyXG4gKlxyXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEEgbWV0aG9kIGNhbGwgZGVzY3JpcHRvci5cclxuICogQHJldHVybnMgVGhlIHJlc3VsdCBvZiB0aGUgY2FsbC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBDYWxsKG9wdGlvbnM6IENhbGxPcHRpb25zKTogQ2FuY2VsbGFibGVQcm9taXNlPGFueT4ge1xyXG4gICAgY29uc3QgaWQgPSBnZW5lcmF0ZUlEKCk7XHJcblxyXG4gICAgY29uc3QgcmVzdWx0ID0gQ2FuY2VsbGFibGVQcm9taXNlLndpdGhSZXNvbHZlcnM8YW55PigpO1xyXG4gICAgY2FsbFJlc3BvbnNlcy5zZXQoaWQsIHsgcmVzb2x2ZTogcmVzdWx0LnJlc29sdmUsIHJlamVjdDogcmVzdWx0LnJlamVjdCB9KTtcclxuXHJcbiAgICBjb25zdCByZXF1ZXN0ID0gY2FsbChDYWxsQmluZGluZywgT2JqZWN0LmFzc2lnbih7IFwiY2FsbC1pZFwiOiBpZCB9LCBvcHRpb25zKSk7XHJcbiAgICBsZXQgcnVubmluZyA9IGZhbHNlO1xyXG5cclxuICAgIHJlcXVlc3QudGhlbigoKSA9PiB7XHJcbiAgICAgICAgcnVubmluZyA9IHRydWU7XHJcbiAgICB9LCAoZXJyKSA9PiB7XHJcbiAgICAgICAgY2FsbFJlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgICAgIHJlc3VsdC5yZWplY3QoZXJyKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IGNhbmNlbCA9ICgpID0+IHtcclxuICAgICAgICBjYWxsUmVzcG9uc2VzLmRlbGV0ZShpZCk7XHJcbiAgICAgICAgcmV0dXJuIGNhbmNlbENhbGwoQ2FuY2VsTWV0aG9kLCB7XCJjYWxsLWlkXCI6IGlkfSkuY2F0Y2goKGVycikgPT4ge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igd2hpbGUgcmVxdWVzdGluZyBiaW5kaW5nIGNhbGwgY2FuY2VsbGF0aW9uOlwiLCBlcnIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXN1bHQub25jYW5jZWxsZWQgPSAoKSA9PiB7XHJcbiAgICAgICAgaWYgKHJ1bm5pbmcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNhbmNlbCgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiByZXF1ZXN0LnRoZW4oY2FuY2VsKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiByZXN1bHQucHJvbWlzZTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENhbGxzIGEgYm91bmQgbWV0aG9kIGJ5IG5hbWUgd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cy5cclxuICogU2VlIHtAbGluayBDYWxsfSBmb3IgZGV0YWlscy5cclxuICpcclxuICogQHBhcmFtIG1ldGhvZE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgbWV0aG9kIGluIHRoZSBmb3JtYXQgJ3BhY2thZ2Uuc3RydWN0Lm1ldGhvZCcuXHJcbiAqIEBwYXJhbSBhcmdzIC0gVGhlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2QuXHJcbiAqIEByZXR1cm5zIFRoZSByZXN1bHQgb2YgdGhlIG1ldGhvZCBjYWxsLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEJ5TmFtZShtZXRob2ROYW1lOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogQ2FuY2VsbGFibGVQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIENhbGwoeyBtZXRob2ROYW1lLCBhcmdzIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsbHMgYSBtZXRob2QgYnkgaXRzIG51bWVyaWMgSUQgd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cy5cclxuICogU2VlIHtAbGluayBDYWxsfSBmb3IgZGV0YWlscy5cclxuICpcclxuICogQHBhcmFtIG1ldGhvZElEIC0gVGhlIElEIG9mIHRoZSBtZXRob2QgdG8gY2FsbC5cclxuICogQHBhcmFtIGFyZ3MgLSBUaGUgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZC5cclxuICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBtZXRob2QgY2FsbC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBCeUlEKG1ldGhvZElEOiBudW1iZXIsIC4uLmFyZ3M6IGFueVtdKTogQ2FuY2VsbGFibGVQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIENhbGwoeyBtZXRob2RJRCwgYXJncyB9KTtcclxufVxyXG4iLCAiLy8gU291cmNlOiBodHRwczovL2dpdGh1Yi5jb20vaW5zcGVjdC1qcy9pcy1jYWxsYWJsZVxyXG5cclxuLy8gVGhlIE1JVCBMaWNlbnNlIChNSVQpXHJcbi8vXHJcbi8vIENvcHlyaWdodCAoYykgMjAxNSBKb3JkYW4gSGFyYmFuZFxyXG4vL1xyXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XHJcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcclxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xyXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXHJcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xyXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxyXG4vL1xyXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcclxuLy8gY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cclxuLy9cclxuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxyXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcclxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXHJcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcclxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcclxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcclxuLy8gU09GVFdBUkUuXHJcblxyXG52YXIgZm5Ub1N0ciA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZztcclxudmFyIHJlZmxlY3RBcHBseTogdHlwZW9mIFJlZmxlY3QuYXBwbHkgfCBmYWxzZSB8IG51bGwgPSB0eXBlb2YgUmVmbGVjdCA9PT0gJ29iamVjdCcgJiYgUmVmbGVjdCAhPT0gbnVsbCAmJiBSZWZsZWN0LmFwcGx5O1xyXG52YXIgYmFkQXJyYXlMaWtlOiBhbnk7XHJcbnZhciBpc0NhbGxhYmxlTWFya2VyOiBhbnk7XHJcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgYmFkQXJyYXlMaWtlID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnbGVuZ3RoJywge1xyXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IGlzQ2FsbGFibGVNYXJrZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBpc0NhbGxhYmxlTWFya2VyID0ge307XHJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcclxuICAgICAgICByZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcclxuICAgIH0gY2F0Y2ggKF8pIHtcclxuICAgICAgICBpZiAoXyAhPT0gaXNDYWxsYWJsZU1hcmtlcikge1xyXG4gICAgICAgICAgICByZWZsZWN0QXBwbHkgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSBlbHNlIHtcclxuICAgIHJlZmxlY3RBcHBseSA9IG51bGw7XHJcbn1cclxuXHJcbnZhciBjb25zdHJ1Y3RvclJlZ2V4ID0gL15cXHMqY2xhc3NcXGIvO1xyXG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcclxuICAgICAgICByZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdCBhIGZ1bmN0aW9uXHJcbiAgICB9XHJcbn07XHJcblxyXG52YXIgdHJ5RnVuY3Rpb25PYmplY3QgPSBmdW5jdGlvbiB0cnlGdW5jdGlvblRvU3RyKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgaWYgKGlzRVM2Q2xhc3NGbih2YWx1ZSkpIHsgcmV0dXJuIGZhbHNlOyB9XHJcbiAgICAgICAgZm5Ub1N0ci5jYWxsKHZhbHVlKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbn07XHJcbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XHJcbnZhciBvYmplY3RDbGFzcyA9ICdbb2JqZWN0IE9iamVjdF0nO1xyXG52YXIgZm5DbGFzcyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XHJcbnZhciBnZW5DbGFzcyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXSc7XHJcbnZhciBkZGFDbGFzcyA9ICdbb2JqZWN0IEhUTUxBbGxDb2xsZWN0aW9uXSc7IC8vIElFIDExXHJcbnZhciBkZGFDbGFzczIgPSAnW29iamVjdCBIVE1MIGRvY3VtZW50LmFsbCBjbGFzc10nO1xyXG52YXIgZGRhQ2xhc3MzID0gJ1tvYmplY3QgSFRNTENvbGxlY3Rpb25dJzsgLy8gSUUgOS0xMFxyXG52YXIgaGFzVG9TdHJpbmdUYWcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnOyAvLyBiZXR0ZXI6IHVzZSBgaGFzLXRvc3RyaW5ndGFnYFxyXG5cclxudmFyIGlzSUU2OCA9ICEoMCBpbiBbLF0pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNwYXJzZS1hcnJheXMsIGNvbW1hLXNwYWNpbmdcclxuXHJcbnZhciBpc0REQTogKHZhbHVlOiBhbnkpID0+IGJvb2xlYW4gPSBmdW5jdGlvbiBpc0RvY3VtZW50RG90QWxsKCkgeyByZXR1cm4gZmFsc2U7IH07XHJcbmlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICdvYmplY3QnKSB7XHJcbiAgICAvLyBGaXJlZm94IDMgY2Fub25pY2FsaXplcyBEREEgdG8gdW5kZWZpbmVkIHdoZW4gaXQncyBub3QgYWNjZXNzZWQgZGlyZWN0bHlcclxuICAgIHZhciBhbGwgPSBkb2N1bWVudC5hbGw7XHJcbiAgICBpZiAodG9TdHIuY2FsbChhbGwpID09PSB0b1N0ci5jYWxsKGRvY3VtZW50LmFsbCkpIHtcclxuICAgICAgICBpc0REQSA9IGZ1bmN0aW9uIGlzRG9jdW1lbnREb3RBbGwodmFsdWUpIHtcclxuICAgICAgICAgICAgLyogZ2xvYmFscyBkb2N1bWVudDogZmFsc2UgKi9cclxuICAgICAgICAgICAgLy8gaW4gSUUgNi04LCB0eXBlb2YgZG9jdW1lbnQuYWxsIGlzIFwib2JqZWN0XCIgYW5kIGl0J3MgdHJ1dGh5XHJcbiAgICAgICAgICAgIGlmICgoaXNJRTY4IHx8ICF2YWx1ZSkgJiYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciA9PT0gZGRhQ2xhc3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3RyID09PSBkZGFDbGFzczJcclxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3RyID09PSBkZGFDbGFzczMgLy8gb3BlcmEgMTIuMTZcclxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3RyID09PSBvYmplY3RDbGFzcyAvLyBJRSA2LThcclxuICAgICAgICAgICAgICAgICAgICApICYmIHZhbHVlKCcnKSA9PSBudWxsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyAvKiovIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gaXNDYWxsYWJsZVJlZkFwcGx5PFQ+KHZhbHVlOiBUIHwgdW5rbm93bik6IHZhbHVlIGlzICguLi5hcmdzOiBhbnlbXSkgPT4gYW55ICB7XHJcbiAgICBpZiAoaXNEREEodmFsdWUpKSB7IHJldHVybiB0cnVlOyB9XHJcbiAgICBpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgICAocmVmbGVjdEFwcGx5IGFzIGFueSkodmFsdWUsIG51bGwsIGJhZEFycmF5TGlrZSk7XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgaWYgKGUgIT09IGlzQ2FsbGFibGVNYXJrZXIpIHsgcmV0dXJuIGZhbHNlOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gIWlzRVM2Q2xhc3NGbih2YWx1ZSkgJiYgdHJ5RnVuY3Rpb25PYmplY3QodmFsdWUpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0NhbGxhYmxlTm9SZWZBcHBseTxUPih2YWx1ZTogVCB8IHVua25vd24pOiB2YWx1ZSBpcyAoLi4uYXJnczogYW55W10pID0+IGFueSB7XHJcbiAgICBpZiAoaXNEREEodmFsdWUpKSB7IHJldHVybiB0cnVlOyB9XHJcbiAgICBpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgaWYgKGhhc1RvU3RyaW5nVGFnKSB7IHJldHVybiB0cnlGdW5jdGlvbk9iamVjdCh2YWx1ZSk7IH1cclxuICAgIGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgdmFyIHN0ckNsYXNzID0gdG9TdHIuY2FsbCh2YWx1ZSk7XHJcbiAgICBpZiAoc3RyQ2xhc3MgIT09IGZuQ2xhc3MgJiYgc3RyQ2xhc3MgIT09IGdlbkNsYXNzICYmICEoL15cXFtvYmplY3QgSFRNTC8pLnRlc3Qoc3RyQ2xhc3MpKSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHJlZmxlY3RBcHBseSA/IGlzQ2FsbGFibGVSZWZBcHBseSA6IGlzQ2FsbGFibGVOb1JlZkFwcGx5O1xyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuaW1wb3J0IGlzQ2FsbGFibGUgZnJvbSBcIi4vY2FsbGFibGUuanNcIjtcclxuXHJcbi8qKlxyXG4gKiBFeGNlcHRpb24gY2xhc3MgdGhhdCB3aWxsIGJlIHVzZWQgYXMgcmVqZWN0aW9uIHJlYXNvblxyXG4gKiBpbiBjYXNlIGEge0BsaW5rIENhbmNlbGxhYmxlUHJvbWlzZX0gaXMgY2FuY2VsbGVkIHN1Y2Nlc3NmdWxseS5cclxuICpcclxuICogVGhlIHZhbHVlIG9mIHRoZSB7QGxpbmsgbmFtZX0gcHJvcGVydHkgaXMgdGhlIHN0cmluZyBgXCJDYW5jZWxFcnJvclwiYC5cclxuICogVGhlIHZhbHVlIG9mIHRoZSB7QGxpbmsgY2F1c2V9IHByb3BlcnR5IGlzIHRoZSBjYXVzZSBwYXNzZWQgdG8gdGhlIGNhbmNlbCBtZXRob2QsIGlmIGFueS5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBDYW5jZWxFcnJvciBleHRlbmRzIEVycm9yIHtcclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBgQ2FuY2VsRXJyb3JgIGluc3RhbmNlLlxyXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgZXJyb3IgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyB0byBiZSBmb3J3YXJkZWQgdG8gdGhlIEVycm9yIGNvbnN0cnVjdG9yLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlPzogc3RyaW5nLCBvcHRpb25zPzogRXJyb3JPcHRpb25zKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSwgb3B0aW9ucyk7XHJcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDYW5jZWxFcnJvclwiO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXhjZXB0aW9uIGNsYXNzIHRoYXQgd2lsbCBiZSByZXBvcnRlZCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uXHJcbiAqIGluIGNhc2UgYSB7QGxpbmsgQ2FuY2VsbGFibGVQcm9taXNlfSByZWplY3RzIGFmdGVyIGJlaW5nIGNhbmNlbGxlZCxcclxuICogb3Igd2hlbiB0aGUgYG9uY2FuY2VsbGVkYCBjYWxsYmFjayB0aHJvd3Mgb3IgcmVqZWN0cy5cclxuICpcclxuICogVGhlIHZhbHVlIG9mIHRoZSB7QGxpbmsgbmFtZX0gcHJvcGVydHkgaXMgdGhlIHN0cmluZyBgXCJDYW5jZWxsZWRSZWplY3Rpb25FcnJvclwiYC5cclxuICogVGhlIHZhbHVlIG9mIHRoZSB7QGxpbmsgY2F1c2V9IHByb3BlcnR5IGlzIHRoZSByZWFzb24gdGhlIHByb21pc2UgcmVqZWN0ZWQgd2l0aC5cclxuICpcclxuICogQmVjYXVzZSB0aGUgb3JpZ2luYWwgcHJvbWlzZSB3YXMgY2FuY2VsbGVkLFxyXG4gKiBhIHdyYXBwZXIgcHJvbWlzZSB3aWxsIGJlIHBhc3NlZCB0byB0aGUgdW5oYW5kbGVkIHJlamVjdGlvbiBsaXN0ZW5lciBpbnN0ZWFkLlxyXG4gKiBUaGUge0BsaW5rIHByb21pc2V9IHByb3BlcnR5IGhvbGRzIGEgcmVmZXJlbmNlIHRvIHRoZSBvcmlnaW5hbCBwcm9taXNlLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIENhbmNlbGxlZFJlamVjdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xyXG4gICAgLyoqXHJcbiAgICAgKiBIb2xkcyBhIHJlZmVyZW5jZSB0byB0aGUgcHJvbWlzZSB0aGF0IHdhcyBjYW5jZWxsZWQgYW5kIHRoZW4gcmVqZWN0ZWQuXHJcbiAgICAgKi9cclxuICAgIHByb21pc2U6IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgYENhbmNlbGxlZFJlamVjdGlvbkVycm9yYCBpbnN0YW5jZS5cclxuICAgICAqIEBwYXJhbSBwcm9taXNlIC0gVGhlIHByb21pc2UgdGhhdCBjYXVzZWQgdGhlIGVycm9yIG9yaWdpbmFsbHkuXHJcbiAgICAgKiBAcGFyYW0gcmVhc29uIC0gVGhlIHJlamVjdGlvbiByZWFzb24uXHJcbiAgICAgKiBAcGFyYW0gaW5mbyAtIEFuIG9wdGlvbmFsIGluZm9ybWF0aXZlIG1lc3NhZ2Ugc3BlY2lmeWluZyB0aGUgY2lyY3Vtc3RhbmNlcyBpbiB3aGljaCB0aGUgZXJyb3Igd2FzIHRocm93bi5cclxuICAgICAqICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gdGhlIHN0cmluZyBgXCJVbmhhbmRsZWQgcmVqZWN0aW9uIGluIGNhbmNlbGxlZCBwcm9taXNlLlwiYC5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IocHJvbWlzZTogQ2FuY2VsbGFibGVQcm9taXNlPHVua25vd24+LCByZWFzb24/OiBhbnksIGluZm8/OiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcigoaW5mbyA/PyBcIlVuaGFuZGxlZCByZWplY3Rpb24gaW4gY2FuY2VsbGVkIHByb21pc2UuXCIpICsgXCIgUmVhc29uOiBcIiArIGVycm9yTWVzc2FnZShyZWFzb24pLCB7IGNhdXNlOiByZWFzb24gfSk7XHJcbiAgICAgICAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcclxuICAgICAgICB0aGlzLm5hbWUgPSBcIkNhbmNlbGxlZFJlamVjdGlvbkVycm9yXCI7XHJcbiAgICB9XHJcbn1cclxuXHJcbnR5cGUgQ2FuY2VsbGFibGVQcm9taXNlUmVzb2x2ZXI8VD4gPSAodmFsdWU6IFQgfCBQcm9taXNlTGlrZTxUPiB8IENhbmNlbGxhYmxlUHJvbWlzZUxpa2U8VD4pID0+IHZvaWQ7XHJcbnR5cGUgQ2FuY2VsbGFibGVQcm9taXNlUmVqZWN0b3IgPSAocmVhc29uPzogYW55KSA9PiB2b2lkO1xyXG50eXBlIENhbmNlbGxhYmxlUHJvbWlzZUNhbmNlbGxlciA9IChjYXVzZT86IGFueSkgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xyXG50eXBlIENhbmNlbGxhYmxlUHJvbWlzZUV4ZWN1dG9yPFQ+ID0gKHJlc29sdmU6IENhbmNlbGxhYmxlUHJvbWlzZVJlc29sdmVyPFQ+LCByZWplY3Q6IENhbmNlbGxhYmxlUHJvbWlzZVJlamVjdG9yKSA9PiB2b2lkO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDYW5jZWxsYWJsZVByb21pc2VMaWtlPFQ+IHtcclxuICAgIHRoZW48VFJlc3VsdDEgPSBULCBUUmVzdWx0MiA9IG5ldmVyPihvbmZ1bGZpbGxlZD86ICgodmFsdWU6IFQpID0+IFRSZXN1bHQxIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDE+IHwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUUmVzdWx0MT4pIHwgdW5kZWZpbmVkIHwgbnVsbCwgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+IHwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUUmVzdWx0Mj4pIHwgdW5kZWZpbmVkIHwgbnVsbCk6IENhbmNlbGxhYmxlUHJvbWlzZUxpa2U8VFJlc3VsdDEgfCBUUmVzdWx0Mj47XHJcbiAgICBjYW5jZWwoY2F1c2U/OiBhbnkpOiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBXcmFwcyBhIGNhbmNlbGxhYmxlIHByb21pc2UgYWxvbmcgd2l0aCBpdHMgcmVzb2x1dGlvbiBtZXRob2RzLlxyXG4gKiBUaGUgYG9uY2FuY2VsbGVkYCBmaWVsZCB3aWxsIGJlIG51bGwgaW5pdGlhbGx5IGJ1dCBtYXkgYmUgc2V0IHRvIHByb3ZpZGUgYSBjdXN0b20gY2FuY2VsbGF0aW9uIGZ1bmN0aW9uLlxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBDYW5jZWxsYWJsZVByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+IHtcclxuICAgIHByb21pc2U6IENhbmNlbGxhYmxlUHJvbWlzZTxUPjtcclxuICAgIHJlc29sdmU6IENhbmNlbGxhYmxlUHJvbWlzZVJlc29sdmVyPFQ+O1xyXG4gICAgcmVqZWN0OiBDYW5jZWxsYWJsZVByb21pc2VSZWplY3RvcjtcclxuICAgIG9uY2FuY2VsbGVkOiBDYW5jZWxsYWJsZVByb21pc2VDYW5jZWxsZXIgfCBudWxsO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgQ2FuY2VsbGFibGVQcm9taXNlU3RhdGUge1xyXG4gICAgcmVhZG9ubHkgcm9vdDogQ2FuY2VsbGFibGVQcm9taXNlU3RhdGU7XHJcbiAgICByZXNvbHZpbmc6IGJvb2xlYW47XHJcbiAgICBzZXR0bGVkOiBib29sZWFuO1xyXG4gICAgcmVhc29uPzogQ2FuY2VsRXJyb3I7XHJcbn1cclxuXHJcbi8vIFByaXZhdGUgZmllbGQgbmFtZXMuXHJcbmNvbnN0IGJhcnJpZXJTeW0gPSBTeW1ib2woXCJiYXJyaWVyXCIpO1xyXG5jb25zdCBjYW5jZWxJbXBsU3ltID0gU3ltYm9sKFwiY2FuY2VsSW1wbFwiKTtcclxuY29uc3Qgc3BlY2llcyA9IFN5bWJvbC5zcGVjaWVzID8/IFN5bWJvbChcInNwZWNpZXNQb2x5ZmlsbFwiKTtcclxuXHJcbi8qKlxyXG4gKiBBIHByb21pc2Ugd2l0aCBhbiBhdHRhY2hlZCBtZXRob2QgZm9yIGNhbmNlbGxpbmcgbG9uZy1ydW5uaW5nIG9wZXJhdGlvbnMgKHNlZSB7QGxpbmsgQ2FuY2VsbGFibGVQcm9taXNlI2NhbmNlbH0pLlxyXG4gKiBDYW5jZWxsYXRpb24gY2FuIG9wdGlvbmFsbHkgYmUgYm91bmQgdG8gYW4ge0BsaW5rIEFib3J0U2lnbmFsfVxyXG4gKiBmb3IgYmV0dGVyIGNvbXBvc2FiaWxpdHkgKHNlZSB7QGxpbmsgQ2FuY2VsbGFibGVQcm9taXNlI2NhbmNlbE9ufSkuXHJcbiAqXHJcbiAqIENhbmNlbGxpbmcgYSBwZW5kaW5nIHByb21pc2Ugd2lsbCByZXN1bHQgaW4gYW4gaW1tZWRpYXRlIHJlamVjdGlvblxyXG4gKiB3aXRoIGFuIGluc3RhbmNlIG9mIHtAbGluayBDYW5jZWxFcnJvcn0gYXMgcmVhc29uLFxyXG4gKiBidXQgd2hvZXZlciBzdGFydGVkIHRoZSBwcm9taXNlIHdpbGwgYmUgcmVzcG9uc2libGVcclxuICogZm9yIGFjdHVhbGx5IGFib3J0aW5nIHRoZSB1bmRlcmx5aW5nIG9wZXJhdGlvbi5cclxuICogVG8gdGhpcyBwdXJwb3NlLCB0aGUgY29uc3RydWN0b3IgYW5kIGFsbCBjaGFpbmluZyBtZXRob2RzXHJcbiAqIGFjY2VwdCBvcHRpb25hbCBjYW5jZWxsYXRpb24gY2FsbGJhY2tzLlxyXG4gKlxyXG4gKiBJZiBhIGBDYW5jZWxsYWJsZVByb21pc2VgIHN0aWxsIHJlc29sdmVzIGFmdGVyIGhhdmluZyBiZWVuIGNhbmNlbGxlZCxcclxuICogdGhlIHJlc3VsdCB3aWxsIGJlIGRpc2NhcmRlZC4gSWYgaXQgcmVqZWN0cywgdGhlIHJlYXNvblxyXG4gKiB3aWxsIGJlIHJlcG9ydGVkIGFzIGFuIHVuaGFuZGxlZCByZWplY3Rpb24sXHJcbiAqIHdyYXBwZWQgaW4gYSB7QGxpbmsgQ2FuY2VsbGVkUmVqZWN0aW9uRXJyb3J9IGluc3RhbmNlLlxyXG4gKiBUbyBmYWNpbGl0YXRlIHRoZSBoYW5kbGluZyBvZiBjYW5jZWxsYXRpb24gcmVxdWVzdHMsXHJcbiAqIGNhbmNlbGxlZCBgQ2FuY2VsbGFibGVQcm9taXNlYHMgd2lsbCBfbm90XyByZXBvcnQgdW5oYW5kbGVkIGBDYW5jZWxFcnJvcmBzXHJcbiAqIHdob3NlIGBjYXVzZWAgZmllbGQgaXMgdGhlIHNhbWUgYXMgdGhlIG9uZSB3aXRoIHdoaWNoIHRoZSBjdXJyZW50IHByb21pc2Ugd2FzIGNhbmNlbGxlZC5cclxuICpcclxuICogQWxsIHVzdWFsIHByb21pc2UgbWV0aG9kcyBhcmUgZGVmaW5lZCBhbmQgcmV0dXJuIGEgYENhbmNlbGxhYmxlUHJvbWlzZWBcclxuICogd2hvc2UgY2FuY2VsIG1ldGhvZCB3aWxsIGNhbmNlbCB0aGUgcGFyZW50IG9wZXJhdGlvbiBhcyB3ZWxsLCBwcm9wYWdhdGluZyB0aGUgY2FuY2VsbGF0aW9uIHJlYXNvblxyXG4gKiB1cHdhcmRzIHRocm91Z2ggcHJvbWlzZSBjaGFpbnMuXHJcbiAqIENvbnZlcnNlbHksIGNhbmNlbGxpbmcgYSBwcm9taXNlIHdpbGwgbm90IGF1dG9tYXRpY2FsbHkgY2FuY2VsIGRlcGVuZGVudCBwcm9taXNlcyBkb3duc3RyZWFtOlxyXG4gKiBgYGB0c1xyXG4gKiBsZXQgcm9vdCA9IG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4geyAuLi4gfSk7XHJcbiAqIGxldCBjaGlsZDEgPSByb290LnRoZW4oKCkgPT4geyAuLi4gfSk7XHJcbiAqIGxldCBjaGlsZDIgPSBjaGlsZDEudGhlbigoKSA9PiB7IC4uLiB9KTtcclxuICogbGV0IGNoaWxkMyA9IHJvb3QuY2F0Y2goKCkgPT4geyAuLi4gfSk7XHJcbiAqIGNoaWxkMS5jYW5jZWwoKTsgLy8gQ2FuY2VscyBjaGlsZDEgYW5kIHJvb3QsIGJ1dCBub3QgY2hpbGQyIG9yIGNoaWxkM1xyXG4gKiBgYGBcclxuICogQ2FuY2VsbGluZyBhIHByb21pc2UgdGhhdCBoYXMgYWxyZWFkeSBzZXR0bGVkIGlzIHNhZmUgYW5kIGhhcyBubyBjb25zZXF1ZW5jZS5cclxuICpcclxuICogVGhlIGBjYW5jZWxgIG1ldGhvZCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IF9hbHdheXMgZnVsZmlsbHNfXHJcbiAqIGFmdGVyIHRoZSB3aG9sZSBjaGFpbiBoYXMgcHJvY2Vzc2VkIHRoZSBjYW5jZWwgcmVxdWVzdFxyXG4gKiBhbmQgYWxsIGF0dGFjaGVkIGNhbGxiYWNrcyB1cCB0byB0aGF0IG1vbWVudCBoYXZlIHJ1bi5cclxuICpcclxuICogQWxsIEVTMjAyNCBwcm9taXNlIG1ldGhvZHMgKHN0YXRpYyBhbmQgaW5zdGFuY2UpIGFyZSBkZWZpbmVkIG9uIENhbmNlbGxhYmxlUHJvbWlzZSxcclxuICogYnV0IGFjdHVhbCBhdmFpbGFiaWxpdHkgbWF5IHZhcnkgd2l0aCBPUy93ZWJ2aWV3IHZlcnNpb24uXHJcbiAqXHJcbiAqIEluIGxpbmUgd2l0aCB0aGUgcHJvcG9zYWwgYXQgaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcm0tYnVpbHRpbi1zdWJjbGFzc2luZyxcclxuICogYENhbmNlbGxhYmxlUHJvbWlzZWAgZG9lcyBub3Qgc3VwcG9ydCB0cmFuc3BhcmVudCBzdWJjbGFzc2luZy5cclxuICogRXh0ZW5kZXJzIHNob3VsZCB0YWtlIGNhcmUgdG8gcHJvdmlkZSB0aGVpciBvd24gbWV0aG9kIGltcGxlbWVudGF0aW9ucy5cclxuICogVGhpcyBtaWdodCBiZSByZWNvbnNpZGVyZWQgaW4gY2FzZSB0aGUgcHJvcG9zYWwgaXMgcmV0aXJlZC5cclxuICpcclxuICogQ2FuY2VsbGFibGVQcm9taXNlIGlzIGEgd3JhcHBlciBhcm91bmQgdGhlIERPTSBQcm9taXNlIG9iamVjdFxyXG4gKiBhbmQgaXMgY29tcGxpYW50IHdpdGggdGhlIFtQcm9taXNlcy9BKyBzcGVjaWZpY2F0aW9uXShodHRwczovL3Byb21pc2VzYXBsdXMuY29tLylcclxuICogKGl0IHBhc3NlcyB0aGUgW2NvbXBsaWFuY2Ugc3VpdGVdKGh0dHBzOi8vZ2l0aHViLmNvbS9wcm9taXNlcy1hcGx1cy9wcm9taXNlcy10ZXN0cykpXHJcbiAqIGlmIHNvIGlzIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIENhbmNlbGxhYmxlUHJvbWlzZTxUPiBleHRlbmRzIFByb21pc2U8VD4gaW1wbGVtZW50cyBQcm9taXNlTGlrZTxUPiwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUPiB7XHJcbiAgICAvLyBQcml2YXRlIGZpZWxkcy5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHByaXZhdGUgW2JhcnJpZXJTeW1dITogUGFydGlhbDxQcm9taXNlV2l0aFJlc29sdmVyczx2b2lkPj4gfCBudWxsO1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBbY2FuY2VsSW1wbFN5bV0hOiAocmVhc29uOiBDYW5jZWxFcnJvcikgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIG5ldyBgQ2FuY2VsbGFibGVQcm9taXNlYC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZXhlY3V0b3IgLSBBIGNhbGxiYWNrIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGUgcHJvbWlzZS4gVGhpcyBjYWxsYmFjayBpcyBwYXNzZWQgdHdvIGFyZ3VtZW50czpcclxuICAgICAqICAgICAgICAgICAgICAgICAgIGEgYHJlc29sdmVgIGNhbGxiYWNrIHVzZWQgdG8gcmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoIGEgdmFsdWVcclxuICAgICAqICAgICAgICAgICAgICAgICAgIG9yIHRoZSByZXN1bHQgb2YgYW5vdGhlciBwcm9taXNlIChwb3NzaWJseSBjYW5jZWxsYWJsZSksXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICBhbmQgYSBgcmVqZWN0YCBjYWxsYmFjayB1c2VkIHRvIHJlamVjdCB0aGUgcHJvbWlzZSB3aXRoIGEgcHJvdmlkZWQgcmVhc29uIG9yIGVycm9yLlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgSWYgdGhlIHZhbHVlIHByb3ZpZGVkIHRvIHRoZSBgcmVzb2x2ZWAgY2FsbGJhY2sgaXMgYSB0aGVuYWJsZSBfYW5kXyBjYW5jZWxsYWJsZSBvYmplY3RcclxuICAgICAqICAgICAgICAgICAgICAgICAgIChpdCBoYXMgYSBgdGhlbmAgX2FuZF8gYSBgY2FuY2VsYCBtZXRob2QpLFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgY2FuY2VsbGF0aW9uIHJlcXVlc3RzIHdpbGwgYmUgZm9yd2FyZGVkIHRvIHRoYXQgb2JqZWN0IGFuZCB0aGUgb25jYW5jZWxsZWQgd2lsbCBub3QgYmUgaW52b2tlZCBhbnltb3JlLlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgSWYgYW55IG9uZSBvZiB0aGUgdHdvIGNhbGxiYWNrcyBpcyBjYWxsZWQgX2FmdGVyXyB0aGUgcHJvbWlzZSBoYXMgYmVlbiBjYW5jZWxsZWQsXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICB0aGUgcHJvdmlkZWQgdmFsdWVzIHdpbGwgYmUgY2FuY2VsbGVkIGFuZCByZXNvbHZlZCBhcyB1c3VhbCxcclxuICAgICAqICAgICAgICAgICAgICAgICAgIGJ1dCB0aGVpciByZXN1bHRzIHdpbGwgYmUgZGlzY2FyZGVkLlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgSG93ZXZlciwgaWYgdGhlIHJlc29sdXRpb24gcHJvY2VzcyB1bHRpbWF0ZWx5IGVuZHMgdXAgaW4gYSByZWplY3Rpb25cclxuICAgICAqICAgICAgICAgICAgICAgICAgIHRoYXQgaXMgbm90IGR1ZSB0byBjYW5jZWxsYXRpb24sIHRoZSByZWplY3Rpb24gcmVhc29uXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICB3aWxsIGJlIHdyYXBwZWQgaW4gYSB7QGxpbmsgQ2FuY2VsbGVkUmVqZWN0aW9uRXJyb3J9XHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICBhbmQgYnViYmxlZCB1cCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLlxyXG4gICAgICogQHBhcmFtIG9uY2FuY2VsbGVkIC0gSXQgaXMgdGhlIGNhbGxlcidzIHJlc3BvbnNpYmlsaXR5IHRvIGVuc3VyZSB0aGF0IGFueSBvcGVyYXRpb25cclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWQgYnkgdGhlIGV4ZWN1dG9yIGlzIHByb3Blcmx5IGhhbHRlZCB1cG9uIGNhbmNlbGxhdGlvbi5cclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIFRoaXMgb3B0aW9uYWwgY2FsbGJhY2sgY2FuIGJlIHVzZWQgdG8gdGhhdCBwdXJwb3NlLlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgSXQgd2lsbCBiZSBjYWxsZWQgX3N5bmNocm9ub3VzbHlfIHdpdGggYSBjYW5jZWxsYXRpb24gY2F1c2VcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHdoZW4gY2FuY2VsbGF0aW9uIGlzIHJlcXVlc3RlZCwgX2FmdGVyXyB0aGUgcHJvbWlzZSBoYXMgYWxyZWFkeSByZWplY3RlZFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgd2l0aCBhIHtAbGluayBDYW5jZWxFcnJvcn0sIGJ1dCBfYmVmb3JlX1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgYW55IHtAbGluayB0aGVufS97QGxpbmsgY2F0Y2h9L3tAbGluayBmaW5hbGx5fSBjYWxsYmFjayBydW5zLlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgYSB0aGVuYWJsZSwgdGhlIHByb21pc2UgcmV0dXJuZWQgZnJvbSB7QGxpbmsgY2FuY2VsfVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgd2lsbCBvbmx5IGZ1bGZpbGwgYWZ0ZXIgdGhlIGZvcm1lciBoYXMgc2V0dGxlZC5cclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIFVuaGFuZGxlZCBleGNlcHRpb25zIG9yIHJlamVjdGlvbnMgZnJvbSB0aGUgY2FsbGJhY2sgd2lsbCBiZSB3cmFwcGVkXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpbiBhIHtAbGluayBDYW5jZWxsZWRSZWplY3Rpb25FcnJvcn0gYW5kIGJ1YmJsZWQgdXAgYXMgdW5oYW5kbGVkIHJlamVjdGlvbnMuXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBJZiB0aGUgYHJlc29sdmVgIGNhbGxiYWNrIGlzIGNhbGxlZCBiZWZvcmUgY2FuY2VsbGF0aW9uIHdpdGggYSBjYW5jZWxsYWJsZSBwcm9taXNlLFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgY2FuY2VsbGF0aW9uIHJlcXVlc3RzIG9uIHRoaXMgcHJvbWlzZSB3aWxsIGJlIGRpdmVydGVkIHRvIHRoYXQgcHJvbWlzZSxcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGFuZCB0aGUgb3JpZ2luYWwgYG9uY2FuY2VsbGVkYCBjYWxsYmFjayB3aWxsIGJlIGRpc2NhcmRlZC5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoZXhlY3V0b3I6IENhbmNlbGxhYmxlUHJvbWlzZUV4ZWN1dG9yPFQ+LCBvbmNhbmNlbGxlZD86IENhbmNlbGxhYmxlUHJvbWlzZUNhbmNlbGxlcikge1xyXG4gICAgICAgIGxldCByZXNvbHZlITogKHZhbHVlOiBUIHwgUHJvbWlzZUxpa2U8VD4pID0+IHZvaWQ7XHJcbiAgICAgICAgbGV0IHJlamVjdCE6IChyZWFzb24/OiBhbnkpID0+IHZvaWQ7XHJcbiAgICAgICAgc3VwZXIoKHJlcywgcmVqKSA9PiB7IHJlc29sdmUgPSByZXM7IHJlamVjdCA9IHJlajsgfSk7XHJcblxyXG4gICAgICAgIGlmICgodGhpcy5jb25zdHJ1Y3RvciBhcyBhbnkpW3NwZWNpZXNdICE9PSBQcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5jZWxsYWJsZVByb21pc2UgZG9lcyBub3Qgc3VwcG9ydCB0cmFuc3BhcmVudCBzdWJjbGFzc2luZy4gUGxlYXNlIHJlZnJhaW4gZnJvbSBvdmVycmlkaW5nIHRoZSBbU3ltYm9sLnNwZWNpZXNdIHN0YXRpYyBwcm9wZXJ0eS5cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgcHJvbWlzZTogQ2FuY2VsbGFibGVQcm9taXNlV2l0aFJlc29sdmVyczxUPiA9IHtcclxuICAgICAgICAgICAgcHJvbWlzZTogdGhpcyxcclxuICAgICAgICAgICAgcmVzb2x2ZSxcclxuICAgICAgICAgICAgcmVqZWN0LFxyXG4gICAgICAgICAgICBnZXQgb25jYW5jZWxsZWQoKSB7IHJldHVybiBvbmNhbmNlbGxlZCA/PyBudWxsOyB9LFxyXG4gICAgICAgICAgICBzZXQgb25jYW5jZWxsZWQoY2IpIHsgb25jYW5jZWxsZWQgPSBjYiA/PyB1bmRlZmluZWQ7IH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBjb25zdCBzdGF0ZTogQ2FuY2VsbGFibGVQcm9taXNlU3RhdGUgPSB7XHJcbiAgICAgICAgICAgIGdldCByb290KCkgeyByZXR1cm4gc3RhdGU7IH0sXHJcbiAgICAgICAgICAgIHJlc29sdmluZzogZmFsc2UsXHJcbiAgICAgICAgICAgIHNldHRsZWQ6IGZhbHNlXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gU2V0dXAgY2FuY2VsbGF0aW9uIHN5c3RlbS5cclxuICAgICAgICB2b2lkIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcclxuICAgICAgICAgICAgW2JhcnJpZXJTeW1dOiB7XHJcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHZhbHVlOiBudWxsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIFtjYW5jZWxJbXBsU3ltXToge1xyXG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgdmFsdWU6IGNhbmNlbGxlckZvcihwcm9taXNlLCBzdGF0ZSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBSdW4gdGhlIGFjdHVhbCBleGVjdXRvci5cclxuICAgICAgICBjb25zdCByZWplY3RvciA9IHJlamVjdG9yRm9yKHByb21pc2UsIHN0YXRlKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBleGVjdXRvcihyZXNvbHZlckZvcihwcm9taXNlLCBzdGF0ZSksIHJlamVjdG9yKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlLnJlc29sdmluZykge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJVbmhhbmRsZWQgZXhjZXB0aW9uIGluIENhbmNlbGxhYmxlUHJvbWlzZSBleGVjdXRvci5cIiwgZXJyKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJlamVjdG9yKGVycik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYW5jZWxzIGltbWVkaWF0ZWx5IHRoZSBleGVjdXRpb24gb2YgdGhlIG9wZXJhdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcm9taXNlLlxyXG4gICAgICogVGhlIHByb21pc2UgcmVqZWN0cyB3aXRoIGEge0BsaW5rIENhbmNlbEVycm9yfSBpbnN0YW5jZSBhcyByZWFzb24sXHJcbiAgICAgKiB3aXRoIHRoZSB7QGxpbmsgQ2FuY2VsRXJyb3IjY2F1c2V9IHByb3BlcnR5IHNldCB0byB0aGUgZ2l2ZW4gYXJndW1lbnQsIGlmIGFueS5cclxuICAgICAqXHJcbiAgICAgKiBIYXMgbm8gZWZmZWN0IGlmIGNhbGxlZCBhZnRlciB0aGUgcHJvbWlzZSBoYXMgYWxyZWFkeSBzZXR0bGVkO1xyXG4gICAgICogcmVwZWF0ZWQgY2FsbHMgaW4gcGFydGljdWxhciBhcmUgc2FmZSwgYnV0IG9ubHkgdGhlIGZpcnN0IG9uZVxyXG4gICAgICogd2lsbCBzZXQgdGhlIGNhbmNlbGxhdGlvbiBjYXVzZS5cclxuICAgICAqXHJcbiAgICAgKiBUaGUgYENhbmNlbEVycm9yYCBleGNlcHRpb24gX25lZWQgbm90XyBiZSBoYW5kbGVkIGV4cGxpY2l0bHkgX29uIHRoZSBwcm9taXNlcyB0aGF0IGFyZSBiZWluZyBjYW5jZWxsZWQ6X1xyXG4gICAgICogY2FuY2VsbGluZyBhIHByb21pc2Ugd2l0aCBubyBhdHRhY2hlZCByZWplY3Rpb24gaGFuZGxlciBkb2VzIG5vdCB0cmlnZ2VyIGFuIHVuaGFuZGxlZCByZWplY3Rpb24gZXZlbnQuXHJcbiAgICAgKiBUaGVyZWZvcmUsIHRoZSBmb2xsb3dpbmcgaWRpb21zIGFyZSBhbGwgZXF1YWxseSBjb3JyZWN0OlxyXG4gICAgICogYGBgdHNcclxuICAgICAqIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4geyAuLi4gfSkuY2FuY2VsKCk7XHJcbiAgICAgKiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsgLi4uIH0pLnRoZW4oLi4uKS5jYW5jZWwoKTtcclxuICAgICAqIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4geyAuLi4gfSkudGhlbiguLi4pLmNhdGNoKC4uLikuY2FuY2VsKCk7XHJcbiAgICAgKiBgYGBcclxuICAgICAqIFdoZW5ldmVyIHNvbWUgY2FuY2VsbGVkIHByb21pc2UgaW4gYSBjaGFpbiByZWplY3RzIHdpdGggYSBgQ2FuY2VsRXJyb3JgXHJcbiAgICAgKiB3aXRoIHRoZSBzYW1lIGNhbmNlbGxhdGlvbiBjYXVzZSBhcyBpdHNlbGYsIHRoZSBlcnJvciB3aWxsIGJlIGRpc2NhcmRlZCBzaWxlbnRseS5cclxuICAgICAqIEhvd2V2ZXIsIHRoZSBgQ2FuY2VsRXJyb3JgIF93aWxsIHN0aWxsIGJlIGRlbGl2ZXJlZF8gdG8gYWxsIGF0dGFjaGVkIHJlamVjdGlvbiBoYW5kbGVyc1xyXG4gICAgICogYWRkZWQgYnkge0BsaW5rIHRoZW59IGFuZCByZWxhdGVkIG1ldGhvZHM6XHJcbiAgICAgKiBgYGB0c1xyXG4gICAgICogbGV0IGNhbmNlbGxhYmxlID0gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7IC4uLiB9KTtcclxuICAgICAqIGNhbmNlbGxhYmxlLnRoZW4oKCkgPT4geyAuLi4gfSkuY2F0Y2goY29uc29sZS5sb2cpO1xyXG4gICAgICogY2FuY2VsbGFibGUuY2FuY2VsKCk7IC8vIEEgQ2FuY2VsRXJyb3IgaXMgcHJpbnRlZCB0byB0aGUgY29uc29sZS5cclxuICAgICAqIGBgYFxyXG4gICAgICogSWYgdGhlIGBDYW5jZWxFcnJvcmAgaXMgbm90IGhhbmRsZWQgZG93bnN0cmVhbSBieSB0aGUgdGltZSBpdCByZWFjaGVzXHJcbiAgICAgKiBhIF9ub24tY2FuY2VsbGVkXyBwcm9taXNlLCBpdCBfd2lsbF8gdHJpZ2dlciBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uIGV2ZW50LFxyXG4gICAgICoganVzdCBsaWtlIG5vcm1hbCByZWplY3Rpb25zIHdvdWxkOlxyXG4gICAgICogYGBgdHNcclxuICAgICAqIGxldCBjYW5jZWxsYWJsZSA9IG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4geyAuLi4gfSk7XHJcbiAgICAgKiBsZXQgY2hhaW5lZCA9IGNhbmNlbGxhYmxlLnRoZW4oKCkgPT4geyAuLi4gfSkudGhlbigoKSA9PiB7IC4uLiB9KTsgLy8gTm8gY2F0Y2guLi5cclxuICAgICAqIGNhbmNlbGxhYmxlLmNhbmNlbCgpOyAvLyBVbmhhbmRsZWQgcmVqZWN0aW9uIGV2ZW50IG9uIGNoYWluZWQhXHJcbiAgICAgKiBgYGBcclxuICAgICAqIFRoZXJlZm9yZSwgaXQgaXMgaW1wb3J0YW50IHRvIGVpdGhlciBjYW5jZWwgd2hvbGUgcHJvbWlzZSBjaGFpbnMgZnJvbSB0aGVpciB0YWlsLFxyXG4gICAgICogYXMgc2hvd24gaW4gdGhlIGNvcnJlY3QgaWRpb21zIGFib3ZlLCBvciB0YWtlIGNhcmUgb2YgaGFuZGxpbmcgZXJyb3JzIGV2ZXJ5d2hlcmUuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMgQSBjYW5jZWxsYWJsZSBwcm9taXNlIHRoYXQgX2Z1bGZpbGxzXyBhZnRlciB0aGUgY2FuY2VsIGNhbGxiYWNrIChpZiBhbnkpXHJcbiAgICAgKiBhbmQgYWxsIGhhbmRsZXJzIGF0dGFjaGVkIHVwIHRvIHRoZSBjYWxsIHRvIGNhbmNlbCBoYXZlIHJ1bi5cclxuICAgICAqIElmIHRoZSBjYW5jZWwgY2FsbGJhY2sgcmV0dXJucyBhIHRoZW5hYmxlLCB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSBgY2FuY2VsYFxyXG4gICAgICogd2lsbCBhbHNvIHdhaXQgZm9yIHRoYXQgdGhlbmFibGUgdG8gc2V0dGxlLlxyXG4gICAgICogVGhpcyBlbmFibGVzIGNhbGxlcnMgdG8gd2FpdCBmb3IgdGhlIGNhbmNlbGxlZCBvcGVyYXRpb24gdG8gdGVybWluYXRlXHJcbiAgICAgKiB3aXRob3V0IGJlaW5nIGZvcmNlZCB0byBoYW5kbGUgcG90ZW50aWFsIGVycm9ycyBhdCB0aGUgY2FsbCBzaXRlLlxyXG4gICAgICogYGBgdHNcclxuICAgICAqIGNhbmNlbGxhYmxlLmNhbmNlbCgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICogICAgIC8vIENsZWFudXAgZmluaXNoZWQsIGl0J3Mgc2FmZSB0byBkbyBzb21ldGhpbmcgZWxzZS5cclxuICAgICAqIH0sIChlcnIpID0+IHtcclxuICAgICAqICAgICAvLyBVbnJlYWNoYWJsZTogdGhlIHByb21pc2UgcmV0dXJuZWQgZnJvbSBjYW5jZWwgd2lsbCBuZXZlciByZWplY3QuXHJcbiAgICAgKiB9KTtcclxuICAgICAqIGBgYFxyXG4gICAgICogTm90ZSB0aGF0IHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgX25vdF8gaGFuZGxlIGltcGxpY2l0bHkgYW55IHJlamVjdGlvblxyXG4gICAgICogdGhhdCBtaWdodCBoYXZlIG9jY3VycmVkIGFscmVhZHkgaW4gdGhlIGNhbmNlbGxlZCBjaGFpbi5cclxuICAgICAqIEl0IHdpbGwganVzdCB0cmFjayB3aGV0aGVyIHJlZ2lzdGVyZWQgaGFuZGxlcnMgaGF2ZSBiZWVuIGV4ZWN1dGVkIG9yIG5vdC5cclxuICAgICAqIFRoZXJlZm9yZSwgdW5oYW5kbGVkIHJlamVjdGlvbnMgd2lsbCBuZXZlciBiZSBzaWxlbnRseSBoYW5kbGVkIGJ5IGNhbGxpbmcgY2FuY2VsLlxyXG4gICAgICovXHJcbiAgICBjYW5jZWwoY2F1c2U/OiBhbnkpOiBDYW5jZWxsYWJsZVByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIC8vIElOVkFSSUFOVDogdGhlIHJlc3VsdCBvZiB0aGlzW2NhbmNlbEltcGxTeW1dIGFuZCB0aGUgYmFycmllciBkbyBub3QgZXZlciByZWplY3QuXHJcbiAgICAgICAgICAgIC8vIFVuZm9ydHVuYXRlbHkgbWFjT1MgSGlnaCBTaWVycmEgZG9lcyBub3Qgc3VwcG9ydCBQcm9taXNlLmFsbFNldHRsZWQuXHJcbiAgICAgICAgICAgIFByb21pc2UuYWxsKFtcclxuICAgICAgICAgICAgICAgIHRoaXNbY2FuY2VsSW1wbFN5bV0obmV3IENhbmNlbEVycm9yKFwiUHJvbWlzZSBjYW5jZWxsZWQuXCIsIHsgY2F1c2UgfSkpLFxyXG4gICAgICAgICAgICAgICAgY3VycmVudEJhcnJpZXIodGhpcylcclxuICAgICAgICAgICAgXSkudGhlbigoKSA9PiByZXNvbHZlKCksICgpID0+IHJlc29sdmUoKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCaW5kcyBwcm9taXNlIGNhbmNlbGxhdGlvbiB0byB0aGUgYWJvcnQgZXZlbnQgb2YgdGhlIGdpdmVuIHtAbGluayBBYm9ydFNpZ25hbH0uXHJcbiAgICAgKiBJZiB0aGUgc2lnbmFsIGhhcyBhbHJlYWR5IGFib3J0ZWQsIHRoZSBwcm9taXNlIHdpbGwgYmUgY2FuY2VsbGVkIGltbWVkaWF0ZWx5LlxyXG4gICAgICogV2hlbiBlaXRoZXIgY29uZGl0aW9uIGlzIHZlcmlmaWVkLCB0aGUgY2FuY2VsbGF0aW9uIGNhdXNlIHdpbGwgYmUgc2V0XHJcbiAgICAgKiB0byB0aGUgc2lnbmFsJ3MgYWJvcnQgcmVhc29uIChzZWUge0BsaW5rIEFib3J0U2lnbmFsI3JlYXNvbn0pLlxyXG4gICAgICpcclxuICAgICAqIEhhcyBubyBlZmZlY3QgaWYgY2FsbGVkIChvciBpZiB0aGUgc2lnbmFsIGFib3J0cykgX2FmdGVyXyB0aGUgcHJvbWlzZSBoYXMgYWxyZWFkeSBzZXR0bGVkLlxyXG4gICAgICogT25seSB0aGUgZmlyc3Qgc2lnbmFsIHRvIGFib3J0IHdpbGwgc2V0IHRoZSBjYW5jZWxsYXRpb24gY2F1c2UuXHJcbiAgICAgKlxyXG4gICAgICogRm9yIG1vcmUgZGV0YWlscyBhYm91dCB0aGUgY2FuY2VsbGF0aW9uIHByb2Nlc3MsXHJcbiAgICAgKiBzZWUge0BsaW5rIGNhbmNlbH0gYW5kIHRoZSBgQ2FuY2VsbGFibGVQcm9taXNlYCBjb25zdHJ1Y3Rvci5cclxuICAgICAqXHJcbiAgICAgKiBUaGlzIG1ldGhvZCBlbmFibGVzIGBhd2FpdGBpbmcgY2FuY2VsbGFibGUgcHJvbWlzZXMgd2l0aG91dCBoYXZpbmdcclxuICAgICAqIHRvIHN0b3JlIHRoZW0gZm9yIGZ1dHVyZSBjYW5jZWxsYXRpb24sIGUuZy46XHJcbiAgICAgKiBgYGB0c1xyXG4gICAgICogYXdhaXQgbG9uZ1J1bm5pbmdPcGVyYXRpb24oKS5jYW5jZWxPbihzaWduYWwpO1xyXG4gICAgICogYGBgXHJcbiAgICAgKiBpbnN0ZWFkIG9mOlxyXG4gICAgICogYGBgdHNcclxuICAgICAqIGxldCBwcm9taXNlVG9CZUNhbmNlbGxlZCA9IGxvbmdSdW5uaW5nT3BlcmF0aW9uKCk7XHJcbiAgICAgKiBhd2FpdCBwcm9taXNlVG9CZUNhbmNlbGxlZDtcclxuICAgICAqIGBgYFxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoaXMgcHJvbWlzZSwgZm9yIG1ldGhvZCBjaGFpbmluZy5cclxuICAgICAqL1xyXG4gICAgY2FuY2VsT24oc2lnbmFsOiBBYm9ydFNpZ25hbCk6IENhbmNlbGxhYmxlUHJvbWlzZTxUPiB7XHJcbiAgICAgICAgaWYgKHNpZ25hbC5hYm9ydGVkKSB7XHJcbiAgICAgICAgICAgIHZvaWQgdGhpcy5jYW5jZWwoc2lnbmFsLnJlYXNvbilcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCAoKSA9PiB2b2lkIHRoaXMuY2FuY2VsKHNpZ25hbC5yZWFzb24pLCB7Y2FwdHVyZTogdHJ1ZX0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBdHRhY2hlcyBjYWxsYmFja3MgZm9yIHRoZSByZXNvbHV0aW9uIGFuZC9vciByZWplY3Rpb24gb2YgdGhlIGBDYW5jZWxsYWJsZVByb21pc2VgLlxyXG4gICAgICpcclxuICAgICAqIFRoZSBvcHRpb25hbCBgb25jYW5jZWxsZWRgIGFyZ3VtZW50IHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSByZXR1cm5lZCBwcm9taXNlIGlzIGNhbmNlbGxlZCxcclxuICAgICAqIHdpdGggdGhlIHNhbWUgc2VtYW50aWNzIGFzIHRoZSBgb25jYW5jZWxsZWRgIGFyZ3VtZW50IG9mIHRoZSBjb25zdHJ1Y3Rvci5cclxuICAgICAqIFdoZW4gdGhlIHBhcmVudCBwcm9taXNlIHJlamVjdHMgb3IgaXMgY2FuY2VsbGVkLCB0aGUgYG9ucmVqZWN0ZWRgIGNhbGxiYWNrIHdpbGwgcnVuLFxyXG4gICAgICogX2V2ZW4gYWZ0ZXIgdGhlIHJldHVybmVkIHByb21pc2UgaGFzIGJlZW4gY2FuY2VsbGVkOl9cclxuICAgICAqIGluIHRoYXQgY2FzZSwgc2hvdWxkIGl0IHJlamVjdCBvciB0aHJvdywgdGhlIHJlYXNvbiB3aWxsIGJlIHdyYXBwZWRcclxuICAgICAqIGluIGEge0BsaW5rIENhbmNlbGxlZFJlamVjdGlvbkVycm9yfSBhbmQgYnViYmxlZCB1cCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBvbmZ1bGZpbGxlZCBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSB3aGVuIHRoZSBQcm9taXNlIGlzIHJlc29sdmVkLlxyXG4gICAgICogQHBhcmFtIG9ucmVqZWN0ZWQgVGhlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgd2hlbiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZC5cclxuICAgICAqIEByZXR1cm5zIEEgYENhbmNlbGxhYmxlUHJvbWlzZWAgZm9yIHRoZSBjb21wbGV0aW9uIG9mIHdoaWNoZXZlciBjYWxsYmFjayBpcyBleGVjdXRlZC5cclxuICAgICAqIFRoZSByZXR1cm5lZCBwcm9taXNlIGlzIGhvb2tlZCB1cCB0byBwcm9wYWdhdGUgY2FuY2VsbGF0aW9uIHJlcXVlc3RzIHVwIHRoZSBjaGFpbiwgYnV0IG5vdCBkb3duOlxyXG4gICAgICpcclxuICAgICAqICAgLSBpZiB0aGUgcGFyZW50IHByb21pc2UgaXMgY2FuY2VsbGVkLCB0aGUgYG9ucmVqZWN0ZWRgIGhhbmRsZXIgd2lsbCBiZSBpbnZva2VkIHdpdGggYSBgQ2FuY2VsRXJyb3JgXHJcbiAgICAgKiAgICAgYW5kIHRoZSByZXR1cm5lZCBwcm9taXNlIF93aWxsIHJlc29sdmUgcmVndWxhcmx5XyB3aXRoIGl0cyByZXN1bHQ7XHJcbiAgICAgKiAgIC0gY29udmVyc2VseSwgaWYgdGhlIHJldHVybmVkIHByb21pc2UgaXMgY2FuY2VsbGVkLCBfdGhlIHBhcmVudCBwcm9taXNlIGlzIGNhbmNlbGxlZCB0b287X1xyXG4gICAgICogICAgIHRoZSBgb25yZWplY3RlZGAgaGFuZGxlciB3aWxsIHN0aWxsIGJlIGludm9rZWQgd2l0aCB0aGUgcGFyZW50J3MgYENhbmNlbEVycm9yYCxcclxuICAgICAqICAgICBidXQgaXRzIHJlc3VsdCB3aWxsIGJlIGRpc2NhcmRlZFxyXG4gICAgICogICAgIGFuZCB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIHJlamVjdCB3aXRoIGEgYENhbmNlbEVycm9yYCBhcyB3ZWxsLlxyXG4gICAgICpcclxuICAgICAqIFRoZSBwcm9taXNlIHJldHVybmVkIGZyb20ge0BsaW5rIGNhbmNlbH0gd2lsbCBmdWxmaWxsIG9ubHkgYWZ0ZXIgYWxsIGF0dGFjaGVkIGhhbmRsZXJzXHJcbiAgICAgKiB1cCB0aGUgZW50aXJlIHByb21pc2UgY2hhaW4gaGF2ZSBiZWVuIHJ1bi5cclxuICAgICAqXHJcbiAgICAgKiBJZiBlaXRoZXIgY2FsbGJhY2sgcmV0dXJucyBhIGNhbmNlbGxhYmxlIHByb21pc2UsXHJcbiAgICAgKiBjYW5jZWxsYXRpb24gcmVxdWVzdHMgd2lsbCBiZSBkaXZlcnRlZCB0byBpdCxcclxuICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGBvbmNhbmNlbGxlZGAgY2FsbGJhY2sgd2lsbCBiZSBkaXNjYXJkZWQuXHJcbiAgICAgKi9cclxuICAgIHRoZW48VFJlc3VsdDEgPSBULCBUUmVzdWx0MiA9IG5ldmVyPihvbmZ1bGZpbGxlZD86ICgodmFsdWU6IFQpID0+IFRSZXN1bHQxIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDE+IHwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUUmVzdWx0MT4pIHwgdW5kZWZpbmVkIHwgbnVsbCwgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+IHwgQ2FuY2VsbGFibGVQcm9taXNlTGlrZTxUUmVzdWx0Mj4pIHwgdW5kZWZpbmVkIHwgbnVsbCwgb25jYW5jZWxsZWQ/OiBDYW5jZWxsYWJsZVByb21pc2VDYW5jZWxsZXIpOiBDYW5jZWxsYWJsZVByb21pc2U8VFJlc3VsdDEgfCBUUmVzdWx0Mj4ge1xyXG4gICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDYW5jZWxsYWJsZVByb21pc2UpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRoZW4gY2FsbGVkIG9uIGFuIGludmFsaWQgb2JqZWN0LlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE5PVEU6IFR5cGVTY3JpcHQncyBidWlsdC1pbiB0eXBlIGZvciB0aGVuIGlzIGJyb2tlbixcclxuICAgICAgICAvLyBhcyBpdCBhbGxvd3Mgc3BlY2lmeWluZyBhbiBhcmJpdHJhcnkgVFJlc3VsdDEgIT0gVCBldmVuIHdoZW4gb25mdWxmaWxsZWQgaXMgbm90IGEgZnVuY3Rpb24uXHJcbiAgICAgICAgLy8gV2UgY2Fubm90IGZpeCBpdCBpZiB3ZSB3YW50IHRvIENhbmNlbGxhYmxlUHJvbWlzZSB0byBpbXBsZW1lbnQgUHJvbWlzZUxpa2U8VD4uXHJcblxyXG4gICAgICAgIGlmICghaXNDYWxsYWJsZShvbmZ1bGZpbGxlZCkpIHsgb25mdWxmaWxsZWQgPSBpZGVudGl0eSBhcyBhbnk7IH1cclxuICAgICAgICBpZiAoIWlzQ2FsbGFibGUob25yZWplY3RlZCkpIHsgb25yZWplY3RlZCA9IHRocm93ZXI7IH1cclxuXHJcbiAgICAgICAgaWYgKG9uZnVsZmlsbGVkID09PSBpZGVudGl0eSAmJiBvbnJlamVjdGVkID09IHRocm93ZXIpIHtcclxuICAgICAgICAgICAgLy8gU2hvcnRjdXQgZm9yIHRyaXZpYWwgYXJndW1lbnRzLlxyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSkgPT4gcmVzb2x2ZSh0aGlzIGFzIGFueSkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYmFycmllcjogUGFydGlhbDxQcm9taXNlV2l0aFJlc29sdmVyczx2b2lkPj4gPSB7fTtcclxuICAgICAgICB0aGlzW2JhcnJpZXJTeW1dID0gYmFycmllcjtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2U8VFJlc3VsdDEgfCBUUmVzdWx0Mj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB2b2lkIHN1cGVyLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAodmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpc1tiYXJyaWVyU3ltXSA9PT0gYmFycmllcikgeyB0aGlzW2JhcnJpZXJTeW1dID0gbnVsbDsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJhcnJpZXIucmVzb2x2ZT8uKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob25mdWxmaWxsZWQhKHZhbHVlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAocmVhc29uPykgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2JhcnJpZXJTeW1dID09PSBiYXJyaWVyKSB7IHRoaXNbYmFycmllclN5bV0gPSBudWxsOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmFycmllci5yZXNvbHZlPy4oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShvbnJlamVjdGVkIShyZWFzb24pKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH0sIGFzeW5jIChjYXVzZT8pID0+IHtcclxuICAgICAgICAgICAgLy9jYW5jZWxsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9uY2FuY2VsbGVkPy4oY2F1c2UpO1xyXG4gICAgICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jYW5jZWwoY2F1c2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBdHRhY2hlcyBhIGNhbGxiYWNrIGZvciBvbmx5IHRoZSByZWplY3Rpb24gb2YgdGhlIFByb21pc2UuXHJcbiAgICAgKlxyXG4gICAgICogVGhlIG9wdGlvbmFsIGBvbmNhbmNlbGxlZGAgYXJndW1lbnQgd2lsbCBiZSBpbnZva2VkIHdoZW4gdGhlIHJldHVybmVkIHByb21pc2UgaXMgY2FuY2VsbGVkLFxyXG4gICAgICogd2l0aCB0aGUgc2FtZSBzZW1hbnRpY3MgYXMgdGhlIGBvbmNhbmNlbGxlZGAgYXJndW1lbnQgb2YgdGhlIGNvbnN0cnVjdG9yLlxyXG4gICAgICogV2hlbiB0aGUgcGFyZW50IHByb21pc2UgcmVqZWN0cyBvciBpcyBjYW5jZWxsZWQsIHRoZSBgb25yZWplY3RlZGAgY2FsbGJhY2sgd2lsbCBydW4sXHJcbiAgICAgKiBfZXZlbiBhZnRlciB0aGUgcmV0dXJuZWQgcHJvbWlzZSBoYXMgYmVlbiBjYW5jZWxsZWQ6X1xyXG4gICAgICogaW4gdGhhdCBjYXNlLCBzaG91bGQgaXQgcmVqZWN0IG9yIHRocm93LCB0aGUgcmVhc29uIHdpbGwgYmUgd3JhcHBlZFxyXG4gICAgICogaW4gYSB7QGxpbmsgQ2FuY2VsbGVkUmVqZWN0aW9uRXJyb3J9IGFuZCBidWJibGVkIHVwIGFzIGFuIHVuaGFuZGxlZCByZWplY3Rpb24uXHJcbiAgICAgKlxyXG4gICAgICogSXQgaXMgZXF1aXZhbGVudCB0b1xyXG4gICAgICogYGBgdHNcclxuICAgICAqIGNhbmNlbGxhYmxlUHJvbWlzZS50aGVuKHVuZGVmaW5lZCwgb25yZWplY3RlZCwgb25jYW5jZWxsZWQpO1xyXG4gICAgICogYGBgXHJcbiAgICAgKiBhbmQgdGhlIHNhbWUgY2F2ZWF0cyBhcHBseS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgZm9yIHRoZSBjb21wbGV0aW9uIG9mIHRoZSBjYWxsYmFjay5cclxuICAgICAqIENhbmNlbGxhdGlvbiByZXF1ZXN0cyBvbiB0aGUgcmV0dXJuZWQgcHJvbWlzZVxyXG4gICAgICogd2lsbCBwcm9wYWdhdGUgdXAgdGhlIGNoYWluIHRvIHRoZSBwYXJlbnQgcHJvbWlzZSxcclxuICAgICAqIGJ1dCBub3QgaW4gdGhlIG90aGVyIGRpcmVjdGlvbi5cclxuICAgICAqXHJcbiAgICAgKiBUaGUgcHJvbWlzZSByZXR1cm5lZCBmcm9tIHtAbGluayBjYW5jZWx9IHdpbGwgZnVsZmlsbCBvbmx5IGFmdGVyIGFsbCBhdHRhY2hlZCBoYW5kbGVyc1xyXG4gICAgICogdXAgdGhlIGVudGlyZSBwcm9taXNlIGNoYWluIGhhdmUgYmVlbiBydW4uXHJcbiAgICAgKlxyXG4gICAgICogSWYgYG9ucmVqZWN0ZWRgIHJldHVybnMgYSBjYW5jZWxsYWJsZSBwcm9taXNlLFxyXG4gICAgICogY2FuY2VsbGF0aW9uIHJlcXVlc3RzIHdpbGwgYmUgZGl2ZXJ0ZWQgdG8gaXQsXHJcbiAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBgb25jYW5jZWxsZWRgIGNhbGxiYWNrIHdpbGwgYmUgZGlzY2FyZGVkLlxyXG4gICAgICogU2VlIHtAbGluayB0aGVufSBmb3IgbW9yZSBkZXRhaWxzLlxyXG4gICAgICovXHJcbiAgICBjYXRjaDxUUmVzdWx0ID0gbmV2ZXI+KG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogYW55KSA9PiAoUHJvbWlzZUxpa2U8VFJlc3VsdD4gfCBUUmVzdWx0KSkgfCB1bmRlZmluZWQgfCBudWxsLCBvbmNhbmNlbGxlZD86IENhbmNlbGxhYmxlUHJvbWlzZUNhbmNlbGxlcik6IENhbmNlbGxhYmxlUHJvbWlzZTxUIHwgVFJlc3VsdD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBvbnJlamVjdGVkLCBvbmNhbmNlbGxlZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBdHRhY2hlcyBhIGNhbGxiYWNrIHRoYXQgaXMgaW52b2tlZCB3aGVuIHRoZSBDYW5jZWxsYWJsZVByb21pc2UgaXMgc2V0dGxlZCAoZnVsZmlsbGVkIG9yIHJlamVjdGVkKS4gVGhlXHJcbiAgICAgKiByZXNvbHZlZCB2YWx1ZSBjYW5ub3QgYmUgYWNjZXNzZWQgb3IgbW9kaWZpZWQgZnJvbSB0aGUgY2FsbGJhY2suXHJcbiAgICAgKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIHNldHRsZSBpbiB0aGUgc2FtZSBzdGF0ZSBhcyB0aGUgb3JpZ2luYWwgb25lXHJcbiAgICAgKiBhZnRlciB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgaGFzIGNvbXBsZXRlZCBleGVjdXRpb24sXHJcbiAgICAgKiB1bmxlc3MgdGhlIGNhbGxiYWNrIHRocm93cyBvciByZXR1cm5zIGEgcmVqZWN0aW5nIHByb21pc2UsXHJcbiAgICAgKiBpbiB3aGljaCBjYXNlIHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgcmVqZWN0IGFzIHdlbGwuXHJcbiAgICAgKlxyXG4gICAgICogVGhlIG9wdGlvbmFsIGBvbmNhbmNlbGxlZGAgYXJndW1lbnQgd2lsbCBiZSBpbnZva2VkIHdoZW4gdGhlIHJldHVybmVkIHByb21pc2UgaXMgY2FuY2VsbGVkLFxyXG4gICAgICogd2l0aCB0aGUgc2FtZSBzZW1hbnRpY3MgYXMgdGhlIGBvbmNhbmNlbGxlZGAgYXJndW1lbnQgb2YgdGhlIGNvbnN0cnVjdG9yLlxyXG4gICAgICogT25jZSB0aGUgcGFyZW50IHByb21pc2Ugc2V0dGxlcywgdGhlIGBvbmZpbmFsbHlgIGNhbGxiYWNrIHdpbGwgcnVuLFxyXG4gICAgICogX2V2ZW4gYWZ0ZXIgdGhlIHJldHVybmVkIHByb21pc2UgaGFzIGJlZW4gY2FuY2VsbGVkOl9cclxuICAgICAqIGluIHRoYXQgY2FzZSwgc2hvdWxkIGl0IHJlamVjdCBvciB0aHJvdywgdGhlIHJlYXNvbiB3aWxsIGJlIHdyYXBwZWRcclxuICAgICAqIGluIGEge0BsaW5rIENhbmNlbGxlZFJlamVjdGlvbkVycm9yfSBhbmQgYnViYmxlZCB1cCBhcyBhbiB1bmhhbmRsZWQgcmVqZWN0aW9uLlxyXG4gICAgICpcclxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGltcGxlbWVudGVkIGluIHRlcm1zIG9mIHtAbGluayB0aGVufSBhbmQgdGhlIHNhbWUgY2F2ZWF0cyBhcHBseS5cclxuICAgICAqIEl0IGlzIHBvbHlmaWxsZWQsIGhlbmNlIGF2YWlsYWJsZSBpbiBldmVyeSBPUy93ZWJ2aWV3IHZlcnNpb24uXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlIGZvciB0aGUgY29tcGxldGlvbiBvZiB0aGUgY2FsbGJhY2suXHJcbiAgICAgKiBDYW5jZWxsYXRpb24gcmVxdWVzdHMgb24gdGhlIHJldHVybmVkIHByb21pc2VcclxuICAgICAqIHdpbGwgcHJvcGFnYXRlIHVwIHRoZSBjaGFpbiB0byB0aGUgcGFyZW50IHByb21pc2UsXHJcbiAgICAgKiBidXQgbm90IGluIHRoZSBvdGhlciBkaXJlY3Rpb24uXHJcbiAgICAgKlxyXG4gICAgICogVGhlIHByb21pc2UgcmV0dXJuZWQgZnJvbSB7QGxpbmsgY2FuY2VsfSB3aWxsIGZ1bGZpbGwgb25seSBhZnRlciBhbGwgYXR0YWNoZWQgaGFuZGxlcnNcclxuICAgICAqIHVwIHRoZSBlbnRpcmUgcHJvbWlzZSBjaGFpbiBoYXZlIGJlZW4gcnVuLlxyXG4gICAgICpcclxuICAgICAqIElmIGBvbmZpbmFsbHlgIHJldHVybnMgYSBjYW5jZWxsYWJsZSBwcm9taXNlLFxyXG4gICAgICogY2FuY2VsbGF0aW9uIHJlcXVlc3RzIHdpbGwgYmUgZGl2ZXJ0ZWQgdG8gaXQsXHJcbiAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBgb25jYW5jZWxsZWRgIGNhbGxiYWNrIHdpbGwgYmUgZGlzY2FyZGVkLlxyXG4gICAgICogU2VlIHtAbGluayB0aGVufSBmb3IgbW9yZSBkZXRhaWxzLlxyXG4gICAgICovXHJcbiAgICBmaW5hbGx5KG9uZmluYWxseT86ICgoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCB8IG51bGwsIG9uY2FuY2VsbGVkPzogQ2FuY2VsbGFibGVQcm9taXNlQ2FuY2VsbGVyKTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+IHtcclxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2FuY2VsbGFibGVQcm9taXNlKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5maW5hbGx5IGNhbGxlZCBvbiBhbiBpbnZhbGlkIG9iamVjdC5cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWlzQ2FsbGFibGUob25maW5hbGx5KSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50aGVuKG9uZmluYWxseSwgb25maW5hbGx5LCBvbmNhbmNlbGxlZCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy50aGVuKFxyXG4gICAgICAgICAgICAodmFsdWUpID0+IENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKG9uZmluYWxseSgpKS50aGVuKCgpID0+IHZhbHVlKSxcclxuICAgICAgICAgICAgKHJlYXNvbj8pID0+IENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKG9uZmluYWxseSgpKS50aGVuKCgpID0+IHsgdGhyb3cgcmVhc29uOyB9KSxcclxuICAgICAgICAgICAgb25jYW5jZWxsZWQsXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdlIHVzZSB0aGUgYFtTeW1ib2wuc3BlY2llc11gIHN0YXRpYyBwcm9wZXJ0eSwgaWYgYXZhaWxhYmxlLFxyXG4gICAgICogdG8gZGlzYWJsZSB0aGUgYnVpbHQtaW4gYXV0b21hdGljIHN1YmNsYXNzaW5nIGZlYXR1cmVzIGZyb20ge0BsaW5rIFByb21pc2V9LlxyXG4gICAgICogSXQgaXMgY3JpdGljYWwgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgdGhhdCBleHRlbmRlcnMgZG8gbm90IG92ZXJyaWRlIHRoaXMuXHJcbiAgICAgKiBPbmNlIHRoZSBwcm9wb3NhbCBhdCBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1ybS1idWlsdGluLXN1YmNsYXNzaW5nXHJcbiAgICAgKiBpcyBlaXRoZXIgYWNjZXB0ZWQgb3IgcmV0aXJlZCwgdGhpcyBpbXBsZW1lbnRhdGlvbiB3aWxsIGhhdmUgdG8gYmUgcmV2aXNlZCBhY2NvcmRpbmdseS5cclxuICAgICAqXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgc3RhdGljIGdldCBbc3BlY2llc10oKSB7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgQ2FuY2VsbGFibGVQcm9taXNlIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCBhbiBhcnJheSBvZiByZXN1bHRzXHJcbiAgICAgKiB3aGVuIGFsbCBvZiB0aGUgcHJvdmlkZWQgUHJvbWlzZXMgcmVzb2x2ZSwgb3IgcmVqZWN0ZWQgd2hlbiBhbnkgUHJvbWlzZSBpcyByZWplY3RlZC5cclxuICAgICAqXHJcbiAgICAgKiBFdmVyeSBvbmUgb2YgdGhlIHByb3ZpZGVkIG9iamVjdHMgdGhhdCBpcyBhIHRoZW5hYmxlIF9hbmRfIGNhbmNlbGxhYmxlIG9iamVjdFxyXG4gICAgICogd2lsbCBiZSBjYW5jZWxsZWQgd2hlbiB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBjYW5jZWxsZWQsIHdpdGggdGhlIHNhbWUgY2F1c2UuXHJcbiAgICAgKlxyXG4gICAgICogQGdyb3VwIFN0YXRpYyBNZXRob2RzXHJcbiAgICAgKi9cclxuICAgIHN0YXRpYyBhbGw8VD4odmFsdWVzOiBJdGVyYWJsZTxUIHwgUHJvbWlzZUxpa2U8VD4+KTogQ2FuY2VsbGFibGVQcm9taXNlPEF3YWl0ZWQ8VD5bXT47XHJcbiAgICBzdGF0aWMgYWxsPFQgZXh0ZW5kcyByZWFkb25seSB1bmtub3duW10gfCBbXT4odmFsdWVzOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPHsgLXJlYWRvbmx5IFtQIGluIGtleW9mIFRdOiBBd2FpdGVkPFRbUF0+OyB9PjtcclxuICAgIHN0YXRpYyBhbGw8VCBleHRlbmRzIEl0ZXJhYmxlPHVua25vd24+IHwgQXJyYXlMaWtlPHVua25vd24+Pih2YWx1ZXM6IFQpOiBDYW5jZWxsYWJsZVByb21pc2U8dW5rbm93bj4ge1xyXG4gICAgICAgIGxldCBjb2xsZWN0ZWQgPSBBcnJheS5mcm9tKHZhbHVlcyk7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IGNvbGxlY3RlZC5sZW5ndGggPT09IDBcclxuICAgICAgICAgICAgPyBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZShjb2xsZWN0ZWQpXHJcbiAgICAgICAgICAgIDogbmV3IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB2b2lkIFByb21pc2UuYWxsKGNvbGxlY3RlZCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xyXG4gICAgICAgICAgICB9LCAoY2F1c2U/KTogUHJvbWlzZTx2b2lkPiA9PiBjYW5jZWxBbGwocHJvbWlzZSwgY29sbGVjdGVkLCBjYXVzZSkpO1xyXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIENhbmNlbGxhYmxlUHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdpdGggYW4gYXJyYXkgb2YgcmVzdWx0c1xyXG4gICAgICogd2hlbiBhbGwgb2YgdGhlIHByb3ZpZGVkIFByb21pc2VzIHJlc29sdmUgb3IgcmVqZWN0LlxyXG4gICAgICpcclxuICAgICAqIEV2ZXJ5IG9uZSBvZiB0aGUgcHJvdmlkZWQgb2JqZWN0cyB0aGF0IGlzIGEgdGhlbmFibGUgX2FuZF8gY2FuY2VsbGFibGUgb2JqZWN0XHJcbiAgICAgKiB3aWxsIGJlIGNhbmNlbGxlZCB3aGVuIHRoZSByZXR1cm5lZCBwcm9taXNlIGlzIGNhbmNlbGxlZCwgd2l0aCB0aGUgc2FtZSBjYXVzZS5cclxuICAgICAqXHJcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcclxuICAgICAqL1xyXG4gICAgc3RhdGljIGFsbFNldHRsZWQ8VD4odmFsdWVzOiBJdGVyYWJsZTxUIHwgUHJvbWlzZUxpa2U8VD4+KTogQ2FuY2VsbGFibGVQcm9taXNlPFByb21pc2VTZXR0bGVkUmVzdWx0PEF3YWl0ZWQ8VD4+W10+O1xyXG4gICAgc3RhdGljIGFsbFNldHRsZWQ8VCBleHRlbmRzIHJlYWRvbmx5IHVua25vd25bXSB8IFtdPih2YWx1ZXM6IFQpOiBDYW5jZWxsYWJsZVByb21pc2U8eyAtcmVhZG9ubHkgW1AgaW4ga2V5b2YgVF06IFByb21pc2VTZXR0bGVkUmVzdWx0PEF3YWl0ZWQ8VFtQXT4+OyB9PjtcclxuICAgIHN0YXRpYyBhbGxTZXR0bGVkPFQgZXh0ZW5kcyBJdGVyYWJsZTx1bmtub3duPiB8IEFycmF5TGlrZTx1bmtub3duPj4odmFsdWVzOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPHVua25vd24+IHtcclxuICAgICAgICBsZXQgY29sbGVjdGVkID0gQXJyYXkuZnJvbSh2YWx1ZXMpO1xyXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBjb2xsZWN0ZWQubGVuZ3RoID09PSAwXHJcbiAgICAgICAgICAgID8gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoY29sbGVjdGVkKVxyXG4gICAgICAgICAgICA6IG5ldyBDYW5jZWxsYWJsZVByb21pc2U8dW5rbm93bj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdm9pZCBQcm9taXNlLmFsbFNldHRsZWQoY29sbGVjdGVkKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XHJcbiAgICAgICAgICAgIH0sIChjYXVzZT8pOiBQcm9taXNlPHZvaWQ+ID0+IGNhbmNlbEFsbChwcm9taXNlLCBjb2xsZWN0ZWQsIGNhdXNlKSk7XHJcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYW55IGZ1bmN0aW9uIHJldHVybnMgYSBwcm9taXNlIHRoYXQgaXMgZnVsZmlsbGVkIGJ5IHRoZSBmaXJzdCBnaXZlbiBwcm9taXNlIHRvIGJlIGZ1bGZpbGxlZCxcclxuICAgICAqIG9yIHJlamVjdGVkIHdpdGggYW4gQWdncmVnYXRlRXJyb3IgY29udGFpbmluZyBhbiBhcnJheSBvZiByZWplY3Rpb24gcmVhc29uc1xyXG4gICAgICogaWYgYWxsIG9mIHRoZSBnaXZlbiBwcm9taXNlcyBhcmUgcmVqZWN0ZWQuXHJcbiAgICAgKiBJdCByZXNvbHZlcyBhbGwgZWxlbWVudHMgb2YgdGhlIHBhc3NlZCBpdGVyYWJsZSB0byBwcm9taXNlcyBhcyBpdCBydW5zIHRoaXMgYWxnb3JpdGhtLlxyXG4gICAgICpcclxuICAgICAqIEV2ZXJ5IG9uZSBvZiB0aGUgcHJvdmlkZWQgb2JqZWN0cyB0aGF0IGlzIGEgdGhlbmFibGUgX2FuZF8gY2FuY2VsbGFibGUgb2JqZWN0XHJcbiAgICAgKiB3aWxsIGJlIGNhbmNlbGxlZCB3aGVuIHRoZSByZXR1cm5lZCBwcm9taXNlIGlzIGNhbmNlbGxlZCwgd2l0aCB0aGUgc2FtZSBjYXVzZS5cclxuICAgICAqXHJcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcclxuICAgICAqL1xyXG4gICAgc3RhdGljIGFueTxUPih2YWx1ZXM6IEl0ZXJhYmxlPFQgfCBQcm9taXNlTGlrZTxUPj4pOiBDYW5jZWxsYWJsZVByb21pc2U8QXdhaXRlZDxUPj47XHJcbiAgICBzdGF0aWMgYW55PFQgZXh0ZW5kcyByZWFkb25seSB1bmtub3duW10gfCBbXT4odmFsdWVzOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPEF3YWl0ZWQ8VFtudW1iZXJdPj47XHJcbiAgICBzdGF0aWMgYW55PFQgZXh0ZW5kcyBJdGVyYWJsZTx1bmtub3duPiB8IEFycmF5TGlrZTx1bmtub3duPj4odmFsdWVzOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPHVua25vd24+IHtcclxuICAgICAgICBsZXQgY29sbGVjdGVkID0gQXJyYXkuZnJvbSh2YWx1ZXMpO1xyXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBjb2xsZWN0ZWQubGVuZ3RoID09PSAwXHJcbiAgICAgICAgICAgID8gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoY29sbGVjdGVkKVxyXG4gICAgICAgICAgICA6IG5ldyBDYW5jZWxsYWJsZVByb21pc2U8dW5rbm93bj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdm9pZCBQcm9taXNlLmFueShjb2xsZWN0ZWQpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcclxuICAgICAgICAgICAgfSwgKGNhdXNlPyk6IFByb21pc2U8dm9pZD4gPT4gY2FuY2VsQWxsKHByb21pc2UsIGNvbGxlY3RlZCwgY2F1c2UpKTtcclxuICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBQcm9taXNlIHRoYXQgaXMgcmVzb2x2ZWQgb3IgcmVqZWN0ZWQgd2hlbiBhbnkgb2YgdGhlIHByb3ZpZGVkIFByb21pc2VzIGFyZSByZXNvbHZlZCBvciByZWplY3RlZC5cclxuICAgICAqXHJcbiAgICAgKiBFdmVyeSBvbmUgb2YgdGhlIHByb3ZpZGVkIG9iamVjdHMgdGhhdCBpcyBhIHRoZW5hYmxlIF9hbmRfIGNhbmNlbGxhYmxlIG9iamVjdFxyXG4gICAgICogd2lsbCBiZSBjYW5jZWxsZWQgd2hlbiB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBjYW5jZWxsZWQsIHdpdGggdGhlIHNhbWUgY2F1c2UuXHJcbiAgICAgKlxyXG4gICAgICogQGdyb3VwIFN0YXRpYyBNZXRob2RzXHJcbiAgICAgKi9cclxuICAgIHN0YXRpYyByYWNlPFQ+KHZhbHVlczogSXRlcmFibGU8VCB8IFByb21pc2VMaWtlPFQ+Pik6IENhbmNlbGxhYmxlUHJvbWlzZTxBd2FpdGVkPFQ+PjtcclxuICAgIHN0YXRpYyByYWNlPFQgZXh0ZW5kcyByZWFkb25seSB1bmtub3duW10gfCBbXT4odmFsdWVzOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPEF3YWl0ZWQ8VFtudW1iZXJdPj47XHJcbiAgICBzdGF0aWMgcmFjZTxUIGV4dGVuZHMgSXRlcmFibGU8dW5rbm93bj4gfCBBcnJheUxpa2U8dW5rbm93bj4+KHZhbHVlczogVCk6IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPiB7XHJcbiAgICAgICAgbGV0IGNvbGxlY3RlZCA9IEFycmF5LmZyb20odmFsdWVzKTtcclxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTx1bmtub3duPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIHZvaWQgUHJvbWlzZS5yYWNlKGNvbGxlY3RlZCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xyXG4gICAgICAgIH0sIChjYXVzZT8pOiBQcm9taXNlPHZvaWQ+ID0+IGNhbmNlbEFsbChwcm9taXNlLCBjb2xsZWN0ZWQsIGNhdXNlKSk7XHJcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGNhbmNlbGxlZCBDYW5jZWxsYWJsZVByb21pc2UgZm9yIHRoZSBwcm92aWRlZCBjYXVzZS5cclxuICAgICAqXHJcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcclxuICAgICAqL1xyXG4gICAgc3RhdGljIGNhbmNlbDxUID0gbmV2ZXI+KGNhdXNlPzogYW55KTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+IHtcclxuICAgICAgICBjb25zdCBwID0gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTxUPigoKSA9PiB7fSk7XHJcbiAgICAgICAgcC5jYW5jZWwoY2F1c2UpO1xyXG4gICAgICAgIHJldHVybiBwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIG5ldyBDYW5jZWxsYWJsZVByb21pc2UgdGhhdCBjYW5jZWxzXHJcbiAgICAgKiBhZnRlciB0aGUgc3BlY2lmaWVkIHRpbWVvdXQsIHdpdGggdGhlIHByb3ZpZGVkIGNhdXNlLlxyXG4gICAgICpcclxuICAgICAqIElmIHRoZSB7QGxpbmsgQWJvcnRTaWduYWwudGltZW91dH0gZmFjdG9yeSBtZXRob2QgaXMgYXZhaWxhYmxlLFxyXG4gICAgICogaXQgaXMgdXNlZCB0byBiYXNlIHRoZSB0aW1lb3V0IG9uIF9hY3RpdmVfIHRpbWUgcmF0aGVyIHRoYW4gX2VsYXBzZWRfIHRpbWUuXHJcbiAgICAgKiBPdGhlcndpc2UsIGB0aW1lb3V0YCBmYWxscyBiYWNrIHRvIHtAbGluayBzZXRUaW1lb3V0fS5cclxuICAgICAqXHJcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcclxuICAgICAqL1xyXG4gICAgc3RhdGljIHRpbWVvdXQ8VCA9IG5ldmVyPihtaWxsaXNlY29uZHM6IG51bWJlciwgY2F1c2U/OiBhbnkpOiBDYW5jZWxsYWJsZVByb21pc2U8VD4ge1xyXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPFQ+KCgpID0+IHt9KTtcclxuICAgICAgICBpZiAoQWJvcnRTaWduYWwgJiYgdHlwZW9mIEFib3J0U2lnbmFsID09PSAnZnVuY3Rpb24nICYmIEFib3J0U2lnbmFsLnRpbWVvdXQgJiYgdHlwZW9mIEFib3J0U2lnbmFsLnRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgQWJvcnRTaWduYWwudGltZW91dChtaWxsaXNlY29uZHMpLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgKCkgPT4gdm9pZCBwcm9taXNlLmNhbmNlbChjYXVzZSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdm9pZCBwcm9taXNlLmNhbmNlbChjYXVzZSksIG1pbGxpc2Vjb25kcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIG5ldyBDYW5jZWxsYWJsZVByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgc3BlY2lmaWVkIHRpbWVvdXQuXHJcbiAgICAgKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSBjYW4gYmUgY2FuY2VsbGVkIHdpdGhvdXQgY29uc2VxdWVuY2VzLlxyXG4gICAgICpcclxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xyXG4gICAgICovXHJcbiAgICBzdGF0aWMgc2xlZXAobWlsbGlzZWNvbmRzOiBudW1iZXIpOiBDYW5jZWxsYWJsZVByb21pc2U8dm9pZD47XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXJcclxuICAgICAqIHRoZSBzcGVjaWZpZWQgdGltZW91dCwgd2l0aCB0aGUgcHJvdmlkZWQgdmFsdWUuXHJcbiAgICAgKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSBjYW4gYmUgY2FuY2VsbGVkIHdpdGhvdXQgY29uc2VxdWVuY2VzLlxyXG4gICAgICpcclxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xyXG4gICAgICovXHJcbiAgICBzdGF0aWMgc2xlZXA8VD4obWlsbGlzZWNvbmRzOiBudW1iZXIsIHZhbHVlOiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+O1xyXG4gICAgc3RhdGljIHNsZWVwPFQgPSB2b2lkPihtaWxsaXNlY29uZHM6IG51bWJlciwgdmFsdWU/OiBUKTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+IHtcclxuICAgICAgICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTxUPigocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUodmFsdWUhKSwgbWlsbGlzZWNvbmRzKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgcmVqZWN0ZWQgQ2FuY2VsbGFibGVQcm9taXNlIGZvciB0aGUgcHJvdmlkZWQgcmVhc29uLlxyXG4gICAgICpcclxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xyXG4gICAgICovXHJcbiAgICBzdGF0aWMgcmVqZWN0PFQgPSBuZXZlcj4ocmVhc29uPzogYW55KTogQ2FuY2VsbGFibGVQcm9taXNlPFQ+IHtcclxuICAgICAgICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTxUPigoXywgcmVqZWN0KSA9PiByZWplY3QocmVhc29uKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHJlc29sdmVkIENhbmNlbGxhYmxlUHJvbWlzZS5cclxuICAgICAqXHJcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcclxuICAgICAqL1xyXG4gICAgc3RhdGljIHJlc29sdmUoKTogQ2FuY2VsbGFibGVQcm9taXNlPHZvaWQ+O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHJlc29sdmVkIENhbmNlbGxhYmxlUHJvbWlzZSBmb3IgdGhlIHByb3ZpZGVkIHZhbHVlLlxyXG4gICAgICpcclxuICAgICAqIEBncm91cCBTdGF0aWMgTWV0aG9kc1xyXG4gICAgICovXHJcbiAgICBzdGF0aWMgcmVzb2x2ZTxUPih2YWx1ZTogVCk6IENhbmNlbGxhYmxlUHJvbWlzZTxBd2FpdGVkPFQ+PjtcclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIG5ldyByZXNvbHZlZCBDYW5jZWxsYWJsZVByb21pc2UgZm9yIHRoZSBwcm92aWRlZCB2YWx1ZS5cclxuICAgICAqXHJcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcclxuICAgICAqL1xyXG4gICAgc3RhdGljIHJlc29sdmU8VD4odmFsdWU6IFQgfCBQcm9taXNlTGlrZTxUPik6IENhbmNlbGxhYmxlUHJvbWlzZTxBd2FpdGVkPFQ+PjtcclxuICAgIHN0YXRpYyByZXNvbHZlPFQgPSB2b2lkPih2YWx1ZT86IFQgfCBQcm9taXNlTGlrZTxUPik6IENhbmNlbGxhYmxlUHJvbWlzZTxBd2FpdGVkPFQ+PiB7XHJcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQ2FuY2VsbGFibGVQcm9taXNlKSB7XHJcbiAgICAgICAgICAgIC8vIE9wdGltaXNlIGZvciBjYW5jZWxsYWJsZSBwcm9taXNlcy5cclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZTxhbnk+KChyZXNvbHZlKSA9PiByZXNvbHZlKHZhbHVlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IENhbmNlbGxhYmxlUHJvbWlzZSBhbmQgcmV0dXJucyBpdCBpbiBhbiBvYmplY3QsIGFsb25nIHdpdGggaXRzIHJlc29sdmUgYW5kIHJlamVjdCBmdW5jdGlvbnNcclxuICAgICAqIGFuZCBhIGdldHRlci9zZXR0ZXIgZm9yIHRoZSBjYW5jZWxsYXRpb24gY2FsbGJhY2suXHJcbiAgICAgKlxyXG4gICAgICogVGhpcyBtZXRob2QgaXMgcG9seWZpbGxlZCwgaGVuY2UgYXZhaWxhYmxlIGluIGV2ZXJ5IE9TL3dlYnZpZXcgdmVyc2lvbi5cclxuICAgICAqXHJcbiAgICAgKiBAZ3JvdXAgU3RhdGljIE1ldGhvZHNcclxuICAgICAqL1xyXG4gICAgc3RhdGljIHdpdGhSZXNvbHZlcnM8VD4oKTogQ2FuY2VsbGFibGVQcm9taXNlV2l0aFJlc29sdmVyczxUPiB7XHJcbiAgICAgICAgbGV0IHJlc3VsdDogQ2FuY2VsbGFibGVQcm9taXNlV2l0aFJlc29sdmVyczxUPiA9IHsgb25jYW5jZWxsZWQ6IG51bGwgfSBhcyBhbnk7XHJcbiAgICAgICAgcmVzdWx0LnByb21pc2UgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgcmVzdWx0LnJlc29sdmUgPSByZXNvbHZlO1xyXG4gICAgICAgICAgICByZXN1bHQucmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0sIChjYXVzZT86IGFueSkgPT4geyByZXN1bHQub25jYW5jZWxsZWQ/LihjYXVzZSk7IH0pO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgY2FsbGJhY2sgdGhhdCBpbXBsZW1lbnRzIHRoZSBjYW5jZWxsYXRpb24gYWxnb3JpdGhtIGZvciB0aGUgZ2l2ZW4gY2FuY2VsbGFibGUgcHJvbWlzZS5cclxuICogVGhlIHByb21pc2UgcmV0dXJuZWQgZnJvbSB0aGUgcmVzdWx0aW5nIGZ1bmN0aW9uIGRvZXMgbm90IHJlamVjdC5cclxuICovXHJcbmZ1bmN0aW9uIGNhbmNlbGxlckZvcjxUPihwcm9taXNlOiBDYW5jZWxsYWJsZVByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+LCBzdGF0ZTogQ2FuY2VsbGFibGVQcm9taXNlU3RhdGUpIHtcclxuICAgIGxldCBjYW5jZWxsYXRpb25Qcm9taXNlOiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD4gPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgcmV0dXJuIChyZWFzb246IENhbmNlbEVycm9yKTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+ID0+IHtcclxuICAgICAgICBpZiAoIXN0YXRlLnNldHRsZWQpIHtcclxuICAgICAgICAgICAgc3RhdGUuc2V0dGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHN0YXRlLnJlYXNvbiA9IHJlYXNvbjtcclxuICAgICAgICAgICAgcHJvbWlzZS5yZWplY3QocmVhc29uKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEF0dGFjaCBhbiBlcnJvciBoYW5kbGVyIHRoYXQgaWdub3JlcyB0aGlzIHNwZWNpZmljIHJlamVjdGlvbiByZWFzb24gYW5kIG5vdGhpbmcgZWxzZS5cclxuICAgICAgICAgICAgLy8gSW4gdGhlb3J5LCBhIHNhbmUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiBhdCB0aGlzIHBvaW50XHJcbiAgICAgICAgICAgIC8vIHNob3VsZCBhbHdheXMgcmVqZWN0IHdpdGggb3VyIGNhbmNlbGxhdGlvbiByZWFzb24sXHJcbiAgICAgICAgICAgIC8vIGhlbmNlIHRoZSBoYW5kbGVyIHdpbGwgbmV2ZXIgdGhyb3cuXHJcbiAgICAgICAgICAgIHZvaWQgUHJvbWlzZS5wcm90b3R5cGUudGhlbi5jYWxsKHByb21pc2UucHJvbWlzZSwgdW5kZWZpbmVkLCAoZXJyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyICE9PSByZWFzb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgcmVhc29uIGlzIG5vdCBzZXQsIHRoZSBwcm9taXNlIHJlc29sdmVkIHJlZ3VsYXJseSwgaGVuY2Ugd2UgbXVzdCBub3QgY2FsbCBvbmNhbmNlbGxlZC5cclxuICAgICAgICAvLyBJZiBvbmNhbmNlbGxlZCBpcyB1bnNldCwgbm8gbmVlZCB0byBnbyBhbnkgZnVydGhlci5cclxuICAgICAgICBpZiAoIXN0YXRlLnJlYXNvbiB8fCAhcHJvbWlzZS5vbmNhbmNlbGxlZCkgeyByZXR1cm47IH1cclxuXHJcbiAgICAgICAgY2FuY2VsbGF0aW9uUHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKHByb21pc2Uub25jYW5jZWxsZWQhKHN0YXRlLnJlYXNvbiEuY2F1c2UpKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGVkUmVqZWN0aW9uRXJyb3IocHJvbWlzZS5wcm9taXNlLCBlcnIsIFwiVW5oYW5kbGVkIGV4Y2VwdGlvbiBpbiBvbmNhbmNlbGxlZCBjYWxsYmFjay5cIikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSkuY2F0Y2goKHJlYXNvbj8pID0+IHtcclxuICAgICAgICAgICAgUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxlZFJlamVjdGlvbkVycm9yKHByb21pc2UucHJvbWlzZSwgcmVhc29uLCBcIlVuaGFuZGxlZCByZWplY3Rpb24gaW4gb25jYW5jZWxsZWQgY2FsbGJhY2suXCIpKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gVW5zZXQgb25jYW5jZWxsZWQgdG8gcHJldmVudCByZXBlYXRlZCBjYWxscy5cclxuICAgICAgICBwcm9taXNlLm9uY2FuY2VsbGVkID0gbnVsbDtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNhbmNlbGxhdGlvblByb21pc2U7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgY2FsbGJhY2sgdGhhdCBpbXBsZW1lbnRzIHRoZSByZXNvbHV0aW9uIGFsZ29yaXRobSBmb3IgdGhlIGdpdmVuIGNhbmNlbGxhYmxlIHByb21pc2UuXHJcbiAqL1xyXG5mdW5jdGlvbiByZXNvbHZlckZvcjxUPihwcm9taXNlOiBDYW5jZWxsYWJsZVByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+LCBzdGF0ZTogQ2FuY2VsbGFibGVQcm9taXNlU3RhdGUpOiBDYW5jZWxsYWJsZVByb21pc2VSZXNvbHZlcjxUPiB7XHJcbiAgICByZXR1cm4gKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgaWYgKHN0YXRlLnJlc29sdmluZykgeyByZXR1cm47IH1cclxuICAgICAgICBzdGF0ZS5yZXNvbHZpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICBpZiAodmFsdWUgPT09IHByb21pc2UucHJvbWlzZSkge1xyXG4gICAgICAgICAgICBpZiAoc3RhdGUuc2V0dGxlZCkgeyByZXR1cm47IH1cclxuICAgICAgICAgICAgc3RhdGUuc2V0dGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHByb21pc2UucmVqZWN0KG5ldyBUeXBlRXJyb3IoXCJBIHByb21pc2UgY2Fubm90IGJlIHJlc29sdmVkIHdpdGggaXRzZWxmLlwiKSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykpIHtcclxuICAgICAgICAgICAgbGV0IHRoZW46IGFueTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHRoZW4gPSAodmFsdWUgYXMgYW55KS50aGVuO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgIHN0YXRlLnNldHRsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZS5yZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGlzQ2FsbGFibGUodGhlbikpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNhbmNlbCA9ICh2YWx1ZSBhcyBhbnkpLmNhbmNlbDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNDYWxsYWJsZShjYW5jZWwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9uY2FuY2VsbGVkID0gKGNhdXNlPzogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWZsZWN0LmFwcGx5KGNhbmNlbCwgdmFsdWUsIFtjYXVzZV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVhc29uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBhbHJlYWR5IGNhbmNlbGxlZCwgcHJvcGFnYXRlIGNhbmNlbGxhdGlvbi5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBwcm9taXNlIHJldHVybmVkIGZyb20gdGhlIGNhbmNlbGxlciBhbGdvcml0aG0gZG9lcyBub3QgcmVqZWN0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyBpdCBjYW4gYmUgZGlzY2FyZGVkIHNhZmVseS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgY2FuY2VsbGVyRm9yKHsgLi4ucHJvbWlzZSwgb25jYW5jZWxsZWQgfSwgc3RhdGUpKHN0YXRlLnJlYXNvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlLm9uY2FuY2VsbGVkID0gb25jYW5jZWxsZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIHt9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U3RhdGU6IENhbmNlbGxhYmxlUHJvbWlzZVN0YXRlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJvb3Q6IHN0YXRlLnJvb3QsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2aW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICBnZXQgc2V0dGxlZCgpIHsgcmV0dXJuIHRoaXMucm9vdC5zZXR0bGVkIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0IHNldHRsZWQodmFsdWUpIHsgdGhpcy5yb290LnNldHRsZWQgPSB2YWx1ZTsgfSxcclxuICAgICAgICAgICAgICAgICAgICBnZXQgcmVhc29uKCkgeyByZXR1cm4gdGhpcy5yb290LnJlYXNvbiB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlamVjdG9yID0gcmVqZWN0b3JGb3IocHJvbWlzZSwgbmV3U3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBSZWZsZWN0LmFwcGx5KHRoZW4sIHZhbHVlLCBbcmVzb2x2ZXJGb3IocHJvbWlzZSwgbmV3U3RhdGUpLCByZWplY3Rvcl0pO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0b3IoZXJyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybjsgLy8gSU1QT1JUQU5UIVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUuc2V0dGxlZCkgeyByZXR1cm47IH1cclxuICAgICAgICBzdGF0ZS5zZXR0bGVkID0gdHJ1ZTtcclxuICAgICAgICBwcm9taXNlLnJlc29sdmUodmFsdWUpO1xyXG4gICAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBjYWxsYmFjayB0aGF0IGltcGxlbWVudHMgdGhlIHJlamVjdGlvbiBhbGdvcml0aG0gZm9yIHRoZSBnaXZlbiBjYW5jZWxsYWJsZSBwcm9taXNlLlxyXG4gKi9cclxuZnVuY3Rpb24gcmVqZWN0b3JGb3I8VD4ocHJvbWlzZTogQ2FuY2VsbGFibGVQcm9taXNlV2l0aFJlc29sdmVyczxUPiwgc3RhdGU6IENhbmNlbGxhYmxlUHJvbWlzZVN0YXRlKTogQ2FuY2VsbGFibGVQcm9taXNlUmVqZWN0b3Ige1xyXG4gICAgcmV0dXJuIChyZWFzb24/KSA9PiB7XHJcbiAgICAgICAgaWYgKHN0YXRlLnJlc29sdmluZykgeyByZXR1cm47IH1cclxuICAgICAgICBzdGF0ZS5yZXNvbHZpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICBpZiAoc3RhdGUuc2V0dGxlZCkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlYXNvbiBpbnN0YW5jZW9mIENhbmNlbEVycm9yICYmIHN0YXRlLnJlYXNvbiBpbnN0YW5jZW9mIENhbmNlbEVycm9yICYmIE9iamVjdC5pcyhyZWFzb24uY2F1c2UsIHN0YXRlLnJlYXNvbi5jYXVzZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBTd2FsbG93IGxhdGUgcmVqZWN0aW9ucyB0aGF0IGFyZSBDYW5jZWxFcnJvcnMgd2hvc2UgY2FuY2VsbGF0aW9uIGNhdXNlIGlzIHRoZSBzYW1lIGFzIG91cnMuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGNhdGNoIHt9XHJcblxyXG4gICAgICAgICAgICB2b2lkIFByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsZWRSZWplY3Rpb25FcnJvcihwcm9taXNlLnByb21pc2UsIHJlYXNvbikpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnNldHRsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlLnJlamVjdChyZWFzb24pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENhbmNlbHMgYWxsIHZhbHVlcyBpbiBhbiBhcnJheSB0aGF0IGxvb2sgbGlrZSBjYW5jZWxsYWJsZSB0aGVuYWJsZXMuXHJcbiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgb25jZSBhbGwgY2FuY2VsbGF0aW9uIHByb2NlZHVyZXMgZm9yIHRoZSBnaXZlbiB2YWx1ZXMgaGF2ZSBzZXR0bGVkLlxyXG4gKi9cclxuZnVuY3Rpb24gY2FuY2VsQWxsKHBhcmVudDogQ2FuY2VsbGFibGVQcm9taXNlPHVua25vd24+LCB2YWx1ZXM6IGFueVtdLCBjYXVzZT86IGFueSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgY29uc3QgcmVzdWx0cyA9IFtdO1xyXG5cclxuICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdmFsdWVzKSB7XHJcbiAgICAgICAgbGV0IGNhbmNlbDogQ2FuY2VsbGFibGVQcm9taXNlQ2FuY2VsbGVyO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZSh2YWx1ZS50aGVuKSkgeyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICBjYW5jZWwgPSB2YWx1ZS5jYW5jZWw7XHJcbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYW5jZWwpKSB7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgfSBjYXRjaCB7IGNvbnRpbnVlOyB9XHJcblxyXG4gICAgICAgIGxldCByZXN1bHQ6IHZvaWQgfCBQcm9taXNlTGlrZTx2b2lkPjtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGNhbmNlbCwgdmFsdWUsIFtjYXVzZV0pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGVkUmVqZWN0aW9uRXJyb3IocGFyZW50LCBlcnIsIFwiVW5oYW5kbGVkIGV4Y2VwdGlvbiBpbiBjYW5jZWwgbWV0aG9kLlwiKSk7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFyZXN1bHQpIHsgY29udGludWU7IH1cclxuICAgICAgICByZXN1bHRzLnB1c2goXHJcbiAgICAgICAgICAgIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlICA/IHJlc3VsdCA6IFByb21pc2UucmVzb2x2ZShyZXN1bHQpKS5jYXRjaCgocmVhc29uPykgPT4ge1xyXG4gICAgICAgICAgICAgICAgUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxlZFJlamVjdGlvbkVycm9yKHBhcmVudCwgcmVhc29uLCBcIlVuaGFuZGxlZCByZWplY3Rpb24gaW4gY2FuY2VsIG1ldGhvZC5cIikpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHJlc3VsdHMpIGFzIGFueTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgaXRzIGFyZ3VtZW50LlxyXG4gKi9cclxuZnVuY3Rpb24gaWRlbnRpdHk8VD4oeDogVCk6IFQge1xyXG4gICAgcmV0dXJuIHg7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaHJvd3MgaXRzIGFyZ3VtZW50LlxyXG4gKi9cclxuZnVuY3Rpb24gdGhyb3dlcihyZWFzb24/OiBhbnkpOiBuZXZlciB7XHJcbiAgICB0aHJvdyByZWFzb247XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBdHRlbXB0cyB2YXJpb3VzIHN0cmF0ZWdpZXMgdG8gY29udmVydCBhbiBlcnJvciB0byBhIHN0cmluZy5cclxuICovXHJcbmZ1bmN0aW9uIGVycm9yTWVzc2FnZShlcnI6IGFueSk6IHN0cmluZyB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvciB8fCB0eXBlb2YgZXJyICE9PSAnb2JqZWN0JyB8fCBlcnIudG9TdHJpbmcgIT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwiXCIgKyBlcnI7XHJcbiAgICAgICAgfVxyXG4gICAgfSBjYXRjaCB7fVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGVycik7XHJcbiAgICB9IGNhdGNoIHt9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGVycik7XHJcbiAgICB9IGNhdGNoIHt9XHJcblxyXG4gICAgcmV0dXJuIFwiPGNvdWxkIG5vdCBjb252ZXJ0IGVycm9yIHRvIHN0cmluZz5cIjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIGN1cnJlbnQgYmFycmllciBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gY2FuY2VsbGFibGUgcHJvbWlzZS4gSWYgbmVjZXNzYXJ5LCBpbml0aWFsaXNlcyB0aGUgYmFycmllci5cclxuICovXHJcbmZ1bmN0aW9uIGN1cnJlbnRCYXJyaWVyPFQ+KHByb21pc2U6IENhbmNlbGxhYmxlUHJvbWlzZTxUPik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgbGV0IHB3cjogUGFydGlhbDxQcm9taXNlV2l0aFJlc29sdmVyczx2b2lkPj4gPSBwcm9taXNlW2JhcnJpZXJTeW1dID8/IHt9O1xyXG4gICAgaWYgKCEoJ3Byb21pc2UnIGluIHB3cikpIHtcclxuICAgICAgICBPYmplY3QuYXNzaWduKHB3ciwgcHJvbWlzZVdpdGhSZXNvbHZlcnM8dm9pZD4oKSk7XHJcbiAgICB9XHJcbiAgICBpZiAocHJvbWlzZVtiYXJyaWVyU3ltXSA9PSBudWxsKSB7XHJcbiAgICAgICAgcHdyLnJlc29sdmUhKCk7XHJcbiAgICAgICAgcHJvbWlzZVtiYXJyaWVyU3ltXSA9IHB3cjtcclxuICAgIH1cclxuICAgIHJldHVybiBwd3IucHJvbWlzZSE7XHJcbn1cclxuXHJcbi8vIFBvbHlmaWxsIFByb21pc2Uud2l0aFJlc29sdmVycy5cclxubGV0IHByb21pc2VXaXRoUmVzb2x2ZXJzID0gUHJvbWlzZS53aXRoUmVzb2x2ZXJzO1xyXG5pZiAocHJvbWlzZVdpdGhSZXNvbHZlcnMgJiYgdHlwZW9mIHByb21pc2VXaXRoUmVzb2x2ZXJzID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICBwcm9taXNlV2l0aFJlc29sdmVycyA9IHByb21pc2VXaXRoUmVzb2x2ZXJzLmJpbmQoUHJvbWlzZSk7XHJcbn0gZWxzZSB7XHJcbiAgICBwcm9taXNlV2l0aFJlc29sdmVycyA9IGZ1bmN0aW9uIDxUPigpOiBQcm9taXNlV2l0aFJlc29sdmVyczxUPiB7XHJcbiAgICAgICAgbGV0IHJlc29sdmUhOiAodmFsdWU6IFQgfCBQcm9taXNlTGlrZTxUPikgPT4gdm9pZDtcclxuICAgICAgICBsZXQgcmVqZWN0ITogKHJlYXNvbj86IGFueSkgPT4gdm9pZDtcclxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8VD4oKHJlcywgcmVqKSA9PiB7IHJlc29sdmUgPSByZXM7IHJlamVjdCA9IHJlajsgfSk7XHJcbiAgICAgICAgcmV0dXJuIHsgcHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0IH07XHJcbiAgICB9XHJcbn0iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyLCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xyXG5cclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0TmFtZXMuQ2xpcGJvYXJkKTtcclxuXHJcbmNvbnN0IENsaXBib2FyZFNldFRleHQgPSAwO1xyXG5jb25zdCBDbGlwYm9hcmRUZXh0ID0gMTtcclxuXHJcbi8qKlxyXG4gKiBTZXRzIHRoZSB0ZXh0IHRvIHRoZSBDbGlwYm9hcmQuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gVGhlIHRleHQgdG8gYmUgc2V0IHRvIHRoZSBDbGlwYm9hcmQuXHJcbiAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIHN1Y2Nlc3NmdWwuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gU2V0VGV4dCh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHJldHVybiBjYWxsKENsaXBib2FyZFNldFRleHQsIHt0ZXh0fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIENsaXBib2FyZCB0ZXh0XHJcbiAqXHJcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHRleHQgZnJvbSB0aGUgQ2xpcGJvYXJkLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFRleHQoKTogUHJvbWlzZTxzdHJpbmc+IHtcclxuICAgIHJldHVybiBjYWxsKENsaXBib2FyZFRleHQpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKipcclxuICogQW55IGlzIGEgZHVtbXkgY3JlYXRpb24gZnVuY3Rpb24gZm9yIHNpbXBsZSBvciB1bmtub3duIHR5cGVzLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEFueTxUID0gYW55Pihzb3VyY2U6IGFueSk6IFQge1xyXG4gICAgcmV0dXJuIHNvdXJjZTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEJ5dGVTbGljZSBpcyBhIGNyZWF0aW9uIGZ1bmN0aW9uIHRoYXQgcmVwbGFjZXNcclxuICogbnVsbCBzdHJpbmdzIHdpdGggZW1wdHkgc3RyaW5ncy5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBCeXRlU2xpY2Uoc291cmNlOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuICgoc291cmNlID09IG51bGwpID8gXCJcIiA6IHNvdXJjZSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBcnJheSB0YWtlcyBhIGNyZWF0aW9uIGZ1bmN0aW9uIGZvciBhbiBhcmJpdHJhcnkgdHlwZVxyXG4gKiBhbmQgcmV0dXJucyBhbiBpbi1wbGFjZSBjcmVhdGlvbiBmdW5jdGlvbiBmb3IgYW4gYXJyYXlcclxuICogd2hvc2UgZWxlbWVudHMgYXJlIG9mIHRoYXQgdHlwZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBBcnJheTxUID0gYW55PihlbGVtZW50OiAoc291cmNlOiBhbnkpID0+IFQpOiAoc291cmNlOiBhbnkpID0+IFRbXSB7XHJcbiAgICBpZiAoZWxlbWVudCA9PT0gQW55KSB7XHJcbiAgICAgICAgcmV0dXJuIChzb3VyY2UpID0+IChzb3VyY2UgPT09IG51bGwgPyBbXSA6IHNvdXJjZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIChzb3VyY2UpID0+IHtcclxuICAgICAgICBpZiAoc291cmNlID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgc291cmNlW2ldID0gZWxlbWVudChzb3VyY2VbaV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc291cmNlO1xyXG4gICAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIE1hcCB0YWtlcyBjcmVhdGlvbiBmdW5jdGlvbnMgZm9yIHR3byBhcmJpdHJhcnkgdHlwZXNcclxuICogYW5kIHJldHVybnMgYW4gaW4tcGxhY2UgY3JlYXRpb24gZnVuY3Rpb24gZm9yIGFuIG9iamVjdFxyXG4gKiB3aG9zZSBrZXlzIGFuZCB2YWx1ZXMgYXJlIG9mIHRob3NlIHR5cGVzLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIE1hcDxWID0gYW55PihrZXk6IChzb3VyY2U6IGFueSkgPT4gc3RyaW5nLCB2YWx1ZTogKHNvdXJjZTogYW55KSA9PiBWKTogKHNvdXJjZTogYW55KSA9PiBSZWNvcmQ8c3RyaW5nLCBWPiB7XHJcbiAgICBpZiAodmFsdWUgPT09IEFueSkge1xyXG4gICAgICAgIHJldHVybiAoc291cmNlKSA9PiAoc291cmNlID09PSBudWxsID8ge30gOiBzb3VyY2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAoc291cmNlKSA9PiB7XHJcbiAgICAgICAgaWYgKHNvdXJjZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge307XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNvdXJjZSkge1xyXG4gICAgICAgICAgICBzb3VyY2Vba2V5XSA9IHZhbHVlKHNvdXJjZVtrZXldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNvdXJjZTtcclxuICAgIH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBOdWxsYWJsZSB0YWtlcyBhIGNyZWF0aW9uIGZ1bmN0aW9uIGZvciBhbiBhcmJpdHJhcnkgdHlwZVxyXG4gKiBhbmQgcmV0dXJucyBhIGNyZWF0aW9uIGZ1bmN0aW9uIGZvciBhIG51bGxhYmxlIHZhbHVlIG9mIHRoYXQgdHlwZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBOdWxsYWJsZTxUID0gYW55PihlbGVtZW50OiAoc291cmNlOiBhbnkpID0+IFQpOiAoc291cmNlOiBhbnkpID0+IChUIHwgbnVsbCkge1xyXG4gICAgaWYgKGVsZW1lbnQgPT09IEFueSkge1xyXG4gICAgICAgIHJldHVybiBBbnk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIChzb3VyY2UpID0+IChzb3VyY2UgPT09IG51bGwgPyBudWxsIDogZWxlbWVudChzb3VyY2UpKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFN0cnVjdCB0YWtlcyBhbiBvYmplY3QgbWFwcGluZyBmaWVsZCBuYW1lcyB0byBjcmVhdGlvbiBmdW5jdGlvbnNcclxuICogYW5kIHJldHVybnMgYW4gaW4tcGxhY2UgY3JlYXRpb24gZnVuY3Rpb24gZm9yIGEgc3RydWN0LlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFN0cnVjdChjcmVhdGVGaWVsZDogUmVjb3JkPHN0cmluZywgKHNvdXJjZTogYW55KSA9PiBhbnk+KTpcclxuICAgIDxVIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiA9IGFueT4oc291cmNlOiBhbnkpID0+IFVcclxue1xyXG4gICAgbGV0IGFsbEFueSA9IHRydWU7XHJcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gY3JlYXRlRmllbGQpIHtcclxuICAgICAgICBpZiAoY3JlYXRlRmllbGRbbmFtZV0gIT09IEFueSkge1xyXG4gICAgICAgICAgICBhbGxBbnkgPSBmYWxzZTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGFsbEFueSkge1xyXG4gICAgICAgIHJldHVybiBBbnk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIChzb3VyY2UpID0+IHtcclxuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gY3JlYXRlRmllbGQpIHtcclxuICAgICAgICAgICAgaWYgKG5hbWUgaW4gc291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICBzb3VyY2VbbmFtZV0gPSBjcmVhdGVGaWVsZFtuYW1lXShzb3VyY2VbbmFtZV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzb3VyY2U7XHJcbiAgICB9O1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFNpemUge1xyXG4gICAgLyoqIFRoZSB3aWR0aCBvZiBhIHJlY3Rhbmd1bGFyIGFyZWEuICovXHJcbiAgICBXaWR0aDogbnVtYmVyO1xyXG4gICAgLyoqIFRoZSBoZWlnaHQgb2YgYSByZWN0YW5ndWxhciBhcmVhLiAqL1xyXG4gICAgSGVpZ2h0OiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVjdCB7XHJcbiAgICAvKiogVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgb3JpZ2luLiAqL1xyXG4gICAgWDogbnVtYmVyO1xyXG4gICAgLyoqIFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIG9yaWdpbi4gKi9cclxuICAgIFk6IG51bWJlcjtcclxuICAgIC8qKiBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZS4gKi9cclxuICAgIFdpZHRoOiBudW1iZXI7XHJcbiAgICAvKiogVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlLiAqL1xyXG4gICAgSGVpZ2h0OiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgU2NyZWVuIHtcclxuICAgIC8qKiBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHNjcmVlbi4gKi9cclxuICAgIElEOiBzdHJpbmc7XHJcbiAgICAvKiogSHVtYW4tcmVhZGFibGUgbmFtZSBvZiB0aGUgc2NyZWVuLiAqL1xyXG4gICAgTmFtZTogc3RyaW5nO1xyXG4gICAgLyoqIFRoZSBzY2FsZSBmYWN0b3Igb2YgdGhlIHNjcmVlbiAoRFBJLzk2KS4gMSA9IHN0YW5kYXJkIERQSSwgMiA9IEhpRFBJIChSZXRpbmEpLCBldGMuICovXHJcbiAgICBTY2FsZUZhY3RvcjogbnVtYmVyO1xyXG4gICAgLyoqIFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHNjcmVlbi4gKi9cclxuICAgIFg6IG51bWJlcjtcclxuICAgIC8qKiBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBzY3JlZW4uICovXHJcbiAgICBZOiBudW1iZXI7XHJcbiAgICAvKiogQ29udGFpbnMgdGhlIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIHNjcmVlbi4gKi9cclxuICAgIFNpemU6IFNpemU7XHJcbiAgICAvKiogQ29udGFpbnMgdGhlIGJvdW5kcyBvZiB0aGUgc2NyZWVuIGluIHRlcm1zIG9mIFgsIFksIFdpZHRoLCBhbmQgSGVpZ2h0LiAqL1xyXG4gICAgQm91bmRzOiBSZWN0O1xyXG4gICAgLyoqIENvbnRhaW5zIHRoZSBwaHlzaWNhbCBib3VuZHMgb2YgdGhlIHNjcmVlbiBpbiB0ZXJtcyBvZiBYLCBZLCBXaWR0aCwgYW5kIEhlaWdodCAoYmVmb3JlIHNjYWxpbmcpLiAqL1xyXG4gICAgUGh5c2ljYWxCb3VuZHM6IFJlY3Q7XHJcbiAgICAvKiogQ29udGFpbnMgdGhlIGFyZWEgb2YgdGhlIHNjcmVlbiB0aGF0IGlzIGFjdHVhbGx5IHVzYWJsZSAoZXhjbHVkaW5nIHRhc2tiYXIgYW5kIG90aGVyIHN5c3RlbSBVSSkuICovXHJcbiAgICBXb3JrQXJlYTogUmVjdDtcclxuICAgIC8qKiBDb250YWlucyB0aGUgcGh5c2ljYWwgV29ya0FyZWEgb2YgdGhlIHNjcmVlbiAoYmVmb3JlIHNjYWxpbmcpLiAqL1xyXG4gICAgUGh5c2ljYWxXb3JrQXJlYTogUmVjdDtcclxuICAgIC8qKiBUcnVlIGlmIHRoaXMgaXMgdGhlIHByaW1hcnkgbW9uaXRvciBzZWxlY3RlZCBieSB0aGUgdXNlciBpbiB0aGUgb3BlcmF0aW5nIHN5c3RlbS4gKi9cclxuICAgIElzUHJpbWFyeTogYm9vbGVhbjtcclxuICAgIC8qKiBUaGUgcm90YXRpb24gb2YgdGhlIHNjcmVlbi4gKi9cclxuICAgIFJvdGF0aW9uOiBudW1iZXI7XHJcbn1cclxuXHJcbmltcG9ydCB7IG5ld1J1bnRpbWVDYWxsZXIsIG9iamVjdE5hbWVzIH0gZnJvbSBcIi4vcnVudGltZS5qc1wiO1xyXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcihvYmplY3ROYW1lcy5TY3JlZW5zKTtcclxuXHJcbmNvbnN0IGdldEFsbCA9IDA7XHJcbmNvbnN0IGdldFByaW1hcnkgPSAxO1xyXG5jb25zdCBnZXRDdXJyZW50ID0gMjtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIGFsbCBzY3JlZW5zLlxyXG4gKlxyXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiBTY3JlZW4gb2JqZWN0cy5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRBbGwoKTogUHJvbWlzZTxTY3JlZW5bXT4ge1xyXG4gICAgcmV0dXJuIGNhbGwoZ2V0QWxsKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIHByaW1hcnkgc2NyZWVuLlxyXG4gKlxyXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgcHJpbWFyeSBzY3JlZW4uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gR2V0UHJpbWFyeSgpOiBQcm9taXNlPFNjcmVlbj4ge1xyXG4gICAgcmV0dXJuIGNhbGwoZ2V0UHJpbWFyeSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBjdXJyZW50IGFjdGl2ZSBzY3JlZW4uXHJcbiAqXHJcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGN1cnJlbnQgYWN0aXZlIHNjcmVlbi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRDdXJyZW50KCk6IFByb21pc2U8U2NyZWVuPiB7XHJcbiAgICByZXR1cm4gY2FsbChnZXRDdXJyZW50KTtcclxufVxyXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7QUNBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7QUNBQTtBQUFBO0FBQUE7QUFBQTs7O0FDNkJBLElBQU0sY0FDRjtBQUVHLFNBQVMsT0FBTyxPQUFlLElBQVk7QUFDOUMsTUFBSSxLQUFLO0FBRVQsTUFBSSxJQUFJLE9BQU87QUFDZixTQUFPLEtBQUs7QUFFUixVQUFNLFlBQWEsS0FBSyxPQUFPLElBQUksS0FBTSxDQUFDO0FBQUEsRUFDOUM7QUFDQSxTQUFPO0FBQ1g7OztBQzdCQSxJQUFNLGFBQWEsT0FBTyxTQUFTLFNBQVM7QUFHckMsSUFBTSxjQUFjLE9BQU8sT0FBTztBQUFBLEVBQ3JDLE1BQU07QUFBQSxFQUNOLFdBQVc7QUFBQSxFQUNYLGFBQWE7QUFBQSxFQUNiLFFBQVE7QUFBQSxFQUNSLGFBQWE7QUFBQSxFQUNiLFFBQVE7QUFBQSxFQUNSLFFBQVE7QUFBQSxFQUNSLFNBQVM7QUFBQSxFQUNULFFBQVE7QUFBQSxFQUNSLFNBQVM7QUFBQSxFQUNULFlBQVk7QUFDaEIsQ0FBQztBQUNNLElBQUksV0FBVyxPQUFPO0FBU3RCLFNBQVMsaUJBQWlCLFFBQWdCLGFBQXFCLElBQUk7QUFDdEUsU0FBTyxTQUFVLFFBQWdCLE9BQVksTUFBTTtBQUMvQyxXQUFPLGtCQUFrQixRQUFRLFFBQVEsWUFBWSxJQUFJO0FBQUEsRUFDN0Q7QUFDSjtBQUVBLGVBQWUsa0JBQWtCLFVBQWtCLFFBQWdCLFlBQW9CLE1BQXlCO0FBM0NoSCxNQUFBQSxLQUFBO0FBNENJLE1BQUksTUFBTSxJQUFJLElBQUksVUFBVTtBQUM1QixNQUFJLGFBQWEsT0FBTyxVQUFVLFNBQVMsU0FBUyxDQUFDO0FBQ3JELE1BQUksYUFBYSxPQUFPLFVBQVUsT0FBTyxTQUFTLENBQUM7QUFDbkQsTUFBSSxNQUFNO0FBQUUsUUFBSSxhQUFhLE9BQU8sUUFBUSxLQUFLLFVBQVUsSUFBSSxDQUFDO0FBQUEsRUFBRztBQUVuRSxNQUFJLFVBQWtDO0FBQUEsSUFDbEMsQ0FBQyxtQkFBbUIsR0FBRztBQUFBLEVBQzNCO0FBQ0EsTUFBSSxZQUFZO0FBQ1osWUFBUSxxQkFBcUIsSUFBSTtBQUFBLEVBQ3JDO0FBRUEsTUFBSSxXQUFXLE1BQU0sTUFBTSxLQUFLLEVBQUUsUUFBUSxDQUFDO0FBQzNDLE1BQUksQ0FBQyxTQUFTLElBQUk7QUFDZCxVQUFNLElBQUksTUFBTSxNQUFNLFNBQVMsS0FBSyxDQUFDO0FBQUEsRUFDekM7QUFFQSxRQUFLLE1BQUFBLE1BQUEsU0FBUyxRQUFRLElBQUksY0FBYyxNQUFuQyxnQkFBQUEsSUFBc0MsUUFBUSx3QkFBOUMsWUFBcUUsUUFBUSxJQUFJO0FBQ2xGLFdBQU8sU0FBUyxLQUFLO0FBQUEsRUFDekIsT0FBTztBQUNILFdBQU8sU0FBUyxLQUFLO0FBQUEsRUFDekI7QUFDSjs7O0FGdERBLElBQU0sT0FBTyxpQkFBaUIsWUFBWSxPQUFPO0FBRWpELElBQU0saUJBQWlCO0FBT2hCLFNBQVMsUUFBUSxLQUFrQztBQUN0RCxTQUFPLEtBQUssZ0JBQWdCLEVBQUMsS0FBSyxJQUFJLFNBQVMsRUFBQyxDQUFDO0FBQ3JEOzs7QUd2QkE7QUFBQTtBQUFBLGVBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFjQSxPQUFPLFNBQVMsT0FBTyxVQUFVLENBQUM7QUFDbEMsT0FBTyxPQUFPLHNCQUFzQjtBQUNwQyxPQUFPLE9BQU8sdUJBQXVCO0FBSXJDLElBQU1DLFFBQU8saUJBQWlCLFlBQVksTUFBTTtBQUNoRCxJQUFNLGtCQUFrQixvQkFBSSxJQUE4QjtBQUcxRCxJQUFNLGFBQWE7QUFDbkIsSUFBTSxnQkFBZ0I7QUFDdEIsSUFBTSxjQUFjO0FBQ3BCLElBQU0saUJBQWlCO0FBQ3ZCLElBQU0saUJBQWlCO0FBQ3ZCLElBQU0saUJBQWlCO0FBMEd2QixTQUFTLHFCQUFxQixJQUFZLE1BQWMsUUFBdUI7QUFDM0UsTUFBSSxZQUFZLHFCQUFxQixFQUFFO0FBQ3ZDLE1BQUksQ0FBQyxXQUFXO0FBQ1o7QUFBQSxFQUNKO0FBRUEsTUFBSSxRQUFRO0FBQ1IsUUFBSTtBQUNBLGdCQUFVLFFBQVEsS0FBSyxNQUFNLElBQUksQ0FBQztBQUFBLElBQ3RDLFNBQVMsS0FBVTtBQUNmLGdCQUFVLE9BQU8sSUFBSSxVQUFVLDZCQUE2QixJQUFJLFNBQVMsRUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDO0FBQUEsSUFDNUY7QUFBQSxFQUNKLE9BQU87QUFDSCxjQUFVLFFBQVEsSUFBSTtBQUFBLEVBQzFCO0FBQ0o7QUFRQSxTQUFTLG9CQUFvQixJQUFZLFNBQXVCO0FBOUpoRSxNQUFBQztBQStKSSxHQUFBQSxNQUFBLHFCQUFxQixFQUFFLE1BQXZCLGdCQUFBQSxJQUEwQixPQUFPLElBQUksT0FBTyxNQUFNLE9BQU87QUFDN0Q7QUFRQSxTQUFTLHFCQUFxQixJQUEwQztBQUNwRSxRQUFNLFdBQVcsZ0JBQWdCLElBQUksRUFBRTtBQUN2QyxrQkFBZ0IsT0FBTyxFQUFFO0FBQ3pCLFNBQU87QUFDWDtBQU9BLFNBQVMsYUFBcUI7QUFDMUIsTUFBSTtBQUNKLEtBQUc7QUFDQyxhQUFTLE9BQU87QUFBQSxFQUNwQixTQUFTLGdCQUFnQixJQUFJLE1BQU07QUFDbkMsU0FBTztBQUNYO0FBU0EsU0FBUyxPQUFPLE1BQWMsVUFBZ0YsQ0FBQyxHQUFpQjtBQUM1SCxRQUFNLEtBQUssV0FBVztBQUN0QixTQUFPLElBQUksUUFBUSxDQUFDLFNBQVMsV0FBVztBQUNwQyxvQkFBZ0IsSUFBSSxJQUFJLEVBQUUsU0FBUyxPQUFPLENBQUM7QUFDM0MsSUFBQUQsTUFBSyxNQUFNLE9BQU8sT0FBTyxFQUFFLGFBQWEsR0FBRyxHQUFHLE9BQU8sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxRQUFhO0FBQ3hFLHNCQUFnQixPQUFPLEVBQUU7QUFDekIsYUFBTyxHQUFHO0FBQUEsSUFDZCxDQUFDO0FBQUEsRUFDTCxDQUFDO0FBQ0w7QUFRTyxTQUFTLEtBQUssU0FBZ0Q7QUFBRSxTQUFPLE9BQU8sWUFBWSxPQUFPO0FBQUc7QUFRcEcsU0FBUyxRQUFRLFNBQWdEO0FBQUUsU0FBTyxPQUFPLGVBQWUsT0FBTztBQUFHO0FBUTFHLFNBQVNFLE9BQU0sU0FBZ0Q7QUFBRSxTQUFPLE9BQU8sYUFBYSxPQUFPO0FBQUc7QUFRdEcsU0FBUyxTQUFTLFNBQWdEO0FBQUUsU0FBTyxPQUFPLGdCQUFnQixPQUFPO0FBQUc7QUFXNUcsU0FBUyxTQUFTLFNBQTREO0FBdFByRixNQUFBRDtBQXNQdUYsVUFBT0EsTUFBQSxPQUFPLGdCQUFnQixPQUFPLE1BQTlCLE9BQUFBLE1BQW1DLENBQUM7QUFBRztBQVE5SCxTQUFTLFNBQVMsU0FBaUQ7QUFBRSxTQUFPLE9BQU8sZ0JBQWdCLE9BQU87QUFBRzs7O0FDOVBwSDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7QUNhTyxJQUFNLGlCQUFpQixvQkFBSSxJQUF3QjtBQUVuRCxJQUFNLFdBQU4sTUFBZTtBQUFBLEVBS2xCLFlBQVksV0FBbUIsVUFBK0IsY0FBc0I7QUFDaEYsU0FBSyxZQUFZO0FBQ2pCLFNBQUssV0FBVztBQUNoQixTQUFLLGVBQWUsZ0JBQWdCO0FBQUEsRUFDeEM7QUFBQSxFQUVBLFNBQVMsTUFBb0I7QUFDekIsUUFBSTtBQUNBLFdBQUssU0FBUyxJQUFJO0FBQUEsSUFDdEIsU0FBUyxLQUFLO0FBQ1YsY0FBUSxNQUFNLEdBQUc7QUFBQSxJQUNyQjtBQUVBLFFBQUksS0FBSyxpQkFBaUIsR0FBSSxRQUFPO0FBQ3JDLFNBQUssZ0JBQWdCO0FBQ3JCLFdBQU8sS0FBSyxpQkFBaUI7QUFBQSxFQUNqQztBQUNKO0FBRU8sU0FBUyxZQUFZLFVBQTBCO0FBQ2xELE1BQUksWUFBWSxlQUFlLElBQUksU0FBUyxTQUFTO0FBQ3JELE1BQUksQ0FBQyxXQUFXO0FBQ1o7QUFBQSxFQUNKO0FBRUEsY0FBWSxVQUFVLE9BQU8sT0FBSyxNQUFNLFFBQVE7QUFDaEQsTUFBSSxVQUFVLFdBQVcsR0FBRztBQUN4QixtQkFBZSxPQUFPLFNBQVMsU0FBUztBQUFBLEVBQzVDLE9BQU87QUFDSCxtQkFBZSxJQUFJLFNBQVMsV0FBVyxTQUFTO0FBQUEsRUFDcEQ7QUFDSjs7O0FDdENPLElBQU0sUUFBUSxPQUFPLE9BQU87QUFBQSxFQUNsQyxTQUFTLE9BQU8sT0FBTztBQUFBLElBQ3RCLHVCQUF1QjtBQUFBLElBQ3ZCLHNCQUFzQjtBQUFBLElBQ3RCLG9CQUFvQjtBQUFBLElBQ3BCLGtCQUFrQjtBQUFBLElBQ2xCLFlBQVk7QUFBQSxJQUNaLG9CQUFvQjtBQUFBLElBQ3BCLG9CQUFvQjtBQUFBLElBQ3BCLDRCQUE0QjtBQUFBLElBQzVCLGNBQWM7QUFBQSxJQUNkLHVCQUF1QjtBQUFBLElBQ3ZCLG1CQUFtQjtBQUFBLElBQ25CLGVBQWU7QUFBQSxJQUNmLGVBQWU7QUFBQSxJQUNmLGlCQUFpQjtBQUFBLElBQ2pCLGtCQUFrQjtBQUFBLElBQ2xCLGdCQUFnQjtBQUFBLElBQ2hCLGlCQUFpQjtBQUFBLElBQ2pCLGlCQUFpQjtBQUFBLElBQ2pCLGdCQUFnQjtBQUFBLElBQ2hCLGVBQWU7QUFBQSxJQUNmLGlCQUFpQjtBQUFBLElBQ2pCLGtCQUFrQjtBQUFBLElBQ2xCLFlBQVk7QUFBQSxJQUNaLGdCQUFnQjtBQUFBLElBQ2hCLGVBQWU7QUFBQSxJQUNmLGFBQWE7QUFBQSxJQUNiLGlCQUFpQjtBQUFBLElBQ2pCLG9CQUFvQjtBQUFBLElBQ3BCLDBCQUEwQjtBQUFBLElBQzFCLDJCQUEyQjtBQUFBLElBQzNCLDBCQUEwQjtBQUFBLElBQzFCLHdCQUF3QjtBQUFBLElBQ3hCLGFBQWE7QUFBQSxJQUNiLGVBQWU7QUFBQSxJQUNmLGdCQUFnQjtBQUFBLElBQ2hCLFlBQVk7QUFBQSxJQUNaLGlCQUFpQjtBQUFBLElBQ2pCLG1CQUFtQjtBQUFBLElBQ25CLG9CQUFvQjtBQUFBLElBQ3BCLHFCQUFxQjtBQUFBLElBQ3JCLGdCQUFnQjtBQUFBLElBQ2hCLGtCQUFrQjtBQUFBLElBQ2xCLGdCQUFnQjtBQUFBLElBQ2hCLGtCQUFrQjtBQUFBLEVBQ25CLENBQUM7QUFBQSxFQUNELEtBQUssT0FBTyxPQUFPO0FBQUEsSUFDbEIsNEJBQTRCO0FBQUEsSUFDNUIsdUNBQXVDO0FBQUEsSUFDdkMseUNBQXlDO0FBQUEsSUFDekMsMEJBQTBCO0FBQUEsSUFDMUIsb0NBQW9DO0FBQUEsSUFDcEMsc0NBQXNDO0FBQUEsSUFDdEMsb0NBQW9DO0FBQUEsSUFDcEMsMENBQTBDO0FBQUEsSUFDMUMsMkJBQTJCO0FBQUEsSUFDM0IsK0JBQStCO0FBQUEsSUFDL0Isb0JBQW9CO0FBQUEsSUFDcEIsNEJBQTRCO0FBQUEsSUFDNUIsc0JBQXNCO0FBQUEsSUFDdEIsc0JBQXNCO0FBQUEsSUFDdEIsK0JBQStCO0FBQUEsSUFDL0IsNkJBQTZCO0FBQUEsSUFDN0IsZ0NBQWdDO0FBQUEsSUFDaEMscUJBQXFCO0FBQUEsSUFDckIsNkJBQTZCO0FBQUEsSUFDN0IsMEJBQTBCO0FBQUEsSUFDMUIsdUJBQXVCO0FBQUEsSUFDdkIsdUJBQXVCO0FBQUEsSUFDdkIsZ0JBQWdCO0FBQUEsSUFDaEIsc0JBQXNCO0FBQUEsSUFDdEIsY0FBYztBQUFBLElBQ2Qsb0JBQW9CO0FBQUEsSUFDcEIsb0JBQW9CO0FBQUEsSUFDcEIsc0JBQXNCO0FBQUEsSUFDdEIsYUFBYTtBQUFBLElBQ2IsY0FBYztBQUFBLElBQ2QsbUJBQW1CO0FBQUEsSUFDbkIsbUJBQW1CO0FBQUEsSUFDbkIseUJBQXlCO0FBQUEsSUFDekIsZUFBZTtBQUFBLElBQ2YsaUJBQWlCO0FBQUEsSUFDakIsdUJBQXVCO0FBQUEsSUFDdkIscUJBQXFCO0FBQUEsSUFDckIscUJBQXFCO0FBQUEsSUFDckIsdUJBQXVCO0FBQUEsSUFDdkIsY0FBYztBQUFBLElBQ2QsZUFBZTtBQUFBLElBQ2Ysb0JBQW9CO0FBQUEsSUFDcEIsb0JBQW9CO0FBQUEsSUFDcEIsMEJBQTBCO0FBQUEsSUFDMUIsZ0JBQWdCO0FBQUEsSUFDaEIsNEJBQTRCO0FBQUEsSUFDNUIsNEJBQTRCO0FBQUEsSUFDNUIseURBQXlEO0FBQUEsSUFDekQsc0NBQXNDO0FBQUEsSUFDdEMsb0JBQW9CO0FBQUEsSUFDcEIscUJBQXFCO0FBQUEsSUFDckIscUJBQXFCO0FBQUEsSUFDckIsc0JBQXNCO0FBQUEsSUFDdEIsZ0NBQWdDO0FBQUEsSUFDaEMsa0NBQWtDO0FBQUEsSUFDbEMsbUNBQW1DO0FBQUEsSUFDbkMsb0NBQW9DO0FBQUEsSUFDcEMsK0JBQStCO0FBQUEsSUFDL0IsNkJBQTZCO0FBQUEsSUFDN0IsdUJBQXVCO0FBQUEsSUFDdkIsaUNBQWlDO0FBQUEsSUFDakMsOEJBQThCO0FBQUEsSUFDOUIsNEJBQTRCO0FBQUEsSUFDNUIsc0NBQXNDO0FBQUEsSUFDdEMsNEJBQTRCO0FBQUEsSUFDNUIsc0JBQXNCO0FBQUEsSUFDdEIsa0NBQWtDO0FBQUEsSUFDbEMsc0JBQXNCO0FBQUEsSUFDdEIsd0JBQXdCO0FBQUEsSUFDeEIsd0JBQXdCO0FBQUEsSUFDeEIsbUJBQW1CO0FBQUEsSUFDbkIsMEJBQTBCO0FBQUEsSUFDMUIsOEJBQThCO0FBQUEsSUFDOUIseUJBQXlCO0FBQUEsSUFDekIsNkJBQTZCO0FBQUEsSUFDN0IsaUJBQWlCO0FBQUEsSUFDakIsZ0JBQWdCO0FBQUEsSUFDaEIsc0JBQXNCO0FBQUEsSUFDdEIsZUFBZTtBQUFBLElBQ2YseUJBQXlCO0FBQUEsSUFDekIsd0JBQXdCO0FBQUEsSUFDeEIsb0JBQW9CO0FBQUEsSUFDcEIscUJBQXFCO0FBQUEsSUFDckIsaUJBQWlCO0FBQUEsSUFDakIsaUJBQWlCO0FBQUEsSUFDakIsc0JBQXNCO0FBQUEsSUFDdEIsbUNBQW1DO0FBQUEsSUFDbkMscUNBQXFDO0FBQUEsSUFDckMsdUJBQXVCO0FBQUEsSUFDdkIsc0JBQXNCO0FBQUEsSUFDdEIsd0JBQXdCO0FBQUEsSUFDeEIsZUFBZTtBQUFBLElBQ2YsMkJBQTJCO0FBQUEsSUFDM0IsMEJBQTBCO0FBQUEsSUFDMUIsNkJBQTZCO0FBQUEsSUFDN0IsWUFBWTtBQUFBLElBQ1osZ0JBQWdCO0FBQUEsSUFDaEIsa0JBQWtCO0FBQUEsSUFDbEIsZ0JBQWdCO0FBQUEsSUFDaEIsa0JBQWtCO0FBQUEsSUFDbEIsbUJBQW1CO0FBQUEsSUFDbkIsWUFBWTtBQUFBLElBQ1oscUJBQXFCO0FBQUEsSUFDckIsc0JBQXNCO0FBQUEsSUFDdEIsc0JBQXNCO0FBQUEsSUFDdEIsOEJBQThCO0FBQUEsSUFDOUIsaUJBQWlCO0FBQUEsSUFDakIseUJBQXlCO0FBQUEsSUFDekIsMkJBQTJCO0FBQUEsSUFDM0IsK0JBQStCO0FBQUEsSUFDL0IsMEJBQTBCO0FBQUEsSUFDMUIsOEJBQThCO0FBQUEsSUFDOUIsaUJB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WDtBQUVBLFNBQU8sQ0FBQyxXQUFXO0FBQ2YsZUFBVyxRQUFRLGFBQWE7QUFDNUIsVUFBSSxRQUFRLFFBQVE7QUFDaEIsZUFBTyxJQUFJLElBQUksWUFBWSxJQUFJLEVBQUUsT0FBTyxJQUFJLENBQUM7QUFBQSxNQUNqRDtBQUFBLElBQ0o7QUFDQSxXQUFPO0FBQUEsRUFDWDtBQUNKOzs7QUN6R0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBd0RBLElBQU1DLFFBQU8saUJBQWlCLFlBQVksT0FBTztBQUVqRCxJQUFNLFNBQVM7QUFDZixJQUFNLGFBQWE7QUFDbkIsSUFBTSxhQUFhO0FBT1osU0FBUyxTQUE0QjtBQUN4QyxTQUFPQSxNQUFLLE1BQU07QUFDdEI7QUFPTyxTQUFTLGFBQThCO0FBQzFDLFNBQU9BLE1BQUssVUFBVTtBQUMxQjtBQU9PLFNBQVMsYUFBOEI7QUFDMUMsU0FBT0EsTUFBSyxVQUFVO0FBQzFCOzs7QXRCNUVBLE9BQU8sU0FBUyxPQUFPLFVBQVUsQ0FBQztBQTRDbEMsT0FBTyxPQUFPLFNBQWdCO0FBQ3ZCLE9BQU8scUJBQXFCOyIsCiAgIm5hbWVzIjogWyJfYSIsICJFcnJvciIsICJjYWxsIiwgIl9hIiwgIkVycm9yIiwgImNhbGwiLCAiX2EiLCAicmVzaXphYmxlIiwgImNhbGwiLCAiX2EiLCAiY2FsbCIsICJjYWxsIiwgIkhpZGVNZXRob2QiLCAiU2hvd01ldGhvZCIsICJpc0RvY3VtZW50RG90QWxsIiwgIl9hIiwgInJlYXNvbiIsICJ2YWx1ZSIsICJjYWxsIiwgImdldEFuZERlbGV0ZVJlc3BvbnNlIiwgImdlbmVyYXRlSUQiLCAiY2FsbCIsICJBcnJheSIsICJNYXAiLCAiQXJyYXkiLCAiTWFwIiwgImtleSIsICJjYWxsIl0KfQo= diff --git a/v3/internal/assetserver/bundledassets/runtime.js b/v3/internal/assetserver/bundledassets/runtime.js index 25dea97a0..3d105fdd2 100644 --- a/v3/internal/assetserver/bundledassets/runtime.js +++ b/v3/internal/assetserver/bundledassets/runtime.js @@ -1 +1 @@ -var Fe=Object.defineProperty,an=Object.defineProperties;var ln=Object.getOwnPropertyDescriptors;var ke=Object.getOwnPropertySymbols;var cn=Object.prototype.hasOwnProperty,dn=Object.prototype.propertyIsEnumerable;var Oe=(n,e,i)=>e in n?Fe(n,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[e]=i,Le=(n,e)=>{for(var i in e||(e={}))cn.call(e,i)&&Oe(n,i,e[i]);if(ke)for(var i of ke(e))dn.call(e,i)&&Oe(n,i,e[i]);return n},Ue=(n,e)=>an(n,ln(e));var u=(n,e)=>{for(var i in e)Fe(n,i,{get:e[i],enumerable:!0})};var ce={};u(ce,{Application:()=>ve,Browser:()=>_,Call:()=>Te,CancelError:()=>k,CancellablePromise:()=>j,CancelledRejectionError:()=>W,Clipboard:()=>xe,Create:()=>Ae,Dialogs:()=>ee,Events:()=>oe,Flags:()=>we,Screens:()=>Ee,System:()=>ue,WML:()=>le,Window:()=>Z});var le={};u(le,{Enable:()=>ae,Reload:()=>Ke});var _={};u(_,{OpenURL:()=>q});var mn="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";function P(n=21){let e="",i=n|0;for(;i--;)e+=mn[Math.random()*64|0];return e}var un=window.location.origin+"/wails/runtime",d=Object.freeze({Call:0,Clipboard:1,Application:2,Events:3,ContextMenu:4,Dialog:5,Window:6,Screens:7,System:8,Browser:9,CancelCall:10}),wn=P();function m(n,e=""){return function(i,o=null){return pn(n,i,e,o)}}async function pn(n,e,i,o){var l,c;let t=new URL(un);t.searchParams.append("object",n.toString()),t.searchParams.append("method",e.toString()),o&&t.searchParams.append("args",JSON.stringify(o));let r={"x-wails-client-id":wn};i&&(r["x-wails-window-name"]=i);let a=await fetch(t,{headers:r});if(!a.ok)throw new Error(await a.text());return((c=(l=a.headers.get("Content-Type"))==null?void 0:l.indexOf("application/json"))!=null?c:-1)!==-1?a.json():a.text()}var fn=m(d.Browser),gn=0;function q(n){return fn(gn,{url:n.toString()})}var ee={};u(ee,{Error:()=>An,Info:()=>Tn,OpenFile:()=>Rn,Question:()=>$,SaveFile:()=>En,Warning:()=>xn});window._wails=window._wails||{};window._wails.dialogErrorCallback=Mn;window._wails.dialogResultCallback=Dn;var hn=m(d.Dialog),F=new Map,Wn=0,bn=1,vn=2,yn=3,Cn=4,Pn=5;function Dn(n,e,i){let o=Ie(n);if(o)if(i)try{o.resolve(JSON.parse(e))}catch(t){o.reject(new TypeError("could not parse result: "+t.message,{cause:t}))}else o.resolve(e)}function Mn(n,e){var i;(i=Ie(n))==null||i.reject(new window.Error(e))}function Ie(n){let e=F.get(n);return F.delete(n),e}function Sn(){let n;do n=P();while(F.has(n));return n}function D(n,e={}){let i=Sn();return new Promise((o,t)=>{F.set(i,{resolve:o,reject:t}),hn(n,Object.assign({"dialog-id":i},e)).catch(r=>{F.delete(i),t(r)})})}function Tn(n){return D(Wn,n)}function xn(n){return D(bn,n)}function An(n){return D(vn,n)}function $(n){return D(yn,n)}function Rn(n){var e;return(e=D(Cn,n))!=null?e:[]}function En(n){return D(Pn,n)}var oe={};u(oe,{Emit:()=>ie,Off:()=>In,OffAll:()=>zn,On:()=>Ln,OnMultiple:()=>ne,Once:()=>Un,Types:()=>je,WailsEvent:()=>M});var p=new Map,B=class{constructor(e,i,o){this.eventName=e,this.callback=i,this.maxCallbacks=o||-1}dispatch(e){try{this.callback(e)}catch(i){}return this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0)}};function ze(n){let e=p.get(n.eventName);e&&(e=e.filter(i=>i!==n),e.length===0?p.delete(n.eventName):p.set(n.eventName,e))}var je=Object.freeze({Windows:Object.freeze({APMPowerSettingChange:"windows:APMPowerSettingChange",APMPowerStatusChange:"windows:APMPowerStatusChange",APMResumeAutomatic:"windows:APMResumeAutomatic",APMResumeSuspend:"windows:APMResumeSuspend",APMSuspend:"windows:APMSuspend",ApplicationStarted:"windows:ApplicationStarted",SystemThemeChanged:"windows:SystemThemeChanged",WebViewNavigationCompleted:"windows:WebViewNavigationCompleted",WindowActive:"windows:WindowActive",WindowBackgroundErase:"windows:WindowBackgroundErase",WindowClickActive:"windows:WindowClickActive",WindowClosing:"windows:WindowClosing",WindowDidMove:"windows:WindowDidMove",WindowDidResize:"windows:WindowDidResize",WindowDPIChanged:"windows:WindowDPIChanged",WindowDragDrop:"windows:WindowDragDrop",WindowDragEnter:"windows:WindowDragEnter",WindowDragLeave:"windows:WindowDragLeave",WindowDragOver:"windows:WindowDragOver",WindowEndMove:"windows:WindowEndMove",WindowEndResize:"windows:WindowEndResize",WindowFullscreen:"windows:WindowFullscreen",WindowHide:"windows:WindowHide",WindowInactive:"windows:WindowInactive",WindowKeyDown:"windows:WindowKeyDown",WindowKeyUp:"windows:WindowKeyUp",WindowKillFocus:"windows:WindowKillFocus",WindowNonClientHit:"windows:WindowNonClientHit",WindowNonClientMouseDown:"windows:WindowNonClientMouseDown",WindowNonClientMouseLeave:"windows:WindowNonClientMouseLeave",WindowNonClientMouseMove:"windows:WindowNonClientMouseMove",WindowNonClientMouseUp:"windows:WindowNonClientMouseUp",WindowPaint:"windows:WindowPaint",WindowRestore:"windows:WindowRestore",WindowSetFocus:"windows:WindowSetFocus",WindowShow:"windows:WindowShow",WindowStartMove:"windows:WindowStartMove",WindowStartResize:"windows:WindowStartResize",WindowUnFullscreen:"windows:WindowUnFullscreen",WindowZOrderChanged:"windows:WindowZOrderChanged",WindowMinimise:"windows:WindowMinimise",WindowUnMinimise:"windows:WindowUnMinimise",WindowMaximise:"windows:WindowMaximise",WindowUnMaximise:"windows:WindowUnMaximise"}),Mac:Object.freeze({ApplicationDidBecomeActive:"mac:ApplicationDidBecomeActive",ApplicationDidChangeBackingProperties:"mac:ApplicationDidChangeBackingProperties",ApplicationDidChangeEffectiveAppearance:"mac:ApplicationDidChangeEffectiveAppearance",ApplicationDidChangeIcon:"mac:ApplicationDidChangeIcon",ApplicationDidChangeOcclusionState:"mac:ApplicationDidChangeOcclusionState",ApplicationDidChangeScreenParameters:"mac:ApplicationDidChangeScreenParameters",ApplicationDidChangeStatusBarFrame:"mac:ApplicationDidChangeStatusBarFrame",ApplicationDidChangeStatusBarOrientation:"mac:ApplicationDidChangeStatusBarOrientation",ApplicationDidChangeTheme:"mac:ApplicationDidChangeTheme",ApplicationDidFinishLaunching:"mac:ApplicationDidFinishLaunching",ApplicationDidHide:"mac:ApplicationDidHide",ApplicationDidResignActive:"mac:ApplicationDidResignActive",ApplicationDidUnhide:"mac:ApplicationDidUnhide",ApplicationDidUpdate:"mac:ApplicationDidUpdate",ApplicationShouldHandleReopen:"mac:ApplicationShouldHandleReopen",ApplicationWillBecomeActive:"mac:ApplicationWillBecomeActive",ApplicationWillFinishLaunching:"mac:ApplicationWillFinishLaunching",ApplicationWillHide:"mac:ApplicationWillHide",ApplicationWillResignActive:"mac:ApplicationWillResignActive",ApplicationWillTerminate:"mac:ApplicationWillTerminate",ApplicationWillUnhide:"mac:ApplicationWillUnhide",ApplicationWillUpdate:"mac:ApplicationWillUpdate",MenuDidAddItem:"mac:MenuDidAddItem",MenuDidBeginTracking:"mac:MenuDidBeginTracking",MenuDidClose:"mac:MenuDidClose",MenuDidDisplayItem:"mac:MenuDidDisplayItem",MenuDidEndTracking:"mac:MenuDidEndTracking",MenuDidHighlightItem:"mac:MenuDidHighlightItem",MenuDidOpen:"mac:MenuDidOpen",MenuDidPopUp:"mac:MenuDidPopUp",MenuDidRemoveItem:"mac:MenuDidRemoveItem",MenuDidSendAction:"mac:MenuDidSendAction",MenuDidSendActionToItem:"mac:MenuDidSendActionToItem",MenuDidUpdate:"mac:MenuDidUpdate",MenuWillAddItem:"mac:MenuWillAddItem",MenuWillBeginTracking:"mac:MenuWillBeginTracking",MenuWillDisplayItem:"mac:MenuWillDisplayItem",MenuWillEndTracking:"mac:MenuWillEndTracking",MenuWillHighlightItem:"mac:MenuWillHighlightItem",MenuWillOpen:"mac:MenuWillOpen",MenuWillPopUp:"mac:MenuWillPopUp",MenuWillRemoveItem:"mac:MenuWillRemoveItem",MenuWillSendAction:"mac:MenuWillSendAction",MenuWillSendActionToItem:"mac:MenuWillSendActionToItem",MenuWillUpdate:"mac:MenuWillUpdate",WebViewDidCommitNavigation:"mac:WebViewDidCommitNavigation",WebViewDidFinishNavigation:"mac:WebViewDidFinishNavigation",WebViewDidReceiveServerRedirectForProvisionalNavigation:"mac:WebViewDidReceiveServerRedirectForProvisionalNavigation",WebViewDidStartProvisionalNavigation:"mac:WebViewDidStartProvisionalNavigation",WindowDidBecomeKey:"mac:WindowDidBecomeKey",WindowDidBecomeMain:"mac:WindowDidBecomeMain",WindowDidBeginSheet:"mac:WindowDidBeginSheet",WindowDidChangeAlpha:"mac:WindowDidChangeAlpha",WindowDidChangeBackingLocation:"mac:WindowDidChangeBackingLocation",WindowDidChangeBackingProperties:"mac:WindowDidChangeBackingProperties",WindowDidChangeCollectionBehavior:"mac:WindowDidChangeCollectionBehavior",WindowDidChangeEffectiveAppearance:"mac:WindowDidChangeEffectiveAppearance",WindowDidChangeOcclusionState:"mac:WindowDidChangeOcclusionState",WindowDidChangeOrderingMode:"mac:WindowDidChangeOrderingMode",WindowDidChangeScreen:"mac:WindowDidChangeScreen",WindowDidChangeScreenParameters:"mac:WindowDidChangeScreenParameters",WindowDidChangeScreenProfile:"mac:WindowDidChangeScreenProfile",WindowDidChangeScreenSpace:"mac:WindowDidChangeScreenSpace",WindowDidChangeScreenSpaceProperties:"mac:WindowDidChangeScreenSpaceProperties",WindowDidChangeSharingType:"mac:WindowDidChangeSharingType",WindowDidChangeSpace:"mac:WindowDidChangeSpace",WindowDidChangeSpaceOrderingMode:"mac:WindowDidChangeSpaceOrderingMode",WindowDidChangeTitle:"mac:WindowDidChangeTitle",WindowDidChangeToolbar:"mac:WindowDidChangeToolbar",WindowDidDeminiaturize:"mac:WindowDidDeminiaturize",WindowDidEndSheet:"mac:WindowDidEndSheet",WindowDidEnterFullScreen:"mac:WindowDidEnterFullScreen",WindowDidEnterVersionBrowser:"mac:WindowDidEnterVersionBrowser",WindowDidExitFullScreen:"mac:WindowDidExitFullScreen",WindowDidExitVersionBrowser:"mac:WindowDidExitVersionBrowser",WindowDidExpose:"mac:WindowDidExpose",WindowDidFocus:"mac:WindowDidFocus",WindowDidMiniaturize:"mac:WindowDidMiniaturize",WindowDidMove:"mac:WindowDidMove",WindowDidOrderOffScreen:"mac:WindowDidOrderOffScreen",WindowDidOrderOnScreen:"mac:WindowDidOrderOnScreen",WindowDidResignKey:"mac:WindowDidResignKey",WindowDidResignMain:"mac:WindowDidResignMain",WindowDidResize:"mac:WindowDidResize",WindowDidUpdate:"mac:WindowDidUpdate",WindowDidUpdateAlpha:"mac:WindowDidUpdateAlpha",WindowDidUpdateCollectionBehavior:"mac:WindowDidUpdateCollectionBehavior",WindowDidUpdateCollectionProperties:"mac:WindowDidUpdateCollectionProperties",WindowDidUpdateShadow:"mac:WindowDidUpdateShadow",WindowDidUpdateTitle:"mac:WindowDidUpdateTitle",WindowDidUpdateToolbar:"mac:WindowDidUpdateToolbar",WindowDidZoom:"mac:WindowDidZoom",WindowFileDraggingEntered:"mac:WindowFileDraggingEntered",WindowFileDraggingExited:"mac:WindowFileDraggingExited",WindowFileDraggingPerformed:"mac:WindowFileDraggingPerformed",WindowHide:"mac:WindowHide",WindowMaximise:"mac:WindowMaximise",WindowUnMaximise:"mac:WindowUnMaximise",WindowMinimise:"mac:WindowMinimise",WindowUnMinimise:"mac:WindowUnMinimise",WindowShouldClose:"mac:WindowShouldClose",WindowShow:"mac:WindowShow",WindowWillBecomeKey:"mac:WindowWillBecomeKey",WindowWillBecomeMain:"mac:WindowWillBecomeMain",WindowWillBeginSheet:"mac:WindowWillBeginSheet",WindowWillChangeOrderingMode:"mac:WindowWillChangeOrderingMode",WindowWillClose:"mac:WindowWillClose",WindowWillDeminiaturize:"mac:WindowWillDeminiaturize",WindowWillEnterFullScreen:"mac:WindowWillEnterFullScreen",WindowWillEnterVersionBrowser:"mac:WindowWillEnterVersionBrowser",WindowWillExitFullScreen:"mac:WindowWillExitFullScreen",WindowWillExitVersionBrowser:"mac:WindowWillExitVersionBrowser",WindowWillFocus:"mac:WindowWillFocus",WindowWillMiniaturize:"mac:WindowWillMiniaturize",WindowWillMove:"mac:WindowWillMove",WindowWillOrderOffScreen:"mac:WindowWillOrderOffScreen",WindowWillOrderOnScreen:"mac:WindowWillOrderOnScreen",WindowWillResignMain:"mac:WindowWillResignMain",WindowWillResize:"mac:WindowWillResize",WindowWillUnfocus:"mac:WindowWillUnfocus",WindowWillUpdate:"mac:WindowWillUpdate",WindowWillUpdateAlpha:"mac:WindowWillUpdateAlpha",WindowWillUpdateCollectionBehavior:"mac:WindowWillUpdateCollectionBehavior",WindowWillUpdateCollectionProperties:"mac:WindowWillUpdateCollectionProperties",WindowWillUpdateShadow:"mac:WindowWillUpdateShadow",WindowWillUpdateTitle:"mac:WindowWillUpdateTitle",WindowWillUpdateToolbar:"mac:WindowWillUpdateToolbar",WindowWillUpdateVisibility:"mac:WindowWillUpdateVisibility",WindowWillUseStandardFrame:"mac:WindowWillUseStandardFrame",WindowZoomIn:"mac:WindowZoomIn",WindowZoomOut:"mac:WindowZoomOut",WindowZoomReset:"mac:WindowZoomReset"}),Linux:Object.freeze({ApplicationStartup:"linux:ApplicationStartup",SystemThemeChanged:"linux:SystemThemeChanged",WindowDeleteEvent:"linux:WindowDeleteEvent",WindowDidMove:"linux:WindowDidMove",WindowDidResize:"linux:WindowDidResize",WindowFocusIn:"linux:WindowFocusIn",WindowFocusOut:"linux:WindowFocusOut",WindowLoadChanged:"linux:WindowLoadChanged"}),Common:Object.freeze({ApplicationOpenedWithFile:"common:ApplicationOpenedWithFile",ApplicationStarted:"common:ApplicationStarted",ThemeChanged:"common:ThemeChanged",WindowClosing:"common:WindowClosing",WindowDidMove:"common:WindowDidMove",WindowDidResize:"common:WindowDidResize",WindowDPIChanged:"common:WindowDPIChanged",WindowFilesDropped:"common:WindowFilesDropped",WindowFocus:"common:WindowFocus",WindowFullscreen:"common:WindowFullscreen",WindowHide:"common:WindowHide",WindowLostFocus:"common:WindowLostFocus",WindowMaximise:"common:WindowMaximise",WindowMinimise:"common:WindowMinimise",WindowRestore:"common:WindowRestore",WindowRuntimeReady:"common:WindowRuntimeReady",WindowShow:"common:WindowShow",WindowUnFullscreen:"common:WindowUnFullscreen",WindowUnMaximise:"common:WindowUnMaximise",WindowUnMinimise:"common:WindowUnMinimise",WindowZoom:"common:WindowZoom",WindowZoomIn:"common:WindowZoomIn",WindowZoomOut:"common:WindowZoomOut",WindowZoomReset:"common:WindowZoomReset"})});window._wails=window._wails||{};window._wails.dispatchWailsEvent=Fn;var kn=m(d.Events),On=0,M=class{constructor(e,i=null){this.name=e,this.data=i}};function Fn(n){let e=p.get(n.name);if(!e)return;let i=new M(n.name,n.data);"sender"in n&&(i.sender=n.sender),e=e.filter(o=>!o.dispatch(i)),e.length===0?p.delete(n.name):p.set(n.name,e)}function ne(n,e,i){let o=p.get(n)||[],t=new B(n,e,i);return o.push(t),p.set(n,o),()=>ze(t)}function Ln(n,e){return ne(n,e,-1)}function Un(n,e){return ne(n,e,1)}function In(...n){n.forEach(e=>p.delete(e))}function zn(){p.clear()}function ie(n){return kn(On,n)}function Be(){return new MouseEvent("mousedown").buttons===0}function He(){if(!EventTarget||!AbortSignal||!AbortController)return!1;let n=!0,e=new EventTarget,i=new AbortController;return e.addEventListener("test",()=>{n=!1},{signal:i.signal}),i.abort(),e.dispatchEvent(new CustomEvent("test")),n}function H(n){var e;return n.target instanceof HTMLElement?n.target:!(n.target instanceof HTMLElement)&&n.target instanceof Node&&(e=n.target.parentElement)!=null?e:document.body}var Ne=!1;document.addEventListener("DOMContentLoaded",()=>{Ne=!0});function Ze(n){Ne||document.readyState==="complete"?n():document.addEventListener("DOMContentLoaded",n)}var jn=0,Bn=1,Hn=2,Nn=3,Zn=4,Vn=5,Gn=6,Kn=7,Yn=8,Xn=9,Jn=10,Qn=11,qn=12,_n=13,$n=14,ei=15,ni=16,ii=17,oi=18,ti=19,ri=20,si=21,ai=22,li=23,ci=24,di=25,mi=26,ui=27,wi=28,pi=29,fi=30,gi=31,hi=32,Wi=33,bi=34,vi=35,yi=36,Ci=37,Pi=38,Di=39,Mi=40,Si=41,Ti=42,xi=43,Ai=44,Ri=45,Ei=46,ki=47,s=Symbol("caller");s;var N=class N{constructor(e=""){this[s]=m(d.Window,e);for(let i of Object.getOwnPropertyNames(N.prototype))i!=="constructor"&&typeof this[i]=="function"&&(this[i]=this[i].bind(this))}Get(e){return new N(e)}Position(){return this[s](jn)}Center(){return this[s](Bn)}Close(){return this[s](Hn)}DisableSizeConstraints(){return this[s](Nn)}EnableSizeConstraints(){return this[s](Zn)}Focus(){return this[s](Vn)}ForceReload(){return this[s](Gn)}Fullscreen(){return this[s](Kn)}GetScreen(){return this[s](Yn)}GetZoom(){return this[s](Xn)}Height(){return this[s](Jn)}Hide(){return this[s](Qn)}IsFocused(){return this[s](qn)}IsFullscreen(){return this[s](_n)}IsMaximised(){return this[s]($n)}IsMinimised(){return this[s](ei)}Maximise(){return this[s](ni)}Minimise(){return this[s](ii)}Name(){return this[s](oi)}OpenDevTools(){return this[s](ti)}RelativePosition(){return this[s](ri)}Reload(){return this[s](si)}Resizable(){return this[s](ai)}Restore(){return this[s](li)}SetPosition(e,i){return this[s](ci,{x:e,y:i})}SetAlwaysOnTop(e){return this[s](di,{alwaysOnTop:e})}SetBackgroundColour(e,i,o,t){return this[s](mi,{r:e,g:i,b:o,a:t})}SetFrameless(e){return this[s](ui,{frameless:e})}SetFullscreenButtonEnabled(e){return this[s](wi,{enabled:e})}SetMaxSize(e,i){return this[s](pi,{width:e,height:i})}SetMinSize(e,i){return this[s](fi,{width:e,height:i})}SetRelativePosition(e,i){return this[s](gi,{x:e,y:i})}SetResizable(e){return this[s](hi,{resizable:e})}SetSize(e,i){return this[s](Wi,{width:e,height:i})}SetTitle(e){return this[s](bi,{title:e})}SetZoom(e){return this[s](vi,{zoom:e})}Show(){return this[s](yi)}Size(){return this[s](Ci)}ToggleFullscreen(){return this[s](Pi)}ToggleMaximise(){return this[s](Di)}UnFullscreen(){return this[s](Mi)}UnMaximise(){return this[s](Si)}UnMinimise(){return this[s](Ti)}Width(){return this[s](xi)}Zoom(){return this[s](Ai)}ZoomIn(){return this[s](Ri)}ZoomOut(){return this[s](Ei)}ZoomReset(){return this[s](ki)}},te=N,Oi=new te(""),Z=Oi;function Fi(n,e=null){ie(new M(n,e))}function Li(n,e){let i=Z.Get(n),o=i[e];if(typeof o=="function")try{o.call(i)}catch(t){}}function Ve(n){let e=n.currentTarget;function i(t="Yes"){if(t!=="Yes")return;let r=e.getAttribute("wml-event")||e.getAttribute("data-wml-event"),a=e.getAttribute("wml-target-window")||e.getAttribute("data-wml-target-window")||"",l=e.getAttribute("wml-window")||e.getAttribute("data-wml-window"),c=e.getAttribute("wml-openurl")||e.getAttribute("data-wml-openurl");r!==null&&Fi(r),l!==null&&Li(a,l),c!==null&&q(c)}let o=e.getAttribute("wml-confirm")||e.getAttribute("data-wml-confirm");o?$({Title:"Confirm",Message:o,Detached:!1,Buttons:[{Label:"Yes"},{Label:"No",IsDefault:!0}]}).then(i):i()}var L=Symbol("controller"),S=Symbol("triggerMap"),b=Symbol("elementCount");L;var re=class{constructor(){this[L]=new AbortController}set(e,i){return{signal:this[L].signal}}reset(){this[L].abort(),this[L]=new AbortController}};S,b;var se=class{constructor(){this[S]=new WeakMap,this[b]=0}set(e,i){return this[S].has(e)||this[b]++,this[S].set(e,i),{}}reset(){if(!(this[b]<=0)){for(let e of document.body.querySelectorAll("*")){if(this[b]<=0)break;let i=this[S].get(e);i!=null&&this[b]--;for(let o of i||[])e.removeEventListener(o,Ve)}this[S]=new WeakMap,this[b]=0}}},Ge=He()?new re:new se;function Ui(n){let e=/\S+/g,i=n.getAttribute("wml-trigger")||n.getAttribute("data-wml-trigger")||"click",o=[],t;for(;(t=e.exec(i))!==null;)o.push(t[0]);let r=Ge.set(n,o);for(let a of o)n.addEventListener(a,Ve,r)}function ae(){Ze(Ke)}function Ke(){Ge.reset(),document.body.querySelectorAll("[wml-event], [wml-window], [wml-openurl], [data-wml-event], [data-wml-window], [data-wml-openurl]").forEach(Ui)}window.wails=ce;ae();var ue={};u(ue,{Capabilities:()=>Bi,Environment:()=>Hi,IsAMD64:()=>Vi,IsARM:()=>Gi,IsARM64:()=>Ki,IsDarkMode:()=>ji,IsDebug:()=>me,IsLinux:()=>Ni,IsMac:()=>Zi,IsWindows:()=>V,invoke:()=>v});var Ye=m(d.System),Ii=0,zi=1,de=function(){var n,e,i,o,t;try{if((e=(n=window.chrome)==null?void 0:n.webview)!=null&&e.postMessage)return window.chrome.webview.postMessage.bind(window.chrome.webview);if((t=(o=(i=window.webkit)==null?void 0:i.messageHandlers)==null?void 0:o.external)!=null&&t.postMessage)return window.webkit.messageHandlers.external.postMessage.bind(window.webkit.messageHandlers.external)}catch(r){}return null}();function v(n){de==null||de(n)}function ji(){return Ye(Ii)}async function Bi(){let n=await fetch("/wails/capabilities");if(n.ok)return n.json();throw new Error("could not fetch capabilities: "+n.statusText)}function Hi(){return Ye(zi)}function V(){return window._wails.environment.OS==="windows"}function Ni(){return window._wails.environment.OS==="linux"}function Zi(){return window._wails.environment.OS==="darwin"}function Vi(){return window._wails.environment.Arch==="amd64"}function Gi(){return window._wails.environment.Arch==="arm"}function Ki(){return window._wails.environment.Arch==="arm64"}function me(){return!!window._wails.environment.Debug}window.addEventListener("contextmenu",Qi);var Yi=m(d.ContextMenu),Xi=0;function Ji(n,e,i,o){Yi(Xi,{id:n,x:e,y:i,data:o})}function Qi(n){let e=H(n),i=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu").trim();if(i){n.preventDefault();let o=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu-data");Ji(i,n.clientX,n.clientY,o)}else qi(n,e)}function qi(n,e){if(me())return;switch(window.getComputedStyle(e).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":n.preventDefault();return}if(e.isContentEditable)return;let i=window.getSelection(),o=i&&i.toString().length>0;if(o)for(let t=0;tU});function U(n){try{return window._wails.flags[n]}catch(e){throw new Error("Unable to retrieve flag '"+n+"': "+e,{cause:e})}}var I=!1,z=!1,he=!1,x=!1,A=!1,y="",Xe="auto",T=0,pe=Be();window._wails=window._wails||{};window._wails.setResizable=n=>{he=n,he||(x=A=!1,w())};window.addEventListener("mousedown",We,{capture:!0});window.addEventListener("mousemove",We,{capture:!0});window.addEventListener("mouseup",We,{capture:!0});for(let n of["click","contextmenu","dblclick"])window.addEventListener(n,_i,{capture:!0});function _i(n){(z||A)&&(n.stopImmediatePropagation(),n.stopPropagation(),n.preventDefault())}var fe=0,$i=1,ge=2;function We(n){let e,i=n.buttons;switch(n.type){case"mousedown":e=fe,pe||(i=T|1<ao,Quit:()=>co,Show:()=>lo});var be=m(d.Application),to=0,ro=1,so=2;function ao(){return be(to)}function lo(){return be(ro)}function co(){return be(so)}var Te={};u(Te,{ByID:()=>ko,ByName:()=>Eo,Call:()=>Se,RuntimeError:()=>X});var Qe=Function.prototype.toString,R=typeof Reflect=="object"&&Reflect!==null&&Reflect.apply,ye,G;if(typeof R=="function"&&typeof Object.defineProperty=="function")try{ye=Object.defineProperty({},"length",{get:function(){throw G}}),G={},R(function(){throw 42},null,ye)}catch(n){n!==G&&(R=null)}else R=null;var mo=/^\s*class\b/,Pe=function(e){try{var i=Qe.call(e);return mo.test(i)}catch(o){return!1}},Ce=function(e){try{return Pe(e)?!1:(Qe.call(e),!0)}catch(i){return!1}},K=Object.prototype.toString,uo="[object Object]",wo="[object Function]",po="[object GeneratorFunction]",fo="[object HTMLAllCollection]",go="[object HTML document.all class]",ho="[object HTMLCollection]",Wo=typeof Symbol=="function"&&!!Symbol.toStringTag,bo=!(0 in[,]),De=function(){return!1};typeof document=="object"&&(Je=document.all,K.call(Je)===K.call(document.all)&&(De=function(e){if((bo||!e)&&(typeof e>"u"||typeof e=="object"))try{var i=K.call(e);return(i===fo||i===go||i===ho||i===uo)&&e("")==null}catch(o){}return!1}));var Je;function vo(n){if(De(n))return!0;if(!n||typeof n!="function"&&typeof n!="object")return!1;try{R(n,null,ye)}catch(e){if(e!==G)return!1}return!Pe(n)&&Ce(n)}function yo(n){if(De(n))return!0;if(!n||typeof n!="function"&&typeof n!="object")return!1;if(Wo)return Ce(n);if(Pe(n))return!1;var e=K.call(n);return e!==wo&&e!==po&&!/^\[object HTML/.test(e)?!1:Ce(n)}var h=R?vo:yo;var k=class extends Error{constructor(e,i){super(e,i),this.name="CancelError"}},W=class extends Error{constructor(e,i,o){super((o!=null?o:"Unhandled rejection in cancelled promise.")+" Reason: "+Co(i),{cause:i}),this.promise=e,this.name="CancelledRejectionError"}},f=Symbol("barrier"),Me=Symbol("cancelImpl"),en,qe=(en=Symbol.species)!=null?en:Symbol("speciesPolyfill"),j=class n extends Promise{constructor(e,i){let o,t;if(super((c,g)=>{o=c,t=g}),this.constructor[qe]!==Promise)throw new TypeError("CancellablePromise does not support transparent subclassing. Please refrain from overriding the [Symbol.species] static property.");let r={promise:this,resolve:o,reject:t,get oncancelled(){return i!=null?i:null},set oncancelled(c){i=c!=null?c:void 0}},a={get root(){return a},resolving:!1,settled:!1};Object.defineProperties(this,{[f]:{configurable:!1,enumerable:!1,writable:!0,value:null},[Me]:{configurable:!1,enumerable:!1,writable:!1,value:nn(r,a)}});let l=tn(r,a);try{e(on(r,a),l)}catch(c){a.resolving||l(c)}}cancel(e){return new n(i=>{Promise.all([this[Me](new k("Promise cancelled.",{cause:e})),Po(this)]).then(()=>i(),()=>i())})}cancelOn(e){return e.aborted?this.cancel(e.reason):e.addEventListener("abort",()=>void this.cancel(e.reason),{capture:!0}),this}then(e,i,o){if(!(this instanceof n))throw new TypeError("CancellablePromise.prototype.then called on an invalid object.");if(h(e)||(e=_e),h(i)||(i=$e),e===_e&&i==$e)return new n(r=>r(this));let t={};return this[f]=t,new n((r,a)=>{super.then(l=>{var c;this[f]===t&&(this[f]=null),(c=t.resolve)==null||c.call(t);try{r(e(l))}catch(g){a(g)}},l=>{var c;this[f]===t&&(this[f]=null),(c=t.resolve)==null||c.call(t);try{r(i(l))}catch(g){a(g)}})},async r=>{try{return o==null?void 0:o(r)}finally{await this.cancel(r)}})}catch(e,i){return this.then(void 0,e,i)}finally(e,i){if(!(this instanceof n))throw new TypeError("CancellablePromise.prototype.finally called on an invalid object.");return h(e)?this.then(o=>n.resolve(e()).then(()=>o),o=>n.resolve(e()).then(()=>{throw o}),i):this.then(e,e,i)}static get[(f,Me,qe)](){return Promise}static all(e){let i=Array.from(e),o=i.length===0?n.resolve(i):new n((t,r)=>{Promise.all(i).then(t,r)},t=>Y(o,i,t));return o}static allSettled(e){let i=Array.from(e),o=i.length===0?n.resolve(i):new n((t,r)=>{Promise.allSettled(i).then(t,r)},t=>Y(o,i,t));return o}static any(e){let i=Array.from(e),o=i.length===0?n.resolve(i):new n((t,r)=>{Promise.any(i).then(t,r)},t=>Y(o,i,t));return o}static race(e){let i=Array.from(e),o=new n((t,r)=>{Promise.race(i).then(t,r)},t=>Y(o,i,t));return o}static cancel(e){let i=new n(()=>{});return i.cancel(e),i}static timeout(e,i){let o=new n(()=>{});return AbortSignal&&typeof AbortSignal=="function"&&AbortSignal.timeout&&typeof AbortSignal.timeout=="function"?AbortSignal.timeout(e).addEventListener("abort",()=>void o.cancel(i)):setTimeout(()=>void o.cancel(i),e),o}static sleep(e,i){return new n(o=>{setTimeout(()=>o(i),e)})}static reject(e){return new n((i,o)=>o(e))}static resolve(e){return e instanceof n?e:new n(i=>i(e))}static withResolvers(){let e={oncancelled:null};return e.promise=new n((i,o)=>{e.resolve=i,e.reject=o},i=>{var o;(o=e.oncancelled)==null||o.call(e,i)}),e}};function nn(n,e){let i;return o=>{if(e.settled||(e.settled=!0,e.reason=o,n.reject(o),Promise.prototype.then.call(n.promise,void 0,t=>{if(t!==o)throw t})),!(!e.reason||!n.oncancelled))return i=new Promise(t=>{try{t(n.oncancelled(e.reason.cause))}catch(r){Promise.reject(new W(n.promise,r,"Unhandled exception in oncancelled callback."))}}).catch(t=>{Promise.reject(new W(n.promise,t,"Unhandled rejection in oncancelled callback."))}),n.oncancelled=null,i}}function on(n,e){return i=>{if(!e.resolving){if(e.resolving=!0,i===n.promise){if(e.settled)return;e.settled=!0,n.reject(new TypeError("A promise cannot be resolved with itself."));return}if(i!=null&&(typeof i=="object"||typeof i=="function")){let o;try{o=i.then}catch(t){e.settled=!0,n.reject(t);return}if(h(o)){try{let a=i.cancel;if(h(a)){let l=c=>{Reflect.apply(a,i,[c])};e.reason?nn(Ue(Le({},n),{oncancelled:l}),e)(e.reason):n.oncancelled=l}}catch(a){}let t={root:e.root,resolving:!1,get settled(){return this.root.settled},set settled(a){this.root.settled=a},get reason(){return this.root.reason}},r=tn(n,t);try{Reflect.apply(o,i,[on(n,t),r])}catch(a){r(a)}return}}e.settled||(e.settled=!0,n.resolve(i))}}}function tn(n,e){return i=>{if(!e.resolving)if(e.resolving=!0,e.settled){try{if(i instanceof k&&e.reason instanceof k&&Object.is(i.cause,e.reason.cause))return}catch(o){}Promise.reject(new W(n.promise,i))}else e.settled=!0,n.reject(i)}}function Y(n,e,i){let o=[];for(let t of e){let r;try{if(!h(t.then)||(r=t.cancel,!h(r)))continue}catch(l){continue}let a;try{a=Reflect.apply(r,t,[i])}catch(l){Promise.reject(new W(n,l,"Unhandled exception in cancel method."));continue}a&&o.push((a instanceof Promise?a:Promise.resolve(a)).catch(l=>{Promise.reject(new W(n,l,"Unhandled rejection in cancel method."))}))}return Promise.all(o)}function _e(n){return n}function $e(n){throw n}function Co(n){try{if(n instanceof Error||typeof n!="object"||n.toString!==Object.prototype.toString)return""+n}catch(e){}try{return JSON.stringify(n)}catch(e){}try{return Object.prototype.toString.call(n)}catch(e){}return""}function Po(n){var i;let e=(i=n[f])!=null?i:{};return"promise"in e||Object.assign(e,E()),n[f]==null&&(e.resolve(),n[f]=e),e.promise}var E=Promise.withResolvers;E&&typeof E=="function"?E=E.bind(Promise):E=function(){let n,e;return{promise:new Promise((o,t)=>{n=o,e=t}),resolve:n,reject:e}};window._wails=window._wails||{};window._wails.callResultHandler=xo;window._wails.callErrorHandler=Ao;var Do=m(d.Call),Mo=m(d.CancelCall),O=new Map,So=0,To=0,X=class extends Error{constructor(e,i){super(e,i),this.name="RuntimeError"}};function xo(n,e,i){let o=rn(n);if(o)if(!e)o.resolve(void 0);else if(!i)o.resolve(e);else try{o.resolve(JSON.parse(e))}catch(t){o.reject(new TypeError("could not parse result: "+t.message,{cause:t}))}}function Ao(n,e,i){let o=rn(n);if(o)if(!i)o.reject(new Error(e));else{let t;try{t=JSON.parse(e)}catch(l){o.reject(new TypeError("could not parse error: "+l.message,{cause:l}));return}let r={};t.cause&&(r.cause=t.cause);let a;switch(t.kind){case"ReferenceError":a=new ReferenceError(t.message,r);break;case"TypeError":a=new TypeError(t.message,r);break;case"RuntimeError":a=new X(t.message,r);break;default:a=new Error(t.message,r);break}o.reject(a)}}function rn(n){let e=O.get(n);return O.delete(n),e}function Ro(){let n;do n=P();while(O.has(n));return n}function Se(n){let e=Ro(),i=j.withResolvers();O.set(e,{resolve:i.resolve,reject:i.reject});let o=Do(So,Object.assign({"call-id":e},n)),t=!1;o.then(()=>{t=!0},a=>{O.delete(e),i.reject(a)});let r=()=>(O.delete(e),Mo(To,{"call-id":e}).catch(a=>{}));return i.oncancelled=()=>t?r():o.then(r),i.promise}function Eo(n,...e){return Se({methodName:n,args:e})}function ko(n,...e){return Se({methodID:n,args:e})}var xe={};u(xe,{SetText:()=>Lo,Text:()=>Uo});var sn=m(d.Clipboard),Oo=0,Fo=1;function Lo(n){return sn(Oo,{text:n})}function Uo(){return sn(Fo)}var Ae={};u(Ae,{Any:()=>C,Array:()=>zo,ByteSlice:()=>Io,Map:()=>jo,Nullable:()=>Bo,Struct:()=>Ho});function C(n){return n}function Io(n){return n==null?"":n}function zo(n){return n===C?e=>e===null?[]:e:e=>{if(e===null)return[];for(let i=0;ii===null?{}:i:i=>{if(i===null)return{};for(let o in i)i[o]=e(i[o]);return i}}function Bo(n){return n===C?C:e=>e===null?null:n(e)}function Ho(n){let e=!0;for(let i in n)if(n[i]!==C){e=!1;break}return e?C:i=>{for(let o in n)o in i&&(i[o]=n[o](i[o]));return i}}var Ee={};u(Ee,{GetAll:()=>Go,GetCurrent:()=>Yo,GetPrimary:()=>Ko});var Re=m(d.Screens),No=0,Zo=1,Vo=2;function Go(){return Re(No)}function Ko(){return Re(Zo)}function Yo(){return Re(Vo)}window._wails=window._wails||{};window._wails.invoke=v;v("wails:runtime:ready");export{ve as Application,_ as Browser,Te as Call,k as CancelError,j as CancellablePromise,W as CancelledRejectionError,xe as Clipboard,Ae as Create,ee as Dialogs,oe as Events,we as Flags,Ee as Screens,ue as System,le as WML,Z as Window}; +var Fe=Object.defineProperty,an=Object.defineProperties;var ln=Object.getOwnPropertyDescriptors;var ke=Object.getOwnPropertySymbols;var cn=Object.prototype.hasOwnProperty,dn=Object.prototype.propertyIsEnumerable;var Oe=(n,e,i)=>e in n?Fe(n,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[e]=i,Le=(n,e)=>{for(var i in e||(e={}))cn.call(e,i)&&Oe(n,i,e[i]);if(ke)for(var i of ke(e))dn.call(e,i)&&Oe(n,i,e[i]);return n},Ue=(n,e)=>an(n,ln(e));var u=(n,e)=>{for(var i in e)Fe(n,i,{get:e[i],enumerable:!0})};var ce={};u(ce,{Application:()=>ve,Browser:()=>_,Call:()=>Te,CancelError:()=>k,CancellablePromise:()=>j,CancelledRejectionError:()=>b,Clipboard:()=>xe,Create:()=>Ae,Dialogs:()=>ee,Events:()=>oe,Flags:()=>we,Screens:()=>Ee,System:()=>ue,WML:()=>le,Window:()=>Z});var le={};u(le,{Enable:()=>ae,Reload:()=>Ke});var _={};u(_,{OpenURL:()=>q});var mn="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";function D(n=21){let e="",i=n|0;for(;i--;)e+=mn[Math.random()*64|0];return e}var un=window.location.origin+"/wails/runtime",d=Object.freeze({Call:0,Clipboard:1,Application:2,Events:3,ContextMenu:4,Dialog:5,Window:6,Screens:7,System:8,Browser:9,CancelCall:10}),wn=D();function m(n,e=""){return function(i,o=null){return pn(n,i,e,o)}}async function pn(n,e,i,o){var l,c;let t=new URL(un);t.searchParams.append("object",n.toString()),t.searchParams.append("method",e.toString()),o&&t.searchParams.append("args",JSON.stringify(o));let r={"x-wails-client-id":wn};i&&(r["x-wails-window-name"]=i);let a=await fetch(t,{headers:r});if(!a.ok)throw new Error(await a.text());return((c=(l=a.headers.get("Content-Type"))==null?void 0:l.indexOf("application/json"))!=null?c:-1)!==-1?a.json():a.text()}var fn=m(d.Browser),gn=0;function q(n){return fn(gn,{url:n.toString()})}var ee={};u(ee,{Error:()=>An,Info:()=>Tn,OpenFile:()=>Rn,Question:()=>$,SaveFile:()=>En,Warning:()=>xn});window._wails=window._wails||{};window._wails.dialogErrorCallback=Mn;window._wails.dialogResultCallback=Dn;var hn=m(d.Dialog),F=new Map,Wn=0,bn=1,vn=2,yn=3,Cn=4,Pn=5;function Dn(n,e,i){let o=Ie(n);if(o)if(i)try{o.resolve(JSON.parse(e))}catch(t){o.reject(new TypeError("could not parse result: "+t.message,{cause:t}))}else o.resolve(e)}function Mn(n,e){var i;(i=Ie(n))==null||i.reject(new window.Error(e))}function Ie(n){let e=F.get(n);return F.delete(n),e}function Sn(){let n;do n=D();while(F.has(n));return n}function M(n,e={}){let i=Sn();return new Promise((o,t)=>{F.set(i,{resolve:o,reject:t}),hn(n,Object.assign({"dialog-id":i},e)).catch(r=>{F.delete(i),t(r)})})}function Tn(n){return M(Wn,n)}function xn(n){return M(bn,n)}function An(n){return M(vn,n)}function $(n){return M(yn,n)}function Rn(n){var e;return(e=M(Cn,n))!=null?e:[]}function En(n){return M(Pn,n)}var oe={};u(oe,{Emit:()=>ie,Off:()=>In,OffAll:()=>zn,On:()=>Ln,OnMultiple:()=>ne,Once:()=>Un,Types:()=>je,WailsEvent:()=>h});var p=new Map,B=class{constructor(e,i,o){this.eventName=e,this.callback=i,this.maxCallbacks=o||-1}dispatch(e){try{this.callback(e)}catch(i){}return this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0)}};function ze(n){let e=p.get(n.eventName);e&&(e=e.filter(i=>i!==n),e.length===0?p.delete(n.eventName):p.set(n.eventName,e))}var je=Object.freeze({Windows:Object.freeze({APMPowerSettingChange:"windows:APMPowerSettingChange",APMPowerStatusChange:"windows:APMPowerStatusChange",APMResumeAutomatic:"windows:APMResumeAutomatic",APMResumeSuspend:"windows:APMResumeSuspend",APMSuspend:"windows:APMSuspend",ApplicationStarted:"windows:ApplicationStarted",SystemThemeChanged:"windows:SystemThemeChanged",WebViewNavigationCompleted:"windows:WebViewNavigationCompleted",WindowActive:"windows:WindowActive",WindowBackgroundErase:"windows:WindowBackgroundErase",WindowClickActive:"windows:WindowClickActive",WindowClosing:"windows:WindowClosing",WindowDidMove:"windows:WindowDidMove",WindowDidResize:"windows:WindowDidResize",WindowDPIChanged:"windows:WindowDPIChanged",WindowDragDrop:"windows:WindowDragDrop",WindowDragEnter:"windows:WindowDragEnter",WindowDragLeave:"windows:WindowDragLeave",WindowDragOver:"windows:WindowDragOver",WindowEndMove:"windows:WindowEndMove",WindowEndResize:"windows:WindowEndResize",WindowFullscreen:"windows:WindowFullscreen",WindowHide:"windows:WindowHide",WindowInactive:"windows:WindowInactive",WindowKeyDown:"windows:WindowKeyDown",WindowKeyUp:"windows:WindowKeyUp",WindowKillFocus:"windows:WindowKillFocus",WindowNonClientHit:"windows:WindowNonClientHit",WindowNonClientMouseDown:"windows:WindowNonClientMouseDown",WindowNonClientMouseLeave:"windows:WindowNonClientMouseLeave",WindowNonClientMouseMove:"windows:WindowNonClientMouseMove",WindowNonClientMouseUp:"windows:WindowNonClientMouseUp",WindowPaint:"windows:WindowPaint",WindowRestore:"windows:WindowRestore",WindowSetFocus:"windows:WindowSetFocus",WindowShow:"windows:WindowShow",WindowStartMove:"windows:WindowStartMove",WindowStartResize:"windows:WindowStartResize",WindowUnFullscreen:"windows:WindowUnFullscreen",WindowZOrderChanged:"windows:WindowZOrderChanged",WindowMinimise:"windows:WindowMinimise",WindowUnMinimise:"windows:WindowUnMinimise",WindowMaximise:"windows:WindowMaximise",WindowUnMaximise:"windows:WindowUnMaximise"}),Mac:Object.freeze({ApplicationDidBecomeActive:"mac:ApplicationDidBecomeActive",ApplicationDidChangeBackingProperties:"mac:ApplicationDidChangeBackingProperties",ApplicationDidChangeEffectiveAppearance:"mac:ApplicationDidChangeEffectiveAppearance",ApplicationDidChangeIcon:"mac:ApplicationDidChangeIcon",ApplicationDidChangeOcclusionState:"mac:ApplicationDidChangeOcclusionState",ApplicationDidChangeScreenParameters:"mac:ApplicationDidChangeScreenParameters",ApplicationDidChangeStatusBarFrame:"mac:ApplicationDidChangeStatusBarFrame",ApplicationDidChangeStatusBarOrientation:"mac:ApplicationDidChangeStatusBarOrientation",ApplicationDidChangeTheme:"mac:ApplicationDidChangeTheme",ApplicationDidFinishLaunching:"mac:ApplicationDidFinishLaunching",ApplicationDidHide:"mac:ApplicationDidHide",ApplicationDidResignActive:"mac:ApplicationDidResignActive",ApplicationDidUnhide:"mac:ApplicationDidUnhide",ApplicationDidUpdate:"mac:ApplicationDidUpdate",ApplicationShouldHandleReopen:"mac:ApplicationShouldHandleReopen",ApplicationWillBecomeActive:"mac:ApplicationWillBecomeActive",ApplicationWillFinishLaunching:"mac:ApplicationWillFinishLaunching",ApplicationWillHide:"mac:ApplicationWillHide",ApplicationWillResignActive:"mac:ApplicationWillResignActive",ApplicationWillTerminate:"mac:ApplicationWillTerminate",ApplicationWillUnhide:"mac:ApplicationWillUnhide",ApplicationWillUpdate:"mac:ApplicationWillUpdate",MenuDidAddItem:"mac:MenuDidAddItem",MenuDidBeginTracking:"mac:MenuDidBeginTracking",MenuDidClose:"mac:MenuDidClose",MenuDidDisplayItem:"mac:MenuDidDisplayItem",MenuDidEndTracking:"mac:MenuDidEndTracking",MenuDidHighlightItem:"mac:MenuDidHighlightItem",MenuDidOpen:"mac:MenuDidOpen",MenuDidPopUp:"mac:MenuDidPopUp",MenuDidRemoveItem:"mac:MenuDidRemoveItem",MenuDidSendAction:"mac:MenuDidSendAction",MenuDidSendActionToItem:"mac:MenuDidSendActionToItem",MenuDidUpdate:"mac:MenuDidUpdate",MenuWillAddItem:"mac:MenuWillAddItem",MenuWillBeginTracking:"mac:MenuWillBeginTracking",MenuWillDisplayItem:"mac:MenuWillDisplayItem",MenuWillEndTracking:"mac:MenuWillEndTracking",MenuWillHighlightItem:"mac:MenuWillHighlightItem",MenuWillOpen:"mac:MenuWillOpen",MenuWillPopUp:"mac:MenuWillPopUp",MenuWillRemoveItem:"mac:MenuWillRemoveItem",MenuWillSendAction:"mac:MenuWillSendAction",MenuWillSendActionToItem:"mac:MenuWillSendActionToItem",MenuWillUpdate:"mac:MenuWillUpdate",WebViewDidCommitNavigation:"mac:WebViewDidCommitNavigation",WebViewDidFinishNavigation:"mac:WebViewDidFinishNavigation",WebViewDidReceiveServerRedirectForProvisionalNavigation:"mac:WebViewDidReceiveServerRedirectForProvisionalNavigation",WebViewDidStartProvisionalNavigation:"mac:WebViewDidStartProvisionalNavigation",WindowDidBecomeKey:"mac:WindowDidBecomeKey",WindowDidBecomeMain:"mac:WindowDidBecomeMain",WindowDidBeginSheet:"mac:WindowDidBeginSheet",WindowDidChangeAlpha:"mac:WindowDidChangeAlpha",WindowDidChangeBackingLocation:"mac:WindowDidChangeBackingLocation",WindowDidChangeBackingProperties:"mac:WindowDidChangeBackingProperties",WindowDidChangeCollectionBehavior:"mac:WindowDidChangeCollectionBehavior",WindowDidChangeEffectiveAppearance:"mac:WindowDidChangeEffectiveAppearance",WindowDidChangeOcclusionState:"mac:WindowDidChangeOcclusionState",WindowDidChangeOrderingMode:"mac:WindowDidChangeOrderingMode",WindowDidChangeScreen:"mac:WindowDidChangeScreen",WindowDidChangeScreenParameters:"mac:WindowDidChangeScreenParameters",WindowDidChangeScreenProfile:"mac:WindowDidChangeScreenProfile",WindowDidChangeScreenSpace:"mac:WindowDidChangeScreenSpace",WindowDidChangeScreenSpaceProperties:"mac:WindowDidChangeScreenSpaceProperties",WindowDidChangeSharingType:"mac:WindowDidChangeSharingType",WindowDidChangeSpace:"mac:WindowDidChangeSpace",WindowDidChangeSpaceOrderingMode:"mac:WindowDidChangeSpaceOrderingMode",WindowDidChangeTitle:"mac:WindowDidChangeTitle",WindowDidChangeToolbar:"mac:WindowDidChangeToolbar",WindowDidDeminiaturize:"mac:WindowDidDeminiaturize",WindowDidEndSheet:"mac:WindowDidEndSheet",WindowDidEnterFullScreen:"mac:WindowDidEnterFullScreen",WindowDidEnterVersionBrowser:"mac:WindowDidEnterVersionBrowser",WindowDidExitFullScreen:"mac:WindowDidExitFullScreen",WindowDidExitVersionBrowser:"mac:WindowDidExitVersionBrowser",WindowDidExpose:"mac:WindowDidExpose",WindowDidFocus:"mac:WindowDidFocus",WindowDidMiniaturize:"mac:WindowDidMiniaturize",WindowDidMove:"mac:WindowDidMove",WindowDidOrderOffScreen:"mac:WindowDidOrderOffScreen",WindowDidOrderOnScreen:"mac:WindowDidOrderOnScreen",WindowDidResignKey:"mac:WindowDidResignKey",WindowDidResignMain:"mac:WindowDidResignMain",WindowDidResize:"mac:WindowDidResize",WindowDidUpdate:"mac:WindowDidUpdate",WindowDidUpdateAlpha:"mac:WindowDidUpdateAlpha",WindowDidUpdateCollectionBehavior:"mac:WindowDidUpdateCollectionBehavior",WindowDidUpdateCollectionProperties:"mac:WindowDidUpdateCollectionProperties",WindowDidUpdateShadow:"mac:WindowDidUpdateShadow",WindowDidUpdateTitle:"mac:WindowDidUpdateTitle",WindowDidUpdateToolbar:"mac:WindowDidUpdateToolbar",WindowDidZoom:"mac:WindowDidZoom",WindowFileDraggingEntered:"mac:WindowFileDraggingEntered",WindowFileDraggingExited:"mac:WindowFileDraggingExited",WindowFileDraggingPerformed:"mac:WindowFileDraggingPerformed",WindowHide:"mac:WindowHide",WindowMaximise:"mac:WindowMaximise",WindowUnMaximise:"mac:WindowUnMaximise",WindowMinimise:"mac:WindowMinimise",WindowUnMinimise:"mac:WindowUnMinimise",WindowShouldClose:"mac:WindowShouldClose",WindowShow:"mac:WindowShow",WindowWillBecomeKey:"mac:WindowWillBecomeKey",WindowWillBecomeMain:"mac:WindowWillBecomeMain",WindowWillBeginSheet:"mac:WindowWillBeginSheet",WindowWillChangeOrderingMode:"mac:WindowWillChangeOrderingMode",WindowWillClose:"mac:WindowWillClose",WindowWillDeminiaturize:"mac:WindowWillDeminiaturize",WindowWillEnterFullScreen:"mac:WindowWillEnterFullScreen",WindowWillEnterVersionBrowser:"mac:WindowWillEnterVersionBrowser",WindowWillExitFullScreen:"mac:WindowWillExitFullScreen",WindowWillExitVersionBrowser:"mac:WindowWillExitVersionBrowser",WindowWillFocus:"mac:WindowWillFocus",WindowWillMiniaturize:"mac:WindowWillMiniaturize",WindowWillMove:"mac:WindowWillMove",WindowWillOrderOffScreen:"mac:WindowWillOrderOffScreen",WindowWillOrderOnScreen:"mac:WindowWillOrderOnScreen",WindowWillResignMain:"mac:WindowWillResignMain",WindowWillResize:"mac:WindowWillResize",WindowWillUnfocus:"mac:WindowWillUnfocus",WindowWillUpdate:"mac:WindowWillUpdate",WindowWillUpdateAlpha:"mac:WindowWillUpdateAlpha",WindowWillUpdateCollectionBehavior:"mac:WindowWillUpdateCollectionBehavior",WindowWillUpdateCollectionProperties:"mac:WindowWillUpdateCollectionProperties",WindowWillUpdateShadow:"mac:WindowWillUpdateShadow",WindowWillUpdateTitle:"mac:WindowWillUpdateTitle",WindowWillUpdateToolbar:"mac:WindowWillUpdateToolbar",WindowWillUpdateVisibility:"mac:WindowWillUpdateVisibility",WindowWillUseStandardFrame:"mac:WindowWillUseStandardFrame",WindowZoomIn:"mac:WindowZoomIn",WindowZoomOut:"mac:WindowZoomOut",WindowZoomReset:"mac:WindowZoomReset"}),Linux:Object.freeze({ApplicationStartup:"linux:ApplicationStartup",SystemThemeChanged:"linux:SystemThemeChanged",WindowDeleteEvent:"linux:WindowDeleteEvent",WindowDidMove:"linux:WindowDidMove",WindowDidResize:"linux:WindowDidResize",WindowFocusIn:"linux:WindowFocusIn",WindowFocusOut:"linux:WindowFocusOut",WindowLoadChanged:"linux:WindowLoadChanged"}),Common:Object.freeze({ApplicationOpenedWithFile:"common:ApplicationOpenedWithFile",ApplicationStarted:"common:ApplicationStarted",ThemeChanged:"common:ThemeChanged",WindowClosing:"common:WindowClosing",WindowDidMove:"common:WindowDidMove",WindowDidResize:"common:WindowDidResize",WindowDPIChanged:"common:WindowDPIChanged",WindowFilesDropped:"common:WindowFilesDropped",WindowFocus:"common:WindowFocus",WindowFullscreen:"common:WindowFullscreen",WindowHide:"common:WindowHide",WindowLostFocus:"common:WindowLostFocus",WindowMaximise:"common:WindowMaximise",WindowMinimise:"common:WindowMinimise",WindowRestore:"common:WindowRestore",WindowRuntimeReady:"common:WindowRuntimeReady",WindowShow:"common:WindowShow",WindowUnFullscreen:"common:WindowUnFullscreen",WindowUnMaximise:"common:WindowUnMaximise",WindowUnMinimise:"common:WindowUnMinimise",WindowZoom:"common:WindowZoom",WindowZoomIn:"common:WindowZoomIn",WindowZoomOut:"common:WindowZoomOut",WindowZoomReset:"common:WindowZoomReset"})});window._wails=window._wails||{};window._wails.dispatchWailsEvent=Fn;var kn=m(d.Events),On=0,h=class{constructor(e,i=null){this.name=e,this.data=i}};function Fn(n){let e=p.get(n.name);if(!e)return;let i=new h(n.name,n.data);"sender"in n&&(i.sender=n.sender),e=e.filter(o=>!o.dispatch(i)),e.length===0?p.delete(n.name):p.set(n.name,e)}function ne(n,e,i){let o=p.get(n)||[],t=new B(n,e,i);return o.push(t),p.set(n,o),()=>ze(t)}function Ln(n,e){return ne(n,e,-1)}function Un(n,e){return ne(n,e,1)}function In(...n){n.forEach(e=>p.delete(e))}function zn(){p.clear()}function ie(n,e){let i;return typeof n=="object"&&n!==null&&"name"in n&&"data"in n?i=new h(n.name,n.data):i=new h(n,e),kn(On,i)}function Be(){return new MouseEvent("mousedown").buttons===0}function He(){if(!EventTarget||!AbortSignal||!AbortController)return!1;let n=!0,e=new EventTarget,i=new AbortController;return e.addEventListener("test",()=>{n=!1},{signal:i.signal}),i.abort(),e.dispatchEvent(new CustomEvent("test")),n}function H(n){var e;return n.target instanceof HTMLElement?n.target:!(n.target instanceof HTMLElement)&&n.target instanceof Node&&(e=n.target.parentElement)!=null?e:document.body}var Ne=!1;document.addEventListener("DOMContentLoaded",()=>{Ne=!0});function Ze(n){Ne||document.readyState==="complete"?n():document.addEventListener("DOMContentLoaded",n)}var jn=0,Bn=1,Hn=2,Nn=3,Zn=4,Vn=5,Gn=6,Kn=7,Yn=8,Xn=9,Jn=10,Qn=11,qn=12,_n=13,$n=14,ei=15,ni=16,ii=17,oi=18,ti=19,ri=20,si=21,ai=22,li=23,ci=24,di=25,mi=26,ui=27,wi=28,pi=29,fi=30,gi=31,hi=32,Wi=33,bi=34,vi=35,yi=36,Ci=37,Pi=38,Di=39,Mi=40,Si=41,Ti=42,xi=43,Ai=44,Ri=45,Ei=46,ki=47,s=Symbol("caller");s;var N=class N{constructor(e=""){this[s]=m(d.Window,e);for(let i of Object.getOwnPropertyNames(N.prototype))i!=="constructor"&&typeof this[i]=="function"&&(this[i]=this[i].bind(this))}Get(e){return new N(e)}Position(){return this[s](jn)}Center(){return this[s](Bn)}Close(){return this[s](Hn)}DisableSizeConstraints(){return this[s](Nn)}EnableSizeConstraints(){return this[s](Zn)}Focus(){return this[s](Vn)}ForceReload(){return this[s](Gn)}Fullscreen(){return this[s](Kn)}GetScreen(){return this[s](Yn)}GetZoom(){return this[s](Xn)}Height(){return this[s](Jn)}Hide(){return this[s](Qn)}IsFocused(){return this[s](qn)}IsFullscreen(){return this[s](_n)}IsMaximised(){return this[s]($n)}IsMinimised(){return this[s](ei)}Maximise(){return this[s](ni)}Minimise(){return this[s](ii)}Name(){return this[s](oi)}OpenDevTools(){return this[s](ti)}RelativePosition(){return this[s](ri)}Reload(){return this[s](si)}Resizable(){return this[s](ai)}Restore(){return this[s](li)}SetPosition(e,i){return this[s](ci,{x:e,y:i})}SetAlwaysOnTop(e){return this[s](di,{alwaysOnTop:e})}SetBackgroundColour(e,i,o,t){return this[s](mi,{r:e,g:i,b:o,a:t})}SetFrameless(e){return this[s](ui,{frameless:e})}SetFullscreenButtonEnabled(e){return this[s](wi,{enabled:e})}SetMaxSize(e,i){return this[s](pi,{width:e,height:i})}SetMinSize(e,i){return this[s](fi,{width:e,height:i})}SetRelativePosition(e,i){return this[s](gi,{x:e,y:i})}SetResizable(e){return this[s](hi,{resizable:e})}SetSize(e,i){return this[s](Wi,{width:e,height:i})}SetTitle(e){return this[s](bi,{title:e})}SetZoom(e){return this[s](vi,{zoom:e})}Show(){return this[s](yi)}Size(){return this[s](Ci)}ToggleFullscreen(){return this[s](Pi)}ToggleMaximise(){return this[s](Di)}UnFullscreen(){return this[s](Mi)}UnMaximise(){return this[s](Si)}UnMinimise(){return this[s](Ti)}Width(){return this[s](xi)}Zoom(){return this[s](Ai)}ZoomIn(){return this[s](Ri)}ZoomOut(){return this[s](Ei)}ZoomReset(){return this[s](ki)}},te=N,Oi=new te(""),Z=Oi;function Fi(n,e=null){ie(new h(n,e))}function Li(n,e){let i=Z.Get(n),o=i[e];if(typeof o=="function")try{o.call(i)}catch(t){}}function Ve(n){let e=n.currentTarget;function i(t="Yes"){if(t!=="Yes")return;let r=e.getAttribute("wml-event")||e.getAttribute("data-wml-event"),a=e.getAttribute("wml-target-window")||e.getAttribute("data-wml-target-window")||"",l=e.getAttribute("wml-window")||e.getAttribute("data-wml-window"),c=e.getAttribute("wml-openurl")||e.getAttribute("data-wml-openurl");r!==null&&Fi(r),l!==null&&Li(a,l),c!==null&&q(c)}let o=e.getAttribute("wml-confirm")||e.getAttribute("data-wml-confirm");o?$({Title:"Confirm",Message:o,Detached:!1,Buttons:[{Label:"Yes"},{Label:"No",IsDefault:!0}]}).then(i):i()}var L=Symbol("controller"),S=Symbol("triggerMap"),v=Symbol("elementCount");L;var re=class{constructor(){this[L]=new AbortController}set(e,i){return{signal:this[L].signal}}reset(){this[L].abort(),this[L]=new AbortController}};S,v;var se=class{constructor(){this[S]=new WeakMap,this[v]=0}set(e,i){return this[S].has(e)||this[v]++,this[S].set(e,i),{}}reset(){if(!(this[v]<=0)){for(let e of document.body.querySelectorAll("*")){if(this[v]<=0)break;let i=this[S].get(e);i!=null&&this[v]--;for(let o of i||[])e.removeEventListener(o,Ve)}this[S]=new WeakMap,this[v]=0}}},Ge=He()?new re:new se;function Ui(n){let e=/\S+/g,i=n.getAttribute("wml-trigger")||n.getAttribute("data-wml-trigger")||"click",o=[],t;for(;(t=e.exec(i))!==null;)o.push(t[0]);let r=Ge.set(n,o);for(let a of o)n.addEventListener(a,Ve,r)}function ae(){Ze(Ke)}function Ke(){Ge.reset(),document.body.querySelectorAll("[wml-event], [wml-window], [wml-openurl], [data-wml-event], [data-wml-window], [data-wml-openurl]").forEach(Ui)}window.wails=ce;ae();var ue={};u(ue,{Capabilities:()=>Bi,Environment:()=>Hi,IsAMD64:()=>Vi,IsARM:()=>Gi,IsARM64:()=>Ki,IsDarkMode:()=>ji,IsDebug:()=>me,IsLinux:()=>Ni,IsMac:()=>Zi,IsWindows:()=>V,invoke:()=>y});var Ye=m(d.System),Ii=0,zi=1,de=function(){var n,e,i,o,t;try{if((e=(n=window.chrome)==null?void 0:n.webview)!=null&&e.postMessage)return window.chrome.webview.postMessage.bind(window.chrome.webview);if((t=(o=(i=window.webkit)==null?void 0:i.messageHandlers)==null?void 0:o.external)!=null&&t.postMessage)return window.webkit.messageHandlers.external.postMessage.bind(window.webkit.messageHandlers.external)}catch(r){}return null}();function y(n){de==null||de(n)}function ji(){return Ye(Ii)}async function Bi(){let n=await fetch("/wails/capabilities");if(n.ok)return n.json();throw new Error("could not fetch capabilities: "+n.statusText)}function Hi(){return Ye(zi)}function V(){return window._wails.environment.OS==="windows"}function Ni(){return window._wails.environment.OS==="linux"}function Zi(){return window._wails.environment.OS==="darwin"}function Vi(){return window._wails.environment.Arch==="amd64"}function Gi(){return window._wails.environment.Arch==="arm"}function Ki(){return window._wails.environment.Arch==="arm64"}function me(){return!!window._wails.environment.Debug}window.addEventListener("contextmenu",Qi);var Yi=m(d.ContextMenu),Xi=0;function Ji(n,e,i,o){Yi(Xi,{id:n,x:e,y:i,data:o})}function Qi(n){let e=H(n),i=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu").trim();if(i){n.preventDefault();let o=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu-data");Ji(i,n.clientX,n.clientY,o)}else qi(n,e)}function qi(n,e){if(me())return;switch(window.getComputedStyle(e).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":n.preventDefault();return}if(e.isContentEditable)return;let i=window.getSelection(),o=i&&i.toString().length>0;if(o)for(let t=0;tU});function U(n){try{return window._wails.flags[n]}catch(e){throw new Error("Unable to retrieve flag '"+n+"': "+e,{cause:e})}}var I=!1,z=!1,he=!1,x=!1,A=!1,C="",Xe="auto",T=0,pe=Be();window._wails=window._wails||{};window._wails.setResizable=n=>{he=n,he||(x=A=!1,w())};window.addEventListener("mousedown",We,{capture:!0});window.addEventListener("mousemove",We,{capture:!0});window.addEventListener("mouseup",We,{capture:!0});for(let n of["click","contextmenu","dblclick"])window.addEventListener(n,_i,{capture:!0});function _i(n){(z||A)&&(n.stopImmediatePropagation(),n.stopPropagation(),n.preventDefault())}var fe=0,$i=1,ge=2;function We(n){let e,i=n.buttons;switch(n.type){case"mousedown":e=fe,pe||(i=T|1<ao,Quit:()=>co,Show:()=>lo});var be=m(d.Application),to=0,ro=1,so=2;function ao(){return be(to)}function lo(){return be(ro)}function co(){return be(so)}var Te={};u(Te,{ByID:()=>ko,ByName:()=>Eo,Call:()=>Se,RuntimeError:()=>X});var Qe=Function.prototype.toString,R=typeof Reflect=="object"&&Reflect!==null&&Reflect.apply,ye,G;if(typeof R=="function"&&typeof Object.defineProperty=="function")try{ye=Object.defineProperty({},"length",{get:function(){throw G}}),G={},R(function(){throw 42},null,ye)}catch(n){n!==G&&(R=null)}else R=null;var mo=/^\s*class\b/,Pe=function(e){try{var i=Qe.call(e);return mo.test(i)}catch(o){return!1}},Ce=function(e){try{return Pe(e)?!1:(Qe.call(e),!0)}catch(i){return!1}},K=Object.prototype.toString,uo="[object Object]",wo="[object Function]",po="[object GeneratorFunction]",fo="[object HTMLAllCollection]",go="[object HTML document.all class]",ho="[object HTMLCollection]",Wo=typeof Symbol=="function"&&!!Symbol.toStringTag,bo=!(0 in[,]),De=function(){return!1};typeof document=="object"&&(Je=document.all,K.call(Je)===K.call(document.all)&&(De=function(e){if((bo||!e)&&(typeof e>"u"||typeof e=="object"))try{var i=K.call(e);return(i===fo||i===go||i===ho||i===uo)&&e("")==null}catch(o){}return!1}));var Je;function vo(n){if(De(n))return!0;if(!n||typeof n!="function"&&typeof n!="object")return!1;try{R(n,null,ye)}catch(e){if(e!==G)return!1}return!Pe(n)&&Ce(n)}function yo(n){if(De(n))return!0;if(!n||typeof n!="function"&&typeof n!="object")return!1;if(Wo)return Ce(n);if(Pe(n))return!1;var e=K.call(n);return e!==wo&&e!==po&&!/^\[object HTML/.test(e)?!1:Ce(n)}var W=R?vo:yo;var k=class extends Error{constructor(e,i){super(e,i),this.name="CancelError"}},b=class extends Error{constructor(e,i,o){super((o!=null?o:"Unhandled rejection in cancelled promise.")+" Reason: "+Co(i),{cause:i}),this.promise=e,this.name="CancelledRejectionError"}},f=Symbol("barrier"),Me=Symbol("cancelImpl"),en,qe=(en=Symbol.species)!=null?en:Symbol("speciesPolyfill"),j=class n extends Promise{constructor(e,i){let o,t;if(super((c,g)=>{o=c,t=g}),this.constructor[qe]!==Promise)throw new TypeError("CancellablePromise does not support transparent subclassing. Please refrain from overriding the [Symbol.species] static property.");let r={promise:this,resolve:o,reject:t,get oncancelled(){return i!=null?i:null},set oncancelled(c){i=c!=null?c:void 0}},a={get root(){return a},resolving:!1,settled:!1};Object.defineProperties(this,{[f]:{configurable:!1,enumerable:!1,writable:!0,value:null},[Me]:{configurable:!1,enumerable:!1,writable:!1,value:nn(r,a)}});let l=tn(r,a);try{e(on(r,a),l)}catch(c){a.resolving||l(c)}}cancel(e){return new n(i=>{Promise.all([this[Me](new k("Promise cancelled.",{cause:e})),Po(this)]).then(()=>i(),()=>i())})}cancelOn(e){return e.aborted?this.cancel(e.reason):e.addEventListener("abort",()=>void this.cancel(e.reason),{capture:!0}),this}then(e,i,o){if(!(this instanceof n))throw new TypeError("CancellablePromise.prototype.then called on an invalid object.");if(W(e)||(e=_e),W(i)||(i=$e),e===_e&&i==$e)return new n(r=>r(this));let t={};return this[f]=t,new n((r,a)=>{super.then(l=>{var c;this[f]===t&&(this[f]=null),(c=t.resolve)==null||c.call(t);try{r(e(l))}catch(g){a(g)}},l=>{var c;this[f]===t&&(this[f]=null),(c=t.resolve)==null||c.call(t);try{r(i(l))}catch(g){a(g)}})},async r=>{try{return o==null?void 0:o(r)}finally{await this.cancel(r)}})}catch(e,i){return this.then(void 0,e,i)}finally(e,i){if(!(this instanceof n))throw new TypeError("CancellablePromise.prototype.finally called on an invalid object.");return W(e)?this.then(o=>n.resolve(e()).then(()=>o),o=>n.resolve(e()).then(()=>{throw o}),i):this.then(e,e,i)}static get[(f,Me,qe)](){return Promise}static all(e){let i=Array.from(e),o=i.length===0?n.resolve(i):new n((t,r)=>{Promise.all(i).then(t,r)},t=>Y(o,i,t));return o}static allSettled(e){let i=Array.from(e),o=i.length===0?n.resolve(i):new n((t,r)=>{Promise.allSettled(i).then(t,r)},t=>Y(o,i,t));return o}static any(e){let i=Array.from(e),o=i.length===0?n.resolve(i):new n((t,r)=>{Promise.any(i).then(t,r)},t=>Y(o,i,t));return o}static race(e){let i=Array.from(e),o=new n((t,r)=>{Promise.race(i).then(t,r)},t=>Y(o,i,t));return o}static cancel(e){let i=new n(()=>{});return i.cancel(e),i}static timeout(e,i){let o=new n(()=>{});return AbortSignal&&typeof AbortSignal=="function"&&AbortSignal.timeout&&typeof AbortSignal.timeout=="function"?AbortSignal.timeout(e).addEventListener("abort",()=>void o.cancel(i)):setTimeout(()=>void o.cancel(i),e),o}static sleep(e,i){return new n(o=>{setTimeout(()=>o(i),e)})}static reject(e){return new n((i,o)=>o(e))}static resolve(e){return e instanceof n?e:new n(i=>i(e))}static withResolvers(){let e={oncancelled:null};return e.promise=new n((i,o)=>{e.resolve=i,e.reject=o},i=>{var o;(o=e.oncancelled)==null||o.call(e,i)}),e}};function nn(n,e){let i;return o=>{if(e.settled||(e.settled=!0,e.reason=o,n.reject(o),Promise.prototype.then.call(n.promise,void 0,t=>{if(t!==o)throw t})),!(!e.reason||!n.oncancelled))return i=new Promise(t=>{try{t(n.oncancelled(e.reason.cause))}catch(r){Promise.reject(new b(n.promise,r,"Unhandled exception in oncancelled callback."))}}).catch(t=>{Promise.reject(new b(n.promise,t,"Unhandled rejection in oncancelled callback."))}),n.oncancelled=null,i}}function on(n,e){return i=>{if(!e.resolving){if(e.resolving=!0,i===n.promise){if(e.settled)return;e.settled=!0,n.reject(new TypeError("A promise cannot be resolved with itself."));return}if(i!=null&&(typeof i=="object"||typeof i=="function")){let o;try{o=i.then}catch(t){e.settled=!0,n.reject(t);return}if(W(o)){try{let a=i.cancel;if(W(a)){let l=c=>{Reflect.apply(a,i,[c])};e.reason?nn(Ue(Le({},n),{oncancelled:l}),e)(e.reason):n.oncancelled=l}}catch(a){}let t={root:e.root,resolving:!1,get settled(){return this.root.settled},set settled(a){this.root.settled=a},get reason(){return this.root.reason}},r=tn(n,t);try{Reflect.apply(o,i,[on(n,t),r])}catch(a){r(a)}return}}e.settled||(e.settled=!0,n.resolve(i))}}}function tn(n,e){return i=>{if(!e.resolving)if(e.resolving=!0,e.settled){try{if(i instanceof k&&e.reason instanceof k&&Object.is(i.cause,e.reason.cause))return}catch(o){}Promise.reject(new b(n.promise,i))}else e.settled=!0,n.reject(i)}}function Y(n,e,i){let o=[];for(let t of e){let r;try{if(!W(t.then)||(r=t.cancel,!W(r)))continue}catch(l){continue}let a;try{a=Reflect.apply(r,t,[i])}catch(l){Promise.reject(new b(n,l,"Unhandled exception in cancel method."));continue}a&&o.push((a instanceof Promise?a:Promise.resolve(a)).catch(l=>{Promise.reject(new b(n,l,"Unhandled rejection in cancel method."))}))}return Promise.all(o)}function _e(n){return n}function $e(n){throw n}function Co(n){try{if(n instanceof Error||typeof n!="object"||n.toString!==Object.prototype.toString)return""+n}catch(e){}try{return JSON.stringify(n)}catch(e){}try{return Object.prototype.toString.call(n)}catch(e){}return""}function Po(n){var i;let e=(i=n[f])!=null?i:{};return"promise"in e||Object.assign(e,E()),n[f]==null&&(e.resolve(),n[f]=e),e.promise}var E=Promise.withResolvers;E&&typeof E=="function"?E=E.bind(Promise):E=function(){let n,e;return{promise:new Promise((o,t)=>{n=o,e=t}),resolve:n,reject:e}};window._wails=window._wails||{};window._wails.callResultHandler=xo;window._wails.callErrorHandler=Ao;var Do=m(d.Call),Mo=m(d.CancelCall),O=new Map,So=0,To=0,X=class extends Error{constructor(e,i){super(e,i),this.name="RuntimeError"}};function xo(n,e,i){let o=rn(n);if(o)if(!e)o.resolve(void 0);else if(!i)o.resolve(e);else try{o.resolve(JSON.parse(e))}catch(t){o.reject(new TypeError("could not parse result: "+t.message,{cause:t}))}}function Ao(n,e,i){let o=rn(n);if(o)if(!i)o.reject(new Error(e));else{let t;try{t=JSON.parse(e)}catch(l){o.reject(new TypeError("could not parse error: "+l.message,{cause:l}));return}let r={};t.cause&&(r.cause=t.cause);let a;switch(t.kind){case"ReferenceError":a=new ReferenceError(t.message,r);break;case"TypeError":a=new TypeError(t.message,r);break;case"RuntimeError":a=new X(t.message,r);break;default:a=new Error(t.message,r);break}o.reject(a)}}function rn(n){let e=O.get(n);return O.delete(n),e}function Ro(){let n;do n=D();while(O.has(n));return n}function Se(n){let e=Ro(),i=j.withResolvers();O.set(e,{resolve:i.resolve,reject:i.reject});let o=Do(So,Object.assign({"call-id":e},n)),t=!1;o.then(()=>{t=!0},a=>{O.delete(e),i.reject(a)});let r=()=>(O.delete(e),Mo(To,{"call-id":e}).catch(a=>{}));return i.oncancelled=()=>t?r():o.then(r),i.promise}function Eo(n,...e){return Se({methodName:n,args:e})}function ko(n,...e){return Se({methodID:n,args:e})}var xe={};u(xe,{SetText:()=>Lo,Text:()=>Uo});var sn=m(d.Clipboard),Oo=0,Fo=1;function Lo(n){return sn(Oo,{text:n})}function Uo(){return sn(Fo)}var Ae={};u(Ae,{Any:()=>P,Array:()=>zo,ByteSlice:()=>Io,Map:()=>jo,Nullable:()=>Bo,Struct:()=>Ho});function P(n){return n}function Io(n){return n==null?"":n}function zo(n){return n===P?e=>e===null?[]:e:e=>{if(e===null)return[];for(let i=0;ii===null?{}:i:i=>{if(i===null)return{};for(let o in i)i[o]=e(i[o]);return i}}function Bo(n){return n===P?P:e=>e===null?null:n(e)}function Ho(n){let e=!0;for(let i in n)if(n[i]!==P){e=!1;break}return e?P:i=>{for(let o in n)o in i&&(i[o]=n[o](i[o]));return i}}var Ee={};u(Ee,{GetAll:()=>Go,GetCurrent:()=>Yo,GetPrimary:()=>Ko});var Re=m(d.Screens),No=0,Zo=1,Vo=2;function Go(){return Re(No)}function Ko(){return Re(Zo)}function Yo(){return Re(Vo)}window._wails=window._wails||{};window._wails.invoke=y;y("wails:runtime:ready");export{ve as Application,_ as Browser,Te as Call,k as CancelError,j as CancellablePromise,b as CancelledRejectionError,xe as Clipboard,Ae as Create,ee as Dialogs,oe as Events,we as Flags,Ee as Screens,ue as System,le as WML,Z as Window}; diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/src/events.ts b/v3/internal/runtime/desktop/@wailsio/runtime/src/events.ts index d8c67b65f..9259bc6c5 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/src/events.ts +++ b/v3/internal/runtime/desktop/@wailsio/runtime/src/events.ts @@ -125,11 +125,23 @@ export function OffAll(): void { } /** - * Emits the given event. + * Emits an event using the name and data. * - * @param event - The name of the event to emit. * @returns A promise that will be fulfilled once the event has been emitted. + * @param name - the name of the event to emit. + * @param data - the data to be sent with the event. */ -export function Emit(event: WailsEvent): Promise { +export function Emit(name: string, data?: any): Promise { + let event: WailsEvent; + + if (typeof name === 'object' && name !== null && 'name' in name && 'data' in name) { + // If name is an object with a name property, use it directly + event = new WailsEvent(name['name'], name['data']); + } else { + // Otherwise use the standard parameters + event = new WailsEvent(name as string, data); + } + return call(EmitMethod, event); } + From d8671de43b2f26c5be3958dbf617fd2cc37c5986 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 11 Mar 2025 21:12:16 +1100 Subject: [PATCH 058/136] Update README --- docs/src/content/docs/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index b18c0bcd6..8c88d41d2 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -75,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add method `Close` on `sqlite` service to close the DB manually by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) +- Gin support by [Lea Anthony](https://github.com/leaanthony) in [PR](https://github.com/wailsapp/wails/pull/3537) based on the original work of [@AnalogJ](https://github.com/AnalogJ) in PR[https://github.com/wailsapp/wails/pull/3537] ### Fixed From 635ddf5c363e01fc6863aa4fd6222d14fa30b9f1 Mon Sep 17 00:00:00 2001 From: Oussama Sethoum <88779394+oSethoum@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:00:22 +0100 Subject: [PATCH 059/136] fix: fullscreen, unfullscreen, unminise and unmaximise window events weren't being emitted. --- v3/pkg/application/webview_window_windows.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 89bea1cbd..92684ae73 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -679,6 +679,7 @@ func (w *windowsWebviewWindow) maximise() { func (w *windowsWebviewWindow) unmaximise() { w.restore() + w.parent.emit(events.Windows.WindowUnMaximise) } func (w *windowsWebviewWindow) restore() { @@ -719,6 +720,7 @@ func (w *windowsWebviewWindow) fullscreen() { int(monitorInfo.RcMonitor.Bottom-monitorInfo.RcMonitor.Top), w32.SWP_NOOWNERZORDER|w32.SWP_FRAMECHANGED) w.chromium.Focus() + w.parent.emit(events.Windows.WindowFullscreen) } func (w *windowsWebviewWindow) unfullscreen() { @@ -738,6 +740,7 @@ func (w *windowsWebviewWindow) unfullscreen() { w32.SetWindowPos(w.hwnd, 0, 0, 0, 0, 0, w32.SWP_NOMOVE|w32.SWP_NOSIZE|w32.SWP_NOZORDER|w32.SWP_NOOWNERZORDER|w32.SWP_FRAMECHANGED) w.enableSizeConstraints() + w.parent.emit(events.Windows.WindowUnFullscreen) } func (w *windowsWebviewWindow) isMinimised() bool { @@ -1202,6 +1205,9 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp case w32.SIZE_MAXIMIZED: w.parent.emit(events.Windows.WindowMaximise) case w32.SIZE_RESTORED: + if w.isMinimizing { + w.parent.emit(events.Windows.WindowUnMinimise) + } w.isMinimizing = false w.parent.emit(events.Windows.WindowRestore) case w32.SIZE_MINIMIZED: From 302c74e90d96bf3c795e0e64a83744511d865d20 Mon Sep 17 00:00:00 2001 From: Oussama Sethoum <88779394+oSethoum@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:34:50 +0100 Subject: [PATCH 060/136] add: entry in the changelog.mdx for reference. --- docs/src/content/docs/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index a64d2e718..326c9c864 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -109,6 +109,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed [#4097](https://github.com/wailsapp/wails/issues/4097) Webpack/angular discards runtime init code by [@fbbdev](https://github.com/fbbdev) in [#4100](https://github.com/wailsapp/wails/pull/4100) - Fixed assetFileServer not serving `.html` files when non-extension request when `[request]` doesn't exist but `[request].html` does - Fixed icon generation paths by [@robin-samuel](https://github.com/robin-samuel) in [#4125](https://github.com/wailsapp/wails/pull/4125) +- Fixed `fullscreen`, `unfullscreen`, `unminimise` and `unmaximise` events not being emitted by [@oSethoum](https://github.com/osethoum) in [#4130](https://github.com/wailsapp/wails/pull/4130) ### Changed From 479e22b7c5a20b55ca5f114ff5261c254c13bd41 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Wed, 12 Mar 2025 11:30:45 -0400 Subject: [PATCH 061/136] Clean up template package.json files --- v3/internal/templates/lit-ts/frontend/package.json | 6 +++--- v3/internal/templates/lit/frontend/package.json | 6 +++--- v3/internal/templates/preact-ts/frontend/package.json | 6 +++--- v3/internal/templates/preact/frontend/package.json | 6 +++--- v3/internal/templates/qwik-ts/frontend/package.json | 8 ++++---- v3/internal/templates/qwik/frontend/package.json | 8 ++++---- .../templates/react-swc-ts/frontend/package.json | 4 ++-- v3/internal/templates/react-swc/frontend/package.json | 4 ++-- v3/internal/templates/react-ts/frontend/package.json | 4 ++-- v3/internal/templates/react/frontend/package.json | 4 ++-- v3/internal/templates/solid-ts/frontend/package.json | 4 ++-- v3/internal/templates/solid/frontend/package.json | 4 ++-- v3/internal/templates/svelte-ts/frontend/package.json | 8 +++++--- v3/internal/templates/svelte/frontend/package.json | 8 +++++--- .../templates/sveltekit-ts/frontend/package.json | 10 +++++----- v3/internal/templates/sveltekit/frontend/package.json | 11 +++++------ .../templates/vanilla-ts/frontend/package.json | 8 +++++--- v3/internal/templates/vanilla/frontend/package.json | 8 +++++--- v3/internal/templates/vue-ts/frontend/package.json | 4 ++-- v3/internal/templates/vue/frontend/package.json | 6 +++--- 20 files changed, 67 insertions(+), 60 deletions(-) diff --git a/v3/internal/templates/lit-ts/frontend/package.json b/v3/internal/templates/lit-ts/frontend/package.json index 80a5e0d96..d208c3fbd 100644 --- a/v3/internal/templates/lit-ts/frontend/package.json +++ b/v3/internal/templates/lit-ts/frontend/package.json @@ -10,11 +10,11 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "lit": "^3.1.0" }, "devDependencies": { "typescript": "^5.2.2", - "vite": "^5.0.0", - "@wailsio/runtime": "latest" + "vite": "^5.0.0" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/lit/frontend/package.json b/v3/internal/templates/lit/frontend/package.json index 7369a3f47..ec30e751a 100644 --- a/v3/internal/templates/lit/frontend/package.json +++ b/v3/internal/templates/lit/frontend/package.json @@ -10,10 +10,10 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "lit": "^3.1.0" }, "devDependencies": { - "vite": "^5.0.0", - "@wailsio/runtime": "latest" + "vite": "^5.0.0" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/preact-ts/frontend/package.json b/v3/internal/templates/preact-ts/frontend/package.json index e26f733b7..b5dd75296 100644 --- a/v3/internal/templates/preact-ts/frontend/package.json +++ b/v3/internal/templates/preact-ts/frontend/package.json @@ -10,12 +10,12 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "preact": "^10.19.3" }, "devDependencies": { "@preact/preset-vite": "^2.7.0", "typescript": "^5.2.2", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/preact/frontend/package.json b/v3/internal/templates/preact/frontend/package.json index 27506286f..863d1fc23 100644 --- a/v3/internal/templates/preact/frontend/package.json +++ b/v3/internal/templates/preact/frontend/package.json @@ -10,11 +10,11 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "preact": "^10.19.3" }, "devDependencies": { "@preact/preset-vite": "^2.7.0", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/qwik-ts/frontend/package.json b/v3/internal/templates/qwik-ts/frontend/package.json index 8452e0e60..b3f359a6b 100644 --- a/v3/internal/templates/qwik-ts/frontend/package.json +++ b/v3/internal/templates/qwik-ts/frontend/package.json @@ -9,12 +9,12 @@ "build": "tsc && vite build --mode production", "preview": "vite preview" }, - "devDependencies": { - "typescript": "^5.2.2", - "vite": "^5.0.8" - }, "dependencies": { "@builder.io/qwik": "^1.3.0", "@wailsio/runtime": "latest" + }, + "devDependencies": { + "typescript": "^5.2.2", + "vite": "^5.0.8" } } diff --git a/v3/internal/templates/qwik/frontend/package.json b/v3/internal/templates/qwik/frontend/package.json index 782a10d42..3139e426b 100644 --- a/v3/internal/templates/qwik/frontend/package.json +++ b/v3/internal/templates/qwik/frontend/package.json @@ -9,12 +9,12 @@ "build": "vite build --mode production", "preview": "vite preview" }, - "devDependencies": { - "typescript": "^5.2.2", - "vite": "^5.0.8" - }, "dependencies": { "@builder.io/qwik": "^1.3.0", "@wailsio/runtime": "latest" + }, + "devDependencies": { + "typescript": "^5.2.2", + "vite": "^5.0.8" } } diff --git a/v3/internal/templates/react-swc-ts/frontend/package.json b/v3/internal/templates/react-swc-ts/frontend/package.json index 5627a60f2..0dcc8cdcd 100644 --- a/v3/internal/templates/react-swc-ts/frontend/package.json +++ b/v3/internal/templates/react-swc-ts/frontend/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -18,7 +19,6 @@ "@types/react-dom": "^18.2.17", "@vitejs/plugin-react-swc": "^3.5.0", "typescript": "^5.2.2", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } } diff --git a/v3/internal/templates/react-swc/frontend/package.json b/v3/internal/templates/react-swc/frontend/package.json index b86bd3722..158ba6880 100644 --- a/v3/internal/templates/react-swc/frontend/package.json +++ b/v3/internal/templates/react-swc/frontend/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -17,7 +18,6 @@ "@types/react": "^18.2.43", "@types/react-dom": "^18.2.17", "@vitejs/plugin-react-swc": "^3.5.0", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } } diff --git a/v3/internal/templates/react-ts/frontend/package.json b/v3/internal/templates/react-ts/frontend/package.json index a72ca0f47..f718c0073 100644 --- a/v3/internal/templates/react-ts/frontend/package.json +++ b/v3/internal/templates/react-ts/frontend/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -18,7 +19,6 @@ "@types/react-dom": "^18.2.17", "@vitejs/plugin-react": "^4.2.1", "typescript": "^5.2.2", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } } diff --git a/v3/internal/templates/react/frontend/package.json b/v3/internal/templates/react/frontend/package.json index ff295952b..59d4d62b3 100644 --- a/v3/internal/templates/react/frontend/package.json +++ b/v3/internal/templates/react/frontend/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -17,7 +18,6 @@ "@types/react": "^18.2.43", "@types/react-dom": "^18.2.17", "@vitejs/plugin-react": "^4.2.1", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } } diff --git a/v3/internal/templates/solid-ts/frontend/package.json b/v3/internal/templates/solid-ts/frontend/package.json index 703d31562..741674ea7 100644 --- a/v3/internal/templates/solid-ts/frontend/package.json +++ b/v3/internal/templates/solid-ts/frontend/package.json @@ -10,12 +10,12 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "solid-js": "^1.8.7" }, "devDependencies": { "typescript": "^5.2.2", "vite": "^5.0.8", - "vite-plugin-solid": "^2.8.0", - "@wailsio/runtime": "latest" + "vite-plugin-solid": "^2.8.0" } } diff --git a/v3/internal/templates/solid/frontend/package.json b/v3/internal/templates/solid/frontend/package.json index 9062b3686..03ed9141f 100644 --- a/v3/internal/templates/solid/frontend/package.json +++ b/v3/internal/templates/solid/frontend/package.json @@ -10,11 +10,11 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "solid-js": "^1.8.7" }, "devDependencies": { "vite": "^5.0.8", - "vite-plugin-solid": "^2.8.0", - "@wailsio/runtime": "latest" + "vite-plugin-solid": "^2.8.0" } } diff --git a/v3/internal/templates/svelte-ts/frontend/package.json b/v3/internal/templates/svelte-ts/frontend/package.json index f3491e928..c14954e77 100644 --- a/v3/internal/templates/svelte-ts/frontend/package.json +++ b/v3/internal/templates/svelte-ts/frontend/package.json @@ -10,6 +10,9 @@ "preview": "vite preview", "check": "svelte-check --tsconfig ./tsconfig.json" }, + "dependencies": { + "@wailsio/runtime": "latest" + }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.1", "@tsconfig/svelte": "^5.0.2", @@ -17,7 +20,6 @@ "svelte-check": "^3.6.2", "tslib": "^2.6.2", "typescript": "^5.2.2", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/svelte/frontend/package.json b/v3/internal/templates/svelte/frontend/package.json index 3a9ca1053..4655c0e95 100644 --- a/v3/internal/templates/svelte/frontend/package.json +++ b/v3/internal/templates/svelte/frontend/package.json @@ -9,10 +9,12 @@ "build": "vite build --mode production", "preview": "vite preview" }, + "dependencies": { + "@wailsio/runtime": "latest" + }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.1", "svelte": "^4.2.8", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/sveltekit-ts/frontend/package.json b/v3/internal/templates/sveltekit-ts/frontend/package.json index c545acab9..5e5c0e86a 100644 --- a/v3/internal/templates/sveltekit-ts/frontend/package.json +++ b/v3/internal/templates/sveltekit-ts/frontend/package.json @@ -2,6 +2,7 @@ "name": "frontend", "version": "0.0.1", "private": true, + "type": "module", "scripts": { "dev": "vite dev", "build:dev": "vite build --minify false --mode development", @@ -10,17 +11,16 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, + "dependencies": { + "@wailsio/runtime": "^3.0.0-alpha.28" + }, "devDependencies": { + "@sveltejs/adapter-static": "^3.0.5", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "svelte": "^4.2.7", "svelte-check": "^4.0.0", "typescript": "^5.0.0", "vite": "^5.0.3" - }, - "type": "module", - "dependencies": { - "@sveltejs/adapter-static": "^3.0.5", - "@wailsio/runtime": "^3.0.0-alpha.28" } } diff --git a/v3/internal/templates/sveltekit/frontend/package.json b/v3/internal/templates/sveltekit/frontend/package.json index 03427d5b8..c07d6da50 100644 --- a/v3/internal/templates/sveltekit/frontend/package.json +++ b/v3/internal/templates/sveltekit/frontend/package.json @@ -2,6 +2,7 @@ "name": "frontend", "version": "0.0.1", "private": true, + "type": "module", "scripts": { "dev": "vite dev", "build:dev": "vite build --minify false --mode development", @@ -10,16 +11,14 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch" }, + "dependencies": { + "@wailsio/runtime": "^3.0.0-alpha.28" + }, "devDependencies": { - "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/adapter-static": "^3.0.5", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "svelte": "^4.2.7", "vite": "^5.0.3" - }, - "type": "module", - "dependencies": { - "@sveltejs/adapter-static": "^3.0.5", - "@wailsio/runtime": "^3.0.0-alpha.28" } } diff --git a/v3/internal/templates/vanilla-ts/frontend/package.json b/v3/internal/templates/vanilla-ts/frontend/package.json index 4d675f189..b39da7ece 100644 --- a/v3/internal/templates/vanilla-ts/frontend/package.json +++ b/v3/internal/templates/vanilla-ts/frontend/package.json @@ -9,9 +9,11 @@ "build": "tsc && vite build --mode production", "preview": "vite preview" }, + "dependencies": { + "@wailsio/runtime": "latest" + }, "devDependencies": { "typescript": "^4.9.3", - "vite": "^5.0.0", - "@wailsio/runtime": "latest" + "vite": "^5.0.0" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/vanilla/frontend/package.json b/v3/internal/templates/vanilla/frontend/package.json index 9ae87549e..b8d7427fb 100644 --- a/v3/internal/templates/vanilla/frontend/package.json +++ b/v3/internal/templates/vanilla/frontend/package.json @@ -9,8 +9,10 @@ "build": "vite build --mode production", "preview": "vite preview" }, + "dependencies": { + "@wailsio/runtime": "latest" + }, "devDependencies": { - "vite": "^5.0.0", - "@wailsio/runtime": "latest" + "vite": "^5.0.0" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/vue-ts/frontend/package.json b/v3/internal/templates/vue-ts/frontend/package.json index 60bd3c63d..dc08ffa11 100644 --- a/v3/internal/templates/vue-ts/frontend/package.json +++ b/v3/internal/templates/vue-ts/frontend/package.json @@ -10,13 +10,13 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "vue": "^3.2.45" }, "devDependencies": { "@vitejs/plugin-vue": "^4.0.0", "typescript": "^4.9.3", "vite": "^5.0.0", - "@wailsio/runtime": "latest", "vue-tsc": "^1.0.11" } -} \ No newline at end of file +} diff --git a/v3/internal/templates/vue/frontend/package.json b/v3/internal/templates/vue/frontend/package.json index 7cd67be52..6958956b3 100644 --- a/v3/internal/templates/vue/frontend/package.json +++ b/v3/internal/templates/vue/frontend/package.json @@ -10,11 +10,11 @@ "preview": "vite preview" }, "dependencies": { + "@wailsio/runtime": "latest", "vue": "^3.2.45" }, "devDependencies": { "@vitejs/plugin-vue": "^4.0.0", - "vite": "^5.0.0", - "@wailsio/runtime": "latest" + "vite": "^5.0.0" } -} \ No newline at end of file +} From 3f2db134c23e55d5bed8677abf579750e95cfdc6 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Wed, 12 Mar 2025 11:31:14 -0400 Subject: [PATCH 062/136] Remove package-lock.json from templates --- .../sveltekit-ts/frontend/package-lock.json | 1288 ----------------- .../sveltekit/frontend/package-lock.json | 1221 ---------------- 2 files changed, 2509 deletions(-) delete mode 100644 v3/internal/templates/sveltekit-ts/frontend/package-lock.json delete mode 100644 v3/internal/templates/sveltekit/frontend/package-lock.json diff --git a/v3/internal/templates/sveltekit-ts/frontend/package-lock.json b/v3/internal/templates/sveltekit-ts/frontend/package-lock.json deleted file mode 100644 index 4ba4bd3f3..000000000 --- a/v3/internal/templates/sveltekit-ts/frontend/package-lock.json +++ /dev/null @@ -1,1288 +0,0 @@ -{ - "name": "frontend", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "frontend", - "version": "0.0.1", - "dependencies": { - "@sveltejs/adapter-static": "^3.0.5", - "@wailsio/runtime": "^3.0.0-alpha.28" - }, - "devDependencies": { - "@sveltejs/kit": "^2.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.2.7", - "svelte-check": "^4.0.0", - "typescript": "^5.0.0", - "vite": "^5.0.3" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.28", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", - "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sveltejs/adapter-static": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.5.tgz", - "integrity": "sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==", - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, - "node_modules/@sveltejs/kit": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.1.tgz", - "integrity": "sha512-TBVnkwgYQT3EafGQK6Eyh5FlLEBlRhCmqPTwcdOs+QdnyUc3eCAxRWtXlFxIWtmk6pqv11zdng8qTpThdTogew==", - "hasInstallScript": true, - "dependencies": { - "@types/cookie": "^0.6.0", - "cookie": "^0.6.0", - "devalue": "^5.1.0", - "esm-env": "^1.0.0", - "import-meta-resolve": "^4.1.0", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", - "sirv": "^3.0.0", - "tiny-glob": "^0.2.9" - }, - "bin": { - "svelte-kit": "svelte-kit.js" - }, - "engines": { - "node": ">=18.13" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.2.tgz", - "integrity": "sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==", - "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", - "debug": "^4.3.4", - "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.10", - "svelte-hmr": "^0.16.0", - "vitefu": "^0.2.5" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", - "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" - }, - "node_modules/@wailsio/runtime": { - "version": "3.0.0-alpha.28", - "resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.28.tgz", - "integrity": "sha512-caMnAcKxxDrIWYgCZAMY2kdL++X4ehO2+JvH5na21xfDqz3VnHkEjxsH3jfhgd34M8LY80QEH8iqoMYytDFE/g==", - "dependencies": { - "nanoid": "^5.0.7" - } - }, - "node_modules/@wailsio/runtime/node_modules/nanoid": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", - "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^18 || >=20" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "dev": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/devalue": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", - "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==" - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/esm-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", - "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==" - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/fdir": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.0.tgz", - "integrity": "sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" - }, - "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/locate-character": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" - }, - "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", - "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==" - }, - "node_modules/sirv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", - "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svelte": { - "version": "4.2.19", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", - "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", - "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/svelte-check": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.5.tgz", - "integrity": "sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "chokidar": "^4.0.1", - "fdir": "^6.2.0", - "picocolors": "^1.0.0", - "sade": "^1.7.4" - }, - "bin": { - "svelte-check": "bin/svelte-check" - }, - "engines": { - "node": ">= 18.0.0" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "typescript": ">=5.0.0" - } - }, - "node_modules/svelte-hmr": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", - "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", - "engines": { - "node": "^12.20 || ^14.13.1 || >= 16" - }, - "peerDependencies": { - "svelte": "^3.19.0 || ^4.0.0" - } - }, - "node_modules/tiny-glob": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", - "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", - "dependencies": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/vite": { - "version": "5.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", - "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vitefu": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", - "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - } - } -} diff --git a/v3/internal/templates/sveltekit/frontend/package-lock.json b/v3/internal/templates/sveltekit/frontend/package-lock.json deleted file mode 100644 index 7e20bdb45..000000000 --- a/v3/internal/templates/sveltekit/frontend/package-lock.json +++ /dev/null @@ -1,1221 +0,0 @@ -{ - "name": "frontend", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "frontend", - "version": "0.0.1", - "dependencies": { - "@sveltejs/adapter-static": "^3.0.5", - "@wailsio/runtime": "^3.0.0-alpha.28" - }, - "devDependencies": { - "@sveltejs/adapter-auto": "^3.0.0", - "@sveltejs/kit": "^2.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.2.7", - "vite": "^5.0.3" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.28", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", - "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sveltejs/adapter-auto": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.5.tgz", - "integrity": "sha512-27LR+uKccZ62lgq4N/hvyU2G+hTP9fxWEAfnZcl70HnyfAjMSsGk1z/SjAPXNCD1mVJIE7IFu3TQ8cQ/UH3c0A==", - "dev": true, - "dependencies": { - "import-meta-resolve": "^4.1.0" - }, - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, - "node_modules/@sveltejs/adapter-static": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.5.tgz", - "integrity": "sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==", - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, - "node_modules/@sveltejs/kit": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.1.tgz", - "integrity": "sha512-TBVnkwgYQT3EafGQK6Eyh5FlLEBlRhCmqPTwcdOs+QdnyUc3eCAxRWtXlFxIWtmk6pqv11zdng8qTpThdTogew==", - "hasInstallScript": true, - "dependencies": { - "@types/cookie": "^0.6.0", - "cookie": "^0.6.0", - "devalue": "^5.1.0", - "esm-env": "^1.0.0", - "import-meta-resolve": "^4.1.0", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", - "sirv": "^3.0.0", - "tiny-glob": "^0.2.9" - }, - "bin": { - "svelte-kit": "svelte-kit.js" - }, - "engines": { - "node": ">=18.13" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.2.tgz", - "integrity": "sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==", - "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", - "debug": "^4.3.4", - "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.10", - "svelte-hmr": "^0.16.0", - "vitefu": "^0.2.5" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", - "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" - }, - "node_modules/@wailsio/runtime": { - "version": "3.0.0-alpha.28", - "resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.28.tgz", - "integrity": "sha512-caMnAcKxxDrIWYgCZAMY2kdL++X4ehO2+JvH5na21xfDqz3VnHkEjxsH3jfhgd34M8LY80QEH8iqoMYytDFE/g==", - "dependencies": { - "nanoid": "^5.0.7" - } - }, - "node_modules/@wailsio/runtime/node_modules/nanoid": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", - "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^18 || >=20" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/devalue": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", - "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==" - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/esm-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", - "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==" - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" - }, - "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/locate-character": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" - }, - "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", - "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==" - }, - "node_modules/sirv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", - "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svelte": { - "version": "4.2.19", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", - "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", - "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/svelte-hmr": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", - "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", - "engines": { - "node": "^12.20 || ^14.13.1 || >= 16" - }, - "peerDependencies": { - "svelte": "^3.19.0 || ^4.0.0" - } - }, - "node_modules/tiny-glob": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", - "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", - "dependencies": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/vite": { - "version": "5.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", - "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vitefu": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", - "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - } - } -} From 0be2efc2751a609402212a1b8c9a5b41ce1e313e Mon Sep 17 00:00:00 2001 From: Oussama Sethoum <88779394+oSethoum@users.noreply.github.com> Date: Wed, 12 Mar 2025 20:48:05 +0100 Subject: [PATCH 063/136] fix: general auto save and general password auto save always enabled --- v3/pkg/application/webview_window_windows.go | 29 ++++++++------------ 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 89bea1cbd..ecd20002f 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -1665,26 +1665,21 @@ func (w *windowsWebviewWindow) setupChromium() { } - if opts.GeneralAutofillEnabled { - err = chromium.PutIsGeneralAutofillEnabled(true) - if err != nil { - if errors.Is(edge.UnsupportedCapabilityError, err) { - // warning - globalApplication.warning("unsupported capability: GeneralAutofillEnabled") - } else { - globalApplication.handleFatalError(err) - } + err = chromium.PutIsGeneralAutofillEnabled(opts.GeneralAutofillEnabled) + if err != nil { + if errors.Is(err, edge.UnsupportedCapabilityError) { + globalApplication.warning("unsupported capability: GeneralAutofillEnabled") + } else { + globalApplication.handleFatalError(err) } } - if opts.PasswordAutosaveEnabled { - err = chromium.PutIsPasswordAutosaveEnabled(true) - if err != nil { - if errors.Is(edge.UnsupportedCapabilityError, err) { - globalApplication.warning("unsupported capability: PasswordAutosaveEnabled") - } else { - globalApplication.handleFatalError(err) - } + err = chromium.PutIsPasswordAutosaveEnabled(opts.PasswordAutosaveEnabled) + if err != nil { + if errors.Is(err, edge.UnsupportedCapabilityError) { + globalApplication.warning("unsupported capability: PasswordAutosaveEnabled") + } else { + globalApplication.handleFatalError(err) } } From 46dd5ef959cf58f4c76bf2f3892c43a7548a51e8 Mon Sep 17 00:00:00 2001 From: Oussama Sethoum <88779394+oSethoum@users.noreply.github.com> Date: Wed, 12 Mar 2025 21:46:53 +0100 Subject: [PATCH 064/136] add: entry in changelog.mdx --- docs/src/content/docs/changelog.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index a64d2e718..d9af1adf3 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -75,7 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add method `Close` on `sqlite` service to close the DB manually by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - +- Fix auto save and password auto save always enabled by [@oSethoum](https://github.com/osethoum) in [#4134](https://github.com/wailsapp/wails/pull/4134) ### Fixed - Fixed Windows+Linux Edit Menu issues by [@leaanthony](https://github.com/leaanthony) in [#3f78a3a](https://github.com/wailsapp/wails/commit/3f78a3a8ce7837e8b32242c8edbbed431c68c062) From ee9e3973bd6b64d28e12b945d94cfdb62436d9cf Mon Sep 17 00:00:00 2001 From: Fabio Massaioli Date: Thu, 13 Mar 2025 08:07:40 +0100 Subject: [PATCH 065/136] Fix indentation of sveltekit-ts package.json --- .../sveltekit-ts/frontend/package.json | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/v3/internal/templates/sveltekit-ts/frontend/package.json b/v3/internal/templates/sveltekit-ts/frontend/package.json index 5e5c0e86a..58a6b3eb7 100644 --- a/v3/internal/templates/sveltekit-ts/frontend/package.json +++ b/v3/internal/templates/sveltekit-ts/frontend/package.json @@ -1,26 +1,26 @@ { - "name": "frontend", - "version": "0.0.1", - "private": true, + "name": "frontend", + "version": "0.0.1", + "private": true, "type": "module", - "scripts": { - "dev": "vite dev", - "build:dev": "vite build --minify false --mode development", - "build": "vite build --mode production", - "preview": "vite preview", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" - }, + "scripts": { + "dev": "vite dev", + "build:dev": "vite build --minify false --mode development", + "build": "vite build --mode production", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, "dependencies": { "@wailsio/runtime": "^3.0.0-alpha.28" }, - "devDependencies": { + "devDependencies": { "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "^2.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.2.7", - "svelte-check": "^4.0.0", - "typescript": "^5.0.0", - "vite": "^5.0.3" - } + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "svelte-check": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^5.0.3" + } } From 959ce42f260f2abb095ff14960454ef8df297a8b Mon Sep 17 00:00:00 2001 From: Fabio Massaioli Date: Thu, 13 Mar 2025 08:09:09 +0100 Subject: [PATCH 066/136] Fix sveltekit template package.json --- .../templates/sveltekit/frontend/package.json | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/v3/internal/templates/sveltekit/frontend/package.json b/v3/internal/templates/sveltekit/frontend/package.json index c07d6da50..54d96b52c 100644 --- a/v3/internal/templates/sveltekit/frontend/package.json +++ b/v3/internal/templates/sveltekit/frontend/package.json @@ -1,24 +1,24 @@ { - "name": "frontend", - "version": "0.0.1", - "private": true, - "type": "module", - "scripts": { - "dev": "vite dev", - "build:dev": "vite build --minify false --mode development", - "build": "vite build --mode production", - "preview": "vite preview", - "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch" - }, - "dependencies": { - "@wailsio/runtime": "^3.0.0-alpha.28" - }, - "devDependencies": { - "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "^2.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.2.7", - "vite": "^5.0.3" - } + "name": "frontend", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev", + "build:dev": "vite build --minify false --mode development", + "build": "vite build --mode production", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch" + }, + "dependencies": { + "@wailsio/runtime": "^3.0.0-alpha.28" + }, + "devDependencies": { + "@sveltejs/adapter-static": "^3.0.5", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "vite": "^5.0.3" + } } From 5bc94ce400e541a2c83ba3876e0317f3c2c1e979 Mon Sep 17 00:00:00 2001 From: Fabio Massaioli Date: Thu, 13 Mar 2025 08:11:51 +0100 Subject: [PATCH 067/136] Fix indentation of vanilla template package.json --- v3/internal/templates/vanilla/frontend/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/v3/internal/templates/vanilla/frontend/package.json b/v3/internal/templates/vanilla/frontend/package.json index b8d7427fb..0a118e984 100644 --- a/v3/internal/templates/vanilla/frontend/package.json +++ b/v3/internal/templates/vanilla/frontend/package.json @@ -10,8 +10,8 @@ "preview": "vite preview" }, "dependencies": { - "@wailsio/runtime": "latest" - }, + "@wailsio/runtime": "latest" + }, "devDependencies": { "vite": "^5.0.0" } From e4ec06a9c86461963585d3d035b0828614c2f313 Mon Sep 17 00:00:00 2001 From: Zach Botterman Date: Thu, 13 Mar 2025 23:33:17 -0700 Subject: [PATCH 068/136] update example --- .../v3/pkg/services/notifications/service.js | 58 +++++++------------ v3/examples/notifications/frontend/main.js | 12 ++-- 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js index 85e54340f..40c55b4a9 100644 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js @@ -16,8 +16,7 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime"; import * as $models from "./models.js"; /** - * CheckNotificationAuthorization is a Windows stub that always returns true. - * (user authorization is macOS-specific) + * CheckNotificationAuthorization checks current notification permission status. * @returns {Promise & { cancel(): void }} */ export function CheckNotificationAuthorization() { @@ -25,17 +24,6 @@ export function CheckNotificationAuthorization() { return $resultPromise; } -/** - * OnNotificationResponse registers a callback function that will be called when - * a notification response is received from the user - * @param {any} callback - * @returns {Promise & { cancel(): void }} - */ -export function OnNotificationResponse(callback) { - let $resultPromise = /** @type {any} */($Call.ByID(2829398511, callback)); - return $resultPromise; -} - /** * RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. * Registering a category with the same name as a previously registered NotificationCategory will override it. @@ -48,8 +36,7 @@ export function RegisterNotificationCategory(category) { } /** - * RemoveAllDeliveredNotifications is a Windows stub that always returns nil. - * (macOS-specific) + * RemoveAllDeliveredNotifications removes all delivered notifications. * @returns {Promise & { cancel(): void }} */ export function RemoveAllDeliveredNotifications() { @@ -58,8 +45,7 @@ export function RemoveAllDeliveredNotifications() { } /** - * RemoveAllPendingNotifications is a Windows stub that always returns nil. - * (macOS-specific) + * RemoveAllPendingNotifications removes all pending notifications. * @returns {Promise & { cancel(): void }} */ export function RemoveAllPendingNotifications() { @@ -68,18 +54,22 @@ export function RemoveAllPendingNotifications() { } /** - * RemoveDeliveredNotification is a Windows stub that always returns nil. - * (macOS-specific) - * @param {string} $0 + * RemoveDeliveredNotification removes a delivered notification matching the unique identifier. + * @param {string} identifier * @returns {Promise & { cancel(): void }} */ -export function RemoveDeliveredNotification($0) { - let $resultPromise = /** @type {any} */($Call.ByID(149440045, $0)); +export function RemoveDeliveredNotification(identifier) { + let $resultPromise = /** @type {any} */($Call.ByID(149440045, identifier)); return $resultPromise; } /** - * RemoveNotification is a Windows stub that always returns nil. + * RemoveNotification is a macOS stub that always returns nil. + * Use one of the following instead: + * RemoveAllPendingNotifications + * RemovePendingNotification + * RemoveAllDeliveredNotifications + * RemoveDeliveredNotification * (Linux-specific) * @param {string} identifier * @returns {Promise & { cancel(): void }} @@ -90,7 +80,7 @@ export function RemoveNotification(identifier) { } /** - * RemoveNotificationCategory removes a previously registered NotificationCategory. + * RemoveNotificationCategory remove a previously registered NotificationCategory. * @param {string} categoryId * @returns {Promise & { cancel(): void }} */ @@ -100,29 +90,26 @@ export function RemoveNotificationCategory(categoryId) { } /** - * RemovePendingNotification is a Windows stub that always returns nil. - * (macOS-specific) - * @param {string} $0 + * RemovePendingNotification removes a pending notification matching the unique identifier. + * @param {string} identifier * @returns {Promise & { cancel(): void }} */ -export function RemovePendingNotification($0) { - let $resultPromise = /** @type {any} */($Call.ByID(3872412470, $0)); +export function RemovePendingNotification(identifier) { + let $resultPromise = /** @type {any} */($Call.ByID(3872412470, identifier)); return $resultPromise; } /** - * RequestUserNotificationAuthorization is a Windows stub that always returns true, nil. - * (user authorization is macOS-specific) + * RequestNotificationAuthorization requests permission for notifications. * @returns {Promise & { cancel(): void }} */ -export function RequestUserNotificationAuthorization() { - let $resultPromise = /** @type {any} */($Call.ByID(3412125712)); +export function RequestNotificationAuthorization() { + let $resultPromise = /** @type {any} */($Call.ByID(729898933)); return $resultPromise; } /** - * SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. - * (subtitle and category id are only available on macOS) + * SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ @@ -135,7 +122,6 @@ export function SendNotification(options) { * SendNotificationWithActions sends a notification with additional actions and inputs. * A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. * If a NotificationCategory is not registered a basic notification will be sent. - * (subtitle and category id are only available on macOS) * @param {$models.NotificationOptions} options * @returns {Promise & { cancel(): void }} */ diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js index 718a9fb4f..2c6d234d4 100644 --- a/v3/examples/notifications/frontend/main.js +++ b/v3/examples/notifications/frontend/main.js @@ -1,12 +1,12 @@ -import * as Notifications from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service"; +import * as Notifications from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications"; import { Events } from "@wailsio/runtime"; const notificationsElement = document.getElementById('notifications'); window.sendNotification = async () => { - const granted = await Notifications.RequestUserNotificationAuthorization(); + const granted = await Notifications.Service.RequestNotificationAuthorization(); if (granted) { - await Notifications.SendNotification({ + await Notifications.Service.SendNotification({ id: crypto.randomUUID(), title: "Title", body: "Body!", @@ -20,9 +20,9 @@ window.sendNotification = async () => { } window.sendComplexNotification = async () => { - const granted = await Notifications.RequestUserNotificationAuthorization(); + const granted = await Notifications.Service.RequestNotificationAuthorization(); if (granted) { - await Notifications.RegisterNotificationCategory({ + await Notifications.Service.RegisterNotificationCategory({ id: "FRONTEND_NOTIF", actions: [ { id: "VIEW_ACTION", title: "View" }, @@ -33,7 +33,7 @@ window.sendComplexNotification = async () => { replyPlaceholder: "Reply to frontend...", }); - await Notifications.SendNotificationWithActions({ + await Notifications.Service.SendNotificationWithActions({ id: crypto.randomUUID(), title: "Complex Frontend Notification", subtitle: "From: Jane Doe", From 1e67e943df24810c3064cf109ec329d19aafed15 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Fri, 14 Mar 2025 18:58:23 -0700 Subject: [PATCH 069/136] rename auth func --- v3/pkg/services/notifications/notifications_linux.go | 4 ++-- v3/pkg/services/notifications/notifications_windows.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 89e577bcb..b9e60a971 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -323,9 +323,9 @@ func (ns *Service) CheckBundleIdentifier() bool { return true } -// RequestUserNotificationAuthorization is a Linux stub that always returns true. +// RequestNotificationAuthorization is a Linux stub that always returns true. // (user authorization is macOS-specific) -func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { +func (ns *Service) RequestNotificationAuthorization() (bool, error) { return true, nil } diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 36466de94..371523ec6 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -106,9 +106,9 @@ func CheckBundleIdentifier() bool { return true } -// RequestUserNotificationAuthorization is a Windows stub that always returns true, nil. +// RequestNotificationAuthorization is a Windows stub that always returns true, nil. // (user authorization is macOS-specific) -func (ns *Service) RequestUserNotificationAuthorization() (bool, error) { +func (ns *Service) RequestNotificationAuthorization() (bool, error) { return true, nil } From 1fa68949e6f3c3f260e1de3c1568d719ce26177e Mon Sep 17 00:00:00 2001 From: popaprozac Date: Fri, 14 Mar 2025 19:03:33 -0700 Subject: [PATCH 070/136] // --- v3/pkg/services/notifications/notifications.go | 1 + 1 file changed, 1 insertion(+) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index c23b8edf5..7d6ed14aa 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -60,6 +60,7 @@ func (ns *Service) ServiceName() string { // OnNotificationResponse registers a callback function that will be called when // a notification response is received from the user. +// //wails:ignore func (ns *Service) OnNotificationResponse(callback func(response NotificationResponse)) { ns.callbackLock.Lock() From e46abdc793335817e4387c5eb2c9ce3bf57ff798 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Fri, 14 Mar 2025 19:05:27 -0700 Subject: [PATCH 071/136] update example --- v3/examples/notifications/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index 34d711f3e..f0a3e46ed 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -47,7 +47,7 @@ func main() { }) go func() { - granted, err := notificationService.RequestUserNotificationAuthorization() + granted, err := notificationService.RequestNotificationAuthorization() if err != nil { log.Default().Printf("WARNING: %s\n", err) return From 2cb0dac6484a571594931ba6eb3d198095e0436d Mon Sep 17 00:00:00 2001 From: popaprozac Date: Fri, 14 Mar 2025 19:13:58 -0700 Subject: [PATCH 072/136] set default action id on MATE --- v3/pkg/services/notifications/notifications_linux.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index b9e60a971..58d78c2e9 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -278,6 +278,10 @@ func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string n.Unlock() if notifID != "" && NotificationService != nil { + if actionKey == "default" { + actionKey = DefaultActionIdentifier + } + // First, send the action response with the user data response := NotificationResponse{ ID: notifID, From e810d6a4b046c32f361c1786d3a589313d3f4dc3 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Fri, 14 Mar 2025 23:47:59 -0700 Subject: [PATCH 073/136] tidy --- v3/go.mod | 1 - v3/go.sum | 2 -- 2 files changed, 3 deletions(-) diff --git a/v3/go.mod b/v3/go.mod index 920108029..947f0495f 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -46,7 +46,6 @@ require ( require ( atomicgo.dev/schedule v0.1.0 // indirect - git.sr.ht/~whereswaldon/shout v0.0.0-20241212204820-26acea6b0007 // indirect github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect github.com/charmbracelet/x/term v0.2.1 // indirect diff --git a/v3/go.sum b/v3/go.sum index 11e1eb371..2c07fe6c8 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -10,8 +10,6 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 h1:N3IGoHHp9pb6mj1cbXbuaSXV/UMKwmbKLf53nQmtqMA= git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3/go.mod h1:QtOLZGz8olr4qH2vWK0QH0w0O4T9fEIjMuWpKUsH7nc= -git.sr.ht/~whereswaldon/shout v0.0.0-20241212204820-26acea6b0007 h1:5xMwYHPm3ym1ccRmVmUEj4hiESj5uqXMYPwG+1Ruf28= -git.sr.ht/~whereswaldon/shout v0.0.0-20241212204820-26acea6b0007/go.mod h1:VJjhIIJD+YFIyJSH6nCDqoo9ikvAEaD63tUo4uI86pA= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= From bccff0f73e3b767f94b6e84f01abb582a7ae83f2 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Tue, 18 Mar 2025 16:21:40 -0400 Subject: [PATCH 074/136] Update changelog --- docs/src/content/docs/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 75dbf824b..e001cea09 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -139,6 +139,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Built-in service types are now consistently called `Service` by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Built-in service creation functions with options are now consistently called `NewWithConfig` by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - `Select` method on `sqlite` service is now named `Query` for consistency with Go APIs by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) +- Templates: moved runtime to "dependencies", organized package.json files by [@IanVS](https://github.com/IanVS) in [#4133](https://github.com/wailsapp/wails/pull/4133) ## v3.0.0-alpha.9 - 2025-01-13 From e4e24a0f00cd4aeda9e8186469052aa5129222c2 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Tue, 18 Mar 2025 21:18:16 -0700 Subject: [PATCH 075/136] clean --- v3/examples/notifications/main.go | 10 +- .../services/notifications/notifications.go | 24 ++- .../notifications/notifications_darwin.go | 175 +++++++++++++----- .../notifications/notifications_darwin.h | 6 +- .../notifications/notifications_darwin.m | 45 +++-- .../notifications/notifications_linux.go | 22 ++- .../notifications/notifications_windows.go | 15 +- 7 files changed, 211 insertions(+), 86 deletions(-) diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index f0a3e46ed..c2a2502a3 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -54,10 +54,14 @@ func main() { } if granted { - notificationService.OnNotificationResponse(func(response notifications.NotificationResponse) { - data, _ := json.Marshal(response) + notificationService.OnNotificationResponse(func(result notifications.NotificationResult) { + if result.Error != nil { + fmt.Printf("notification response error: %s", result.Error) + return + } + data, _ := json.Marshal(result.Response) fmt.Printf("%s\n", string(data)) - app.EmitEvent("notification:response", response) + app.EmitEvent("notification:response", result.Response) }) time.Sleep(time.Second * 2) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 7d6ed14aa..ccbcc7e1c 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -5,7 +5,7 @@ import "sync" // Service represents the notifications service type Service struct { // notificationResponseCallback is called when a notification response is received - notificationResponseCallback func(response NotificationResponse) + notificationResultCallback func(result NotificationResult) callbackLock sync.RWMutex } @@ -53,30 +53,42 @@ type NotificationResponse = struct { UserInfo map[string]interface{} `json:"userInfo,omitempty"` } +// NotificationResult +type NotificationResult = struct { + Response NotificationResponse + Error error +} + // ServiceName returns the name of the service. func (ns *Service) ServiceName() string { return "github.com/wailsapp/wails/v3/services/notifications" } +func getNotificationService() *Service { + notificationServiceLock.RLock() + defer notificationServiceLock.RUnlock() + return NotificationService +} + // OnNotificationResponse registers a callback function that will be called when // a notification response is received from the user. // //wails:ignore -func (ns *Service) OnNotificationResponse(callback func(response NotificationResponse)) { +func (ns *Service) OnNotificationResponse(callback func(result NotificationResult)) { ns.callbackLock.Lock() defer ns.callbackLock.Unlock() - ns.notificationResponseCallback = callback + ns.notificationResultCallback = callback } // handleNotificationResponse is an internal method to handle notification responses // and invoke the registered callback if one exists -func (ns *Service) handleNotificationResponse(response NotificationResponse) { +func (ns *Service) handleNotificationResult(result NotificationResult) { ns.callbackLock.RLock() - callback := ns.notificationResponseCallback + callback := ns.notificationResultCallback ns.callbackLock.RUnlock() if callback != nil { - callback(response) + callback(result) } } diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 426b7a411..88769fe04 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -9,15 +9,17 @@ package notifications */ import "C" import ( + "context" "encoding/json" "fmt" "sync" + "time" "unsafe" ) type notificationChannel struct { - authorized bool - err error + success bool + err error } var ( @@ -55,26 +57,47 @@ func CheckBundleIdentifier() bool { // RequestNotificationAuthorization requests permission for notifications. func (ns *Service) RequestNotificationAuthorization() (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + id, resultCh := registerChannel() C.requestNotificationAuthorization(C.int(id)) - result := <-resultCh - return result.authorized, result.err + select { + case result := <-resultCh: + return result.success, result.err + case <-ctx.Done(): + cleanupChannel(id) + return false, fmt.Errorf("notification authorization timed out after 15s: %w", ctx.Err()) + } } // CheckNotificationAuthorization checks current notification permission status. func (ns *Service) CheckNotificationAuthorization() (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + id, resultCh := registerChannel() C.checkNotificationAuthorization(C.int(id)) - result := <-resultCh - return result.authorized, result.err + select { + case result := <-resultCh: + return result.success, result.err + case <-ctx.Done(): + cleanupChannel(id) + return false, fmt.Errorf("notification authorization timed out after 15s: %w", ctx.Err()) + } } // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ns *Service) SendNotification(options NotificationOptions) error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + id, resultCh := registerChannel() + cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) cSubtitle := C.CString(options.Subtitle) @@ -94,14 +117,32 @@ func (ns *Service) SendNotification(options NotificationOptions) error { defer C.free(unsafe.Pointer(cDataJSON)) } - C.sendNotification(cIdentifier, cTitle, cSubtitle, cBody, cDataJSON) - return nil + C.sendNotification(C.int(id), cIdentifier, cTitle, cSubtitle, cBody, cDataJSON) + + select { + case result := <-resultCh: + if !result.success { + if result.err != nil { + return result.err + } + return fmt.Errorf("sending notification failed") + } + return nil + case <-ctx.Done(): + cleanupChannel(id) + return fmt.Errorf("sending notification timed out: %w", ctx.Err()) + } } // SendNotificationWithActions sends a notification with additional actions and inputs. // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + id, resultCh := registerChannel() + cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) cSubtitle := C.CString(options.Subtitle) @@ -123,13 +164,30 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro defer C.free(unsafe.Pointer(cDataJSON)) } - C.sendNotificationWithActions(cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cDataJSON) - return nil + C.sendNotificationWithActions(C.int(id), cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cDataJSON) + select { + case result := <-resultCh: + if !result.success { + if result.err != nil { + return result.err + } + return fmt.Errorf("sending notification failed") + } + return nil + case <-ctx.Done(): + cleanupChannel(id) + return fmt.Errorf("sending notification timed out: %w", ctx.Err()) + } } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. // Registering a category with the same name as a previously registered NotificationCategory will override it. func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + id, resultCh := registerChannel() + cCategoryID := C.CString(category.ID) defer C.free(unsafe.Pointer(cCategoryID)) @@ -148,9 +206,22 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e defer C.free(unsafe.Pointer(cReplyButtonTitle)) } - C.registerNotificationCategory(cCategoryID, cActionsJSON, C.bool(category.HasReplyField), + C.registerNotificationCategory(C.int(id), cCategoryID, cActionsJSON, C.bool(category.HasReplyField), cReplyPlaceholder, cReplyButtonTitle) - return nil + + select { + case result := <-resultCh: + if !result.success { + if result.err != nil { + return result.err + } + return fmt.Errorf("category registration failed") + } + return nil + case <-ctx.Done(): + cleanupChannel(id) + return fmt.Errorf("category registration timed out: %w", ctx.Err()) + } } // RemoveNotificationCategory remove a previously registered NotificationCategory. @@ -201,8 +272,8 @@ func (ns *Service) RemoveNotification(identifier string) error { return nil } -//export requestNotificationAuthorizationResponse -func requestNotificationAuthorizationResponse(channelID C.int, authorized C.bool, errorMsg *C.char) { +//export notificationResponse +func notificationResponse(channelID C.int, success C.bool, errorMsg *C.char) { resultCh, exists := getChannel(int(channelID)) if !exists { // handle this @@ -216,41 +287,42 @@ func requestNotificationAuthorizationResponse(channelID C.int, authorized C.bool } resultCh <- notificationChannel{ - authorized: bool(authorized), - err: err, - } - - close(resultCh) -} - -//export checkNotificationAuthorizationResponse -func checkNotificationAuthorizationResponse(channelID C.int, authorized C.bool, errorMsg *C.char) { - resultCh, exists := getChannel(int(channelID)) - if !exists { - // handle this - return - } - - var err error - if errorMsg != nil { - err = fmt.Errorf("%s", C.GoString(errorMsg)) - C.free(unsafe.Pointer(errorMsg)) - } - - resultCh <- notificationChannel{ - authorized: bool(authorized), - err: err, + success: bool(success), + err: err, } close(resultCh) } //export didReceiveNotificationResponse -func didReceiveNotificationResponse(jsonPayload *C.char) { +func didReceiveNotificationResponse(jsonPayload *C.char, err *C.char) { + result := NotificationResult{} + + if err != nil { + errMsg := C.GoString(err) + result.Error = fmt.Errorf("notification response error: %s", errMsg) + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } + return + } + + if jsonPayload == nil { + result.Error = fmt.Errorf("received nil JSON payload in notification response") + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } + return + } + payload := C.GoString(jsonPayload) var response NotificationResponse if err := json.Unmarshal([]byte(payload), &response); err != nil { + result.Error = fmt.Errorf("failed to unmarshal notification response: %w", err) + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } return } @@ -258,18 +330,9 @@ func didReceiveNotificationResponse(jsonPayload *C.char) { response.ActionIdentifier = DefaultActionIdentifier } - notificationServiceLock.RLock() - ns := NotificationService - notificationServiceLock.RUnlock() - - if ns != nil { - ns.callbackLock.RLock() - callback := ns.notificationResponseCallback - ns.callbackLock.RUnlock() - - if callback != nil { - callback(response) - } + result.Response = response + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) } } @@ -296,3 +359,13 @@ func getChannel(id int) (chan notificationChannel, bool) { } return ch, exists } + +func cleanupChannel(id int) { + notificationChannelsLock.Lock() + defer notificationChannelsLock.Unlock() + + if ch, exists := notificationChannels[id]; exists { + delete(notificationChannels, id) + close(ch) + } +} diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index 6848dc68e..a8b7c2298 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -8,9 +8,9 @@ bool checkBundleIdentifier(void); void requestNotificationAuthorization(int channelID); void checkNotificationAuthorization(int channelID); -void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json); -void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json); -void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); +void sendNotification(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json); +void sendNotificationWithActions(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json); +void registerNotificationCategory(int channelID, const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); void removeNotificationCategory(const char *categoryId); void removeAllPendingNotifications(void); void removePendingNotification(const char *identifier); diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 8329cdc26..66461df99 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -2,9 +2,8 @@ #import #import -extern void requestNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); -extern void checkNotificationAuthorizationResponse(int channelID, bool authorized, const char* error); -extern void didReceiveNotificationResponse(const char *jsonPayload); +extern void notificationResponse(int channelID, bool success, const char* error); +extern void didReceiveNotificationResponse(const char *jsonPayload, const char* error); @interface NotificationsDelegate : NSObject @end @@ -50,9 +49,12 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response NSError *error = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload options:0 error:&error]; - if (!error) { + if (error) { + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; + didReceiveNotificationResponse(NULL, [errorMsg UTF8String]); + } else { NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - didReceiveNotificationResponse([jsonString UTF8String]); + didReceiveNotificationResponse([jsonString UTF8String], NULL); } completionHandler(); @@ -86,9 +88,10 @@ void requestNotificationAuthorization(int channelID) { [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) { if (error) { - requestNotificationAuthorizationResponse(channelID, false, [[error localizedDescription] UTF8String]); + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; + notificationResponse(channelID, false, [errorMsg UTF8String]); } else { - requestNotificationAuthorizationResponse(channelID, granted, NULL); + notificationResponse(channelID, granted, NULL); } }]; } @@ -99,11 +102,11 @@ void checkNotificationAuthorization(int channelID) { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) { BOOL isAuthorized = (settings.authorizationStatus == UNAuthorizationStatusAuthorized); - checkNotificationAuthorizationResponse(channelID, isAuthorized, NULL); + notificationResponse(channelID, isAuthorized, NULL); }]; } -void sendNotification(const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json) { +void sendNotification(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json) { ensureDelegateInitialized(); NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; @@ -117,6 +120,11 @@ void sendNotification(const char *identifier, const char *title, const char *sub NSData *jsonData = [dataJsonStr dataUsingEncoding:NSUTF8StringEncoding]; NSError *error = nil; NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; + if (error) { + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; + notificationResponse(channelID, false, [errorMsg UTF8String]); + return; + } if (!error && parsedData) { [customData addEntriesFromDictionary:parsedData]; } @@ -140,12 +148,15 @@ void sendNotification(const char *identifier, const char *title, const char *sub [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (error) { - NSLog(@"Error scheduling notification: %@", error.localizedDescription); + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; + notificationResponse(channelID, false, [errorMsg UTF8String]); + } else { + notificationResponse(channelID, true, NULL); } }]; } -void sendNotificationWithActions(const char *identifier, const char *title, const char *subtitle, +void sendNotificationWithActions(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json) { ensureDelegateInitialized(); @@ -187,12 +198,15 @@ void sendNotificationWithActions(const char *identifier, const char *title, cons [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (error) { - NSLog(@"Error scheduling notification: %@", error.localizedDescription); + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; + notificationResponse(channelID, false, [errorMsg UTF8String]); + } else { + notificationResponse(channelID, true, NULL); } }]; } -void registerNotificationCategory(const char *categoryId, const char *actions_json, bool hasReplyField, +void registerNotificationCategory(int channelID, const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle) { ensureDelegateInitialized(); @@ -204,7 +218,8 @@ void registerNotificationCategory(const char *categoryId, const char *actions_js NSArray *actionsArray = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; if (error) { - NSLog(@"Error parsing notification actions JSON: %@", error); + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; + notificationResponse(channelID, false, [errorMsg UTF8String]); return; } @@ -265,6 +280,8 @@ void registerNotificationCategory(const char *categoryId, const char *actions_js // Add the new category [updatedCategories addObject:newCategory]; [center setNotificationCategories:updatedCategories]; + + notificationResponse(channelID, true, NULL); }]; } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 58d78c2e9..68217d861 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -235,7 +235,7 @@ func (n *internalNotifier) handleNotificationClosed(systemID uint32, reason stri } n.Unlock() - if notifID != "" && NotificationService != nil { + if notifID != "" { response := NotificationResponse{ ID: notifID, ActionIdentifier: DefaultActionIdentifier, @@ -251,7 +251,11 @@ func (n *internalNotifier) handleNotificationClosed(systemID uint32, reason stri response.UserInfo["reason"] = reason } - NotificationService.handleNotificationResponse(response) + result := NotificationResult{} + result.Response = response + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } // Clean up the context n.Lock() @@ -277,7 +281,7 @@ func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string } n.Unlock() - if notifID != "" && NotificationService != nil { + if notifID != "" { if actionKey == "default" { actionKey = DefaultActionIdentifier } @@ -293,7 +297,11 @@ func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string response.UserInfo = ctx.UserData } - NotificationService.handleNotificationResponse(response) + result := NotificationResult{} + result.Response = response + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } // Then, trigger a closed event with "activated-by-user" reason closeResponse := NotificationResponse{ @@ -311,7 +319,11 @@ func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string // Add the reason to the user info closeResponse.UserInfo["reason"] = closedReason(5).string() // "activated-by-user" - NotificationService.handleNotificationResponse(closeResponse) + closeResult := NotificationResult{} + closeResult.Response = closeResponse + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(closeResult) + } // Clean up the context n.Lock() diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 371523ec6..10e0f01a0 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -71,6 +71,7 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi }) toast.SetActivationCallback(func(args string, data []toast.UserData) { + result := NotificationResult{} actionIdentifier, userInfo := parseNotificationResponse(args) response := NotificationResponse{ ActionIdentifier: actionIdentifier, @@ -78,17 +79,23 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi if userInfo != "" { var userInfoMap map[string]interface{} - if err := json.Unmarshal([]byte(userInfo), &userInfoMap); err == nil { - response.UserInfo = userInfoMap + if err := json.Unmarshal([]byte(userInfo), &userInfoMap); err != nil { + result.Error = fmt.Errorf("failed to unmarshal notification response: %w", err) + + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } } + response.UserInfo = userInfoMap } if userText, found := getUserText(data); found { response.UserText = userText } - if NotificationService != nil { - NotificationService.handleNotificationResponse(response) + result.Response = response + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) } }) From b60ef7729e8a76d24f702546efcef2f7b6e7eba7 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Tue, 18 Mar 2025 22:46:44 -0700 Subject: [PATCH 076/136] coderabbit impr --- v3/examples/notifications/frontend/main.js | 14 +++ .../services/notifications/notifications.go | 1 + .../notifications/notifications_darwin.go | 56 ++++++--- .../notifications/notifications_darwin.h | 2 +- .../notifications/notifications_darwin.m | 34 +++--- .../notifications/notifications_linux.go | 108 ++++++++++++++---- .../notifications/notifications_windows.go | 2 +- 7 files changed, 156 insertions(+), 61 deletions(-) diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js index 2c6d234d4..781f8983e 100644 --- a/v3/examples/notifications/frontend/main.js +++ b/v3/examples/notifications/frontend/main.js @@ -48,6 +48,20 @@ window.sendComplexNotification = async () => { } } +window.removeNotification = async (id) => { + const granted = await Notifications.Service.RequestNotificationAuthorization(); + if (granted) { + await Notifications.Service.RemoveDeliveredNotification(id); + } +} + +window.removeAllNotifications = async (id) => { + const granted = await Notifications.Service.RequestNotificationAuthorization(); + if (granted) { + await Notifications.Service.RemoveAllDeliveredNotifications(); + } +} + Events.On("notification:response", (response) => { notificationsElement.innerText = JSON.stringify(response.data[0]); }); \ No newline at end of file diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index ccbcc7e1c..fb519aed2 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -5,6 +5,7 @@ import "sync" // Service represents the notifications service type Service struct { // notificationResponseCallback is called when a notification response is received + // Only one callback can be assigned at a time. notificationResultCallback func(result NotificationResult) callbackLock sync.RWMutex diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 88769fe04..217e75ad4 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -18,8 +18,8 @@ import ( ) type notificationChannel struct { - success bool - err error + Success bool + Error error } var ( @@ -66,7 +66,7 @@ func (ns *Service) RequestNotificationAuthorization() (bool, error) { select { case result := <-resultCh: - return result.success, result.err + return result.Success, result.Error case <-ctx.Done(): cleanupChannel(id) return false, fmt.Errorf("notification authorization timed out after 15s: %w", ctx.Err()) @@ -84,7 +84,7 @@ func (ns *Service) CheckNotificationAuthorization() (bool, error) { select { case result := <-resultCh: - return result.success, result.err + return result.Success, result.Error case <-ctx.Done(): cleanupChannel(id) return false, fmt.Errorf("notification authorization timed out after 15s: %w", ctx.Err()) @@ -121,9 +121,9 @@ func (ns *Service) SendNotification(options NotificationOptions) error { select { case result := <-resultCh: - if !result.success { - if result.err != nil { - return result.err + if !result.Success { + if result.Error != nil { + return result.Error } return fmt.Errorf("sending notification failed") } @@ -167,9 +167,9 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro C.sendNotificationWithActions(C.int(id), cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cDataJSON) select { case result := <-resultCh: - if !result.success { - if result.err != nil { - return result.err + if !result.Success { + if result.Error != nil { + return result.Error } return fmt.Errorf("sending notification failed") } @@ -211,9 +211,9 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e select { case result := <-resultCh: - if !result.success { - if result.err != nil { - return result.err + if !result.Success { + if result.Error != nil { + return result.Error } return fmt.Errorf("category registration failed") } @@ -226,11 +226,29 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e // RemoveNotificationCategory remove a previously registered NotificationCategory. func (ns *Service) RemoveNotificationCategory(categoryId string) error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + id, resultCh := registerChannel() + cCategoryID := C.CString(categoryId) defer C.free(unsafe.Pointer(cCategoryID)) - C.removeNotificationCategory(cCategoryID) - return nil + C.removeNotificationCategory(C.int(id), cCategoryID) + + select { + case result := <-resultCh: + if !result.Success { + if result.Error != nil { + return result.Error + } + return fmt.Errorf("category registration failed") + } + return nil + case <-ctx.Done(): + cleanupChannel(id) + return fmt.Errorf("category registration timed out: %w", ctx.Err()) + } } // RemoveAllPendingNotifications removes all pending notifications. @@ -272,8 +290,8 @@ func (ns *Service) RemoveNotification(identifier string) error { return nil } -//export notificationResponse -func notificationResponse(channelID C.int, success C.bool, errorMsg *C.char) { +//export captureResult +func captureResult(channelID C.int, success C.bool, errorMsg *C.char) { resultCh, exists := getChannel(int(channelID)) if !exists { // handle this @@ -287,8 +305,8 @@ func notificationResponse(channelID C.int, success C.bool, errorMsg *C.char) { } resultCh <- notificationChannel{ - success: bool(success), - err: err, + Success: bool(success), + Error: err, } close(resultCh) diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index a8b7c2298..f7acf6d1a 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -11,7 +11,7 @@ void checkNotificationAuthorization(int channelID); void sendNotification(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json); void sendNotificationWithActions(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *actions_json); void registerNotificationCategory(int channelID, const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle); -void removeNotificationCategory(const char *categoryId); +void removeNotificationCategory(int channelID, const char *categoryId); void removeAllPendingNotifications(void); void removePendingNotification(const char *identifier); void removeAllDeliveredNotifications(void); diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 66461df99..abb129842 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -2,7 +2,7 @@ #import #import -extern void notificationResponse(int channelID, bool success, const char* error); +extern void captureResult(int channelID, bool success, const char* error); extern void didReceiveNotificationResponse(const char *jsonPayload, const char* error); @interface NotificationsDelegate : NSObject @@ -89,9 +89,9 @@ void requestNotificationAuthorization(int channelID) { [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) { if (error) { NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; - notificationResponse(channelID, false, [errorMsg UTF8String]); + captureResult(channelID, false, [errorMsg UTF8String]); } else { - notificationResponse(channelID, granted, NULL); + captureResult(channelID, granted, NULL); } }]; } @@ -102,7 +102,7 @@ void checkNotificationAuthorization(int channelID) { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) { BOOL isAuthorized = (settings.authorizationStatus == UNAuthorizationStatusAuthorized); - notificationResponse(channelID, isAuthorized, NULL); + captureResult(channelID, isAuthorized, NULL); }]; } @@ -122,10 +122,10 @@ void sendNotification(int channelID, const char *identifier, const char *title, NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; if (error) { NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; - notificationResponse(channelID, false, [errorMsg UTF8String]); + captureResult(channelID, false, [errorMsg UTF8String]); return; } - if (!error && parsedData) { + if (parsedData) { [customData addEntriesFromDictionary:parsedData]; } } @@ -142,16 +142,16 @@ void sendNotification(int channelID, const char *identifier, const char *title, content.userInfo = customData; } - UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO]; + UNTimeIntervalNotificationTrigger *trigger = nil; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (error) { NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; - notificationResponse(channelID, false, [errorMsg UTF8String]); + captureResult(channelID, false, [errorMsg UTF8String]); } else { - notificationResponse(channelID, true, NULL); + captureResult(channelID, true, NULL); } }]; } @@ -192,16 +192,16 @@ void sendNotificationWithActions(int channelID, const char *identifier, const ch content.userInfo = customData; } - UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO]; + UNTimeIntervalNotificationTrigger *trigger = nil; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (error) { NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; - notificationResponse(channelID, false, [errorMsg UTF8String]); + captureResult(channelID, false, [errorMsg UTF8String]); } else { - notificationResponse(channelID, true, NULL); + captureResult(channelID, true, NULL); } }]; } @@ -219,7 +219,7 @@ void registerNotificationCategory(int channelID, const char *categoryId, const c if (error) { NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; - notificationResponse(channelID, false, [errorMsg UTF8String]); + captureResult(channelID, false, [errorMsg UTF8String]); return; } @@ -281,11 +281,11 @@ void registerNotificationCategory(int channelID, const char *categoryId, const c [updatedCategories addObject:newCategory]; [center setNotificationCategories:updatedCategories]; - notificationResponse(channelID, true, NULL); + captureResult(channelID, true, NULL); }]; } -void removeNotificationCategory(const char *categoryId) { +void removeNotificationCategory(int channelID, const char *categoryId) { NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; @@ -304,6 +304,10 @@ void removeNotificationCategory(const char *categoryId) { if (categoryToRemove) { [updatedCategories removeObject:categoryToRemove]; [center setNotificationCategories:updatedCategories]; + captureResult(channelID, true, NULL); + } else { + NSString *errorMsg = [NSString stringWithFormat:@"Category '%@' not found", nsCategoryId]; + captureResult(channelID, false, [errorMsg UTF8String]); } }]; } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 68217d861..34b110987 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -1,7 +1,5 @@ //go:build linux -// WIP - WILL NOT WORK PROPERLY - package notifications import ( @@ -69,11 +67,14 @@ type notificationContext struct { type internalNotifier struct { sync.Mutex - method string - dbusConn *dbus.Conn - sendPath string - activeNotifs map[string]uint32 // Maps our notification IDs to system IDs - contexts map[string]*notificationContext // Stores notification contexts by our ID + method string + dbusConn *dbus.Conn + sendPath string + activeNotifs map[string]uint32 // Maps our notification IDs to system IDs + contexts map[string]*notificationContext // Stores notification contexts by our ID + listenerCtx context.Context + listenerCancel context.CancelFunc + listenerRunning bool } var notifier *internalNotifier @@ -107,10 +108,33 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi return err } +func (n *internalNotifier) shutdown() { + n.Lock() + defer n.Unlock() + + // Cancel the listener context if it's running + if n.listenerCancel != nil { + n.listenerCancel() + n.listenerCancel = nil + } + + // Close the connection + if n.dbusConn != nil { + n.dbusConn.Close() + n.dbusConn = nil + } + + // Clear state + n.activeNotifs = make(map[string]uint32) + n.contexts = make(map[string]*notificationContext) + n.method = "none" + n.sendPath = "" +} + // ServiceShutdown is called when the service is unloaded func (ns *Service) ServiceShutdown() error { - if notifier != nil && notifier.dbusConn != nil { - notifier.dbusConn.Close() + if notifier != nil { + notifier.shutdown() } return saveCategories() } @@ -119,6 +143,19 @@ func (ns *Service) ServiceShutdown() error { func (n *internalNotifier) init() error { var err error + // Cancel any existing listener before starting a new one + if n.listenerCancel != nil { + n.listenerCancel() + } + + // Create a new context for the listener + n.listenerCtx, n.listenerCancel = context.WithCancel(context.Background()) + + // Reset state + n.activeNotifs = make(map[string]uint32) + n.contexts = make(map[string]*notificationContext) + n.listenerRunning = false + checkDbus := func() (*dbus.Conn, error) { conn, err := dbus.SessionBusPrivate() if err != nil { @@ -161,8 +198,9 @@ func (n *internalNotifier) init() error { n.dbusConn, err = checkDbus() if err == nil { n.method = MethodDbus - // Start the dbus signal listener - go n.startDBusListener() + // Start the dbus signal listener with context + go n.startDBusListener(n.listenerCtx) + n.listenerRunning = true return nil } if n.dbusConn != nil { @@ -194,24 +232,44 @@ func (n *internalNotifier) init() error { } // startDBusListener listens for DBus signals for notification actions and closures -func (n *internalNotifier) startDBusListener() { +func (n *internalNotifier) startDBusListener(ctx context.Context) { signal := make(chan *dbus.Signal, notifyChannelBufferSize) n.dbusConn.Signal(signal) - for s := range signal { - if s == nil || len(s.Body) < 2 { - continue - } + defer func() { + n.Lock() + n.listenerRunning = false + n.Unlock() + n.dbusConn.RemoveSignal(signal) // Remove signal handler + close(signal) // Clean up channel + }() - switch s.Name { - case signalNotificationClosed: - systemID := s.Body[0].(uint32) - reason := closedReason(s.Body[1].(uint32)).string() - n.handleNotificationClosed(systemID, reason) - case signalActionInvoked: - systemID := s.Body[0].(uint32) - actionKey := s.Body[1].(string) - n.handleActionInvoked(systemID, actionKey) + for { + select { + case <-ctx.Done(): + // Context was cancelled, exit gracefully + return + + case s := <-signal: + if s == nil { + // Channel closed or nil signal + continue + } + + if len(s.Body) < 2 { + continue + } + + switch s.Name { + case signalNotificationClosed: + systemID := s.Body[0].(uint32) + reason := closedReason(s.Body[1].(uint32)).string() + n.handleNotificationClosed(systemID, reason) + case signalActionInvoked: + systemID := s.Body[0].(uint32) + actionKey := s.Body[1].(string) + n.handleActionInvoked(systemID, actionKey) + } } } } diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 10e0f01a0..6afda46b4 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -305,7 +305,7 @@ func parseNotificationResponse(response string) (action string, data string) { func saveIconToDir() error { icon, err := application.NewIconFromResource(w32.GetModuleHandle(""), uint16(3)) if err != nil { - return fmt.Errorf("failed to retrieve application icon") + return fmt.Errorf("failed to retrieve application icon: %w", err) } return saveHIconAsPNG(icon, iconPath) From ee885fea44f1e6b03b0561581b5b8f5adc50c5e0 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Tue, 18 Mar 2025 23:13:37 -0700 Subject: [PATCH 077/136] fix mem crash --- v3/pkg/services/notifications/notifications_darwin.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 217e75ad4..f17dd5a69 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -56,8 +56,9 @@ func CheckBundleIdentifier() bool { } // RequestNotificationAuthorization requests permission for notifications. +// Default timeout is 5 minutes func (ns *Service) RequestNotificationAuthorization() (bool, error) { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*900) defer cancel() id, resultCh := registerChannel() @@ -294,14 +295,12 @@ func (ns *Service) RemoveNotification(identifier string) error { func captureResult(channelID C.int, success C.bool, errorMsg *C.char) { resultCh, exists := getChannel(int(channelID)) if !exists { - // handle this return } var err error if errorMsg != nil { err = fmt.Errorf("%s", C.GoString(errorMsg)) - C.free(unsafe.Pointer(errorMsg)) } resultCh <- notificationChannel{ From 4af058bd02ee74d16a8b80de9f54cba12a8c1a1a Mon Sep 17 00:00:00 2001 From: popaprozac Date: Wed, 19 Mar 2025 18:10:59 -0700 Subject: [PATCH 078/136] more cleanup --- .../services/notifications/notifications.go | 31 +++++++- .../notifications/notifications_darwin.go | 12 ++- .../notifications/notifications_darwin.m | 75 ++++++++----------- .../notifications/notifications_linux.go | 8 ++ .../notifications/notifications_windows.go | 36 ++++++--- 5 files changed, 103 insertions(+), 59 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index fb519aed2..d3295d8c1 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -1,10 +1,25 @@ +// Package notifications provides cross-platform notification capabilities for desktop applications. +// It supports macOS, Windows, and Linux with a consistent API while handling platform-specific +// differences internally. Key features include: +// - Basic notifications with title, subtitle, and body +// - Interactive notifications with buttons and actions +// - Notification categories for reusing configurations +// - User feedback handling with a unified callback system +// +// Platform-specific notes: +// - macOS: Requires a properly bundled and signed application +// - Windows: Uses Windows Toast notifications +// - Linux: Falls back between D-Bus, notify-send, or other methods and does not support text inputs package notifications -import "sync" +import ( + "fmt" + "sync" +) // Service represents the notifications service type Service struct { - // notificationResponseCallback is called when a notification response is received + // notificationResponseCallback is called when a notification result is received. // Only one callback can be assigned at a time. notificationResultCallback func(result NotificationResult) @@ -93,3 +108,15 @@ func (ns *Service) handleNotificationResult(result NotificationResult) { callback(result) } } + +func validateNotificationOptions(options NotificationOptions) error { + if options.ID == "" { + return fmt.Errorf("notification ID cannot be empty") + } + + if options.Title == "" { + return fmt.Errorf("notification title cannot be empty") + } + + return nil +} diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index f17dd5a69..638c8b3a4 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -56,7 +56,7 @@ func CheckBundleIdentifier() bool { } // RequestNotificationAuthorization requests permission for notifications. -// Default timeout is 5 minutes +// Default timeout is 15 minutes func (ns *Service) RequestNotificationAuthorization() (bool, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*900) defer cancel() @@ -94,6 +94,10 @@ func (ns *Service) CheckNotificationAuthorization() (bool, error) { // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ns *Service) SendNotification(options NotificationOptions) error { + if err := validateNotificationOptions(options); err != nil { + return err + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -139,6 +143,10 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + if err := validateNotificationOptions(options); err != nil { + return err + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -243,7 +251,7 @@ func (ns *Service) RemoveNotificationCategory(categoryId string) error { if result.Error != nil { return result.Error } - return fmt.Errorf("category registration failed") + return fmt.Errorf("category removal failed") } return nil case <-ctx.Done(): diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index abb129842..cd1c96898 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -106,37 +106,43 @@ void checkNotificationAuthorization(int channelID) { }]; } -void sendNotification(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json) { - ensureDelegateInitialized(); - - NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; +// Helper function to create notification content +UNMutableNotificationContent* createNotificationContent(const char *title, const char *subtitle, + const char *body, const char *data_json) { NSString *nsTitle = [NSString stringWithUTF8String:title]; - NSString *nsSubtitle = [NSString stringWithUTF8String:subtitle]; + NSString *nsSubtitle = subtitle ? [NSString stringWithUTF8String:subtitle] : @""; NSString *nsBody = [NSString stringWithUTF8String:body]; - NSMutableDictionary *customData = [NSMutableDictionary dictionary]; + UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; + content.title = nsTitle; + if (![nsSubtitle isEqualToString:@""]) { + content.subtitle = nsSubtitle; + } + content.body = nsBody; + content.sound = [UNNotificationSound defaultSound]; + + // Parse JSON data if provided if (data_json) { NSString *dataJsonStr = [NSString stringWithUTF8String:data_json]; NSData *jsonData = [dataJsonStr dataUsingEncoding:NSUTF8StringEncoding]; NSError *error = nil; NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; - if (error) { - NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]]; - captureResult(channelID, false, [errorMsg UTF8String]); - return; - } - if (parsedData) { - [customData addEntriesFromDictionary:parsedData]; + if (!error && parsedData) { + content.userInfo = parsedData; } } - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + return content; +} + +void sendNotification(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json) { + ensureDelegateInitialized(); - UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; - content.title = nsTitle; - content.subtitle = nsSubtitle; - content.body = nsBody; - content.sound = [UNNotificationSound defaultSound]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + + NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; + UNMutableNotificationContent *content = createNotificationContent(title, subtitle, body, data_json); + NSMutableDictionary *customData = [NSMutableDictionary dictionary]; if (customData.count > 0) { content.userInfo = customData; @@ -157,35 +163,16 @@ void sendNotification(int channelID, const char *identifier, const char *title, } void sendNotificationWithActions(int channelID, const char *identifier, const char *title, const char *subtitle, - const char *body, const char *categoryId, const char *actions_json) { + const char *body, const char *categoryId, const char *data_json) { ensureDelegateInitialized(); - NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; - NSString *nsTitle = [NSString stringWithUTF8String:title]; - NSString *nsSubtitle = subtitle ? [NSString stringWithUTF8String:subtitle] : @""; - NSString *nsBody = [NSString stringWithUTF8String:body]; - NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; - - NSMutableDictionary *customData = [NSMutableDictionary dictionary]; - if (actions_json) { - NSString *actionsJsonStr = [NSString stringWithUTF8String:actions_json]; - NSData *jsonData = [actionsJsonStr dataUsingEncoding:NSUTF8StringEncoding]; - NSError *error = nil; - NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; - if (!error && parsedData) { - [customData addEntriesFromDictionary:parsedData]; - } - } - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + + NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; + NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; + UNMutableNotificationContent *content = createNotificationContent(title, subtitle, body, data_json); + NSMutableDictionary *customData = [NSMutableDictionary dictionary]; - UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; - content.title = nsTitle; - if (![nsSubtitle isEqualToString:@""]) { - content.subtitle = nsSubtitle; - } - content.body = nsBody; - content.sound = [UNNotificationSound defaultSound]; content.categoryIdentifier = nsCategoryId; if (customData.count > 0) { diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 34b110987..a75996f50 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -415,6 +415,10 @@ func (ns *Service) SendNotification(options NotificationOptions) error { return errors.New("notification service not initialized") } + if err := validateNotificationOptions(options); err != nil { + return err + } + notifier.Lock() defer notifier.Unlock() @@ -454,6 +458,10 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro return errors.New("notification service not initialized") } + if err := validateNotificationOptions(options); err != nil { + return err + } + notificationLock.RLock() category, exists := notificationCategories[options.CategoryID] notificationLock.RUnlock() diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 6afda46b4..06884f3f6 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -128,6 +128,10 @@ func (ns *Service) CheckNotificationAuthorization() bool { // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotification(options NotificationOptions) error { + if err := validateNotificationOptions(options); err != nil { + return err + } + if err := saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) } @@ -140,9 +144,10 @@ func (ns *Service) SendNotification(options NotificationOptions) error { if options.Data != nil { encodedPayload, err := encodePayload(DefaultActionIdentifier, options.Data) - if err == nil { - n.ActivationArguments = encodedPayload + if err != nil { + return fmt.Errorf("failed to encode notification data: %w", err) } + n.ActivationArguments = encodedPayload } return n.Push() @@ -153,6 +158,10 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // If a NotificationCategory is not registered a basic notification will be sent. // (subtitle and category id are only available on macOS) func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + if err := validateNotificationOptions(options); err != nil { + return err + } + if err := saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) } @@ -191,15 +200,15 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro n.ActivationArguments, _ = encodePayload(n.ActivationArguments, options.Data) for index := range n.Actions { - n.Actions[index].Arguments, _ = encodePayload(n.Actions[index].Arguments, options.Data) + encodedPayload, err := encodePayload(n.Actions[index].Arguments, options.Data) + if err != nil { + return fmt.Errorf("failed to encode notification data: %w", err) + } + n.Actions[index].Arguments = encodedPayload } } - err := n.Push() - if err != nil { - return err - } - return nil + return n.Push() } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. @@ -344,20 +353,25 @@ func loadCategoriesFromRegistry() error { ) if err != nil { if err == registry.ErrNotExist { + // Not an error, no saved categories return nil } - return err + return fmt.Errorf("failed to open registry key: %w", err) } defer key.Close() data, _, err := key.GetStringValue(NotificationCategoriesRegistryKey) if err != nil { - return err + if err == registry.ErrNotExist { + // No value yet, but key exists + return nil + } + return fmt.Errorf("failed to read categories from registry: %w", err) } categories := make(map[string]NotificationCategory) if err := json.Unmarshal([]byte(data), &categories); err != nil { - return err + return fmt.Errorf("failed to parse notification categories from registry: %w", err) } notificationCategoriesLock.Lock() From 25256f747f570b3020ae69a8490c8ec7ec526af7 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Wed, 19 Mar 2025 21:40:26 -0700 Subject: [PATCH 079/136] allow only one notification service per app --- .../services/notifications/notifications.go | 8 ++++-- .../notifications/notifications_darwin.go | 28 +++++++++---------- .../notifications/notifications_linux.go | 8 ++++-- .../notifications/notifications_windows.go | 10 +++---- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index d3295d8c1..297a21059 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -26,8 +26,11 @@ type Service struct { callbackLock sync.RWMutex } -var NotificationService *Service -var notificationServiceLock sync.RWMutex +var ( + notificationServiceOnce sync.Once + NotificationService *Service + notificationServiceLock sync.RWMutex +) // NotificationAction represents an action button for a notification type NotificationAction = struct { @@ -109,6 +112,7 @@ func (ns *Service) handleNotificationResult(result NotificationResult) { } } +// validateNotificationOptions validates an ID and Title are provided for notifications func validateNotificationOptions(options NotificationOptions) error { if options.ID == "" { return fmt.Errorf("notification ID cannot be empty") diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 638c8b3a4..d6eee5464 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -33,21 +33,21 @@ const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdent // Creates a new Notifications Service. // Your app must be packaged and signed for this feature to work. func New() *Service { - if !CheckBundleIdentifier() { - panic("\nError: Cannot use the notification API in development mode on macOS.\n" + - "Notifications require the app to be properly bundled with a bundle identifier and signed.\n" + - "To use the notification API on macOS:\n" + - " 1. Build and package your app using 'wails3 package'\n" + - " 2. Sign the packaged .app\n" + - " 3. Run the signed .app bundle") - } + notificationServiceOnce.Do(func() { + if !CheckBundleIdentifier() { + panic("\nError: Cannot use the notification API in development mode on macOS.\n" + + "Notifications require the app to be properly bundled with a bundle identifier and signed.\n" + + "To use the notification API on macOS:\n" + + " 1. Build and package your app using 'wails3 package'\n" + + " 2. Sign the packaged .app\n" + + " 3. Run the signed .app bundle") + } - notificationServiceLock.Lock() - defer notificationServiceLock.Unlock() + if NotificationService == nil { + NotificationService = &Service{} + } + }) - if NotificationService == nil { - NotificationService = &Service{} - } return NotificationService } @@ -70,7 +70,7 @@ func (ns *Service) RequestNotificationAuthorization() (bool, error) { return result.Success, result.Error case <-ctx.Done(): cleanupChannel(id) - return false, fmt.Errorf("notification authorization timed out after 15s: %w", ctx.Err()) + return false, fmt.Errorf("notification authorization timed out after 15 minutes: %w", ctx.Err()) } } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index a75996f50..54b0d2a99 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -81,9 +81,11 @@ var notifier *internalNotifier // New creates a new Notifications Service func New() *Service { - if NotificationService == nil { - NotificationService = &Service{} - } + notificationServiceOnce.Do(func() { + if NotificationService == nil { + NotificationService = &Service{} + } + }) return NotificationService } diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 06884f3f6..1367f194c 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -42,12 +42,12 @@ type NotificationPayload struct { // Creates a new Notifications Service. func New() *Service { - notificationServiceLock.Lock() - defer notificationServiceLock.Unlock() + notificationServiceOnce.Do(func() { + if NotificationService == nil { + NotificationService = &Service{} + } + }) - if NotificationService == nil { - NotificationService = &Service{} - } return NotificationService } From bd857385d3c726f6d6f9ea0fb8179ee12a5324eb Mon Sep 17 00:00:00 2001 From: popaprozac Date: Wed, 19 Mar 2025 21:51:57 -0700 Subject: [PATCH 080/136] fix err message --- v3/pkg/services/notifications/notifications_darwin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index d6eee5464..05ca217c7 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -256,7 +256,7 @@ func (ns *Service) RemoveNotificationCategory(categoryId string) error { return nil case <-ctx.Done(): cleanupChannel(id) - return fmt.Errorf("category registration timed out: %w", ctx.Err()) + return fmt.Errorf("category removal timed out: %w", ctx.Err()) } } From c58709c1a340961f7390ecc358ddf83ec57e06a6 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Wed, 19 Mar 2025 22:14:17 -0700 Subject: [PATCH 081/136] lock registry access/writes --- v3/pkg/services/notifications/notifications_windows.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 1367f194c..e63850cd1 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -321,6 +321,9 @@ func saveIconToDir() error { } func saveCategoriesToRegistry() error { + notificationCategoriesLock.Lock() + defer notificationCategoriesLock.Unlock() + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, appName) key, _, err := registry.CreateKey( @@ -333,9 +336,7 @@ func saveCategoriesToRegistry() error { } defer key.Close() - notificationCategoriesLock.RLock() data, err := json.Marshal(NotificationCategories) - notificationCategoriesLock.RUnlock() if err != nil { return err } @@ -344,6 +345,9 @@ func saveCategoriesToRegistry() error { } func loadCategoriesFromRegistry() error { + notificationCategoriesLock.Lock() + defer notificationCategoriesLock.Unlock() + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, appName) key, err := registry.OpenKey( @@ -374,9 +378,7 @@ func loadCategoriesFromRegistry() error { return fmt.Errorf("failed to parse notification categories from registry: %w", err) } - notificationCategoriesLock.Lock() NotificationCategories = categories - notificationCategoriesLock.Unlock() return nil } From 14d6623c13e86975f9842392c85a0757a55583a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=BCbke?= <60359335+johannes-luebke@users.noreply.github.com> Date: Thu, 20 Mar 2025 14:46:24 +0100 Subject: [PATCH 082/136] fix: unhandled error in dialogs.go Does lead to deadlocks otherwise --- v3/pkg/application/dialogs.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/v3/pkg/application/dialogs.go b/v3/pkg/application/dialogs.go index 1e52225ce..2c832d5f2 100644 --- a/v3/pkg/application/dialogs.go +++ b/v3/pkg/application/dialogs.go @@ -291,6 +291,9 @@ func (d *OpenFileDialogStruct) PromptForMultipleSelection() ([]string, error) { } selections, err := InvokeSyncWithResultAndError(d.impl.show) + if err != nil { + return nil, err + } var result []string for filename := range selections { From 010100456d884433e446e3ccae133d5e5c064cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=BCbke?= <60359335+johannes-luebke@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:50:24 +0000 Subject: [PATCH 083/136] chore: update changelog --- website/src/pages/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index d1b405813..5978d1594 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed build issues on Linux for some glibc versions. Fixed in [PR](https://github.com/wailsapp/wails/pull/3545) by @leaanthony. +- Fixed locking issue on Windows when multiselect dialog returns an error. Fixed in [PR](https://github.com/wailsapp/wails/pull/4156) by @johannes-luebke ## v2.9.0 - 2024-06-16 From 471402556bea88387f4540aac6ddfa1bb3213851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=BCbke?= <60359335+johannes-luebke@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:56:33 +0000 Subject: [PATCH 084/136] chore: fix changelog --- website/src/pages/changelog.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 5978d1594..c5f51220e 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -14,11 +14,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fixed locking issue on Windows when multiselect dialog returns an error. Fixed in [PR](https://github.com/wailsapp/wails/pull/4156) by @johannes-luebke + ## v2.9.1 - 2024-06-18 ### Fixed - Fixed build issues on Linux for some glibc versions. Fixed in [PR](https://github.com/wailsapp/wails/pull/3545) by @leaanthony. -- Fixed locking issue on Windows when multiselect dialog returns an error. Fixed in [PR](https://github.com/wailsapp/wails/pull/4156) by @johannes-luebke ## v2.9.0 - 2024-06-16 From b1db2bba12780265408b5c041d648959f0042953 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Mar 2025 10:59:12 -0700 Subject: [PATCH 085/136] add missing error --- v3/pkg/services/notifications/notifications_windows.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index e63850cd1..020637f87 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -197,7 +197,11 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } if options.Data != nil { - n.ActivationArguments, _ = encodePayload(n.ActivationArguments, options.Data) + encodedPayload, err := encodePayload(n.ActivationArguments, options.Data) + if err != nil { + return fmt.Errorf("failed to encode notification data: %w", err) + } + n.ActivationArguments = encodedPayload for index := range n.Actions { encodedPayload, err := encodePayload(n.Actions[index].Arguments, options.Data) From 88f13369b695bd9696ddcafdcb32cad1ccf4aba9 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Mar 2025 13:47:03 -0700 Subject: [PATCH 086/136] reorg platform impl --- .../services/notifications/notifications.go | 99 ++++++++- .../notifications/notifications_darwin.go | 121 ++++++---- .../notifications/notifications_linux.go | 208 +++++++++--------- .../notifications/notifications_windows.go | 152 ++++++------- 4 files changed, 348 insertions(+), 232 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 297a21059..bfa0b4489 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -13,12 +13,38 @@ package notifications import ( + "context" "fmt" "sync" ) +type notificationImpl interface { + // Lifecycle methods + Startup(ctx context.Context) error + Shutdown() error + + // Core notification methods + RequestNotificationAuthorization() (bool, error) + CheckNotificationAuthorization() (bool, error) + SendNotification(options NotificationOptions) error + SendNotificationWithActions(options NotificationOptions) error + + // Category management + RegisterNotificationCategory(category NotificationCategory) error + RemoveNotificationCategory(categoryID string) error + + // Notification management + RemoveAllPendingNotifications() error + RemovePendingNotification(identifier string) error + RemoveAllDeliveredNotifications() error + RemoveDeliveredNotification(identifier string) error + RemoveNotification(identifier string) error +} + // Service represents the notifications service type Service struct { + impl notificationImpl + // notificationResponseCallback is called when a notification result is received. // Only one callback can be assigned at a time. notificationResultCallback func(result NotificationResult) @@ -83,12 +109,6 @@ func (ns *Service) ServiceName() string { return "github.com/wailsapp/wails/v3/services/notifications" } -func getNotificationService() *Service { - notificationServiceLock.RLock() - defer notificationServiceLock.RUnlock() - return NotificationService -} - // OnNotificationResponse registers a callback function that will be called when // a notification response is received from the user. // @@ -112,6 +132,73 @@ func (ns *Service) handleNotificationResult(result NotificationResult) { } } +// ServiceStartup is called when the service is loaded +func (ns *Service) ServiceStartup(ctx context.Context, options interface{}) error { + return ns.impl.Startup(ctx) +} + +// ServiceShutdown is called when the service is unloaded +func (ns *Service) ServiceShutdown() error { + return ns.impl.Shutdown() +} + +// Public methods that delegate to the implementation +func (ns *Service) RequestNotificationAuthorization() (bool, error) { + return ns.impl.RequestNotificationAuthorization() +} + +func (ns *Service) CheckNotificationAuthorization() (bool, error) { + return ns.impl.CheckNotificationAuthorization() +} + +func (ns *Service) SendNotification(options NotificationOptions) error { + if err := validateNotificationOptions(options); err != nil { + return err + } + return ns.impl.SendNotification(options) +} + +func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { + if err := validateNotificationOptions(options); err != nil { + return err + } + return ns.impl.SendNotificationWithActions(options) +} + +func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { + return ns.impl.RegisterNotificationCategory(category) +} + +func (ns *Service) RemoveNotificationCategory(categoryID string) error { + return ns.impl.RemoveNotificationCategory(categoryID) +} + +func (ns *Service) RemoveAllPendingNotifications() error { + return ns.impl.RemoveAllPendingNotifications() +} + +func (ns *Service) RemovePendingNotification(identifier string) error { + return ns.impl.RemovePendingNotification(identifier) +} + +func (ns *Service) RemoveAllDeliveredNotifications() error { + return ns.impl.RemoveAllDeliveredNotifications() +} + +func (ns *Service) RemoveDeliveredNotification(identifier string) error { + return ns.impl.RemoveDeliveredNotification(identifier) +} + +func (ns *Service) RemoveNotification(identifier string) error { + return ns.impl.RemoveNotification(identifier) +} + +func getNotificationService() *Service { + notificationServiceLock.RLock() + defer notificationServiceLock.RUnlock() + return NotificationService +} + // validateNotificationOptions validates an ID and Title are provided for notifications func validateNotificationOptions(options NotificationOptions) error { if options.ID == "" { diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 05ca217c7..0be1fd10c 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -17,17 +17,17 @@ import ( "unsafe" ) +type darwinNotifier struct { + channels map[int]chan notificationChannel + channelsLock sync.Mutex + nextChannelID int +} + type notificationChannel struct { Success bool Error error } -var ( - notificationChannels = make(map[int]chan notificationChannel) - notificationChannelsLock sync.Mutex - nextChannelID int -) - const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" // Creates a new Notifications Service. @@ -43,25 +43,38 @@ func New() *Service { " 3. Run the signed .app bundle") } - if NotificationService == nil { - NotificationService = &Service{} + impl := &darwinNotifier{ + channels: make(map[int]chan notificationChannel), + nextChannelID: 0, + } + + NotificationService = &Service{ + impl: impl, } }) return NotificationService } +func (dn *darwinNotifier) Startup(ctx context.Context) error { + return nil +} + +func (dn *darwinNotifier) Shutdown() error { + return nil +} + func CheckBundleIdentifier() bool { return bool(C.checkBundleIdentifier()) } // RequestNotificationAuthorization requests permission for notifications. // Default timeout is 15 minutes -func (ns *Service) RequestNotificationAuthorization() (bool, error) { +func (dn *darwinNotifier) RequestNotificationAuthorization() (bool, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*900) defer cancel() - id, resultCh := registerChannel() + id, resultCh := dn.registerChannel() C.requestNotificationAuthorization(C.int(id)) @@ -69,17 +82,17 @@ func (ns *Service) RequestNotificationAuthorization() (bool, error) { case result := <-resultCh: return result.Success, result.Error case <-ctx.Done(): - cleanupChannel(id) + dn.cleanupChannel(id) return false, fmt.Errorf("notification authorization timed out after 15 minutes: %w", ctx.Err()) } } // CheckNotificationAuthorization checks current notification permission status. -func (ns *Service) CheckNotificationAuthorization() (bool, error) { +func (dn *darwinNotifier) CheckNotificationAuthorization() (bool, error) { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() - id, resultCh := registerChannel() + id, resultCh := dn.registerChannel() C.checkNotificationAuthorization(C.int(id)) @@ -87,13 +100,13 @@ func (ns *Service) CheckNotificationAuthorization() (bool, error) { case result := <-resultCh: return result.Success, result.Error case <-ctx.Done(): - cleanupChannel(id) + dn.cleanupChannel(id) return false, fmt.Errorf("notification authorization timed out after 15s: %w", ctx.Err()) } } // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. -func (ns *Service) SendNotification(options NotificationOptions) error { +func (dn *darwinNotifier) SendNotification(options NotificationOptions) error { if err := validateNotificationOptions(options); err != nil { return err } @@ -101,7 +114,7 @@ func (ns *Service) SendNotification(options NotificationOptions) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := registerChannel() + id, resultCh := dn.registerChannel() cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) @@ -134,7 +147,7 @@ func (ns *Service) SendNotification(options NotificationOptions) error { } return nil case <-ctx.Done(): - cleanupChannel(id) + dn.cleanupChannel(id) return fmt.Errorf("sending notification timed out: %w", ctx.Err()) } } @@ -142,7 +155,7 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // SendNotificationWithActions sends a notification with additional actions and inputs. // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. -func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { +func (dn *darwinNotifier) SendNotificationWithActions(options NotificationOptions) error { if err := validateNotificationOptions(options); err != nil { return err } @@ -150,7 +163,7 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := registerChannel() + id, resultCh := dn.registerChannel() cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) @@ -184,18 +197,18 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } return nil case <-ctx.Done(): - cleanupChannel(id) + dn.cleanupChannel(id) return fmt.Errorf("sending notification timed out: %w", ctx.Err()) } } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. // Registering a category with the same name as a previously registered NotificationCategory will override it. -func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { +func (dn *darwinNotifier) RegisterNotificationCategory(category NotificationCategory) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := registerChannel() + id, resultCh := dn.registerChannel() cCategoryID := C.CString(category.ID) defer C.free(unsafe.Pointer(cCategoryID)) @@ -228,17 +241,17 @@ func (ns *Service) RegisterNotificationCategory(category NotificationCategory) e } return nil case <-ctx.Done(): - cleanupChannel(id) + dn.cleanupChannel(id) return fmt.Errorf("category registration timed out: %w", ctx.Err()) } } // RemoveNotificationCategory remove a previously registered NotificationCategory. -func (ns *Service) RemoveNotificationCategory(categoryId string) error { +func (dn *darwinNotifier) RemoveNotificationCategory(categoryId string) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := registerChannel() + id, resultCh := dn.registerChannel() cCategoryID := C.CString(categoryId) defer C.free(unsafe.Pointer(cCategoryID)) @@ -255,19 +268,19 @@ func (ns *Service) RemoveNotificationCategory(categoryId string) error { } return nil case <-ctx.Done(): - cleanupChannel(id) + dn.cleanupChannel(id) return fmt.Errorf("category removal timed out: %w", ctx.Err()) } } // RemoveAllPendingNotifications removes all pending notifications. -func (ns *Service) RemoveAllPendingNotifications() error { +func (dn *darwinNotifier) RemoveAllPendingNotifications() error { C.removeAllPendingNotifications() return nil } // RemovePendingNotification removes a pending notification matching the unique identifier. -func (ns *Service) RemovePendingNotification(identifier string) error { +func (dn *darwinNotifier) RemovePendingNotification(identifier string) error { cIdentifier := C.CString(identifier) defer C.free(unsafe.Pointer(cIdentifier)) C.removePendingNotification(cIdentifier) @@ -275,13 +288,13 @@ func (ns *Service) RemovePendingNotification(identifier string) error { } // RemoveAllDeliveredNotifications removes all delivered notifications. -func (ns *Service) RemoveAllDeliveredNotifications() error { +func (dn *darwinNotifier) RemoveAllDeliveredNotifications() error { C.removeAllDeliveredNotifications() return nil } // RemoveDeliveredNotification removes a delivered notification matching the unique identifier. -func (ns *Service) RemoveDeliveredNotification(identifier string) error { +func (dn *darwinNotifier) RemoveDeliveredNotification(identifier string) error { cIdentifier := C.CString(identifier) defer C.free(unsafe.Pointer(cIdentifier)) C.removeDeliveredNotification(cIdentifier) @@ -295,13 +308,23 @@ func (ns *Service) RemoveDeliveredNotification(identifier string) error { // RemoveAllDeliveredNotifications // RemoveDeliveredNotification // (Linux-specific) -func (ns *Service) RemoveNotification(identifier string) error { +func (dn *darwinNotifier) RemoveNotification(identifier string) error { return nil } //export captureResult func captureResult(channelID C.int, success C.bool, errorMsg *C.char) { - resultCh, exists := getChannel(int(channelID)) + ns := getNotificationService() + if ns != nil { + return + } + + dn, ok := ns.impl.(*darwinNotifier) + if !ok { + return + } + + resultCh, exists := dn.getChannel(int(channelID)) if !exists { return } @@ -361,36 +384,38 @@ func didReceiveNotificationResponse(jsonPayload *C.char, err *C.char) { } } -func registerChannel() (int, chan notificationChannel) { - notificationChannelsLock.Lock() - defer notificationChannelsLock.Unlock() +// Helper methods - id := nextChannelID - nextChannelID++ +func (dn *darwinNotifier) registerChannel() (int, chan notificationChannel) { + dn.channelsLock.Lock() + defer dn.channelsLock.Unlock() + + id := dn.nextChannelID + dn.nextChannelID++ resultCh := make(chan notificationChannel, 1) - notificationChannels[id] = resultCh + dn.channels[id] = resultCh return id, resultCh } -func getChannel(id int) (chan notificationChannel, bool) { - notificationChannelsLock.Lock() - defer notificationChannelsLock.Unlock() +func (dn *darwinNotifier) getChannel(id int) (chan notificationChannel, bool) { + dn.channelsLock.Lock() + defer dn.channelsLock.Unlock() - ch, exists := notificationChannels[id] + ch, exists := dn.channels[id] if exists { - delete(notificationChannels, id) + delete(dn.channels, id) } return ch, exists } -func cleanupChannel(id int) { - notificationChannelsLock.Lock() - defer notificationChannelsLock.Unlock() +func (dn *darwinNotifier) cleanupChannel(id int) { + dn.channelsLock.Lock() + defer dn.channelsLock.Unlock() - if ch, exists := notificationChannels[id]; exists { - delete(notificationChannels, id) + if ch, exists := dn.channels[id]; exists { + delete(dn.channels, id) close(ch) } } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 54b0d2a99..712b93868 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -16,6 +16,15 @@ import ( "github.com/wailsapp/wails/v3/pkg/application" ) +type linuxNotifier struct { + categories map[string]NotificationCategory + categoriesLock sync.RWMutex + appName string + internal *internalNotifier + notificationInitErr error + initOnce sync.Once +} + const ( dbusObjectPath = "/org/freedesktop/Notifications" dbusNotificationsInterface = "org.freedesktop.Notifications" @@ -31,32 +40,8 @@ const ( notifyChannelBufferSize = 25 ) -var ( - notificationLock sync.RWMutex - notificationCategories = make(map[string]NotificationCategory) - appName string - initOnce sync.Once -) - type closedReason uint32 -func (r closedReason) string() string { - switch r { - case 1: - return "expired" - case 2: - return "dismissed-by-user" - case 3: - return "closed-by-call" - case 4: - return "unknown" - case 5: - return "activated-by-user" - default: - return "other" - } -} - // internalNotifier handles the actual notification sending via dbus or command line type notificationContext struct { ID string @@ -77,34 +62,36 @@ type internalNotifier struct { listenerRunning bool } -var notifier *internalNotifier - // New creates a new Notifications Service func New() *Service { notificationServiceOnce.Do(func() { - if NotificationService == nil { - NotificationService = &Service{} + impl := &linuxNotifier{ + categories: make(map[string]NotificationCategory), + } + + NotificationService = &Service{ + impl: impl, } }) return NotificationService } -// ServiceStartup is called when the service is loaded -func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - appName = application.Get().Config().Name +// Startup is called when the service is loaded +func (ls *linuxNotifier) Startup(ctx context.Context) error { + ls.appName = application.Get().Config().Name - if err := loadCategories(); err != nil { + if err := ls.loadCategories(); err != nil { fmt.Printf("Failed to load notification categories: %v\n", err) } - notifier = &internalNotifier{ + ls.internal = &internalNotifier{ activeNotifs: make(map[string]uint32), contexts: make(map[string]*notificationContext), } var err error - initOnce.Do(func() { - err = notifier.init() + ls.initOnce.Do(func() { + err = ls.internal.init() }) return err @@ -133,12 +120,12 @@ func (n *internalNotifier) shutdown() { n.sendPath = "" } -// ServiceShutdown is called when the service is unloaded -func (ns *Service) ServiceShutdown() error { - if notifier != nil { - notifier.shutdown() +// Shutdown is called when the service is unloaded +func (ls *linuxNotifier) Shutdown() error { + if ls.internal != nil { + ls.internal.shutdown() } - return saveCategories() + return ls.saveCategories() } // Initialize the notifier and choose the best available notification method @@ -395,25 +382,25 @@ func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string // CheckBundleIdentifier is a Linux stub that always returns true. // (bundle identifiers are macOS-specific) -func (ns *Service) CheckBundleIdentifier() bool { +func (ls *linuxNotifier) CheckBundleIdentifier() bool { return true } // RequestNotificationAuthorization is a Linux stub that always returns true. // (user authorization is macOS-specific) -func (ns *Service) RequestNotificationAuthorization() (bool, error) { +func (ls *linuxNotifier) RequestNotificationAuthorization() (bool, error) { return true, nil } // CheckNotificationAuthorization is a Linux stub that always returns true. // (user authorization is macOS-specific) -func (ns *Service) CheckNotificationAuthorization() (bool, error) { +func (ls *linuxNotifier) CheckNotificationAuthorization() (bool, error) { return true, nil } // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. -func (ns *Service) SendNotification(options NotificationOptions) error { - if notifier == nil { +func (ls *linuxNotifier) SendNotification(options NotificationOptions) error { + if ls.internal == nil { return errors.New("notification service not initialized") } @@ -421,26 +408,26 @@ func (ns *Service) SendNotification(options NotificationOptions) error { return err } - notifier.Lock() - defer notifier.Unlock() + ls.internal.Lock() + defer ls.internal.Unlock() var ( systemID uint32 err error ) - switch notifier.method { + switch ls.internal.method { case MethodDbus: - systemID, err = notifier.sendViaDbus(options, nil) + systemID, err = ls.sendViaDbus(options, nil) case MethodNotifySend: - systemID, err = notifier.sendViaNotifySend(options) + systemID, err = ls.sendViaNotifySend(options) default: err = errors.New("no notification method is available") } if err == nil && systemID > 0 { // Store the system ID mapping - notifier.activeNotifs[options.ID] = systemID + ls.internal.activeNotifs[options.ID] = systemID // Create and store the notification context ctx := ¬ificationContext{ @@ -448,15 +435,15 @@ func (ns *Service) SendNotification(options NotificationOptions) error { SystemID: systemID, UserData: options.Data, } - notifier.contexts[options.ID] = ctx + ls.internal.contexts[options.ID] = ctx } return err } // SendNotificationWithActions sends a notification with additional actions. -func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { - if notifier == nil { +func (ls *linuxNotifier) SendNotificationWithActions(options NotificationOptions) error { + if ls.internal == nil { return errors.New("notification service not initialized") } @@ -464,35 +451,35 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro return err } - notificationLock.RLock() - category, exists := notificationCategories[options.CategoryID] - notificationLock.RUnlock() + ls.categoriesLock.RLock() + category, exists := ls.categories[options.CategoryID] + ls.categoriesLock.RUnlock() if !exists { - return ns.SendNotification(options) + return ls.SendNotification(options) } - notifier.Lock() - defer notifier.Unlock() + ls.internal.Lock() + defer ls.internal.Unlock() var ( systemID uint32 err error ) - switch notifier.method { + switch ls.internal.method { case MethodDbus: - systemID, err = notifier.sendViaDbus(options, &category) + systemID, err = ls.sendViaDbus(options, &category) case MethodNotifySend: // notify-send doesn't support actions, fall back to basic notification - systemID, err = notifier.sendViaNotifySend(options) + systemID, err = ls.sendViaNotifySend(options) default: err = errors.New("no notification method is available") } if err == nil && systemID > 0 { // Store the system ID mapping - notifier.activeNotifs[options.ID] = systemID + ls.internal.activeNotifs[options.ID] = systemID // Create and store the notification context with actions ctx := ¬ificationContext{ @@ -509,14 +496,14 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } } - notifier.contexts[options.ID] = ctx + ls.internal.contexts[options.ID] = ctx } return err } // sendViaDbus sends a notification via dbus -func (n *internalNotifier) sendViaDbus(options NotificationOptions, category *NotificationCategory) (result uint32, err error) { +func (ls *linuxNotifier) sendViaDbus(options NotificationOptions, category *NotificationCategory) (result uint32, err error) { // Prepare actions var actions []string if category != nil { @@ -542,9 +529,9 @@ func (n *internalNotifier) sendViaDbus(options NotificationOptions, category *No } // Send the notification - obj := n.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) + obj := ls.internal.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) dbusArgs := []interface{}{ - appName, // App name + ls.appName, // App name uint32(0), // Replaces ID (0 means new notification) "", // App icon (empty for now) options.Title, // Title @@ -568,7 +555,7 @@ func (n *internalNotifier) sendViaDbus(options NotificationOptions, category *No } // sendViaNotifySend sends a notification via notify-send command -func (n *internalNotifier) sendViaNotifySend(options NotificationOptions) (uint32, error) { +func (ls *linuxNotifier) sendViaNotifySend(options NotificationOptions) (uint32, error) { args := []string{ options.Title, options.Body, @@ -581,7 +568,7 @@ func (n *internalNotifier) sendViaNotifySend(options NotificationOptions) (uint3 args = append(args, "--urgency=normal") // Execute the command - cmd := exec.Command(n.sendPath, args...) + cmd := exec.Command(ls.internal.sendPath, args...) err := cmd.Run() if err != nil { return 0, fmt.Errorf("notify-send error: %v", err) @@ -592,77 +579,77 @@ func (n *internalNotifier) sendViaNotifySend(options NotificationOptions) (uint3 } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. -func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { - notificationLock.Lock() - notificationCategories[category.ID] = category - notificationLock.Unlock() +func (ls *linuxNotifier) RegisterNotificationCategory(category NotificationCategory) error { + ls.categoriesLock.Lock() + ls.categories[category.ID] = category + ls.categoriesLock.Unlock() - return saveCategories() + return ls.saveCategories() } // RemoveNotificationCategory removes a previously registered NotificationCategory. -func (ns *Service) RemoveNotificationCategory(categoryId string) error { - notificationLock.Lock() - delete(notificationCategories, categoryId) - notificationLock.Unlock() +func (ls *linuxNotifier) RemoveNotificationCategory(categoryId string) error { + ls.categoriesLock.Lock() + delete(ls.categories, categoryId) + ls.categoriesLock.Unlock() - return saveCategories() + return ls.saveCategories() } // RemoveAllPendingNotifications is a Linux stub that always returns nil. // (macOS-specific) -func (ns *Service) RemoveAllPendingNotifications() error { +func (ls *linuxNotifier) RemoveAllPendingNotifications() error { return nil } // RemovePendingNotification is a Linux stub that always returns nil. // (macOS-specific) -func (ns *Service) RemovePendingNotification(_ string) error { +func (ls *linuxNotifier) RemovePendingNotification(_ string) error { return nil } // RemoveAllDeliveredNotifications is a Linux stub that always returns nil. // (macOS-specific) -func (ns *Service) RemoveAllDeliveredNotifications() error { +func (ls *linuxNotifier) RemoveAllDeliveredNotifications() error { return nil } // RemoveDeliveredNotification is a Linux stub that always returns nil. // (macOS-specific) -func (ns *Service) RemoveDeliveredNotification(_ string) error { +func (ls *linuxNotifier) RemoveDeliveredNotification(_ string) error { return nil } // RemoveNotification removes a notification by ID (Linux-specific) -func (ns *Service) RemoveNotification(identifier string) error { - if notifier == nil || notifier.method != MethodDbus || notifier.dbusConn == nil { +func (ls *linuxNotifier) RemoveNotification(identifier string) error { + if ls.internal == nil || ls.internal.method != MethodDbus || ls.internal.dbusConn == nil { return errors.New("dbus not available for closing notifications") } // Get the system ID for this notification - notifier.Lock() - systemID, exists := notifier.activeNotifs[identifier] - notifier.Unlock() + ls.internal.Lock() + systemID, exists := ls.internal.activeNotifs[identifier] + ls.internal.Unlock() if !exists { return nil // Already closed or unknown } // Call CloseNotification on dbus - obj := notifier.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) + obj := ls.internal.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) call := obj.Call(callCloseNotification, 0, systemID) return call.Err } // getConfigFilePath returns the path to the configuration file for storing notification categories -func getConfigFilePath() (string, error) { +func (ls *linuxNotifier) getConfigFilePath() (string, error) { configDir, err := os.UserConfigDir() if err != nil { return "", fmt.Errorf("failed to get user config directory: %v", err) } - appConfigDir := filepath.Join(configDir, appName) + appConfigDir := filepath.Join(configDir, ls.appName) if err := os.MkdirAll(appConfigDir, 0755); err != nil { return "", fmt.Errorf("failed to create config directory: %v", err) } @@ -671,15 +658,15 @@ func getConfigFilePath() (string, error) { } // saveCategories saves the notification categories to a file. -func saveCategories() error { - filePath, err := getConfigFilePath() +func (ls *linuxNotifier) saveCategories() error { + filePath, err := ls.getConfigFilePath() if err != nil { return err } - notificationLock.RLock() - data, err := json.Marshal(notificationCategories) - notificationLock.RUnlock() + ls.categoriesLock.RLock() + data, err := json.Marshal(ls.categories) + ls.categoriesLock.RUnlock() if err != nil { return fmt.Errorf("failed to marshal notification categories: %v", err) @@ -693,8 +680,8 @@ func saveCategories() error { } // loadCategories loads notification categories from a file. -func loadCategories() error { - filePath, err := getConfigFilePath() +func (ls *linuxNotifier) loadCategories() error { + filePath, err := ls.getConfigFilePath() if err != nil { return err } @@ -717,9 +704,26 @@ func loadCategories() error { return fmt.Errorf("failed to unmarshal notification categories: %v", err) } - notificationLock.Lock() - notificationCategories = categories - notificationLock.Unlock() + ls.categoriesLock.Lock() + ls.categories = categories + ls.categoriesLock.Unlock() return nil } + +func (r closedReason) string() string { + switch r { + case 1: + return "expired" + case 2: + return "dismissed-by-user" + case 3: + return "closed-by-call" + case 4: + return "unknown" + case 5: + return "activated-by-user" + default: + return "other" + } +} diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 020637f87..ea3dc449e 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -19,13 +19,13 @@ import ( "golang.org/x/sys/windows/registry" ) -var ( - NotificationCategories = make(map[string]NotificationCategory) - notificationCategoriesLock sync.RWMutex - appName string - appGUID string - iconPath string -) +type windowsNotifier struct { + categories map[string]NotificationCategory + categoriesLock sync.RWMutex + appName string + appGUID string + iconPath string +} const ( ToastRegistryPath = `Software\Classes\AppUserModelId\` @@ -43,31 +43,35 @@ type NotificationPayload struct { // Creates a new Notifications Service. func New() *Service { notificationServiceOnce.Do(func() { - if NotificationService == nil { - NotificationService = &Service{} + impl := &windowsNotifier{ + categories: make(map[string]NotificationCategory), + } + + NotificationService = &Service{ + impl: impl, } }) return NotificationService } -// ServiceStartup is called when the service is loaded +// Startup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. -func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - appName = application.Get().Config().Name +func (wn *windowsNotifier) Startup(ctx context.Context) error { + wn.appName = application.Get().Config().Name - guid, err := getGUID() + guid, err := wn.getGUID() if err != nil { return err } - appGUID = guid + wn.appGUID = guid - iconPath = filepath.Join(os.TempDir(), appName+appGUID+".png") + wn.iconPath = filepath.Join(os.TempDir(), wn.appName+wn.appGUID+".png") toast.SetAppData(toast.AppData{ - AppID: appName, + AppID: wn.appName, GUID: guid, - IconPath: iconPath, + IconPath: wn.iconPath, }) toast.SetActivationCallback(func(args string, data []toast.UserData) { @@ -89,7 +93,7 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi response.UserInfo = userInfoMap } - if userText, found := getUserText(data); found { + if userText, found := wn.getUserText(data); found { response.UserText = userText } @@ -99,40 +103,34 @@ func (ns *Service) ServiceStartup(ctx context.Context, options application.Servi } }) - return loadCategoriesFromRegistry() + return wn.loadCategoriesFromRegistry() } -// ServiceShutdown is called when the service is unloaded -func (ns *Service) ServiceShutdown() error { - return saveCategoriesToRegistry() -} - -// CheckBundleIdentifier is a Windows stub that always returns true. -// (bundle identifiers are macOS-specific) -func CheckBundleIdentifier() bool { - return true +// Shutdown will attempt to save the categories to the registry when the service unloads +func (wn *windowsNotifier) Shutdown() error { + return wn.saveCategoriesToRegistry() } // RequestNotificationAuthorization is a Windows stub that always returns true, nil. // (user authorization is macOS-specific) -func (ns *Service) RequestNotificationAuthorization() (bool, error) { +func (wn *windowsNotifier) RequestNotificationAuthorization() (bool, error) { return true, nil } // CheckNotificationAuthorization is a Windows stub that always returns true. // (user authorization is macOS-specific) -func (ns *Service) CheckNotificationAuthorization() bool { - return true +func (wn *windowsNotifier) CheckNotificationAuthorization() (bool, error) { + return true, nil } // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. -// (subtitle and category id are only available on macOS) -func (ns *Service) SendNotification(options NotificationOptions) error { +// (subtitle is only available on macOS) +func (wn *windowsNotifier) SendNotification(options NotificationOptions) error { if err := validateNotificationOptions(options); err != nil { return err } - if err := saveIconToDir(); err != nil { + if err := wn.saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) } @@ -143,7 +141,7 @@ func (ns *Service) SendNotification(options NotificationOptions) error { } if options.Data != nil { - encodedPayload, err := encodePayload(DefaultActionIdentifier, options.Data) + encodedPayload, err := wn.encodePayload(DefaultActionIdentifier, options.Data) if err != nil { return fmt.Errorf("failed to encode notification data: %w", err) } @@ -156,19 +154,19 @@ func (ns *Service) SendNotification(options NotificationOptions) error { // SendNotificationWithActions sends a notification with additional actions and inputs. // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. -// (subtitle and category id are only available on macOS) -func (ns *Service) SendNotificationWithActions(options NotificationOptions) error { +// (subtitle is only available on macOS) +func (wn *windowsNotifier) SendNotificationWithActions(options NotificationOptions) error { if err := validateNotificationOptions(options); err != nil { return err } - if err := saveIconToDir(); err != nil { + if err := wn.saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) } - notificationCategoriesLock.RLock() - nCategory := NotificationCategories[options.CategoryID] - notificationCategoriesLock.RUnlock() + wn.categoriesLock.RLock() + nCategory := wn.categories[options.CategoryID] + wn.categoriesLock.RUnlock() n := toast.Notification{ Title: options.Title, @@ -197,14 +195,14 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro } if options.Data != nil { - encodedPayload, err := encodePayload(n.ActivationArguments, options.Data) + encodedPayload, err := wn.encodePayload(n.ActivationArguments, options.Data) if err != nil { return fmt.Errorf("failed to encode notification data: %w", err) } n.ActivationArguments = encodedPayload for index := range n.Actions { - encodedPayload, err := encodePayload(n.Actions[index].Arguments, options.Data) + encodedPayload, err := wn.encodePayload(n.Actions[index].Arguments, options.Data) if err != nil { return fmt.Errorf("failed to encode notification data: %w", err) } @@ -217,61 +215,63 @@ func (ns *Service) SendNotificationWithActions(options NotificationOptions) erro // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. // Registering a category with the same name as a previously registered NotificationCategory will override it. -func (ns *Service) RegisterNotificationCategory(category NotificationCategory) error { - notificationCategoriesLock.Lock() - NotificationCategories[category.ID] = NotificationCategory{ +func (wn *windowsNotifier) RegisterNotificationCategory(category NotificationCategory) error { + wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() + + wn.categories[category.ID] = NotificationCategory{ ID: category.ID, Actions: category.Actions, HasReplyField: bool(category.HasReplyField), ReplyPlaceholder: category.ReplyPlaceholder, ReplyButtonTitle: category.ReplyButtonTitle, } - notificationCategoriesLock.Unlock() - return saveCategoriesToRegistry() + return wn.saveCategoriesToRegistry() } // RemoveNotificationCategory removes a previously registered NotificationCategory. -func (ns *Service) RemoveNotificationCategory(categoryId string) error { - notificationCategoriesLock.Lock() - delete(NotificationCategories, categoryId) - notificationCategoriesLock.Unlock() +func (wn *windowsNotifier) RemoveNotificationCategory(categoryId string) error { + wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() - return saveCategoriesToRegistry() + delete(wn.categories, categoryId) + + return wn.saveCategoriesToRegistry() } // RemoveAllPendingNotifications is a Windows stub that always returns nil. // (macOS-specific) -func (ns *Service) RemoveAllPendingNotifications() error { +func (wn *windowsNotifier) RemoveAllPendingNotifications() error { return nil } // RemovePendingNotification is a Windows stub that always returns nil. // (macOS-specific) -func (ns *Service) RemovePendingNotification(_ string) error { +func (wn *windowsNotifier) RemovePendingNotification(_ string) error { return nil } // RemoveAllDeliveredNotifications is a Windows stub that always returns nil. // (macOS-specific) -func (ns *Service) RemoveAllDeliveredNotifications() error { +func (wn *windowsNotifier) RemoveAllDeliveredNotifications() error { return nil } // RemoveDeliveredNotification is a Windows stub that always returns nil. // (macOS-specific) -func (ns *Service) RemoveDeliveredNotification(_ string) error { +func (wn *windowsNotifier) RemoveDeliveredNotification(_ string) error { return nil } // RemoveNotification is a Windows stub that always returns nil. // (Linux-specific) -func (ns *Service) RemoveNotification(identifier string) error { +func (wn *windowsNotifier) RemoveNotification(identifier string) error { return nil } // encodePayload combines an action ID and user data into a single encoded string -func encodePayload(actionID string, data map[string]interface{}) (string, error) { +func (wn *windowsNotifier) encodePayload(actionID string, data map[string]interface{}) (string, error) { payload := NotificationPayload{ Action: actionID, Data: data, @@ -315,20 +315,20 @@ func parseNotificationResponse(response string) (action string, data string) { return actionID, "" } -func saveIconToDir() error { +func (wn *windowsNotifier) saveIconToDir() error { icon, err := application.NewIconFromResource(w32.GetModuleHandle(""), uint16(3)) if err != nil { return fmt.Errorf("failed to retrieve application icon: %w", err) } - return saveHIconAsPNG(icon, iconPath) + return saveHIconAsPNG(icon, wn.iconPath) } -func saveCategoriesToRegistry() error { - notificationCategoriesLock.Lock() - defer notificationCategoriesLock.Unlock() +func (wn *windowsNotifier) saveCategoriesToRegistry() error { + wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() - registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, appName) + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, wn.appName) key, _, err := registry.CreateKey( registry.CURRENT_USER, @@ -340,7 +340,7 @@ func saveCategoriesToRegistry() error { } defer key.Close() - data, err := json.Marshal(NotificationCategories) + data, err := json.Marshal(wn.categories) if err != nil { return err } @@ -348,11 +348,11 @@ func saveCategoriesToRegistry() error { return key.SetStringValue(NotificationCategoriesRegistryKey, string(data)) } -func loadCategoriesFromRegistry() error { - notificationCategoriesLock.Lock() - defer notificationCategoriesLock.Unlock() +func (wn *windowsNotifier) loadCategoriesFromRegistry() error { + wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() - registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, appName) + registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, wn.appName) key, err := registry.OpenKey( registry.CURRENT_USER, @@ -382,12 +382,12 @@ func loadCategoriesFromRegistry() error { return fmt.Errorf("failed to parse notification categories from registry: %w", err) } - NotificationCategories = categories + wn.categories = categories return nil } -func getUserText(data []toast.UserData) (string, bool) { +func (wn *windowsNotifier) getUserText(data []toast.UserData) (string, bool) { for _, d := range data { if d.Key == "userText" { return d.Value, true @@ -396,8 +396,8 @@ func getUserText(data []toast.UserData) (string, bool) { return "", false } -func getGUID() (string, error) { - keyPath := ToastRegistryPath + appName +func (wn *windowsNotifier) getGUID() (string, error) { + keyPath := ToastRegistryPath + wn.appName k, err := registry.OpenKey(registry.CURRENT_USER, keyPath, registry.QUERY_VALUE) if err == nil { @@ -408,7 +408,7 @@ func getGUID() (string, error) { } } - guid := generateGUID() + guid := wn.generateGUID() k, _, err = registry.CreateKey(registry.CURRENT_USER, keyPath, registry.WRITE) if err != nil { @@ -423,7 +423,7 @@ func getGUID() (string, error) { return guid, nil } -func generateGUID() string { +func (wn *windowsNotifier) generateGUID() string { guid := uuid.New() return fmt.Sprintf("{%s}", guid.String()) } From 94f245f035e14986f28aa5c464767b8cdbf01487 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Mar 2025 13:49:49 -0700 Subject: [PATCH 087/136] bug fix --- v3/pkg/services/notifications/notifications_darwin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 0be1fd10c..8ebbff35d 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -315,7 +315,7 @@ func (dn *darwinNotifier) RemoveNotification(identifier string) error { //export captureResult func captureResult(channelID C.int, success C.bool, errorMsg *C.char) { ns := getNotificationService() - if ns != nil { + if ns == nil { return } From e55bf8dffce083e1b96b5a64e164e8865298788c Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Mar 2025 13:56:47 -0700 Subject: [PATCH 088/136] linux bug fix --- .../notifications/notifications_linux.go | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 712b93868..0b6cdafdb 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -91,59 +91,59 @@ func (ls *linuxNotifier) Startup(ctx context.Context) error { var err error ls.initOnce.Do(func() { - err = ls.internal.init() + err = ls.init() }) return err } -func (n *internalNotifier) shutdown() { - n.Lock() - defer n.Unlock() +func (ls *linuxNotifier) shutdown() { + ls.internal.Lock() + defer ls.internal.Unlock() // Cancel the listener context if it's running - if n.listenerCancel != nil { - n.listenerCancel() - n.listenerCancel = nil + if ls.internal.listenerCancel != nil { + ls.internal.listenerCancel() + ls.internal.listenerCancel = nil } // Close the connection - if n.dbusConn != nil { - n.dbusConn.Close() - n.dbusConn = nil + if ls.internal.dbusConn != nil { + ls.internal.dbusConn.Close() + ls.internal.dbusConn = nil } // Clear state - n.activeNotifs = make(map[string]uint32) - n.contexts = make(map[string]*notificationContext) - n.method = "none" - n.sendPath = "" + ls.internal.activeNotifs = make(map[string]uint32) + ls.internal.contexts = make(map[string]*notificationContext) + ls.internal.method = "none" + ls.internal.sendPath = "" } // Shutdown is called when the service is unloaded func (ls *linuxNotifier) Shutdown() error { if ls.internal != nil { - ls.internal.shutdown() + ls.shutdown() } return ls.saveCategories() } // Initialize the notifier and choose the best available notification method -func (n *internalNotifier) init() error { +func (ls *linuxNotifier) init() error { var err error // Cancel any existing listener before starting a new one - if n.listenerCancel != nil { - n.listenerCancel() + if ls.internal.listenerCancel != nil { + ls.internal.listenerCancel() } // Create a new context for the listener - n.listenerCtx, n.listenerCancel = context.WithCancel(context.Background()) + ls.internal.listenerCtx, ls.internal.listenerCancel = context.WithCancel(context.Background()) // Reset state - n.activeNotifs = make(map[string]uint32) - n.contexts = make(map[string]*notificationContext) - n.listenerRunning = false + ls.internal.activeNotifs = make(map[string]uint32) + ls.internal.contexts = make(map[string]*notificationContext) + ls.internal.listenerRunning = false checkDbus := func() (*dbus.Conn, error) { conn, err := dbus.SessionBusPrivate() @@ -184,53 +184,53 @@ func (n *internalNotifier) init() error { } // Try dbus first - n.dbusConn, err = checkDbus() + ls.internal.dbusConn, err = checkDbus() if err == nil { - n.method = MethodDbus + ls.internal.method = MethodDbus // Start the dbus signal listener with context - go n.startDBusListener(n.listenerCtx) - n.listenerRunning = true + go ls.startDBusListener(ls.internal.listenerCtx) + ls.internal.listenerRunning = true return nil } - if n.dbusConn != nil { - n.dbusConn.Close() - n.dbusConn = nil + if ls.internal.dbusConn != nil { + ls.internal.dbusConn.Close() + ls.internal.dbusConn = nil } // Try notify-send send, err := exec.LookPath("notify-send") if err == nil { - n.sendPath = send - n.method = MethodNotifySend + ls.internal.sendPath = send + ls.internal.method = MethodNotifySend return nil } // Try sw-notify-send send, err = exec.LookPath("sw-notify-send") if err == nil { - n.sendPath = send - n.method = MethodNotifySend + ls.internal.sendPath = send + ls.internal.method = MethodNotifySend return nil } // No method available - n.method = "none" - n.sendPath = "" + ls.internal.method = "none" + ls.internal.sendPath = "" return errors.New("no notification method is available") } // startDBusListener listens for DBus signals for notification actions and closures -func (n *internalNotifier) startDBusListener(ctx context.Context) { +func (ls *linuxNotifier) startDBusListener(ctx context.Context) { signal := make(chan *dbus.Signal, notifyChannelBufferSize) - n.dbusConn.Signal(signal) + ls.internal.dbusConn.Signal(signal) defer func() { - n.Lock() - n.listenerRunning = false - n.Unlock() - n.dbusConn.RemoveSignal(signal) // Remove signal handler - close(signal) // Clean up channel + ls.internal.Lock() + ls.internal.listenerRunning = false + ls.internal.Unlock() + ls.internal.dbusConn.RemoveSignal(signal) // Remove signal handler + close(signal) // Clean up channel }() for { @@ -253,34 +253,34 @@ func (n *internalNotifier) startDBusListener(ctx context.Context) { case signalNotificationClosed: systemID := s.Body[0].(uint32) reason := closedReason(s.Body[1].(uint32)).string() - n.handleNotificationClosed(systemID, reason) + ls.handleNotificationClosed(systemID, reason) case signalActionInvoked: systemID := s.Body[0].(uint32) actionKey := s.Body[1].(string) - n.handleActionInvoked(systemID, actionKey) + ls.handleActionInvoked(systemID, actionKey) } } } } // handleNotificationClosed processes notification closed signals -func (n *internalNotifier) handleNotificationClosed(systemID uint32, reason string) { +func (ls *linuxNotifier) handleNotificationClosed(systemID uint32, reason string) { // Find our notification ID for this system ID var notifID string var userData map[string]interface{} - n.Lock() - for id, sysID := range n.activeNotifs { + ls.internal.Lock() + for id, sysID := range ls.internal.activeNotifs { if sysID == systemID { notifID = id // Get the user data from context if available - if ctx, exists := n.contexts[id]; exists { + if ctx, exists := ls.internal.contexts[id]; exists { userData = ctx.UserData } break } } - n.Unlock() + ls.internal.Unlock() if notifID != "" { response := NotificationResponse{ @@ -305,28 +305,28 @@ func (n *internalNotifier) handleNotificationClosed(systemID uint32, reason stri } // Clean up the context - n.Lock() - delete(n.contexts, notifID) - delete(n.activeNotifs, notifID) - n.Unlock() + ls.internal.Lock() + delete(ls.internal.contexts, notifID) + delete(ls.internal.activeNotifs, notifID) + ls.internal.Unlock() } } // handleActionInvoked processes action invoked signals -func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string) { +func (ls *linuxNotifier) handleActionInvoked(systemID uint32, actionKey string) { // Find our notification ID and context for this system ID var notifID string var ctx *notificationContext - n.Lock() - for id, sysID := range n.activeNotifs { + ls.internal.Lock() + for id, sysID := range ls.internal.activeNotifs { if sysID == systemID { notifID = id - ctx = n.contexts[id] + ctx = ls.internal.contexts[id] break } } - n.Unlock() + ls.internal.Unlock() if notifID != "" { if actionKey == "default" { @@ -373,10 +373,10 @@ func (n *internalNotifier) handleActionInvoked(systemID uint32, actionKey string } // Clean up the context - n.Lock() - delete(n.contexts, notifID) - delete(n.activeNotifs, notifID) - n.Unlock() + ls.internal.Lock() + delete(ls.internal.contexts, notifID) + delete(ls.internal.activeNotifs, notifID) + ls.internal.Unlock() } } From 9adeef2bdf28b886a4e0db7b98787183c952bfb9 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Mar 2025 16:21:37 -0700 Subject: [PATCH 089/136] fix linux and remove dup code --- .../notifications/notifications_darwin.go | 8 --- .../notifications/notifications_linux.go | 63 ++++++++++--------- .../notifications/notifications_windows.go | 8 --- 3 files changed, 32 insertions(+), 47 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 8ebbff35d..380460f43 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -107,10 +107,6 @@ func (dn *darwinNotifier) CheckNotificationAuthorization() (bool, error) { // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (dn *darwinNotifier) SendNotification(options NotificationOptions) error { - if err := validateNotificationOptions(options); err != nil { - return err - } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -156,10 +152,6 @@ func (dn *darwinNotifier) SendNotification(options NotificationOptions) error { // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. func (dn *darwinNotifier) SendNotificationWithActions(options NotificationOptions) error { - if err := validateNotificationOptions(options); err != nil { - return err - } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 0b6cdafdb..ec5cc089c 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -84,6 +84,7 @@ func (ls *linuxNotifier) Startup(ctx context.Context) error { fmt.Printf("Failed to load notification categories: %v\n", err) } + // Initialize the internal notifier ls.internal = &internalNotifier{ activeNotifs: make(map[string]uint32), contexts: make(map[string]*notificationContext), @@ -91,45 +92,43 @@ func (ls *linuxNotifier) Startup(ctx context.Context) error { var err error ls.initOnce.Do(func() { - err = ls.init() + // Initialize notification system + err = ls.initNotificationSystem() }) return err } -func (ls *linuxNotifier) shutdown() { - ls.internal.Lock() - defer ls.internal.Unlock() - - // Cancel the listener context if it's running - if ls.internal.listenerCancel != nil { - ls.internal.listenerCancel() - ls.internal.listenerCancel = nil - } - - // Close the connection - if ls.internal.dbusConn != nil { - ls.internal.dbusConn.Close() - ls.internal.dbusConn = nil - } - - // Clear state - ls.internal.activeNotifs = make(map[string]uint32) - ls.internal.contexts = make(map[string]*notificationContext) - ls.internal.method = "none" - ls.internal.sendPath = "" -} - // Shutdown is called when the service is unloaded func (ls *linuxNotifier) Shutdown() error { if ls.internal != nil { - ls.shutdown() + ls.internal.Lock() + defer ls.internal.Unlock() + + // Cancel the listener context if it's running + if ls.internal.listenerCancel != nil { + ls.internal.listenerCancel() + ls.internal.listenerCancel = nil + } + + // Close the connection + if ls.internal.dbusConn != nil { + ls.internal.dbusConn.Close() + ls.internal.dbusConn = nil + } + + // Clear state + ls.internal.activeNotifs = make(map[string]uint32) + ls.internal.contexts = make(map[string]*notificationContext) + ls.internal.method = "none" + ls.internal.sendPath = "" } + return ls.saveCategories() } -// Initialize the notifier and choose the best available notification method -func (ls *linuxNotifier) init() error { +// initNotificationSystem initializes the notification system, choosing the best available method +func (ls *linuxNotifier) initNotificationSystem() error { var err error // Cancel any existing listener before starting a new one @@ -404,8 +403,9 @@ func (ls *linuxNotifier) SendNotification(options NotificationOptions) error { return errors.New("notification service not initialized") } - if err := validateNotificationOptions(options); err != nil { - return err + if ls.internal.method == "" || (ls.internal.method == MethodDbus && ls.internal.dbusConn == nil) || + (ls.internal.method == MethodNotifySend && ls.internal.sendPath == "") { + return errors.New("notification system not properly initialized") } ls.internal.Lock() @@ -447,8 +447,9 @@ func (ls *linuxNotifier) SendNotificationWithActions(options NotificationOptions return errors.New("notification service not initialized") } - if err := validateNotificationOptions(options); err != nil { - return err + if ls.internal.method == "" || (ls.internal.method == MethodDbus && ls.internal.dbusConn == nil) || + (ls.internal.method == MethodNotifySend && ls.internal.sendPath == "") { + return errors.New("notification system not properly initialized") } ls.categoriesLock.RLock() diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index ea3dc449e..064a6343f 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -126,10 +126,6 @@ func (wn *windowsNotifier) CheckNotificationAuthorization() (bool, error) { // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. // (subtitle is only available on macOS) func (wn *windowsNotifier) SendNotification(options NotificationOptions) error { - if err := validateNotificationOptions(options); err != nil { - return err - } - if err := wn.saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) } @@ -156,10 +152,6 @@ func (wn *windowsNotifier) SendNotification(options NotificationOptions) error { // If a NotificationCategory is not registered a basic notification will be sent. // (subtitle is only available on macOS) func (wn *windowsNotifier) SendNotificationWithActions(options NotificationOptions) error { - if err := validateNotificationOptions(options); err != nil { - return err - } - if err := wn.saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) } From 5dc7bd97f26ffa8318c006819b87d9c98c806583 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Mar 2025 16:32:53 -0700 Subject: [PATCH 090/136] refactor/simplify linux --- .../notifications/notifications_linux.go | 511 +++++++++--------- 1 file changed, 255 insertions(+), 256 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index ec5cc089c..cff22b336 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -17,12 +17,36 @@ import ( ) type linuxNotifier struct { - categories map[string]NotificationCategory - categoriesLock sync.RWMutex - appName string - internal *internalNotifier - notificationInitErr error - initOnce sync.Once + // Categories + categories map[string]NotificationCategory + categoriesLock sync.RWMutex + + // App info + appName string + + // Notification system + sync.Mutex + method string + dbusConn *dbus.Conn + sendPath string + activeNotifs map[string]uint32 // Maps our notification IDs to system IDs + contexts map[string]*notificationContext // Stores notification contexts by our ID + + // Listener management + listenerCtx context.Context + listenerCancel context.CancelFunc + listenerRunning bool + + // Initialization + initOnce sync.Once + initialized bool +} + +type notificationContext struct { + ID string + SystemID uint32 + Actions map[string]string // Maps action keys to display labels + UserData map[string]interface{} // The original user data } const ( @@ -35,38 +59,19 @@ const ( MethodNotifySend = "notify-send" MethodDbus = "dbus" - MethodKdialog = "kdialog" notifyChannelBufferSize = 25 ) type closedReason uint32 -// internalNotifier handles the actual notification sending via dbus or command line -type notificationContext struct { - ID string - SystemID uint32 - Actions map[string]string // Maps action keys to display labels - UserData map[string]interface{} // The original user data -} - -type internalNotifier struct { - sync.Mutex - method string - dbusConn *dbus.Conn - sendPath string - activeNotifs map[string]uint32 // Maps our notification IDs to system IDs - contexts map[string]*notificationContext // Stores notification contexts by our ID - listenerCtx context.Context - listenerCancel context.CancelFunc - listenerRunning bool -} - // New creates a new Notifications Service func New() *Service { notificationServiceOnce.Do(func() { impl := &linuxNotifier{ - categories: make(map[string]NotificationCategory), + categories: make(map[string]NotificationCategory), + activeNotifs: make(map[string]uint32), + contexts: make(map[string]*notificationContext), } NotificationService = &Service{ @@ -77,159 +82,167 @@ func New() *Service { } // Startup is called when the service is loaded -func (ls *linuxNotifier) Startup(ctx context.Context) error { - ls.appName = application.Get().Config().Name +func (ln *linuxNotifier) Startup(ctx context.Context) error { + ln.appName = application.Get().Config().Name - if err := ls.loadCategories(); err != nil { + if err := ln.loadCategories(); err != nil { fmt.Printf("Failed to load notification categories: %v\n", err) } - // Initialize the internal notifier - ls.internal = &internalNotifier{ - activeNotifs: make(map[string]uint32), - contexts: make(map[string]*notificationContext), - } - var err error - ls.initOnce.Do(func() { - // Initialize notification system - err = ls.initNotificationSystem() + ln.initOnce.Do(func() { + err = ln.initNotificationSystem() + ln.initialized = err == nil }) return err } -// Shutdown is called when the service is unloaded -func (ls *linuxNotifier) Shutdown() error { - if ls.internal != nil { - ls.internal.Lock() - defer ls.internal.Unlock() +// initNotificationSystem initializes the notification system +func (ln *linuxNotifier) initNotificationSystem() error { + ln.Lock() + defer ln.Unlock() - // Cancel the listener context if it's running - if ls.internal.listenerCancel != nil { - ls.internal.listenerCancel() - ls.internal.listenerCancel = nil - } - - // Close the connection - if ls.internal.dbusConn != nil { - ls.internal.dbusConn.Close() - ls.internal.dbusConn = nil - } - - // Clear state - ls.internal.activeNotifs = make(map[string]uint32) - ls.internal.contexts = make(map[string]*notificationContext) - ls.internal.method = "none" - ls.internal.sendPath = "" - } - - return ls.saveCategories() -} - -// initNotificationSystem initializes the notification system, choosing the best available method -func (ls *linuxNotifier) initNotificationSystem() error { - var err error - - // Cancel any existing listener before starting a new one - if ls.internal.listenerCancel != nil { - ls.internal.listenerCancel() + // Cancel any existing listener + if ln.listenerCancel != nil { + ln.listenerCancel() + ln.listenerCancel = nil } // Create a new context for the listener - ls.internal.listenerCtx, ls.internal.listenerCancel = context.WithCancel(context.Background()) + ln.listenerCtx, ln.listenerCancel = context.WithCancel(context.Background()) // Reset state - ls.internal.activeNotifs = make(map[string]uint32) - ls.internal.contexts = make(map[string]*notificationContext) - ls.internal.listenerRunning = false - - checkDbus := func() (*dbus.Conn, error) { - conn, err := dbus.SessionBusPrivate() - if err != nil { - return conn, err - } - - if err = conn.Auth(nil); err != nil { - return conn, err - } - - if err = conn.Hello(); err != nil { - return conn, err - } - - obj := conn.Object(dbusNotificationsInterface, dbusObjectPath) - call := obj.Call(callGetCapabilities, 0) - if call.Err != nil { - return conn, call.Err - } - - var ret []string - err = call.Store(&ret) - if err != nil { - return conn, err - } - - // Add a listener for notification signals - err = conn.AddMatchSignal( - dbus.WithMatchObjectPath(dbusObjectPath), - dbus.WithMatchInterface(dbusNotificationsInterface), - ) - if err != nil { - return nil, err - } - - return conn, nil - } + ln.activeNotifs = make(map[string]uint32) + ln.contexts = make(map[string]*notificationContext) + ln.listenerRunning = false // Try dbus first - ls.internal.dbusConn, err = checkDbus() + dbusConn, err := ln.initDBus() if err == nil { - ls.internal.method = MethodDbus - // Start the dbus signal listener with context - go ls.startDBusListener(ls.internal.listenerCtx) - ls.internal.listenerRunning = true - return nil - } - if ls.internal.dbusConn != nil { - ls.internal.dbusConn.Close() - ls.internal.dbusConn = nil - } + ln.dbusConn = dbusConn + ln.method = MethodDbus - // Try notify-send - send, err := exec.LookPath("notify-send") - if err == nil { - ls.internal.sendPath = send - ls.internal.method = MethodNotifySend + // Start the dbus signal listener + go ln.startDBusListener(ln.listenerCtx) + ln.listenerRunning = true return nil } - // Try sw-notify-send - send, err = exec.LookPath("sw-notify-send") + // Try notify-send as fallback + sendPath, err := ln.initNotifySend() if err == nil { - ls.internal.sendPath = send - ls.internal.method = MethodNotifySend + ln.sendPath = sendPath + ln.method = MethodNotifySend return nil } // No method available - ls.internal.method = "none" - ls.internal.sendPath = "" - + ln.method = "" + ln.sendPath = "" return errors.New("no notification method is available") } +// initDBus attempts to initialize D-Bus notifications +func (ln *linuxNotifier) initDBus() (*dbus.Conn, error) { + conn, err := dbus.SessionBusPrivate() + if err != nil { + return nil, err + } + + if err = conn.Auth(nil); err != nil { + conn.Close() + return nil, err + } + + if err = conn.Hello(); err != nil { + conn.Close() + return nil, err + } + + obj := conn.Object(dbusNotificationsInterface, dbusObjectPath) + call := obj.Call(callGetCapabilities, 0) + if call.Err != nil { + conn.Close() + return nil, call.Err + } + + var ret []string + err = call.Store(&ret) + if err != nil { + conn.Close() + return nil, err + } + + // Add a listener for notification signals + err = conn.AddMatchSignal( + dbus.WithMatchObjectPath(dbusObjectPath), + dbus.WithMatchInterface(dbusNotificationsInterface), + ) + if err != nil { + conn.Close() + return nil, err + } + + return conn, nil +} + +// initNotifySend attempts to find notify-send binary +func (ln *linuxNotifier) initNotifySend() (string, error) { + // Try standard notify-send + send, err := exec.LookPath("notify-send") + if err == nil { + return send, nil + } + + // Try sw-notify-send (in some distros) + send, err = exec.LookPath("sw-notify-send") + if err == nil { + return send, nil + } + + return "", errors.New("notify-send not found") +} + +// Shutdown is called when the service is unloaded +func (ln *linuxNotifier) Shutdown() error { + ln.Lock() + + // Cancel the listener context if it's running + if ln.listenerCancel != nil { + ln.listenerCancel() + ln.listenerCancel = nil + } + + // Close the connection + if ln.dbusConn != nil { + ln.dbusConn.Close() + ln.dbusConn = nil + } + + // Clear state + ln.activeNotifs = make(map[string]uint32) + ln.contexts = make(map[string]*notificationContext) + ln.method = "" + ln.sendPath = "" + ln.initialized = false + + ln.Unlock() + + return ln.saveCategories() +} + // startDBusListener listens for DBus signals for notification actions and closures -func (ls *linuxNotifier) startDBusListener(ctx context.Context) { +func (ln *linuxNotifier) startDBusListener(ctx context.Context) { signal := make(chan *dbus.Signal, notifyChannelBufferSize) - ls.internal.dbusConn.Signal(signal) + ln.dbusConn.Signal(signal) defer func() { - ls.internal.Lock() - ls.internal.listenerRunning = false - ls.internal.Unlock() - ls.internal.dbusConn.RemoveSignal(signal) // Remove signal handler - close(signal) // Clean up channel + ln.Lock() + ln.listenerRunning = false + ln.Unlock() + ln.dbusConn.RemoveSignal(signal) // Remove signal handler + close(signal) // Clean up channel }() for { @@ -252,34 +265,34 @@ func (ls *linuxNotifier) startDBusListener(ctx context.Context) { case signalNotificationClosed: systemID := s.Body[0].(uint32) reason := closedReason(s.Body[1].(uint32)).string() - ls.handleNotificationClosed(systemID, reason) + ln.handleNotificationClosed(systemID, reason) case signalActionInvoked: systemID := s.Body[0].(uint32) actionKey := s.Body[1].(string) - ls.handleActionInvoked(systemID, actionKey) + ln.handleActionInvoked(systemID, actionKey) } } } } // handleNotificationClosed processes notification closed signals -func (ls *linuxNotifier) handleNotificationClosed(systemID uint32, reason string) { +func (ln *linuxNotifier) handleNotificationClosed(systemID uint32, reason string) { // Find our notification ID for this system ID var notifID string var userData map[string]interface{} - ls.internal.Lock() - for id, sysID := range ls.internal.activeNotifs { + ln.Lock() + for id, sysID := range ln.activeNotifs { if sysID == systemID { notifID = id // Get the user data from context if available - if ctx, exists := ls.internal.contexts[id]; exists { + if ctx, exists := ln.contexts[id]; exists { userData = ctx.UserData } break } } - ls.internal.Unlock() + ln.Unlock() if notifID != "" { response := NotificationResponse{ @@ -304,28 +317,28 @@ func (ls *linuxNotifier) handleNotificationClosed(systemID uint32, reason string } // Clean up the context - ls.internal.Lock() - delete(ls.internal.contexts, notifID) - delete(ls.internal.activeNotifs, notifID) - ls.internal.Unlock() + ln.Lock() + delete(ln.contexts, notifID) + delete(ln.activeNotifs, notifID) + ln.Unlock() } } // handleActionInvoked processes action invoked signals -func (ls *linuxNotifier) handleActionInvoked(systemID uint32, actionKey string) { +func (ln *linuxNotifier) handleActionInvoked(systemID uint32, actionKey string) { // Find our notification ID and context for this system ID var notifID string var ctx *notificationContext - ls.internal.Lock() - for id, sysID := range ls.internal.activeNotifs { + ln.Lock() + for id, sysID := range ln.activeNotifs { if sysID == systemID { notifID = id - ctx = ls.internal.contexts[id] + ctx = ln.contexts[id] break } } - ls.internal.Unlock() + ln.Unlock() if notifID != "" { if actionKey == "default" { @@ -372,62 +385,58 @@ func (ls *linuxNotifier) handleActionInvoked(systemID uint32, actionKey string) } // Clean up the context - ls.internal.Lock() - delete(ls.internal.contexts, notifID) - delete(ls.internal.activeNotifs, notifID) - ls.internal.Unlock() + ln.Lock() + delete(ln.contexts, notifID) + delete(ln.activeNotifs, notifID) + ln.Unlock() } } // CheckBundleIdentifier is a Linux stub that always returns true. -// (bundle identifiers are macOS-specific) -func (ls *linuxNotifier) CheckBundleIdentifier() bool { +func (ln *linuxNotifier) CheckBundleIdentifier() bool { return true } // RequestNotificationAuthorization is a Linux stub that always returns true. -// (user authorization is macOS-specific) -func (ls *linuxNotifier) RequestNotificationAuthorization() (bool, error) { +func (ln *linuxNotifier) RequestNotificationAuthorization() (bool, error) { return true, nil } // CheckNotificationAuthorization is a Linux stub that always returns true. -// (user authorization is macOS-specific) -func (ls *linuxNotifier) CheckNotificationAuthorization() (bool, error) { +func (ln *linuxNotifier) CheckNotificationAuthorization() (bool, error) { return true, nil } // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. -func (ls *linuxNotifier) SendNotification(options NotificationOptions) error { - if ls.internal == nil { +func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { + if !ln.initialized { return errors.New("notification service not initialized") } - if ls.internal.method == "" || (ls.internal.method == MethodDbus && ls.internal.dbusConn == nil) || - (ls.internal.method == MethodNotifySend && ls.internal.sendPath == "") { - return errors.New("notification system not properly initialized") + if err := validateNotificationOptions(options); err != nil { + return err } - ls.internal.Lock() - defer ls.internal.Unlock() + ln.Lock() + defer ln.Unlock() var ( systemID uint32 err error ) - switch ls.internal.method { + switch ln.method { case MethodDbus: - systemID, err = ls.sendViaDbus(options, nil) + systemID, err = ln.sendViaDbus(options, nil) case MethodNotifySend: - systemID, err = ls.sendViaNotifySend(options) + systemID, err = ln.sendViaNotifySend(options) default: err = errors.New("no notification method is available") } if err == nil && systemID > 0 { // Store the system ID mapping - ls.internal.activeNotifs[options.ID] = systemID + ln.activeNotifs[options.ID] = systemID // Create and store the notification context ctx := ¬ificationContext{ @@ -435,52 +444,51 @@ func (ls *linuxNotifier) SendNotification(options NotificationOptions) error { SystemID: systemID, UserData: options.Data, } - ls.internal.contexts[options.ID] = ctx + ln.contexts[options.ID] = ctx } return err } // SendNotificationWithActions sends a notification with additional actions. -func (ls *linuxNotifier) SendNotificationWithActions(options NotificationOptions) error { - if ls.internal == nil { +func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions) error { + if !ln.initialized { return errors.New("notification service not initialized") } - if ls.internal.method == "" || (ls.internal.method == MethodDbus && ls.internal.dbusConn == nil) || - (ls.internal.method == MethodNotifySend && ls.internal.sendPath == "") { - return errors.New("notification system not properly initialized") + if err := validateNotificationOptions(options); err != nil { + return err } - ls.categoriesLock.RLock() - category, exists := ls.categories[options.CategoryID] - ls.categoriesLock.RUnlock() + ln.categoriesLock.RLock() + category, exists := ln.categories[options.CategoryID] + ln.categoriesLock.RUnlock() if !exists { - return ls.SendNotification(options) + return ln.SendNotification(options) } - ls.internal.Lock() - defer ls.internal.Unlock() + ln.Lock() + defer ln.Unlock() var ( systemID uint32 err error ) - switch ls.internal.method { + switch ln.method { case MethodDbus: - systemID, err = ls.sendViaDbus(options, &category) + systemID, err = ln.sendViaDbus(options, &category) case MethodNotifySend: // notify-send doesn't support actions, fall back to basic notification - systemID, err = ls.sendViaNotifySend(options) + systemID, err = ln.sendViaNotifySend(options) default: err = errors.New("no notification method is available") } if err == nil && systemID > 0 { // Store the system ID mapping - ls.internal.activeNotifs[options.ID] = systemID + ln.activeNotifs[options.ID] = systemID // Create and store the notification context with actions ctx := ¬ificationContext{ @@ -497,14 +505,14 @@ func (ls *linuxNotifier) SendNotificationWithActions(options NotificationOptions } } - ls.internal.contexts[options.ID] = ctx + ln.contexts[options.ID] = ctx } return err } // sendViaDbus sends a notification via dbus -func (ls *linuxNotifier) sendViaDbus(options NotificationOptions, category *NotificationCategory) (result uint32, err error) { +func (ln *linuxNotifier) sendViaDbus(options NotificationOptions, category *NotificationCategory) (result uint32, err error) { // Prepare actions var actions []string if category != nil { @@ -530,9 +538,9 @@ func (ls *linuxNotifier) sendViaDbus(options NotificationOptions, category *Noti } // Send the notification - obj := ls.internal.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) + obj := ln.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) dbusArgs := []interface{}{ - ls.appName, // App name + ln.appName, // App name uint32(0), // Replaces ID (0 means new notification) "", // App icon (empty for now) options.Title, // Title @@ -556,20 +564,15 @@ func (ls *linuxNotifier) sendViaDbus(options NotificationOptions, category *Noti } // sendViaNotifySend sends a notification via notify-send command -func (ls *linuxNotifier) sendViaNotifySend(options NotificationOptions) (uint32, error) { +func (ln *linuxNotifier) sendViaNotifySend(options NotificationOptions) (uint32, error) { args := []string{ options.Title, options.Body, + "--urgency=normal", } - // Add icon if eventually supported - // if options.Icon != "" { ... } - - // Add urgency (normal by default) - args = append(args, "--urgency=normal") - // Execute the command - cmd := exec.Command(ls.internal.sendPath, args...) + cmd := exec.Command(ln.sendPath, args...) err := cmd.Run() if err != nil { return 0, fmt.Errorf("notify-send error: %v", err) @@ -579,78 +582,74 @@ func (ls *linuxNotifier) sendViaNotifySend(options NotificationOptions) (uint32, return 0, nil } -// RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. -func (ls *linuxNotifier) RegisterNotificationCategory(category NotificationCategory) error { - ls.categoriesLock.Lock() - ls.categories[category.ID] = category - ls.categoriesLock.Unlock() +// RegisterNotificationCategory registers a new NotificationCategory +func (ln *linuxNotifier) RegisterNotificationCategory(category NotificationCategory) error { + ln.categoriesLock.Lock() + ln.categories[category.ID] = category + ln.categoriesLock.Unlock() - return ls.saveCategories() + return ln.saveCategories() } -// RemoveNotificationCategory removes a previously registered NotificationCategory. -func (ls *linuxNotifier) RemoveNotificationCategory(categoryId string) error { - ls.categoriesLock.Lock() - delete(ls.categories, categoryId) - ls.categoriesLock.Unlock() +// RemoveNotificationCategory removes a previously registered NotificationCategory +func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error { + ln.categoriesLock.Lock() + delete(ln.categories, categoryId) + ln.categoriesLock.Unlock() - return ls.saveCategories() + return ln.saveCategories() } -// RemoveAllPendingNotifications is a Linux stub that always returns nil. -// (macOS-specific) -func (ls *linuxNotifier) RemoveAllPendingNotifications() error { +// RemoveAllPendingNotifications is a Linux stub that always returns nil +func (ln *linuxNotifier) RemoveAllPendingNotifications() error { return nil } -// RemovePendingNotification is a Linux stub that always returns nil. -// (macOS-specific) -func (ls *linuxNotifier) RemovePendingNotification(_ string) error { +// RemovePendingNotification is a Linux stub that always returns nil +func (ln *linuxNotifier) RemovePendingNotification(_ string) error { return nil } -// RemoveAllDeliveredNotifications is a Linux stub that always returns nil. -// (macOS-specific) -func (ls *linuxNotifier) RemoveAllDeliveredNotifications() error { +// RemoveAllDeliveredNotifications is a Linux stub that always returns nil +func (ln *linuxNotifier) RemoveAllDeliveredNotifications() error { return nil } -// RemoveDeliveredNotification is a Linux stub that always returns nil. -// (macOS-specific) -func (ls *linuxNotifier) RemoveDeliveredNotification(_ string) error { +// RemoveDeliveredNotification is a Linux stub that always returns nil +func (ln *linuxNotifier) RemoveDeliveredNotification(_ string) error { return nil } // RemoveNotification removes a notification by ID (Linux-specific) -func (ls *linuxNotifier) RemoveNotification(identifier string) error { - if ls.internal == nil || ls.internal.method != MethodDbus || ls.internal.dbusConn == nil { +func (ln *linuxNotifier) RemoveNotification(identifier string) error { + if !ln.initialized || ln.method != MethodDbus || ln.dbusConn == nil { return errors.New("dbus not available for closing notifications") } // Get the system ID for this notification - ls.internal.Lock() - systemID, exists := ls.internal.activeNotifs[identifier] - ls.internal.Unlock() + ln.Lock() + systemID, exists := ln.activeNotifs[identifier] + ln.Unlock() if !exists { return nil // Already closed or unknown } // Call CloseNotification on dbus - obj := ls.internal.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) + obj := ln.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) call := obj.Call(callCloseNotification, 0, systemID) return call.Err } -// getConfigFilePath returns the path to the configuration file for storing notification categories -func (ls *linuxNotifier) getConfigFilePath() (string, error) { +// getConfigFilePath returns the path to the configuration file +func (ln *linuxNotifier) getConfigFilePath() (string, error) { configDir, err := os.UserConfigDir() if err != nil { return "", fmt.Errorf("failed to get user config directory: %v", err) } - appConfigDir := filepath.Join(configDir, ls.appName) + appConfigDir := filepath.Join(configDir, ln.appName) if err := os.MkdirAll(appConfigDir, 0755); err != nil { return "", fmt.Errorf("failed to create config directory: %v", err) } @@ -658,16 +657,16 @@ func (ls *linuxNotifier) getConfigFilePath() (string, error) { return filepath.Join(appConfigDir, "notification-categories.json"), nil } -// saveCategories saves the notification categories to a file. -func (ls *linuxNotifier) saveCategories() error { - filePath, err := ls.getConfigFilePath() +// saveCategories saves the notification categories to a file +func (ln *linuxNotifier) saveCategories() error { + filePath, err := ln.getConfigFilePath() if err != nil { return err } - ls.categoriesLock.RLock() - data, err := json.Marshal(ls.categories) - ls.categoriesLock.RUnlock() + ln.categoriesLock.RLock() + data, err := json.Marshal(ln.categories) + ln.categoriesLock.RUnlock() if err != nil { return fmt.Errorf("failed to marshal notification categories: %v", err) @@ -680,9 +679,9 @@ func (ls *linuxNotifier) saveCategories() error { return nil } -// loadCategories loads notification categories from a file. -func (ls *linuxNotifier) loadCategories() error { - filePath, err := ls.getConfigFilePath() +// loadCategories loads notification categories from a file +func (ln *linuxNotifier) loadCategories() error { + filePath, err := ln.getConfigFilePath() if err != nil { return err } @@ -705,9 +704,9 @@ func (ls *linuxNotifier) loadCategories() error { return fmt.Errorf("failed to unmarshal notification categories: %v", err) } - ls.categoriesLock.Lock() - ls.categories = categories - ls.categoriesLock.Unlock() + ln.categoriesLock.Lock() + ln.categories = categories + ln.categoriesLock.Unlock() return nil } From be1da68dbcd007b327cc1cf2d2c79f433dd3ab7d Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 20 Mar 2025 22:12:21 -0700 Subject: [PATCH 091/136] avoid deadlock on win --- v3/pkg/services/notifications/notifications.go | 4 +++- v3/pkg/services/notifications/notifications_linux.go | 1 + v3/pkg/services/notifications/notifications_windows.go | 6 ++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index bfa0b4489..1f50d6031 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -16,6 +16,8 @@ import ( "context" "fmt" "sync" + + "github.com/wailsapp/wails/v3/pkg/application" ) type notificationImpl interface { @@ -133,7 +135,7 @@ func (ns *Service) handleNotificationResult(result NotificationResult) { } // ServiceStartup is called when the service is loaded -func (ns *Service) ServiceStartup(ctx context.Context, options interface{}) error { +func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { return ns.impl.Startup(ctx) } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index cff22b336..349756e21 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -78,6 +78,7 @@ func New() *Service { impl: impl, } }) + return NotificationService } diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 064a6343f..ef4aacc85 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -209,8 +209,6 @@ func (wn *windowsNotifier) SendNotificationWithActions(options NotificationOptio // Registering a category with the same name as a previously registered NotificationCategory will override it. func (wn *windowsNotifier) RegisterNotificationCategory(category NotificationCategory) error { wn.categoriesLock.Lock() - defer wn.categoriesLock.Unlock() - wn.categories[category.ID] = NotificationCategory{ ID: category.ID, Actions: category.Actions, @@ -218,6 +216,7 @@ func (wn *windowsNotifier) RegisterNotificationCategory(category NotificationCat ReplyPlaceholder: category.ReplyPlaceholder, ReplyButtonTitle: category.ReplyButtonTitle, } + wn.categoriesLock.Unlock() return wn.saveCategoriesToRegistry() } @@ -225,9 +224,8 @@ func (wn *windowsNotifier) RegisterNotificationCategory(category NotificationCat // RemoveNotificationCategory removes a previously registered NotificationCategory. func (wn *windowsNotifier) RemoveNotificationCategory(categoryId string) error { wn.categoriesLock.Lock() - defer wn.categoriesLock.Unlock() - delete(wn.categories, categoryId) + wn.categoriesLock.Unlock() return wn.saveCategoriesToRegistry() } From ef3b7d2bc3bcef30752ddd40a4f17a5d1b965b6a Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 11:51:02 -0700 Subject: [PATCH 092/136] pass service options --- v3/pkg/services/notifications/notifications.go | 8 ++++---- v3/pkg/services/notifications/notifications_darwin.go | 4 +++- v3/pkg/services/notifications/notifications_linux.go | 2 +- v3/pkg/services/notifications/notifications_windows.go | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 1f50d6031..d7549fbf9 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -20,9 +20,9 @@ import ( "github.com/wailsapp/wails/v3/pkg/application" ) -type notificationImpl interface { +type platformNotifier interface { // Lifecycle methods - Startup(ctx context.Context) error + Startup(ctx context.Context, options application.ServiceOptions) error Shutdown() error // Core notification methods @@ -45,7 +45,7 @@ type notificationImpl interface { // Service represents the notifications service type Service struct { - impl notificationImpl + impl platformNotifier // notificationResponseCallback is called when a notification result is received. // Only one callback can be assigned at a time. @@ -136,7 +136,7 @@ func (ns *Service) handleNotificationResult(result NotificationResult) { // ServiceStartup is called when the service is loaded func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - return ns.impl.Startup(ctx) + return ns.impl.Startup(ctx, options) } // ServiceShutdown is called when the service is unloaded diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 380460f43..c97e80531 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -15,6 +15,8 @@ import ( "sync" "time" "unsafe" + + "github.com/wailsapp/wails/v3/pkg/application" ) type darwinNotifier struct { @@ -56,7 +58,7 @@ func New() *Service { return NotificationService } -func (dn *darwinNotifier) Startup(ctx context.Context) error { +func (dn *darwinNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { return nil } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 349756e21..2050c84df 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -83,7 +83,7 @@ func New() *Service { } // Startup is called when the service is loaded -func (ln *linuxNotifier) Startup(ctx context.Context) error { +func (ln *linuxNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { ln.appName = application.Get().Config().Name if err := ln.loadCategories(); err != nil { diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index ef4aacc85..6219665f6 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -57,7 +57,7 @@ func New() *Service { // Startup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. -func (wn *windowsNotifier) Startup(ctx context.Context) error { +func (wn *windowsNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { wn.appName = application.Get().Config().Name guid, err := wn.getGUID() From 81b40d2afeabb09bef0ea61e6f8471837e28eff5 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 12:16:47 -0700 Subject: [PATCH 093/136] ensure exactly one delegate created --- .../notifications/notifications_darwin.m | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index cd1c96898..01d85c1bc 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -63,13 +63,22 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response @end static NotificationsDelegate *delegateInstance = nil; +static dispatch_once_t onceToken; -static void ensureDelegateInitialized(void) { - if (!delegateInstance) { +static BOOL ensureDelegateInitialized(void) { + __block BOOL success = YES; + + dispatch_once(&onceToken, ^{ delegateInstance = [[NotificationsDelegate alloc] init]; UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = delegateInstance; + }); + + if (!delegateInstance) { + success = NO; } + + return success; } bool checkBundleIdentifier(void) { @@ -81,7 +90,11 @@ bool checkBundleIdentifier(void) { } void requestNotificationAuthorization(int channelID) { - ensureDelegateInitialized(); + if (!ensureDelegateInitialized()) { + NSString *errorMsg = @"Notification delegate has been lost. Reinitialize the notification service."; + captureResult(channelID, false, [errorMsg UTF8String]); + return; + } UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; @@ -97,7 +110,11 @@ void requestNotificationAuthorization(int channelID) { } void checkNotificationAuthorization(int channelID) { - ensureDelegateInitialized(); + if (!ensureDelegateInitialized()) { + NSString *errorMsg = @"Notification delegate has been lost. Reinitialize the notification service."; + captureResult(channelID, false, [errorMsg UTF8String]); + return; + } UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) { @@ -136,7 +153,11 @@ UNMutableNotificationContent* createNotificationContent(const char *title, const } void sendNotification(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json) { - ensureDelegateInitialized(); + if (!ensureDelegateInitialized()) { + NSString *errorMsg = @"Notification delegate has been lost. Reinitialize the notification service."; + captureResult(channelID, false, [errorMsg UTF8String]); + return; + } UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; @@ -164,7 +185,11 @@ void sendNotification(int channelID, const char *identifier, const char *title, void sendNotificationWithActions(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *categoryId, const char *data_json) { - ensureDelegateInitialized(); + if (!ensureDelegateInitialized()) { + NSString *errorMsg = @"Notification delegate has been lost. Reinitialize the notification service."; + captureResult(channelID, false, [errorMsg UTF8String]); + return; + } UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; @@ -195,7 +220,11 @@ void sendNotificationWithActions(int channelID, const char *identifier, const ch void registerNotificationCategory(int channelID, const char *categoryId, const char *actions_json, bool hasReplyField, const char *replyPlaceholder, const char *replyButtonTitle) { - ensureDelegateInitialized(); + if (!ensureDelegateInitialized()) { + NSString *errorMsg = @"Notification delegate has been lost. Reinitialize the notification service."; + captureResult(channelID, false, [errorMsg UTF8String]); + return; + } NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; NSString *actionsJsonStr = actions_json ? [NSString stringWithUTF8String:actions_json] : @"[]"; From f6a5bed582bc26b499a9ae27f8cc796796b3bbcd Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 12:48:47 -0700 Subject: [PATCH 094/136] windows err handling --- .../notifications/notifications_darwin.go | 4 +- .../notifications/notifications_windows.go | 48 ++++++++++++++----- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index c97e80531..7264a7f71 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -71,9 +71,9 @@ func CheckBundleIdentifier() bool { } // RequestNotificationAuthorization requests permission for notifications. -// Default timeout is 15 minutes +// Default timeout is 3 minutes func (dn *darwinNotifier) RequestNotificationAuthorization() (bool, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*900) + ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second) defer cancel() id, resultCh := dn.registerChannel() diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 6219665f6..de476898d 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -58,6 +58,9 @@ func New() *Service { // Startup is called when the service is loaded // Sets an activation callback to emit an event when notifications are interacted with. func (wn *windowsNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { + wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() + wn.appName = application.Get().Config().Name guid, err := wn.getGUID() @@ -76,7 +79,17 @@ func (wn *windowsNotifier) Startup(ctx context.Context, options application.Serv toast.SetActivationCallback(func(args string, data []toast.UserData) { result := NotificationResult{} - actionIdentifier, userInfo := parseNotificationResponse(args) + actionIdentifier, userInfo, err := parseNotificationResponse(args) + + if err != nil { + result.Error = err + + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } + return + } + response := NotificationResponse{ ActionIdentifier: actionIdentifier, } @@ -89,6 +102,7 @@ func (wn *windowsNotifier) Startup(ctx context.Context, options application.Serv if ns := getNotificationService(); ns != nil { ns.handleNotificationResult(result) } + return } response.UserInfo = userInfoMap } @@ -108,6 +122,9 @@ func (wn *windowsNotifier) Startup(ctx context.Context, options application.Serv // Shutdown will attempt to save the categories to the registry when the service unloads func (wn *windowsNotifier) Shutdown() error { + wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() + return wn.saveCategoriesToRegistry() } @@ -209,6 +226,8 @@ func (wn *windowsNotifier) SendNotificationWithActions(options NotificationOptio // Registering a category with the same name as a previously registered NotificationCategory will override it. func (wn *windowsNotifier) RegisterNotificationCategory(category NotificationCategory) error { wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() + wn.categories[category.ID] = NotificationCategory{ ID: category.ID, Actions: category.Actions, @@ -216,7 +235,6 @@ func (wn *windowsNotifier) RegisterNotificationCategory(category NotificationCat ReplyPlaceholder: category.ReplyPlaceholder, ReplyButtonTitle: category.ReplyButtonTitle, } - wn.categoriesLock.Unlock() return wn.saveCategoriesToRegistry() } @@ -224,8 +242,9 @@ func (wn *windowsNotifier) RegisterNotificationCategory(category NotificationCat // RemoveNotificationCategory removes a previously registered NotificationCategory. func (wn *windowsNotifier) RemoveNotificationCategory(categoryId string) error { wn.categoriesLock.Lock() + defer wn.categoriesLock.Unlock() + delete(wn.categories, categoryId) - wn.categoriesLock.Unlock() return wn.saveCategoriesToRegistry() } @@ -280,29 +299,34 @@ func (wn *windowsNotifier) encodePayload(actionID string, data map[string]interf func decodePayload(encodedString string) (string, map[string]interface{}, error) { jsonData, err := base64.StdEncoding.DecodeString(encodedString) if err != nil { - return encodedString, nil, nil + return encodedString, nil, fmt.Errorf("failed to decode base64 payload: %w", err) } var payload NotificationPayload if err := json.Unmarshal(jsonData, &payload); err != nil { - return encodedString, nil, nil + return encodedString, nil, fmt.Errorf("failed to unmarshal notification payload: %w", err) } return payload.Action, payload.Data, nil } // parseNotificationResponse updated to use structured payload decoding -func parseNotificationResponse(response string) (action string, data string) { - actionID, userData, _ := decodePayload(response) +func parseNotificationResponse(response string) (action string, data string, err error) { + actionID, userData, err := decodePayload(response) + + if err != nil { + fmt.Printf("Warning: Failed to decode notification response: %v\n", err) + return response, "", err + } if userData != nil { userDataJSON, err := json.Marshal(userData) if err == nil { - return actionID, string(userDataJSON) + return actionID, string(userDataJSON), nil } } - return actionID, "" + return actionID, "", nil } func (wn *windowsNotifier) saveIconToDir() error { @@ -315,8 +339,7 @@ func (wn *windowsNotifier) saveIconToDir() error { } func (wn *windowsNotifier) saveCategoriesToRegistry() error { - wn.categoriesLock.Lock() - defer wn.categoriesLock.Unlock() + // We assume lock is held by caller registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, wn.appName) @@ -339,8 +362,7 @@ func (wn *windowsNotifier) saveCategoriesToRegistry() error { } func (wn *windowsNotifier) loadCategoriesFromRegistry() error { - wn.categoriesLock.Lock() - defer wn.categoriesLock.Unlock() + // We assume lock is held by caller registryPath := fmt.Sprintf(NotificationCategoriesRegistryPath, wn.appName) From b2b8f140532403b09a6ee3c4b58126295c664f27 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 16:01:47 -0700 Subject: [PATCH 095/136] windows err handling --- v3/pkg/services/notifications/notifications_windows.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index de476898d..30abd61b1 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -174,9 +174,13 @@ func (wn *windowsNotifier) SendNotificationWithActions(options NotificationOptio } wn.categoriesLock.RLock() - nCategory := wn.categories[options.CategoryID] + nCategory, categoryExists := wn.categories[options.CategoryID] wn.categoriesLock.RUnlock() + if options.CategoryID == "" || !categoryExists { + fmt.Printf("Category '%s' not found, sending basic notification without actions\n", options.CategoryID) + } + n := toast.Notification{ Title: options.Title, Body: options.Body, From f870dcc168fa880e324f2bb65ec094bc82c1031b Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 17:39:20 -0700 Subject: [PATCH 096/136] handle notif content errors --- .../notifications/notifications_darwin.m | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 01d85c1bc..cd429c5d6 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -1,4 +1,5 @@ #import "notifications_darwin.h" +#include #import #import @@ -125,7 +126,7 @@ void checkNotificationAuthorization(int channelID) { // Helper function to create notification content UNMutableNotificationContent* createNotificationContent(const char *title, const char *subtitle, - const char *body, const char *data_json) { + const char *body, const char *data_json, NSError **contentError) { NSString *nsTitle = [NSString stringWithUTF8String:title]; NSString *nsSubtitle = subtitle ? [NSString stringWithUTF8String:subtitle] : @""; NSString *nsBody = [NSString stringWithUTF8String:body]; @@ -146,6 +147,8 @@ UNMutableNotificationContent* createNotificationContent(const char *title, const NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; if (!error && parsedData) { content.userInfo = parsedData; + } else if (error) { + *contentError = error; } } @@ -162,13 +165,16 @@ void sendNotification(int channelID, const char *identifier, const char *title, UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; - UNMutableNotificationContent *content = createNotificationContent(title, subtitle, body, data_json); - NSMutableDictionary *customData = [NSMutableDictionary dictionary]; + + NSError *contentError = nil; + UNMutableNotificationContent *content = createNotificationContent(title, subtitle, body, data_json, &contentError); - if (customData.count > 0) { - content.userInfo = customData; + if (contentError) { + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [contentError localizedDescription]]; + captureResult(channelID, false, [errorMsg UTF8String]); + return; } - + UNTimeIntervalNotificationTrigger *trigger = nil; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:nsIdentifier content:content trigger:trigger]; @@ -195,13 +201,14 @@ void sendNotificationWithActions(int channelID, const char *identifier, const ch NSString *nsIdentifier = [NSString stringWithUTF8String:identifier]; NSString *nsCategoryId = [NSString stringWithUTF8String:categoryId]; - UNMutableNotificationContent *content = createNotificationContent(title, subtitle, body, data_json); - NSMutableDictionary *customData = [NSMutableDictionary dictionary]; - content.categoryIdentifier = nsCategoryId; + NSError *contentError = nil; + UNMutableNotificationContent *content = createNotificationContent(title, subtitle, body, data_json, &contentError); - if (customData.count > 0) { - content.userInfo = customData; + if (contentError) { + NSString *errorMsg = [NSString stringWithFormat:@"Error: %@", [contentError localizedDescription]]; + captureResult(channelID, false, [errorMsg UTF8String]); + return; } UNTimeIntervalNotificationTrigger *trigger = nil; From 9948cee1f715943553f342c22d33296f10dd0224 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 17:51:51 -0700 Subject: [PATCH 097/136] monitor dbus connection --- .../notifications/notifications_darwin.go | 2 +- .../notifications/notifications_linux.go | 76 ++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 7264a7f71..e27d6f010 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -85,7 +85,7 @@ func (dn *darwinNotifier) RequestNotificationAuthorization() (bool, error) { return result.Success, result.Error case <-ctx.Done(): dn.cleanupChannel(id) - return false, fmt.Errorf("notification authorization timed out after 15 minutes: %w", ctx.Err()) + return false, fmt.Errorf("notification authorization timed out after 3 minutes: %w", ctx.Err()) } } diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 2050c84df..551095dec 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -11,6 +11,7 @@ import ( "os/exec" "path/filepath" "sync" + "time" "github.com/godbus/dbus/v5" "github.com/wailsapp/wails/v3/pkg/application" @@ -246,12 +247,55 @@ func (ln *linuxNotifier) startDBusListener(ctx context.Context) { close(signal) // Clean up channel }() + // Create a separate goroutine to monitor the D-Bus connection + disconnected := ln.monitorDBusConnection(ctx) + for { select { case <-ctx.Done(): // Context was cancelled, exit gracefully return + case <-disconnected: + // D-Bus connection lost + fmt.Println("D-Bus connection lost, attempting to reconnect...") + ln.Lock() + + // Attempt to reconnect + var err error + newConn, err := ln.initDBus() + if err != nil { + fmt.Printf("Failed to reconnect to D-Bus: %v\n", err) + ln.dbusConn = nil + ln.method = "" // No longer using D-Bus + + // Try fallback to notify-send + sendPath, err := ln.initNotifySend() + if err == nil { + fmt.Println("Falling back to notify-send method") + ln.sendPath = sendPath + ln.method = MethodNotifySend + } else { + fmt.Println("No notification methods available after D-Bus disconnect") + } + + ln.Unlock() + return // Exit listener as we can't continue without D-Bus + } + + // Successfully reconnected + ln.dbusConn = newConn + ln.Unlock() + + // Re-register for signals + signal = make(chan *dbus.Signal, notifyChannelBufferSize) + ln.dbusConn.Signal(signal) + + // Restart the monitor goroutine + disconnected = ln.monitorDBusConnection(ctx) + fmt.Println("Successfully reconnected to D-Bus") + continue + case s := <-signal: if s == nil { // Channel closed or nil signal @@ -512,6 +556,33 @@ func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions return err } +// monitorDBusConnection creates a goroutine to monitor the D-Bus connection +// Returns a channel that will be closed if the connection is lost +func (ln *linuxNotifier) monitorDBusConnection(ctx context.Context) chan struct{} { + disconnected := make(chan struct{}) + + go func() { + for { + select { + case <-ctx.Done(): + return // Context cancelled, exit monitor + default: + ln.Lock() + connected := ln.dbusConn != nil && ln.dbusConn.Connected() + ln.Unlock() + + if !connected { + close(disconnected) + return + } + time.Sleep(1 * time.Second) // Check every second + } + } + }() + + return disconnected +} + // sendViaDbus sends a notification via dbus func (ln *linuxNotifier) sendViaDbus(options NotificationOptions, category *NotificationCategory) (result uint32, err error) { // Prepare actions @@ -623,14 +694,15 @@ func (ln *linuxNotifier) RemoveDeliveredNotification(_ string) error { // RemoveNotification removes a notification by ID (Linux-specific) func (ln *linuxNotifier) RemoveNotification(identifier string) error { + ln.Lock() + defer ln.Unlock() + if !ln.initialized || ln.method != MethodDbus || ln.dbusConn == nil { return errors.New("dbus not available for closing notifications") } // Get the system ID for this notification - ln.Lock() systemID, exists := ln.activeNotifs[identifier] - ln.Unlock() if !exists { return nil // Already closed or unknown From ace4f70e3a9b8d8bf95a8cff2ad64914df86c3dc Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 18:04:30 -0700 Subject: [PATCH 098/136] fix channel cleanup linux --- .../notifications/notifications_linux.go | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 551095dec..0fc21275a 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -41,6 +41,9 @@ type linuxNotifier struct { // Initialization initOnce sync.Once initialized bool + + monitorCtx context.Context + monitorCancel context.CancelFunc } type notificationContext struct { @@ -105,6 +108,8 @@ func (ln *linuxNotifier) initNotificationSystem() error { ln.Lock() defer ln.Unlock() + ln.monitorCtx, ln.monitorCancel = context.WithCancel(context.Background()) + // Cancel any existing listener if ln.listenerCancel != nil { ln.listenerCancel() @@ -210,6 +215,12 @@ func (ln *linuxNotifier) initNotifySend() (string, error) { func (ln *linuxNotifier) Shutdown() error { ln.Lock() + // Cancel monitor goroutine first + if ln.monitorCancel != nil { + ln.monitorCancel() + ln.monitorCancel = nil + } + // Cancel the listener context if it's running if ln.listenerCancel != nil { ln.listenerCancel() @@ -562,11 +573,16 @@ func (ln *linuxNotifier) monitorDBusConnection(ctx context.Context) chan struct{ disconnected := make(chan struct{}) go func() { + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + for { select { case <-ctx.Done(): - return // Context cancelled, exit monitor - default: + return // Parent context cancelled + case <-ln.monitorCtx.Done(): + return // Monitor specifically cancelled + case <-ticker.C: ln.Lock() connected := ln.dbusConn != nil && ln.dbusConn.Connected() ln.Unlock() @@ -575,7 +591,6 @@ func (ln *linuxNotifier) monitorDBusConnection(ctx context.Context) chan struct{ close(disconnected) return } - time.Sleep(1 * time.Second) // Check every second } } }() From 448c78b226a461c3c5e29d5d1d12f6e6a77f349a Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 22:36:29 -0700 Subject: [PATCH 099/136] rewrite and simplify linux impl --- .../notifications/notifications_linux.go | 1079 +++++++---------- .../notifications/notifications_windows.go | 4 +- 2 files changed, 433 insertions(+), 650 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 0fc21275a..911bba8c4 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -5,77 +5,37 @@ package notifications import ( "context" "encoding/json" - "errors" "fmt" "os" - "os/exec" "path/filepath" "sync" - "time" "github.com/godbus/dbus/v5" "github.com/wailsapp/wails/v3/pkg/application" ) type linuxNotifier struct { - // Categories - categories map[string]NotificationCategory - categoriesLock sync.RWMutex - - // App info - appName string - - // Notification system - sync.Mutex - method string - dbusConn *dbus.Conn - sendPath string - activeNotifs map[string]uint32 // Maps our notification IDs to system IDs - contexts map[string]*notificationContext // Stores notification contexts by our ID - - // Listener management - listenerCtx context.Context - listenerCancel context.CancelFunc - listenerRunning bool - - // Initialization - initOnce sync.Once - initialized bool - - monitorCtx context.Context - monitorCancel context.CancelFunc -} - -type notificationContext struct { - ID string - SystemID uint32 - Actions map[string]string // Maps action keys to display labels - UserData map[string]interface{} // The original user data + conn *dbus.Conn + categories map[string]NotificationCategory + categoriesLock sync.RWMutex + activeNotifs map[uint32]string + notificationMeta map[uint32]map[string]interface{} + activeNotifsLock sync.RWMutex + appName string } const ( - dbusObjectPath = "/org/freedesktop/Notifications" - dbusNotificationsInterface = "org.freedesktop.Notifications" - signalNotificationClosed = "org.freedesktop.Notifications.NotificationClosed" - signalActionInvoked = "org.freedesktop.Notifications.ActionInvoked" - callGetCapabilities = "org.freedesktop.Notifications.GetCapabilities" - callCloseNotification = "org.freedesktop.Notifications.CloseNotification" - - MethodNotifySend = "notify-send" - MethodDbus = "dbus" - - notifyChannelBufferSize = 25 + dbusNotificationInterface = "org.freedesktop.Notifications" + dbusNotificationPath = "/org/freedesktop/Notifications" ) -type closedReason uint32 - -// New creates a new Notifications Service +// Creates a new Notifications Service. func New() *Service { notificationServiceOnce.Do(func() { impl := &linuxNotifier{ - categories: make(map[string]NotificationCategory), - activeNotifs: make(map[string]uint32), - contexts: make(map[string]*notificationContext), + categories: make(map[string]NotificationCategory), + activeNotifs: make(map[uint32]string), + notificationMeta: make(map[uint32]map[string]interface{}), } NotificationService = &Service{ @@ -88,708 +48,373 @@ func New() *Service { // Startup is called when the service is loaded func (ln *linuxNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { - ln.appName = application.Get().Config().Name + app := application.Get() + if app != nil && app.Config().Name != "" { + ln.appName = app.Config().Name + } + + conn, err := dbus.ConnectSessionBus() + if err != nil { + return fmt.Errorf("failed to connect to session bus: %w", err) + } + ln.conn = conn if err := ln.loadCategories(); err != nil { fmt.Printf("Failed to load notification categories: %v\n", err) } - var err error - ln.initOnce.Do(func() { - err = ln.initNotificationSystem() - ln.initialized = err == nil - }) + if err := ln.setupSignalHandling(); err != nil { + return fmt.Errorf("failed to set up notification signal handling: %w", err) + } - return err + return nil } -// initNotificationSystem initializes the notification system -func (ln *linuxNotifier) initNotificationSystem() error { - ln.Lock() - defer ln.Unlock() - - ln.monitorCtx, ln.monitorCancel = context.WithCancel(context.Background()) - - // Cancel any existing listener - if ln.listenerCancel != nil { - ln.listenerCancel() - ln.listenerCancel = nil - } - - // Create a new context for the listener - ln.listenerCtx, ln.listenerCancel = context.WithCancel(context.Background()) - - // Reset state - ln.activeNotifs = make(map[string]uint32) - ln.contexts = make(map[string]*notificationContext) - ln.listenerRunning = false - - // Try dbus first - dbusConn, err := ln.initDBus() - if err == nil { - ln.dbusConn = dbusConn - ln.method = MethodDbus - - // Start the dbus signal listener - go ln.startDBusListener(ln.listenerCtx) - ln.listenerRunning = true - return nil - } - - // Try notify-send as fallback - sendPath, err := ln.initNotifySend() - if err == nil { - ln.sendPath = sendPath - ln.method = MethodNotifySend - return nil - } - - // No method available - ln.method = "" - ln.sendPath = "" - return errors.New("no notification method is available") -} - -// initDBus attempts to initialize D-Bus notifications -func (ln *linuxNotifier) initDBus() (*dbus.Conn, error) { - conn, err := dbus.SessionBusPrivate() - if err != nil { - return nil, err - } - - if err = conn.Auth(nil); err != nil { - conn.Close() - return nil, err - } - - if err = conn.Hello(); err != nil { - conn.Close() - return nil, err - } - - obj := conn.Object(dbusNotificationsInterface, dbusObjectPath) - call := obj.Call(callGetCapabilities, 0) - if call.Err != nil { - conn.Close() - return nil, call.Err - } - - var ret []string - err = call.Store(&ret) - if err != nil { - conn.Close() - return nil, err - } - - // Add a listener for notification signals - err = conn.AddMatchSignal( - dbus.WithMatchObjectPath(dbusObjectPath), - dbus.WithMatchInterface(dbusNotificationsInterface), - ) - if err != nil { - conn.Close() - return nil, err - } - - return conn, nil -} - -// initNotifySend attempts to find notify-send binary -func (ln *linuxNotifier) initNotifySend() (string, error) { - // Try standard notify-send - send, err := exec.LookPath("notify-send") - if err == nil { - return send, nil - } - - // Try sw-notify-send (in some distros) - send, err = exec.LookPath("sw-notify-send") - if err == nil { - return send, nil - } - - return "", errors.New("notify-send not found") -} - -// Shutdown is called when the service is unloaded +// Shutdown will save categories and close the D-Bus connection when the service unloads func (ln *linuxNotifier) Shutdown() error { - ln.Lock() - - // Cancel monitor goroutine first - if ln.monitorCancel != nil { - ln.monitorCancel() - ln.monitorCancel = nil + if err := ln.saveCategories(); err != nil { + fmt.Printf("Failed to save notification categories: %v\n", err) } - // Cancel the listener context if it's running - if ln.listenerCancel != nil { - ln.listenerCancel() - ln.listenerCancel = nil + if ln.conn != nil { + return ln.conn.Close() } - // Close the connection - if ln.dbusConn != nil { - ln.dbusConn.Close() - ln.dbusConn = nil - } - - // Clear state - ln.activeNotifs = make(map[string]uint32) - ln.contexts = make(map[string]*notificationContext) - ln.method = "" - ln.sendPath = "" - ln.initialized = false - - ln.Unlock() - - return ln.saveCategories() + return nil } -// startDBusListener listens for DBus signals for notification actions and closures -func (ln *linuxNotifier) startDBusListener(ctx context.Context) { - signal := make(chan *dbus.Signal, notifyChannelBufferSize) - ln.dbusConn.Signal(signal) - - defer func() { - ln.Lock() - ln.listenerRunning = false - ln.Unlock() - ln.dbusConn.RemoveSignal(signal) // Remove signal handler - close(signal) // Clean up channel - }() - - // Create a separate goroutine to monitor the D-Bus connection - disconnected := ln.monitorDBusConnection(ctx) - - for { - select { - case <-ctx.Done(): - // Context was cancelled, exit gracefully - return - - case <-disconnected: - // D-Bus connection lost - fmt.Println("D-Bus connection lost, attempting to reconnect...") - ln.Lock() - - // Attempt to reconnect - var err error - newConn, err := ln.initDBus() - if err != nil { - fmt.Printf("Failed to reconnect to D-Bus: %v\n", err) - ln.dbusConn = nil - ln.method = "" // No longer using D-Bus - - // Try fallback to notify-send - sendPath, err := ln.initNotifySend() - if err == nil { - fmt.Println("Falling back to notify-send method") - ln.sendPath = sendPath - ln.method = MethodNotifySend - } else { - fmt.Println("No notification methods available after D-Bus disconnect") - } - - ln.Unlock() - return // Exit listener as we can't continue without D-Bus - } - - // Successfully reconnected - ln.dbusConn = newConn - ln.Unlock() - - // Re-register for signals - signal = make(chan *dbus.Signal, notifyChannelBufferSize) - ln.dbusConn.Signal(signal) - - // Restart the monitor goroutine - disconnected = ln.monitorDBusConnection(ctx) - fmt.Println("Successfully reconnected to D-Bus") - continue - - case s := <-signal: - if s == nil { - // Channel closed or nil signal - continue - } - - if len(s.Body) < 2 { - continue - } - - switch s.Name { - case signalNotificationClosed: - systemID := s.Body[0].(uint32) - reason := closedReason(s.Body[1].(uint32)).string() - ln.handleNotificationClosed(systemID, reason) - case signalActionInvoked: - systemID := s.Body[0].(uint32) - actionKey := s.Body[1].(string) - ln.handleActionInvoked(systemID, actionKey) - } - } - } -} - -// handleNotificationClosed processes notification closed signals -func (ln *linuxNotifier) handleNotificationClosed(systemID uint32, reason string) { - // Find our notification ID for this system ID - var notifID string - var userData map[string]interface{} - - ln.Lock() - for id, sysID := range ln.activeNotifs { - if sysID == systemID { - notifID = id - // Get the user data from context if available - if ctx, exists := ln.contexts[id]; exists { - userData = ctx.UserData - } - break - } - } - ln.Unlock() - - if notifID != "" { - response := NotificationResponse{ - ID: notifID, - ActionIdentifier: DefaultActionIdentifier, - UserInfo: userData, - } - - // Add reason to UserInfo or create it if none exists - if response.UserInfo == nil { - response.UserInfo = map[string]interface{}{ - "reason": reason, - } - } else { - response.UserInfo["reason"] = reason - } - - result := NotificationResult{} - result.Response = response - if ns := getNotificationService(); ns != nil { - ns.handleNotificationResult(result) - } - - // Clean up the context - ln.Lock() - delete(ln.contexts, notifID) - delete(ln.activeNotifs, notifID) - ln.Unlock() - } -} - -// handleActionInvoked processes action invoked signals -func (ln *linuxNotifier) handleActionInvoked(systemID uint32, actionKey string) { - // Find our notification ID and context for this system ID - var notifID string - var ctx *notificationContext - - ln.Lock() - for id, sysID := range ln.activeNotifs { - if sysID == systemID { - notifID = id - ctx = ln.contexts[id] - break - } - } - ln.Unlock() - - if notifID != "" { - if actionKey == "default" { - actionKey = DefaultActionIdentifier - } - - // First, send the action response with the user data - response := NotificationResponse{ - ID: notifID, - ActionIdentifier: actionKey, - } - - // Include the user data if we have it - if ctx != nil { - response.UserInfo = ctx.UserData - } - - result := NotificationResult{} - result.Response = response - if ns := getNotificationService(); ns != nil { - ns.handleNotificationResult(result) - } - - // Then, trigger a closed event with "activated-by-user" reason - closeResponse := NotificationResponse{ - ID: notifID, - ActionIdentifier: DefaultActionIdentifier, - } - - // Include the same user data in the close response - if ctx != nil { - closeResponse.UserInfo = ctx.UserData - } else { - closeResponse.UserInfo = map[string]interface{}{} - } - - // Add the reason to the user info - closeResponse.UserInfo["reason"] = closedReason(5).string() // "activated-by-user" - - closeResult := NotificationResult{} - closeResult.Response = closeResponse - if ns := getNotificationService(); ns != nil { - ns.handleNotificationResult(closeResult) - } - - // Clean up the context - ln.Lock() - delete(ln.contexts, notifID) - delete(ln.activeNotifs, notifID) - ln.Unlock() - } -} - -// CheckBundleIdentifier is a Linux stub that always returns true. -func (ln *linuxNotifier) CheckBundleIdentifier() bool { - return true -} - -// RequestNotificationAuthorization is a Linux stub that always returns true. +// RequestNotificationAuthorization is a Linux stub that always returns true, nil. +// (authorization is macOS-specific) func (ln *linuxNotifier) RequestNotificationAuthorization() (bool, error) { return true, nil } // CheckNotificationAuthorization is a Linux stub that always returns true. +// (authorization is macOS-specific) func (ln *linuxNotifier) CheckNotificationAuthorization() (bool, error) { return true, nil } // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { - if !ln.initialized { - return errors.New("notification service not initialized") + hints := map[string]dbus.Variant{} + + // Use subtitle as part of the body if provided + body := options.Body + if options.Subtitle != "" { + body = options.Subtitle + "\n" + body } - if err := validateNotificationOptions(options); err != nil { - return err + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err != nil { + return fmt.Errorf("failed to marshal notification data: %w", err) + } + hints["x-user-info"] = dbus.MakeVariant(string(jsonData)) } - ln.Lock() - defer ln.Unlock() + metadataJSON, err := json.Marshal(map[string]interface{}{ + "id": options.ID, + "title": options.Title, + "subtitle": options.Subtitle, + "body": options.Body, + "data": options.Data, + }) + if err != nil { + return fmt.Errorf("failed to marshal notification metadata: %w", err) + } + hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON)) - var ( - systemID uint32 - err error + actions := []string{} + timeout := int32(0) // Timeout in milliseconds (5 seconds) + + // Call the Notify method on the D-Bus interface + obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) + call := obj.Call( + dbusNotificationInterface+".Notify", + 0, + ln.appName, + uint32(0), + "", // Icon + options.Title, + body, + actions, + hints, + timeout, ) - switch ln.method { - case MethodDbus: - systemID, err = ln.sendViaDbus(options, nil) - case MethodNotifySend: - systemID, err = ln.sendViaNotifySend(options) - default: - err = errors.New("no notification method is available") + if call.Err != nil { + return fmt.Errorf("failed to send notification: %w", call.Err) } - if err == nil && systemID > 0 { - // Store the system ID mapping - ln.activeNotifs[options.ID] = systemID - - // Create and store the notification context - ctx := ¬ificationContext{ - ID: options.ID, - SystemID: systemID, - UserData: options.Data, - } - ln.contexts[options.ID] = ctx + var notifID uint32 + if err := call.Store(¬ifID); err != nil { + return fmt.Errorf("failed to store notification ID: %w", err) } - return err + ln.activeNotifsLock.Lock() + ln.activeNotifs[notifID] = options.ID + + ln.notificationMeta[notifID] = map[string]interface{}{ + "id": options.ID, + "title": options.Title, + "subtitle": options.Subtitle, + "body": options.Body, + "data": options.Data, + } + ln.activeNotifsLock.Unlock() + + return nil } // SendNotificationWithActions sends a notification with additional actions. +// (Inputs are only supported on macOS and Windows) func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions) error { - if !ln.initialized { - return errors.New("notification service not initialized") - } - - if err := validateNotificationOptions(options); err != nil { - return err - } - ln.categoriesLock.RLock() category, exists := ln.categories[options.CategoryID] ln.categoriesLock.RUnlock() - if !exists { + if options.CategoryID == "" || !exists { + // Fall back to basic notification return ln.SendNotification(options) } - ln.Lock() - defer ln.Unlock() + // Use subtitle as part of the body if provided + body := options.Body + if options.Subtitle != "" { + body = options.Subtitle + "\n" + body + } - var ( - systemID uint32 - err error + var actions []string + for _, action := range category.Actions { + actions = append(actions, action.ID, action.Title) + } + + hints := map[string]dbus.Variant{} + + if options.Data != nil { + jsonData, err := json.Marshal(options.Data) + if err != nil { + return fmt.Errorf("failed to marshal notification data: %w", err) + } + hints["x-user-info"] = dbus.MakeVariant(string(jsonData)) + } + + hints["category"] = dbus.MakeVariant(options.CategoryID) + + metadataJSON, err := json.Marshal(map[string]interface{}{ + "id": options.ID, + "title": options.Title, + "subtitle": options.Subtitle, + "body": options.Body, + "categoryId": options.CategoryID, + "data": options.Data, + }) + if err != nil { + return fmt.Errorf("failed to marshal notification metadata: %w", err) + } + hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON)) + + timeout := int32(0) + + obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) + call := obj.Call( + dbusNotificationInterface+".Notify", + 0, + ln.appName, + uint32(0), + "", // Icon + options.Title, + body, + actions, + hints, + timeout, ) - switch ln.method { - case MethodDbus: - systemID, err = ln.sendViaDbus(options, &category) - case MethodNotifySend: - // notify-send doesn't support actions, fall back to basic notification - systemID, err = ln.sendViaNotifySend(options) - default: - err = errors.New("no notification method is available") - } - - if err == nil && systemID > 0 { - // Store the system ID mapping - ln.activeNotifs[options.ID] = systemID - - // Create and store the notification context with actions - ctx := ¬ificationContext{ - ID: options.ID, - SystemID: systemID, - UserData: options.Data, - Actions: make(map[string]string), - } - - // Store action mappings - if exists { - for _, action := range category.Actions { - ctx.Actions[action.ID] = action.Title - } - } - - ln.contexts[options.ID] = ctx - } - - return err -} - -// monitorDBusConnection creates a goroutine to monitor the D-Bus connection -// Returns a channel that will be closed if the connection is lost -func (ln *linuxNotifier) monitorDBusConnection(ctx context.Context) chan struct{} { - disconnected := make(chan struct{}) - - go func() { - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - - for { - select { - case <-ctx.Done(): - return // Parent context cancelled - case <-ln.monitorCtx.Done(): - return // Monitor specifically cancelled - case <-ticker.C: - ln.Lock() - connected := ln.dbusConn != nil && ln.dbusConn.Connected() - ln.Unlock() - - if !connected { - close(disconnected) - return - } - } - } - }() - - return disconnected -} - -// sendViaDbus sends a notification via dbus -func (ln *linuxNotifier) sendViaDbus(options NotificationOptions, category *NotificationCategory) (result uint32, err error) { - // Prepare actions - var actions []string - if category != nil { - for _, action := range category.Actions { - actions = append(actions, action.ID, action.Title) - } - } - - // Default timeout (-1 means use system default) - timeout := int32(-1) - - // Prepare hints - hints := map[string]dbus.Variant{ - // Normal urgency by default - "urgency": dbus.MakeVariant(byte(1)), - } - - // Add user data to hints if available - if options.Data != nil { - if userData, err := json.Marshal(options.Data); err == nil { - hints["x-wails-user-data"] = dbus.MakeVariant(string(userData)) - } - } - - // Send the notification - obj := ln.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) - dbusArgs := []interface{}{ - ln.appName, // App name - uint32(0), // Replaces ID (0 means new notification) - "", // App icon (empty for now) - options.Title, // Title - options.Body, // Body - actions, // Actions - hints, // Hints - timeout, // Timeout - } - - call := obj.Call("org.freedesktop.Notifications.Notify", 0, dbusArgs...) if call.Err != nil { - return 0, fmt.Errorf("dbus notification error: %v", call.Err) + return fmt.Errorf("failed to send notification: %w", call.Err) } - err = call.Store(&result) - if err != nil { - return 0, err + var notifID uint32 + if err := call.Store(¬ifID); err != nil { + return fmt.Errorf("failed to store notification ID: %w", err) } - return result, nil + ln.activeNotifsLock.Lock() + + ln.activeNotifs[notifID] = options.ID + + metadata := map[string]interface{}{ + "id": options.ID, + "title": options.Title, + "subtitle": options.Subtitle, + "body": options.Body, + "categoryId": options.CategoryID, + "data": options.Data, + } + + ln.notificationMeta[notifID] = metadata + ln.activeNotifsLock.Unlock() + + return nil } -// sendViaNotifySend sends a notification via notify-send command -func (ln *linuxNotifier) sendViaNotifySend(options NotificationOptions) (uint32, error) { - args := []string{ - options.Title, - options.Body, - "--urgency=normal", - } - - // Execute the command - cmd := exec.Command(ln.sendPath, args...) - err := cmd.Run() - if err != nil { - return 0, fmt.Errorf("notify-send error: %v", err) - } - - // notify-send doesn't return IDs, so we use 0 - return 0, nil -} - -// RegisterNotificationCategory registers a new NotificationCategory +// RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. +// Registering a category with the same name as a previously registered NotificationCategory will override it. func (ln *linuxNotifier) RegisterNotificationCategory(category NotificationCategory) error { ln.categoriesLock.Lock() - ln.categories[category.ID] = category - ln.categoriesLock.Unlock() + defer ln.categoriesLock.Unlock() - return ln.saveCategories() + ln.categories[category.ID] = category + + go ln.saveCategories() + + return nil } -// RemoveNotificationCategory removes a previously registered NotificationCategory +// RemoveNotificationCategory removes a previously registered NotificationCategory. func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error { ln.categoriesLock.Lock() + defer ln.categoriesLock.Unlock() + delete(ln.categories, categoryId) - ln.categoriesLock.Unlock() - return ln.saveCategories() + go ln.saveCategories() + + return nil } -// RemoveAllPendingNotifications is a Linux stub that always returns nil +// RemoveAllPendingNotifications is not directly supported in Linux D-Bus +// but we can try to remove all active notifications. func (ln *linuxNotifier) RemoveAllPendingNotifications() error { + ln.activeNotifsLock.RLock() + notifIDs := make([]uint32, 0, len(ln.activeNotifs)) + for id := range ln.activeNotifs { + notifIDs = append(notifIDs, id) + } + ln.activeNotifsLock.RUnlock() + + for _, id := range notifIDs { + ln.closeNotification(id) + } + return nil } -// RemovePendingNotification is a Linux stub that always returns nil -func (ln *linuxNotifier) RemovePendingNotification(_ string) error { - return nil +// RemovePendingNotification removes a pending notification. +func (ln *linuxNotifier) RemovePendingNotification(identifier string) error { + var notifID uint32 + found := false + + ln.activeNotifsLock.RLock() + for id, ident := range ln.activeNotifs { + if ident == identifier { + notifID = id + found = true + break + } + } + ln.activeNotifsLock.RUnlock() + + if !found { + return nil + } + + return ln.closeNotification(notifID) } -// RemoveAllDeliveredNotifications is a Linux stub that always returns nil +// RemoveAllDeliveredNotifications functionally equivalent to RemoveAllPendingNotification on Linux. func (ln *linuxNotifier) RemoveAllDeliveredNotifications() error { - return nil + return ln.RemoveAllPendingNotifications() } -// RemoveDeliveredNotification is a Linux stub that always returns nil -func (ln *linuxNotifier) RemoveDeliveredNotification(_ string) error { - return nil +// RemoveDeliveredNotification functionally equivalent RemovePendingNotification on Linux. +func (ln *linuxNotifier) RemoveDeliveredNotification(identifier string) error { + return ln.RemovePendingNotification(identifier) } -// RemoveNotification removes a notification by ID (Linux-specific) +// RemoveNotification removes a notification by identifier. func (ln *linuxNotifier) RemoveNotification(identifier string) error { - ln.Lock() - defer ln.Unlock() - - if !ln.initialized || ln.method != MethodDbus || ln.dbusConn == nil { - return errors.New("dbus not available for closing notifications") - } - - // Get the system ID for this notification - systemID, exists := ln.activeNotifs[identifier] - - if !exists { - return nil // Already closed or unknown - } - - // Call CloseNotification on dbus - obj := ln.dbusConn.Object(dbusNotificationsInterface, dbusObjectPath) - call := obj.Call(callCloseNotification, 0, systemID) - - return call.Err + return ln.RemovePendingNotification(identifier) } -// getConfigFilePath returns the path to the configuration file -func (ln *linuxNotifier) getConfigFilePath() (string, error) { +// Helper method to close a notification. +func (ln *linuxNotifier) closeNotification(id uint32) error { + obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) + call := obj.Call(dbusNotificationInterface+".CloseNotification", 0, id) + + if call.Err != nil { + return fmt.Errorf("failed to close notification: %w", call.Err) + } + + ln.activeNotifsLock.Lock() + delete(ln.activeNotifs, id) + delete(ln.notificationMeta, id) + ln.activeNotifsLock.Unlock() + + return nil +} + +// Get the config directory for the app. +func (ln *linuxNotifier) getConfigDir() (string, error) { configDir, err := os.UserConfigDir() if err != nil { - return "", fmt.Errorf("failed to get user config directory: %v", err) + return "", fmt.Errorf("failed to get user config directory: %w", err) } appConfigDir := filepath.Join(configDir, ln.appName) if err := os.MkdirAll(appConfigDir, 0755); err != nil { - return "", fmt.Errorf("failed to create config directory: %v", err) + return "", fmt.Errorf("failed to create app config directory: %w", err) } - return filepath.Join(appConfigDir, "notification-categories.json"), nil + return appConfigDir, nil } -// saveCategories saves the notification categories to a file +// Save notification categories. func (ln *linuxNotifier) saveCategories() error { - filePath, err := ln.getConfigFilePath() + configDir, err := ln.getConfigDir() if err != nil { return err } + categoriesFile := filepath.Join(configDir, "notification-categories.json") + ln.categoriesLock.RLock() - data, err := json.Marshal(ln.categories) + categoriesData, err := json.MarshalIndent(ln.categories, "", " ") ln.categoriesLock.RUnlock() if err != nil { - return fmt.Errorf("failed to marshal notification categories: %v", err) + return fmt.Errorf("failed to marshal notification categories: %w", err) } - if err := os.WriteFile(filePath, data, 0644); err != nil { - return fmt.Errorf("failed to write notification categories to file: %v", err) + if err := os.WriteFile(categoriesFile, categoriesData, 0644); err != nil { + return fmt.Errorf("failed to write notification categories to disk: %w", err) } return nil } -// loadCategories loads notification categories from a file +// Load notification categories. func (ln *linuxNotifier) loadCategories() error { - filePath, err := ln.getConfigFilePath() + configDir, err := ln.getConfigDir() if err != nil { return err } - if _, err := os.Stat(filePath); os.IsNotExist(err) { + categoriesFile := filepath.Join(configDir, "notification-categories.json") + + if _, err := os.Stat(categoriesFile); os.IsNotExist(err) { return nil } - data, err := os.ReadFile(filePath) + categoriesData, err := os.ReadFile(categoriesFile) if err != nil { - return fmt.Errorf("failed to read notification categories file: %v", err) - } - - if len(data) == 0 { - return nil + return fmt.Errorf("failed to read notification categories from disk: %w", err) } categories := make(map[string]NotificationCategory) - if err := json.Unmarshal(data, &categories); err != nil { - return fmt.Errorf("failed to unmarshal notification categories: %v", err) + if err := json.Unmarshal(categoriesData, &categories); err != nil { + return fmt.Errorf("failed to unmarshal notification categories: %w", err) } ln.categoriesLock.Lock() @@ -799,19 +424,177 @@ func (ln *linuxNotifier) loadCategories() error { return nil } -func (r closedReason) string() string { - switch r { - case 1: - return "expired" - case 2: - return "dismissed-by-user" - case 3: - return "closed-by-call" - case 4: - return "unknown" - case 5: - return "activated-by-user" - default: - return "other" +// Setup signal handling for notification actions. +func (ln *linuxNotifier) setupSignalHandling() error { + if err := ln.conn.AddMatchSignal( + dbus.WithMatchInterface(dbusNotificationInterface), + dbus.WithMatchMember("ActionInvoked"), + ); err != nil { + return err + } + + if err := ln.conn.AddMatchSignal( + dbus.WithMatchInterface(dbusNotificationInterface), + dbus.WithMatchMember("NotificationClosed"), + ); err != nil { + return err + } + + go ln.handleSignals() + + return nil +} + +// Handle incoming D-Bus signals. +func (ln *linuxNotifier) handleSignals() { + c := make(chan *dbus.Signal, 10) + ln.conn.Signal(c) + + for signal := range c { + switch signal.Name { + case dbusNotificationInterface + ".ActionInvoked": + ln.handleActionInvoked(signal) + case dbusNotificationInterface + ".NotificationClosed": + ln.handleNotificationClosed(signal) + } } } + +// Handle ActionInvoked signal. +func (ln *linuxNotifier) handleActionInvoked(signal *dbus.Signal) { + if len(signal.Body) < 2 { + return + } + + notifID, ok := signal.Body[0].(uint32) + if !ok { + return + } + + actionID, ok := signal.Body[1].(string) + if !ok { + return + } + + ln.activeNotifsLock.RLock() + identifier, idExists := ln.activeNotifs[notifID] + metadata, metaExists := ln.notificationMeta[notifID] + ln.activeNotifsLock.RUnlock() + + if !idExists || !metaExists { + return + } + + response := NotificationResponse{ + ID: identifier, + ActionIdentifier: actionID, + } + + if title, ok := metadata["title"].(string); ok { + response.Title = title + } + + if subtitle, ok := metadata["subtitle"].(string); ok { + response.Subtitle = subtitle + } + + if body, ok := metadata["body"].(string); ok { + response.Body = body + } + + if categoryID, ok := metadata["categoryId"].(string); ok { + response.CategoryID = categoryID + } + + if userData, ok := metadata["data"].(map[string]interface{}); ok { + response.UserInfo = userData + } + + if actionID == DefaultActionIdentifier { + response.ActionIdentifier = DefaultActionIdentifier + } + + result := NotificationResult{ + Response: response, + } + + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } + + ln.activeNotifsLock.Lock() + delete(ln.activeNotifs, notifID) + delete(ln.notificationMeta, notifID) + ln.activeNotifsLock.Unlock() +} + +// Handle NotificationClosed signal. +// The second parameter contains the close reason: +// 1 - expired timeout +// 2 - dismissed by user (click on X) +// 3 - closed by CloseNotification call +// 4 - undefined/reserved +func (ln *linuxNotifier) handleNotificationClosed(signal *dbus.Signal) { + if len(signal.Body) < 1 { + return + } + + notifID, ok := signal.Body[0].(uint32) + if !ok { + return + } + + var reason uint32 = 0 + if len(signal.Body) > 1 { + if r, ok := signal.Body[1].(uint32); ok { + reason = r + } + } + + if reason != 1 && reason != 3 { + ln.activeNotifsLock.RLock() + identifier, idExists := ln.activeNotifs[notifID] + metadata, metaExists := ln.notificationMeta[notifID] + ln.activeNotifsLock.RUnlock() + + if idExists && metaExists { + response := NotificationResponse{ + ID: identifier, + ActionIdentifier: DefaultActionIdentifier, + } + + if title, ok := metadata["title"].(string); ok { + response.Title = title + } + + if subtitle, ok := metadata["subtitle"].(string); ok { + response.Subtitle = subtitle + } + + if body, ok := metadata["body"].(string); ok { + response.Body = body + } + + if categoryID, ok := metadata["categoryId"].(string); ok { + response.CategoryID = categoryID + } + + if userData, ok := metadata["data"].(map[string]interface{}); ok { + response.UserInfo = userData + } + + result := NotificationResult{ + Response: response, + } + + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } + } + } + + ln.activeNotifsLock.Lock() + delete(ln.activeNotifs, notifID) + delete(ln.notificationMeta, notifID) + ln.activeNotifsLock.Unlock() +} diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index 30abd61b1..dde22ec30 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -141,7 +141,7 @@ func (wn *windowsNotifier) CheckNotificationAuthorization() (bool, error) { } // SendNotification sends a basic notification with a name, title, and body. All other options are ignored on Windows. -// (subtitle is only available on macOS) +// (subtitle is only available on macOS and Linux) func (wn *windowsNotifier) SendNotification(options NotificationOptions) error { if err := wn.saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) @@ -167,7 +167,7 @@ func (wn *windowsNotifier) SendNotification(options NotificationOptions) error { // SendNotificationWithActions sends a notification with additional actions and inputs. // A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. // If a NotificationCategory is not registered a basic notification will be sent. -// (subtitle is only available on macOS) +// (subtitle is only available on macOS and Linux) func (wn *windowsNotifier) SendNotificationWithActions(options NotificationOptions) error { if err := wn.saveIconToDir(); err != nil { fmt.Printf("Error saving icon: %v\n", err) From 5ddb27fd3fcb2895f924287c733d9cedea7e93c6 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 22 Mar 2025 23:07:44 -0700 Subject: [PATCH 100/136] move chan creation on macos and handle linux shutdown --- .../notifications/notifications_darwin.go | 13 ++-- .../notifications/notifications_linux.go | 61 ++++++++++++------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index e27d6f010..1a64cbb9e 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -112,8 +112,6 @@ func (dn *darwinNotifier) SendNotification(options NotificationOptions) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := dn.registerChannel() - cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) cSubtitle := C.CString(options.Subtitle) @@ -133,6 +131,7 @@ func (dn *darwinNotifier) SendNotification(options NotificationOptions) error { defer C.free(unsafe.Pointer(cDataJSON)) } + id, resultCh := dn.registerChannel() C.sendNotification(C.int(id), cIdentifier, cTitle, cSubtitle, cBody, cDataJSON) select { @@ -157,8 +156,6 @@ func (dn *darwinNotifier) SendNotificationWithActions(options NotificationOption ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := dn.registerChannel() - cIdentifier := C.CString(options.ID) cTitle := C.CString(options.Title) cSubtitle := C.CString(options.Subtitle) @@ -180,7 +177,9 @@ func (dn *darwinNotifier) SendNotificationWithActions(options NotificationOption defer C.free(unsafe.Pointer(cDataJSON)) } + id, resultCh := dn.registerChannel() C.sendNotificationWithActions(C.int(id), cIdentifier, cTitle, cSubtitle, cBody, cCategoryID, cDataJSON) + select { case result := <-resultCh: if !result.Success { @@ -202,8 +201,6 @@ func (dn *darwinNotifier) RegisterNotificationCategory(category NotificationCate ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := dn.registerChannel() - cCategoryID := C.CString(category.ID) defer C.free(unsafe.Pointer(cCategoryID)) @@ -222,6 +219,7 @@ func (dn *darwinNotifier) RegisterNotificationCategory(category NotificationCate defer C.free(unsafe.Pointer(cReplyButtonTitle)) } + id, resultCh := dn.registerChannel() C.registerNotificationCategory(C.int(id), cCategoryID, cActionsJSON, C.bool(category.HasReplyField), cReplyPlaceholder, cReplyButtonTitle) @@ -245,11 +243,10 @@ func (dn *darwinNotifier) RemoveNotificationCategory(categoryId string) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - id, resultCh := dn.registerChannel() - cCategoryID := C.CString(categoryId) defer C.free(unsafe.Pointer(cCategoryID)) + id, resultCh := dn.registerChannel() C.removeNotificationCategory(C.int(id), cCategoryID) select { diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 911bba8c4..6c0ed299e 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -22,6 +22,7 @@ type linuxNotifier struct { notificationMeta map[uint32]map[string]interface{} activeNotifsLock sync.RWMutex appName string + cancel context.CancelFunc } const ( @@ -63,7 +64,11 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic fmt.Printf("Failed to load notification categories: %v\n", err) } - if err := ln.setupSignalHandling(); err != nil { + var signalCtx context.Context + signalCtx, ln.cancel = context.WithCancel(context.Background()) + + // Set up signal handling for notification actions + if err := ln.setupSignalHandling(signalCtx); err != nil { return fmt.Errorf("failed to set up notification signal handling: %w", err) } @@ -72,15 +77,13 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic // Shutdown will save categories and close the D-Bus connection when the service unloads func (ln *linuxNotifier) Shutdown() error { + ln.cancel() + if err := ln.saveCategories(); err != nil { fmt.Printf("Failed to save notification categories: %v\n", err) } - if ln.conn != nil { - return ln.conn.Close() - } - - return nil + return ln.conn.Close() } // RequestNotificationAuthorization is a Linux stub that always returns true, nil. @@ -126,7 +129,7 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON)) actions := []string{} - timeout := int32(0) // Timeout in milliseconds (5 seconds) + timeout := int32(0) // Call the Notify method on the D-Bus interface obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) @@ -153,15 +156,18 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { } ln.activeNotifsLock.Lock() + ln.activeNotifs[notifID] = options.ID - ln.notificationMeta[notifID] = map[string]interface{}{ + metadata := map[string]interface{}{ "id": options.ID, "title": options.Title, "subtitle": options.Subtitle, "body": options.Body, "data": options.Data, } + + ln.notificationMeta[notifID] = metadata ln.activeNotifsLock.Unlock() return nil @@ -267,7 +273,9 @@ func (ln *linuxNotifier) RegisterNotificationCategory(category NotificationCateg ln.categories[category.ID] = category - go ln.saveCategories() + if err := ln.saveCategories(); err != nil { + fmt.Printf("Failed to save notification categories: %v\n", err) + } return nil } @@ -279,7 +287,9 @@ func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error { delete(ln.categories, categoryId) - go ln.saveCategories() + if err := ln.saveCategories(); err != nil { + fmt.Printf("Failed to save notification categories: %v\n", err) + } return nil } @@ -425,7 +435,7 @@ func (ln *linuxNotifier) loadCategories() error { } // Setup signal handling for notification actions. -func (ln *linuxNotifier) setupSignalHandling() error { +func (ln *linuxNotifier) setupSignalHandling(ctx context.Context) error { if err := ln.conn.AddMatchSignal( dbus.WithMatchInterface(dbusNotificationInterface), dbus.WithMatchMember("ActionInvoked"), @@ -440,22 +450,31 @@ func (ln *linuxNotifier) setupSignalHandling() error { return err } - go ln.handleSignals() + c := make(chan *dbus.Signal, 10) + ln.conn.Signal(c) + + go ln.handleSignals(ctx, c) return nil } // Handle incoming D-Bus signals. -func (ln *linuxNotifier) handleSignals() { - c := make(chan *dbus.Signal, 10) - ln.conn.Signal(c) +func (ln *linuxNotifier) handleSignals(ctx context.Context, c chan *dbus.Signal) { + for { + select { + case <-ctx.Done(): + return + case signal, ok := <-c: + if !ok { + return + } - for signal := range c { - switch signal.Name { - case dbusNotificationInterface + ".ActionInvoked": - ln.handleActionInvoked(signal) - case dbusNotificationInterface + ".NotificationClosed": - ln.handleNotificationClosed(signal) + switch signal.Name { + case dbusNotificationInterface + ".ActionInvoked": + ln.handleActionInvoked(signal) + case dbusNotificationInterface + ".NotificationClosed": + ln.handleNotificationClosed(signal) + } } } } From a68391880c81cf6f673934174cf198eb9bb9471e Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sun, 23 Mar 2025 00:05:20 -0700 Subject: [PATCH 101/136] remove deadlock --- v3/pkg/services/notifications/notifications_linux.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 6c0ed299e..cfc068c32 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -129,7 +129,6 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON)) actions := []string{} - timeout := int32(0) // Call the Notify method on the D-Bus interface obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) @@ -143,7 +142,7 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { body, actions, hints, - timeout, + uint32(0), ) if call.Err != nil { @@ -156,7 +155,6 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { } ln.activeNotifsLock.Lock() - ln.activeNotifs[notifID] = options.ID metadata := map[string]interface{}{ @@ -221,8 +219,6 @@ func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions } hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON)) - timeout := int32(0) - obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) call := obj.Call( dbusNotificationInterface+".Notify", @@ -234,7 +230,7 @@ func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions body, actions, hints, - timeout, + uint32(0), ) if call.Err != nil { @@ -481,7 +477,7 @@ func (ln *linuxNotifier) handleSignals(ctx context.Context, c chan *dbus.Signal) // Handle ActionInvoked signal. func (ln *linuxNotifier) handleActionInvoked(signal *dbus.Signal) { - if len(signal.Body) < 2 { + if len(signal.Body) < 1 { return } From 9a4542347dcc968e0ce0733dfff5c7042264ad27 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sun, 23 Mar 2025 23:40:03 -0700 Subject: [PATCH 102/136] follow dbus spec --- .../notifications/notifications_linux.go | 360 ++++++++---------- .../notifications/notifications_windows.go | 8 +- 2 files changed, 159 insertions(+), 209 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index cfc068c32..bdc8312ff 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -15,14 +15,24 @@ import ( ) type linuxNotifier struct { - conn *dbus.Conn - categories map[string]NotificationCategory - categoriesLock sync.RWMutex - activeNotifs map[uint32]string - notificationMeta map[uint32]map[string]interface{} - activeNotifsLock sync.RWMutex - appName string - cancel context.CancelFunc + conn *dbus.Conn + categories map[string]NotificationCategory + categoriesLock sync.RWMutex + notifications map[uint32]*notificationData + notificationsLock sync.RWMutex + appName string + cancel context.CancelFunc +} + +type notificationData struct { + ID string + Title string + Subtitle string + Body string + CategoryID string + Data map[string]interface{} + DBusID uint32 + ActionMap map[string]string } const ( @@ -34,9 +44,8 @@ const ( func New() *Service { notificationServiceOnce.Do(func() { impl := &linuxNotifier{ - categories: make(map[string]NotificationCategory), - activeNotifs: make(map[uint32]string), - notificationMeta: make(map[uint32]map[string]interface{}), + categories: make(map[string]NotificationCategory), + notifications: make(map[uint32]*notificationData), } NotificationService = &Service{ @@ -47,12 +56,9 @@ func New() *Service { return NotificationService } -// Startup is called when the service is loaded +// Startup is called when the service is loaded. func (ln *linuxNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { - app := application.Get() - if app != nil && app.Config().Name != "" { - ln.appName = app.Config().Name - } + ln.appName = application.Get().Config().Name conn, err := dbus.ConnectSessionBus() if err != nil { @@ -67,7 +73,6 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic var signalCtx context.Context signalCtx, ln.cancel = context.WithCancel(context.Background()) - // Set up signal handling for notification actions if err := ln.setupSignalHandling(signalCtx); err != nil { return fmt.Errorf("failed to set up notification signal handling: %w", err) } @@ -75,15 +80,20 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic return nil } -// Shutdown will save categories and close the D-Bus connection when the service unloads +// Shutdown will save categories and close the D-Bus connection when the service unloads. func (ln *linuxNotifier) Shutdown() error { - ln.cancel() + if ln.cancel != nil { + ln.cancel() + } if err := ln.saveCategories(); err != nil { fmt.Printf("Failed to save notification categories: %v\n", err) } - return ln.conn.Close() + if ln.conn != nil { + return ln.conn.Close() + } + return nil } // RequestNotificationAuthorization is a Linux stub that always returns true, nil. @@ -102,34 +112,27 @@ func (ln *linuxNotifier) CheckNotificationAuthorization() (bool, error) { func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { hints := map[string]dbus.Variant{} - // Use subtitle as part of the body if provided body := options.Body if options.Subtitle != "" { body = options.Subtitle + "\n" + body } + defaultActionID := "default" + actions := []string{defaultActionID, "Default"} + + actionMap := map[string]string{ + defaultActionID: DefaultActionIdentifier, + } + + hints["x-notification-id"] = dbus.MakeVariant(options.ID) + if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err != nil { - return fmt.Errorf("failed to marshal notification data: %w", err) + userData, err := json.Marshal(options.Data) + if err == nil { + hints["x-user-data"] = dbus.MakeVariant(string(userData)) } - hints["x-user-info"] = dbus.MakeVariant(string(jsonData)) } - metadataJSON, err := json.Marshal(map[string]interface{}{ - "id": options.ID, - "title": options.Title, - "subtitle": options.Subtitle, - "body": options.Body, - "data": options.Data, - }) - if err != nil { - return fmt.Errorf("failed to marshal notification metadata: %w", err) - } - hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON)) - - actions := []string{} - // Call the Notify method on the D-Bus interface obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) call := obj.Call( @@ -142,37 +145,36 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { body, actions, hints, - uint32(0), + int32(-1), ) if call.Err != nil { return fmt.Errorf("failed to send notification: %w", call.Err) } - var notifID uint32 - if err := call.Store(¬ifID); err != nil { + var dbusID uint32 + if err := call.Store(&dbusID); err != nil { return fmt.Errorf("failed to store notification ID: %w", err) } - ln.activeNotifsLock.Lock() - ln.activeNotifs[notifID] = options.ID - - metadata := map[string]interface{}{ - "id": options.ID, - "title": options.Title, - "subtitle": options.Subtitle, - "body": options.Body, - "data": options.Data, + notification := ¬ificationData{ + ID: options.ID, + Title: options.Title, + Subtitle: options.Subtitle, + Body: options.Body, + Data: options.Data, + DBusID: dbusID, + ActionMap: actionMap, } - ln.notificationMeta[notifID] = metadata - ln.activeNotifsLock.Unlock() + ln.notificationsLock.Lock() + ln.notifications[dbusID] = notification + ln.notificationsLock.Unlock() return nil } // SendNotificationWithActions sends a notification with additional actions. -// (Inputs are only supported on macOS and Windows) func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions) error { ln.categoriesLock.RLock() category, exists := ln.categories[options.CategoryID] @@ -183,42 +185,36 @@ func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions return ln.SendNotification(options) } - // Use subtitle as part of the body if provided body := options.Body if options.Subtitle != "" { body = options.Subtitle + "\n" + body } var actions []string + actionMap := make(map[string]string) + + defaultActionID := "default" + actions = append(actions, defaultActionID, "Default") + actionMap[defaultActionID] = DefaultActionIdentifier + for _, action := range category.Actions { actions = append(actions, action.ID, action.Title) + actionMap[action.ID] = action.ID } hints := map[string]dbus.Variant{} + hints["x-notification-id"] = dbus.MakeVariant(options.ID) + + hints["x-category-id"] = dbus.MakeVariant(options.CategoryID) + if options.Data != nil { - jsonData, err := json.Marshal(options.Data) - if err != nil { - return fmt.Errorf("failed to marshal notification data: %w", err) + userData, err := json.Marshal(options.Data) + if err == nil { + hints["x-user-data"] = dbus.MakeVariant(string(userData)) } - hints["x-user-info"] = dbus.MakeVariant(string(jsonData)) } - hints["category"] = dbus.MakeVariant(options.CategoryID) - - metadataJSON, err := json.Marshal(map[string]interface{}{ - "id": options.ID, - "title": options.Title, - "subtitle": options.Subtitle, - "body": options.Body, - "categoryId": options.CategoryID, - "data": options.Data, - }) - if err != nil { - return fmt.Errorf("failed to marshal notification metadata: %w", err) - } - hints["x-wails-metadata"] = dbus.MakeVariant(string(metadataJSON)) - obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) call := obj.Call( dbusNotificationInterface+".Notify", @@ -230,44 +226,41 @@ func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions body, actions, hints, - uint32(0), + int32(-1), ) if call.Err != nil { return fmt.Errorf("failed to send notification: %w", call.Err) } - var notifID uint32 - if err := call.Store(¬ifID); err != nil { + var dbusID uint32 + if err := call.Store(&dbusID); err != nil { return fmt.Errorf("failed to store notification ID: %w", err) } - ln.activeNotifsLock.Lock() - - ln.activeNotifs[notifID] = options.ID - - metadata := map[string]interface{}{ - "id": options.ID, - "title": options.Title, - "subtitle": options.Subtitle, - "body": options.Body, - "categoryId": options.CategoryID, - "data": options.Data, + notification := ¬ificationData{ + ID: options.ID, + Title: options.Title, + Subtitle: options.Subtitle, + Body: options.Body, + CategoryID: options.CategoryID, + Data: options.Data, + DBusID: dbusID, + ActionMap: actionMap, } - ln.notificationMeta[notifID] = metadata - ln.activeNotifsLock.Unlock() + ln.notificationsLock.Lock() + ln.notifications[dbusID] = notification + ln.notificationsLock.Unlock() return nil } // RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. -// Registering a category with the same name as a previously registered NotificationCategory will override it. func (ln *linuxNotifier) RegisterNotificationCategory(category NotificationCategory) error { ln.categoriesLock.Lock() - defer ln.categoriesLock.Unlock() - ln.categories[category.ID] = category + ln.categoriesLock.Unlock() if err := ln.saveCategories(); err != nil { fmt.Printf("Failed to save notification categories: %v\n", err) @@ -279,9 +272,8 @@ func (ln *linuxNotifier) RegisterNotificationCategory(category NotificationCateg // RemoveNotificationCategory removes a previously registered NotificationCategory. func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error { ln.categoriesLock.Lock() - defer ln.categoriesLock.Unlock() - delete(ln.categories, categoryId) + ln.categoriesLock.Unlock() if err := ln.saveCategories(); err != nil { fmt.Printf("Failed to save notification categories: %v\n", err) @@ -290,17 +282,16 @@ func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error { return nil } -// RemoveAllPendingNotifications is not directly supported in Linux D-Bus -// but we can try to remove all active notifications. +// RemoveAllPendingNotifications attempts to remove all active notifications. func (ln *linuxNotifier) RemoveAllPendingNotifications() error { - ln.activeNotifsLock.RLock() - notifIDs := make([]uint32, 0, len(ln.activeNotifs)) - for id := range ln.activeNotifs { - notifIDs = append(notifIDs, id) + ln.notificationsLock.Lock() + dbusIDs := make([]uint32, 0, len(ln.notifications)) + for id := range ln.notifications { + dbusIDs = append(dbusIDs, id) } - ln.activeNotifsLock.RUnlock() + ln.notificationsLock.Unlock() - for _, id := range notifIDs { + for _, id := range dbusIDs { ln.closeNotification(id) } @@ -309,24 +300,24 @@ func (ln *linuxNotifier) RemoveAllPendingNotifications() error { // RemovePendingNotification removes a pending notification. func (ln *linuxNotifier) RemovePendingNotification(identifier string) error { - var notifID uint32 + var dbusID uint32 found := false - ln.activeNotifsLock.RLock() - for id, ident := range ln.activeNotifs { - if ident == identifier { - notifID = id + ln.notificationsLock.Lock() + for id, notif := range ln.notifications { + if notif.ID == identifier { + dbusID = id found = true break } } - ln.activeNotifsLock.RUnlock() + ln.notificationsLock.Unlock() if !found { return nil } - return ln.closeNotification(notifID) + return ln.closeNotification(dbusID) } // RemoveAllDeliveredNotifications functionally equivalent to RemoveAllPendingNotification on Linux. @@ -353,15 +344,9 @@ func (ln *linuxNotifier) closeNotification(id uint32) error { return fmt.Errorf("failed to close notification: %w", call.Err) } - ln.activeNotifsLock.Lock() - delete(ln.activeNotifs, id) - delete(ln.notificationMeta, id) - ln.activeNotifsLock.Unlock() - return nil } -// Get the config directory for the app. func (ln *linuxNotifier) getConfigDir() (string, error) { configDir, err := os.UserConfigDir() if err != nil { @@ -477,11 +462,11 @@ func (ln *linuxNotifier) handleSignals(ctx context.Context, c chan *dbus.Signal) // Handle ActionInvoked signal. func (ln *linuxNotifier) handleActionInvoked(signal *dbus.Signal) { - if len(signal.Body) < 1 { + if len(signal.Body) < 2 { return } - notifID, ok := signal.Body[0].(uint32) + dbusID, ok := signal.Body[0].(uint32) if !ok { return } @@ -491,42 +476,30 @@ func (ln *linuxNotifier) handleActionInvoked(signal *dbus.Signal) { return } - ln.activeNotifsLock.RLock() - identifier, idExists := ln.activeNotifs[notifID] - metadata, metaExists := ln.notificationMeta[notifID] - ln.activeNotifsLock.RUnlock() + ln.notificationsLock.Lock() + notification, exists := ln.notifications[dbusID] + if exists { + delete(ln.notifications, dbusID) + } + ln.notificationsLock.Unlock() - if !idExists || !metaExists { + if !exists { return } + appActionID, ok := notification.ActionMap[actionID] + if !ok { + appActionID = actionID + } + response := NotificationResponse{ - ID: identifier, - ActionIdentifier: actionID, - } - - if title, ok := metadata["title"].(string); ok { - response.Title = title - } - - if subtitle, ok := metadata["subtitle"].(string); ok { - response.Subtitle = subtitle - } - - if body, ok := metadata["body"].(string); ok { - response.Body = body - } - - if categoryID, ok := metadata["categoryId"].(string); ok { - response.CategoryID = categoryID - } - - if userData, ok := metadata["data"].(map[string]interface{}); ok { - response.UserInfo = userData - } - - if actionID == DefaultActionIdentifier { - response.ActionIdentifier = DefaultActionIdentifier + ID: notification.ID, + ActionIdentifier: appActionID, + Title: notification.Title, + Subtitle: notification.Subtitle, + Body: notification.Body, + CategoryID: notification.CategoryID, + UserInfo: notification.Data, } result := NotificationResult{ @@ -536,80 +509,57 @@ func (ln *linuxNotifier) handleActionInvoked(signal *dbus.Signal) { if ns := getNotificationService(); ns != nil { ns.handleNotificationResult(result) } - - ln.activeNotifsLock.Lock() - delete(ln.activeNotifs, notifID) - delete(ln.notificationMeta, notifID) - ln.activeNotifsLock.Unlock() } // Handle NotificationClosed signal. -// The second parameter contains the close reason: +// Reason codes: // 1 - expired timeout // 2 - dismissed by user (click on X) // 3 - closed by CloseNotification call // 4 - undefined/reserved func (ln *linuxNotifier) handleNotificationClosed(signal *dbus.Signal) { - if len(signal.Body) < 1 { + if len(signal.Body) < 2 { return } - notifID, ok := signal.Body[0].(uint32) + dbusID, ok := signal.Body[0].(uint32) if !ok { return } - var reason uint32 = 0 - if len(signal.Body) > 1 { - if r, ok := signal.Body[1].(uint32); ok { - reason = r - } + reason, ok := signal.Body[1].(uint32) + if !ok { + reason = 0 // Unknown reason } - if reason != 1 && reason != 3 { - ln.activeNotifsLock.RLock() - identifier, idExists := ln.activeNotifs[notifID] - metadata, metaExists := ln.notificationMeta[notifID] - ln.activeNotifsLock.RUnlock() + ln.notificationsLock.Lock() + notification, exists := ln.notifications[dbusID] + if exists { + delete(ln.notifications, dbusID) + } + ln.notificationsLock.Unlock() - if idExists && metaExists { - response := NotificationResponse{ - ID: identifier, - ActionIdentifier: DefaultActionIdentifier, - } - - if title, ok := metadata["title"].(string); ok { - response.Title = title - } - - if subtitle, ok := metadata["subtitle"].(string); ok { - response.Subtitle = subtitle - } - - if body, ok := metadata["body"].(string); ok { - response.Body = body - } - - if categoryID, ok := metadata["categoryId"].(string); ok { - response.CategoryID = categoryID - } - - if userData, ok := metadata["data"].(map[string]interface{}); ok { - response.UserInfo = userData - } - - result := NotificationResult{ - Response: response, - } - - if ns := getNotificationService(); ns != nil { - ns.handleNotificationResult(result) - } - } + if !exists { + return } - ln.activeNotifsLock.Lock() - delete(ln.activeNotifs, notifID) - delete(ln.notificationMeta, notifID) - ln.activeNotifsLock.Unlock() + if reason == 2 { + response := NotificationResponse{ + ID: notification.ID, + ActionIdentifier: DefaultActionIdentifier, + Title: notification.Title, + Subtitle: notification.Subtitle, + Body: notification.Body, + CategoryID: notification.CategoryID, + UserInfo: notification.Data, + } + + result := NotificationResult{ + Response: response, + } + + if ns := getNotificationService(); ns != nil { + ns.handleNotificationResult(result) + } + } } diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index dde22ec30..d792d6949 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -254,25 +254,25 @@ func (wn *windowsNotifier) RemoveNotificationCategory(categoryId string) error { } // RemoveAllPendingNotifications is a Windows stub that always returns nil. -// (macOS-specific) +// (macOS and Linux only) func (wn *windowsNotifier) RemoveAllPendingNotifications() error { return nil } // RemovePendingNotification is a Windows stub that always returns nil. -// (macOS-specific) +// (macOS and Linux only) func (wn *windowsNotifier) RemovePendingNotification(_ string) error { return nil } // RemoveAllDeliveredNotifications is a Windows stub that always returns nil. -// (macOS-specific) +// (macOS and Linux only) func (wn *windowsNotifier) RemoveAllDeliveredNotifications() error { return nil } // RemoveDeliveredNotification is a Windows stub that always returns nil. -// (macOS-specific) +// (macOS and Linux only) func (wn *windowsNotifier) RemoveDeliveredNotification(_ string) error { return nil } From 7f496c971d9178dddb2863c9fbf805c6707f3b3f Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Mar 2025 00:16:45 -0700 Subject: [PATCH 103/136] fix linux note --- v3/pkg/services/notifications/notifications.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index d7549fbf9..1e36c7932 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -9,7 +9,7 @@ // Platform-specific notes: // - macOS: Requires a properly bundled and signed application // - Windows: Uses Windows Toast notifications -// - Linux: Falls back between D-Bus, notify-send, or other methods and does not support text inputs +// - Linux: Uses D-Bus and does not support text inputs package notifications import ( From 1f821667f2fff02f97abdd21caa65c76a416abfb Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Mar 2025 13:56:47 -0700 Subject: [PATCH 104/136] ensure cat id is set for macOS and other rabbit suggestions --- .../services/notifications/notifications.go | 39 ++++++++++--------- .../notifications/notifications_darwin.m | 2 + 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/v3/pkg/services/notifications/notifications.go b/v3/pkg/services/notifications/notifications.go index 1e36c7932..1a33d6d56 100644 --- a/v3/pkg/services/notifications/notifications.go +++ b/v3/pkg/services/notifications/notifications.go @@ -60,15 +60,15 @@ var ( notificationServiceLock sync.RWMutex ) -// NotificationAction represents an action button for a notification -type NotificationAction = struct { +// NotificationAction represents an action button for a notification. +type NotificationAction struct { ID string `json:"id,omitempty"` Title string `json:"title,omitempty"` Destructive bool `json:"destructive,omitempty"` // (macOS-specific) } -// NotificationCategory groups actions for notifications -type NotificationCategory = struct { +// NotificationCategory groups actions for notifications. +type NotificationCategory struct { ID string `json:"id,omitempty"` Actions []NotificationAction `json:"actions,omitempty"` HasReplyField bool `json:"hasReplyField,omitempty"` @@ -77,31 +77,32 @@ type NotificationCategory = struct { } // NotificationOptions contains configuration for a notification -type NotificationOptions = struct { - ID string `json:"id,omitempty"` - Title string `json:"title,omitempty"` - Subtitle string `json:"subtitle,omitempty"` // (macOS-specific) +type NotificationOptions struct { + ID string `json:"id"` + Title string `json:"title"` + Subtitle string `json:"subtitle,omitempty"` // (macOS and Linux only) Body string `json:"body,omitempty"` CategoryID string `json:"categoryId,omitempty"` Data map[string]interface{} `json:"data,omitempty"` } -var DefaultActionIdentifier = "DEFAULT_ACTION" +const DefaultActionIdentifier = "DEFAULT_ACTION" -// NotificationResponse represents a user's response to a notification -type NotificationResponse = struct { +// NotificationResponse represents the response sent by interacting with a notification. +type NotificationResponse struct { ID string `json:"id,omitempty"` ActionIdentifier string `json:"actionIdentifier,omitempty"` CategoryID string `json:"categoryIdentifier,omitempty"` Title string `json:"title,omitempty"` - Subtitle string `json:"subtitle,omitempty"` // (macOS-specific) + Subtitle string `json:"subtitle,omitempty"` // (macOS and Linux only) Body string `json:"body,omitempty"` UserText string `json:"userText,omitempty"` UserInfo map[string]interface{} `json:"userInfo,omitempty"` } -// NotificationResult -type NotificationResult = struct { +// NotificationResult represents the result of a notification response, +// returning the response or any errors that occurred. +type NotificationResult struct { Response NotificationResponse Error error } @@ -123,7 +124,7 @@ func (ns *Service) OnNotificationResponse(callback func(result NotificationResul } // handleNotificationResponse is an internal method to handle notification responses -// and invoke the registered callback if one exists +// and invoke the registered callback if one exists. func (ns *Service) handleNotificationResult(result NotificationResult) { ns.callbackLock.RLock() callback := ns.notificationResultCallback @@ -134,17 +135,17 @@ func (ns *Service) handleNotificationResult(result NotificationResult) { } } -// ServiceStartup is called when the service is loaded +// ServiceStartup is called when the service is loaded. func (ns *Service) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { return ns.impl.Startup(ctx, options) } -// ServiceShutdown is called when the service is unloaded +// ServiceShutdown is called when the service is unloaded. func (ns *Service) ServiceShutdown() error { return ns.impl.Shutdown() } -// Public methods that delegate to the implementation +// Public methods that delegate to the implementation. func (ns *Service) RequestNotificationAuthorization() (bool, error) { return ns.impl.RequestNotificationAuthorization() } @@ -201,7 +202,7 @@ func getNotificationService() *Service { return NotificationService } -// validateNotificationOptions validates an ID and Title are provided for notifications +// validateNotificationOptions validates an ID and Title are provided for notifications. func validateNotificationOptions(options NotificationOptions) error { if options.ID == "" { return fmt.Errorf("notification ID cannot be empty") diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index cd429c5d6..4ea4918ae 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -210,6 +210,8 @@ void sendNotificationWithActions(int channelID, const char *identifier, const ch captureResult(channelID, false, [errorMsg UTF8String]); return; } + + content.categoryIdentifier = nsCategoryId; UNTimeIntervalNotificationTrigger *trigger = nil; From b102279630d048b0a26aca0fd9282f2992dd282b Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Mar 2025 16:05:57 -0700 Subject: [PATCH 105/136] update example --- v3/examples/notifications/README.md | 59 ++ v3/examples/notifications/Taskfile.yml | 34 + v3/examples/notifications/build/Taskfile.yml | 86 ++ v3/examples/notifications/build/appicon.png | Bin 0 -> 132625 bytes v3/examples/notifications/build/config.yml | 62 ++ .../notifications/build/darwin/Info.dev.plist | 32 + .../notifications/build/darwin/Info.plist | 27 + .../notifications/build/darwin/Taskfile.yml | 80 ++ .../notifications/build/darwin/icons.icns | Bin 0 -> 356592 bytes .../notifications/build/linux/Taskfile.yml | 119 +++ .../build/linux/appimage/build.sh | 35 + .../notifications/build/linux/nfpm/nfpm.yaml | 50 + .../build/linux/nfpm/scripts/postinstall.sh | 1 + .../build/linux/nfpm/scripts/postremove.sh | 1 + .../build/linux/nfpm/scripts/preinstall.sh | 1 + .../build/linux/nfpm/scripts/preremove.sh | 1 + .../notifications/build/windows/Taskfile.yml | 63 ++ .../notifications/build/windows/icon.ico | Bin 0 -> 21677 bytes .../notifications/build/windows/info.json | 15 + .../build/windows/nsis/project.nsi | 112 +++ .../build/windows/nsis/wails_tools.nsh | 212 ++++ .../build/windows/wails.exe.manifest | 15 + .../v3/pkg/services/notifications/index.js | 25 - .../v3/pkg/services/notifications/index.ts | 13 + .../v3/pkg/services/notifications/models.js | 36 - .../v3/pkg/services/notifications/models.ts | 107 ++ .../v3/pkg/services/notifications/service.js | 131 --- .../v3/pkg/services/notifications/service.ts | 62 ++ v3/examples/notifications/frontend/index.html | 17 +- v3/examples/notifications/frontend/main.js | 67 -- .../notifications/frontend/package-lock.json | 935 ++++++++++++++++++ .../notifications/frontend/package.json | 5 +- .../frontend/public/javascript.svg | 1 - .../notifications/frontend/public/style.css | 67 +- .../frontend/public/typescript.svg | 1 + .../notifications/frontend/src/main.ts | 95 ++ .../notifications/frontend/src/vite-env.d.ts | 1 + .../notifications/frontend/tsconfig.json | 20 + v3/examples/notifications/go.mod | 53 + v3/examples/notifications/main.go | 128 ++- 40 files changed, 2406 insertions(+), 363 deletions(-) create mode 100644 v3/examples/notifications/README.md create mode 100644 v3/examples/notifications/Taskfile.yml create mode 100644 v3/examples/notifications/build/Taskfile.yml create mode 100644 v3/examples/notifications/build/appicon.png create mode 100644 v3/examples/notifications/build/config.yml create mode 100644 v3/examples/notifications/build/darwin/Info.dev.plist create mode 100644 v3/examples/notifications/build/darwin/Info.plist create mode 100644 v3/examples/notifications/build/darwin/Taskfile.yml create mode 100644 v3/examples/notifications/build/darwin/icons.icns create mode 100644 v3/examples/notifications/build/linux/Taskfile.yml create mode 100644 v3/examples/notifications/build/linux/appimage/build.sh create mode 100644 v3/examples/notifications/build/linux/nfpm/nfpm.yaml create mode 100644 v3/examples/notifications/build/linux/nfpm/scripts/postinstall.sh create mode 100644 v3/examples/notifications/build/linux/nfpm/scripts/postremove.sh create mode 100644 v3/examples/notifications/build/linux/nfpm/scripts/preinstall.sh create mode 100644 v3/examples/notifications/build/linux/nfpm/scripts/preremove.sh create mode 100644 v3/examples/notifications/build/windows/Taskfile.yml create mode 100644 v3/examples/notifications/build/windows/icon.ico create mode 100644 v3/examples/notifications/build/windows/info.json create mode 100644 v3/examples/notifications/build/windows/nsis/project.nsi create mode 100644 v3/examples/notifications/build/windows/nsis/wails_tools.nsh create mode 100644 v3/examples/notifications/build/windows/wails.exe.manifest delete mode 100644 v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js create mode 100644 v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.ts delete mode 100644 v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js create mode 100644 v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.ts delete mode 100644 v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js create mode 100644 v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.ts delete mode 100644 v3/examples/notifications/frontend/main.js create mode 100644 v3/examples/notifications/frontend/package-lock.json delete mode 100644 v3/examples/notifications/frontend/public/javascript.svg create mode 100644 v3/examples/notifications/frontend/public/typescript.svg create mode 100644 v3/examples/notifications/frontend/src/main.ts create mode 100644 v3/examples/notifications/frontend/src/vite-env.d.ts create mode 100644 v3/examples/notifications/frontend/tsconfig.json create mode 100644 v3/examples/notifications/go.mod diff --git a/v3/examples/notifications/README.md b/v3/examples/notifications/README.md new file mode 100644 index 000000000..ad12c3f40 --- /dev/null +++ b/v3/examples/notifications/README.md @@ -0,0 +1,59 @@ +# Welcome to Your New Wails3 Project! + +Congratulations on generating your Wails3 application! This README will guide you through the next steps to get your project up and running. + +## Getting Started + +1. Navigate to your project directory in the terminal. + +2. To run your application in development mode, use the following command: + + ``` + wails3 dev + ``` + + This will start your application and enable hot-reloading for both frontend and backend changes. + +3. To build your application for production, use: + + ``` + wails3 build + ``` + + This will create a production-ready executable in the `build` directory. + +## Exploring Wails3 Features + +Now that you have your project set up, it's time to explore the features that Wails3 offers: + +1. **Check out the examples**: The best way to learn is by example. Visit the `examples` directory in the `v3/examples` directory to see various sample applications. + +2. **Run an example**: To run any of the examples, navigate to the example's directory and use: + + ``` + go run . + ``` + + Note: Some examples may be under development during the alpha phase. + +3. **Explore the documentation**: Visit the [Wails3 documentation](https://v3.wails.io/) for in-depth guides and API references. + +4. **Join the community**: Have questions or want to share your progress? Join the [Wails Discord](https://discord.gg/JDdSxwjhGf) or visit the [Wails discussions on GitHub](https://github.com/wailsapp/wails/discussions). + +## Project Structure + +Take a moment to familiarize yourself with your project structure: + +- `frontend/`: Contains your frontend code (HTML, CSS, JavaScript/TypeScript) +- `main.go`: The entry point of your Go backend +- `app.go`: Define your application structure and methods here +- `wails.json`: Configuration file for your Wails project + +## Next Steps + +1. Modify the frontend in the `frontend/` directory to create your desired UI. +2. Add backend functionality in `main.go`. +3. Use `wails3 dev` to see your changes in real-time. +4. When ready, build your application with `wails3 build`. + +Happy coding with Wails3! If you encounter any issues or have questions, don't hesitate to consult the documentation or reach out to the Wails community. diff --git a/v3/examples/notifications/Taskfile.yml b/v3/examples/notifications/Taskfile.yml new file mode 100644 index 000000000..1455cd70c --- /dev/null +++ b/v3/examples/notifications/Taskfile.yml @@ -0,0 +1,34 @@ +version: '3' + +includes: + common: ./build/Taskfile.yml + windows: ./build/windows/Taskfile.yml + darwin: ./build/darwin/Taskfile.yml + linux: ./build/linux/Taskfile.yml + +vars: + APP_NAME: "Notifications\\ Demo" + BIN_DIR: "bin" + VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}' + +tasks: + build: + summary: Builds the application + cmds: + - task: "{{OS}}:build" + + package: + summary: Packages a production build of the application + cmds: + - task: "{{OS}}:package" + + run: + summary: Runs the application + cmds: + - task: "{{OS}}:run" + + dev: + summary: Runs the application in development mode + cmds: + - wails3 dev -config ./build/config.yml -port {{.VITE_PORT}} + diff --git a/v3/examples/notifications/build/Taskfile.yml b/v3/examples/notifications/build/Taskfile.yml new file mode 100644 index 000000000..5f3517efc --- /dev/null +++ b/v3/examples/notifications/build/Taskfile.yml @@ -0,0 +1,86 @@ +version: '3' + +tasks: + go:mod:tidy: + summary: Runs `go mod tidy` + internal: true + cmds: + - go mod tidy + + install:frontend:deps: + summary: Install frontend dependencies + dir: frontend + sources: + - package.json + - package-lock.json + generates: + - node_modules/* + preconditions: + - sh: npm version + msg: "Looks like npm isn't installed. Npm is part of the Node installer: https://nodejs.org/en/download/" + cmds: + - npm install + + build:frontend: + label: build:frontend (PRODUCTION={{.PRODUCTION}}) + summary: Build the frontend project + dir: frontend + sources: + - "**/*" + generates: + - dist/**/* + deps: + - task: install:frontend:deps + - task: generate:bindings + vars: + BUILD_FLAGS: + ref: .BUILD_FLAGS + cmds: + - npm run {{.BUILD_COMMAND}} -q + env: + PRODUCTION: '{{.PRODUCTION | default "false"}}' + vars: + BUILD_COMMAND: '{{if eq .PRODUCTION "true"}}build{{else}}build:dev{{end}}' + + + generate:bindings: + label: generate:bindings (BUILD_FLAGS={{.BUILD_FLAGS}}) + summary: Generates bindings for the frontend + deps: + - task: go:mod:tidy + sources: + - "**/*.[jt]s" + - exclude: frontend/**/* + - frontend/bindings/**/* # Rerun when switching between dev/production mode causes changes in output + - "**/*.go" + - go.mod + - go.sum + generates: + - frontend/bindings/**/* + cmds: + - wails3 generate bindings -f '{{.BUILD_FLAGS}}' -clean=true -ts + + generate:icons: + summary: Generates Windows `.ico` and Mac `.icns` files from an image + dir: build + sources: + - "appicon.png" + generates: + - "darwin/icons.icns" + - "windows/icon.ico" + cmds: + - wails3 generate icons -input appicon.png -macfilename darwin/icons.icns -windowsfilename windows/icon.ico + + dev:frontend: + summary: Runs the frontend in development mode + dir: frontend + deps: + - task: install:frontend:deps + cmds: + - npm run dev -- --port {{.VITE_PORT}} --strictPort + + update:build-assets: + summary: Updates the build assets + dir: build + cmds: + - wails3 update build-assets -name "{{.APP_NAME}}" -binaryname "{{.APP_NAME}}" -config config.yml -dir . diff --git a/v3/examples/notifications/build/appicon.png b/v3/examples/notifications/build/appicon.png new file mode 100644 index 0000000000000000000000000000000000000000..63617fe4f746b8a878bd5f44725f4f317b9d9850 GIT binary patch literal 132625 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 z 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 DB$9&s literal 0 HcmV?d00001 diff --git a/v3/examples/notifications/build/config.yml b/v3/examples/notifications/build/config.yml new file mode 100644 index 000000000..bc09a6d28 --- /dev/null +++ b/v3/examples/notifications/build/config.yml @@ -0,0 +1,62 @@ +# This file contains the configuration for this project. +# When you update `info` or `fileAssociations`, run `wails3 task common:update:build-assets` to update the assets. +# Note that this will overwrite any changes you have made to the assets. +version: '3' + +# This information is used to generate the build assets. +info: + companyName: "My Company" # The name of the company + productName: "My Product" # The name of the application + productIdentifier: "com.mycompany.myproduct" # The unique product identifier + description: "A program that does X" # The application description + copyright: "(c) 2025, My Company" # Copyright text + comments: "Some Product Comments" # Comments + version: "v0.0.1" # The application version + +# Dev mode configuration +dev_mode: + root_path: . + log_level: warn + debounce: 1000 + ignore: + dir: + - .git + - node_modules + - frontend + - bin + file: + - .DS_Store + - .gitignore + - .gitkeep + watched_extension: + - "*.go" + git_ignore: true + executes: + - cmd: wails3 task common:install:frontend:deps + type: once + - cmd: wails3 task common:dev:frontend + type: background + - cmd: go mod tidy + type: blocking + - cmd: wails3 task build + type: blocking + - cmd: wails3 task run + type: primary + +# File Associations +# More information at: https://v3.wails.io/noit/done/yet +fileAssociations: +# - ext: wails +# name: Wails +# description: Wails Application File +# iconName: wailsFileIcon +# role: Editor +# - ext: jpg +# name: JPEG +# description: Image File +# iconName: jpegFileIcon +# role: Editor + +# Other data +other: + - name: My Other Data \ No newline at end of file diff --git a/v3/examples/notifications/build/darwin/Info.dev.plist b/v3/examples/notifications/build/darwin/Info.dev.plist new file mode 100644 index 000000000..3a5b9735f --- /dev/null +++ b/v3/examples/notifications/build/darwin/Info.dev.plist @@ -0,0 +1,32 @@ + + + + CFBundlePackageType + APPL + CFBundleName + My Product + CFBundleExecutable + Notifications Demo + CFBundleIdentifier + com.wails.notifications-demo + CFBundleVersion + 0.1.0 + CFBundleGetInfoString + This is a comment + CFBundleShortVersionString + 0.1.0 + CFBundleIconFile + icons + LSMinimumSystemVersion + 10.15.0 + NSHighResolutionCapable + true + NSHumanReadableCopyright + © now, My Company + NSAppTransportSecurity + + NSAllowsLocalNetworking + + + + \ No newline at end of file diff --git a/v3/examples/notifications/build/darwin/Info.plist b/v3/examples/notifications/build/darwin/Info.plist new file mode 100644 index 000000000..464270019 --- /dev/null +++ b/v3/examples/notifications/build/darwin/Info.plist @@ -0,0 +1,27 @@ + + + + CFBundlePackageType + APPL + CFBundleName + My Product + CFBundleExecutable + Notifications Demo + CFBundleIdentifier + com.wails.notifications-demo + CFBundleVersion + 0.1.0 + CFBundleGetInfoString + This is a comment + CFBundleShortVersionString + 0.1.0 + CFBundleIconFile + icons + LSMinimumSystemVersion + 10.15.0 + NSHighResolutionCapable + true + NSHumanReadableCopyright + © now, My Company + + \ No newline at end of file diff --git a/v3/examples/notifications/build/darwin/Taskfile.yml b/v3/examples/notifications/build/darwin/Taskfile.yml new file mode 100644 index 000000000..3b6a9dc99 --- /dev/null +++ b/v3/examples/notifications/build/darwin/Taskfile.yml @@ -0,0 +1,80 @@ +version: '3' + +includes: + common: ../Taskfile.yml + +tasks: + build: + summary: Creates a production build of the application + deps: + - task: common:go:mod:tidy + - task: common:build:frontend + vars: + BUILD_FLAGS: + ref: .BUILD_FLAGS + PRODUCTION: + ref: .PRODUCTION + - task: common:generate:icons + cmds: + - go build {{.BUILD_FLAGS}} -o {{.OUTPUT}} + vars: + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}' + DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}' + OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}' + env: + GOOS: darwin + CGO_ENABLED: 1 + GOARCH: '{{.ARCH | default ARCH}}' + CGO_CFLAGS: "-mmacosx-version-min=10.15" + CGO_LDFLAGS: "-mmacosx-version-min=10.15" + MACOSX_DEPLOYMENT_TARGET: "10.15" + PRODUCTION: '{{.PRODUCTION | default "false"}}' + + build:universal: + summary: Builds darwin universal binary (arm64 + amd64) + deps: + - task: build + vars: + ARCH: amd64 + OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" + - task: build + vars: + ARCH: arm64 + OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" + cmds: + - lipo -create -output "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" + - rm "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" + + package: + summary: Packages a production build of the application into a `.app` bundle + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + - task: create:app:bundle + + package:universal: + summary: Packages darwin universal binary (arm64 + amd64) + deps: + - task: build:universal + cmds: + - task: create:app:bundle + + + create:app:bundle: + summary: Creates an `.app` bundle + cmds: + - mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/{MacOS,Resources} + - cp build/darwin/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources + - cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS + - cp build/darwin/Info.plist {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents + + run: + cmds: + - mkdir -p {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/{MacOS,Resources} + - cp build/darwin/icons.icns {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/Resources + - cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/MacOS + - cp build/darwin/Info.dev.plist {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/Info.plist + - codesign --force --deep --sign - {{.BIN_DIR}}/dev/{{.APP_NAME}}.app + - '{{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/MacOS/{{.APP_NAME}}' diff --git a/v3/examples/notifications/build/darwin/icons.icns b/v3/examples/notifications/build/darwin/icons.icns new file mode 100644 index 0000000000000000000000000000000000000000..1b5bd4c86c4533471d6044c5edc0c8c86b87e612 GIT binary patch literal 356592 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

^Lg7K@^M66wF^U#m6$MQA`NxZ%~uf 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 KmPKi1yf9{GFYLn7< +description: "My Product Description" +vendor: "My Company" +homepage: "https://wails.io" +license: "MIT" +release: "1" + +contents: + - src: "./bin/notifications" + dst: "/usr/local/bin/notifications" + - src: "./build/appicon.png" + dst: "/usr/share/icons/hicolor/128x128/apps/notifications.png" + - src: "./build/linux/notifications.desktop" + dst: "/usr/share/applications/notifications.desktop" + +depends: + - gtk3 + - libwebkit2gtk + +# replaces: +# - foobar +# provides: +# - bar +# depends: +# - gtk3 +# - libwebkit2gtk +# recommends: +# - whatever +# suggests: +# - something-else +# conflicts: +# - not-foo +# - not-bar +# changelog: "changelog.yaml" +# scripts: +# preinstall: ./build/linux/nfpm/scripts/preinstall.sh +# postinstall: ./build/linux/nfpm/scripts/postinstall.sh +# preremove: ./build/linux/nfpm/scripts/preremove.sh +# postremove: ./build/linux/nfpm/scripts/postremove.sh diff --git a/v3/examples/notifications/build/linux/nfpm/scripts/postinstall.sh b/v3/examples/notifications/build/linux/nfpm/scripts/postinstall.sh new file mode 100644 index 000000000..a9bf588e2 --- /dev/null +++ b/v3/examples/notifications/build/linux/nfpm/scripts/postinstall.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/examples/notifications/build/linux/nfpm/scripts/postremove.sh b/v3/examples/notifications/build/linux/nfpm/scripts/postremove.sh new file mode 100644 index 000000000..a9bf588e2 --- /dev/null +++ b/v3/examples/notifications/build/linux/nfpm/scripts/postremove.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/examples/notifications/build/linux/nfpm/scripts/preinstall.sh b/v3/examples/notifications/build/linux/nfpm/scripts/preinstall.sh new file mode 100644 index 000000000..a9bf588e2 --- /dev/null +++ b/v3/examples/notifications/build/linux/nfpm/scripts/preinstall.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/examples/notifications/build/linux/nfpm/scripts/preremove.sh b/v3/examples/notifications/build/linux/nfpm/scripts/preremove.sh new file mode 100644 index 000000000..a9bf588e2 --- /dev/null +++ b/v3/examples/notifications/build/linux/nfpm/scripts/preremove.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/examples/notifications/build/windows/Taskfile.yml b/v3/examples/notifications/build/windows/Taskfile.yml new file mode 100644 index 000000000..534f4fb31 --- /dev/null +++ b/v3/examples/notifications/build/windows/Taskfile.yml @@ -0,0 +1,63 @@ +version: '3' + +includes: + common: ../Taskfile.yml + +tasks: + build: + summary: Builds the application for Windows + deps: + - task: common:go:mod:tidy + - task: common:build:frontend + vars: + BUILD_FLAGS: + ref: .BUILD_FLAGS + PRODUCTION: + ref: .PRODUCTION + - task: common:generate:icons + cmds: + - task: generate:syso + - go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}.exe + - cmd: powershell Remove-item *.syso + platforms: [windows] + - cmd: rm -f *.syso + platforms: [linux, darwin] + vars: + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s -H windowsgui"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}' + env: + GOOS: windows + CGO_ENABLED: 0 + GOARCH: '{{.ARCH | default ARCH}}' + PRODUCTION: '{{.PRODUCTION | default "false"}}' + + package: + summary: Packages a production build of the application into a `.exe` bundle + cmds: + - task: create:nsis:installer + + generate:syso: + summary: Generates Windows `.syso` file + dir: build + cmds: + - wails3 generate syso -arch {{.ARCH}} -icon windows/icon.ico -manifest windows/wails.exe.manifest -info windows/info.json -out ../wails_windows_{{.ARCH}}.syso + vars: + ARCH: '{{.ARCH | default ARCH}}' + + create:nsis:installer: + summary: Creates an NSIS installer + dir: build/windows/nsis + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + # Create the Microsoft WebView2 bootstrapper if it doesn't exist + - wails3 generate webview2bootstrapper -dir "{{.ROOT_DIR}}/build/windows/nsis" + - makensis -DARG_WAILS_{{.ARG_FLAG}}_BINARY="{{.ROOT_DIR}}/{{.BIN_DIR}}/{{.APP_NAME}}.exe" project.nsi + vars: + ARCH: '{{.ARCH | default ARCH}}' + ARG_FLAG: '{{if eq .ARCH "amd64"}}AMD64{{else}}ARM64{{end}}' + + run: + cmds: + - '{{.BIN_DIR}}/{{.APP_NAME}}.exe' diff --git a/v3/examples/notifications/build/windows/icon.ico b/v3/examples/notifications/build/windows/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bfa0690b7f8aea8d793026b51f9fc4eed2e00af7 GIT binary patch literal 21677 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 ou5=8}@A^#05^yFjv{|%CV0m?W0y8r+H literal 0 HcmV?d00001 diff --git a/v3/examples/notifications/build/windows/info.json b/v3/examples/notifications/build/windows/info.json new file mode 100644 index 000000000..850b2b5b0 --- /dev/null +++ b/v3/examples/notifications/build/windows/info.json @@ -0,0 +1,15 @@ +{ + "fixed": { + "file_version": "0.1.0" + }, + "info": { + "0000": { + "ProductVersion": "0.1.0", + "CompanyName": "My Company", + "FileDescription": "My Product Description", + "LegalCopyright": "© now, My Company", + "ProductName": "My Product", + "Comments": "This is a comment" + } + } +} \ No newline at end of file diff --git a/v3/examples/notifications/build/windows/nsis/project.nsi b/v3/examples/notifications/build/windows/nsis/project.nsi new file mode 100644 index 000000000..4cb18e04f --- /dev/null +++ b/v3/examples/notifications/build/windows/nsis/project.nsi @@ -0,0 +1,112 @@ +Unicode true + +#### +## Please note: Template replacements don't work in this file. They are provided with default defines like +## mentioned underneath. +## If the keyword is not defined, "wails_tools.nsh" will populate them. +## If they are defined here, "wails_tools.nsh" will not touch them. This allows you to use this project.nsi manually +## from outside of Wails for debugging and development of the installer. +## +## For development first make a wails nsis build to populate the "wails_tools.nsh": +## > wails build --target windows/amd64 --nsis +## Then you can call makensis on this file with specifying the path to your binary: +## For a AMD64 only installer: +## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app.exe +## For a ARM64 only installer: +## > makensis -DARG_WAILS_ARM64_BINARY=..\..\bin\app.exe +## For a installer with both architectures: +## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app-amd64.exe -DARG_WAILS_ARM64_BINARY=..\..\bin\app-arm64.exe +#### +## The following information is taken from the wails_tools.nsh file, but they can be overwritten here. +#### +## !define INFO_PROJECTNAME "my-project" # Default "notifications" +## !define INFO_COMPANYNAME "My Company" # Default "My Company" +## !define INFO_PRODUCTNAME "My Product Name" # Default "My Product" +## !define INFO_PRODUCTVERSION "1.0.0" # Default "0.1.0" +## !define INFO_COPYRIGHT "(c) Now, My Company" # Default "© now, My Company" +### +## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe" +## !define UNINST_KEY_NAME "UninstKeyInRegistry" # Default "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" +#### +## !define REQUEST_EXECUTION_LEVEL "admin" # Default "admin" see also https://nsis.sourceforge.io/Docs/Chapter4.html +#### +## Include the wails tools +#### +!include "wails_tools.nsh" + +# The version information for this two must consist of 4 parts +VIProductVersion "${INFO_PRODUCTVERSION}.0" +VIFileVersion "${INFO_PRODUCTVERSION}.0" + +VIAddVersionKey "CompanyName" "${INFO_COMPANYNAME}" +VIAddVersionKey "FileDescription" "${INFO_PRODUCTNAME} Installer" +VIAddVersionKey "ProductVersion" "${INFO_PRODUCTVERSION}" +VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}" +VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}" +VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}" + +# Enable HiDPI support. https://nsis.sourceforge.io/Reference/ManifestDPIAware +ManifestDPIAware true + +!include "MUI.nsh" + +!define MUI_ICON "..\icon.ico" +!define MUI_UNICON "..\icon.ico" +# !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\leftimage.bmp" #Include this to add a bitmap on the left side of the Welcome Page. Must be a size of 164x314 +!define MUI_FINISHPAGE_NOAUTOCLOSE # Wait on the INSTFILES page so the user can take a look into the details of the installation steps +!define MUI_ABORTWARNING # This will warn the user if they exit from the installer. + +!insertmacro MUI_PAGE_WELCOME # Welcome to the installer page. +# !insertmacro MUI_PAGE_LICENSE "resources\eula.txt" # Adds a EULA page to the installer +!insertmacro MUI_PAGE_DIRECTORY # In which folder install page. +!insertmacro MUI_PAGE_INSTFILES # Installing page. +!insertmacro MUI_PAGE_FINISH # Finished installation page. + +!insertmacro MUI_UNPAGE_INSTFILES # Uninstalling page + +!insertmacro MUI_LANGUAGE "English" # Set the Language of the installer + +## The following two statements can be used to sign the installer and the uninstaller. The path to the binaries are provided in %1 +#!uninstfinalize 'signtool --file "%1"' +#!finalize 'signtool --file "%1"' + +Name "${INFO_PRODUCTNAME}" +OutFile "..\..\..\bin\${INFO_PROJECTNAME}-${ARCH}-installer.exe" # Name of the installer's file. +InstallDir "$PROGRAMFILES64\${INFO_COMPANYNAME}\${INFO_PRODUCTNAME}" # Default installing folder ($PROGRAMFILES is Program Files folder). +ShowInstDetails show # This will always show the installation details. + +Function .onInit + !insertmacro wails.checkArchitecture +FunctionEnd + +Section + !insertmacro wails.setShellContext + + !insertmacro wails.webview2runtime + + SetOutPath $INSTDIR + + !insertmacro wails.files + + CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + + !insertmacro wails.associateFiles + + !insertmacro wails.writeUninstaller +SectionEnd + +Section "uninstall" + !insertmacro wails.setShellContext + + RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath + + RMDir /r $INSTDIR + + Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" + Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk" + + !insertmacro wails.unassociateFiles + + !insertmacro wails.deleteUninstaller +SectionEnd diff --git a/v3/examples/notifications/build/windows/nsis/wails_tools.nsh b/v3/examples/notifications/build/windows/nsis/wails_tools.nsh new file mode 100644 index 000000000..ee4c8ca1a --- /dev/null +++ b/v3/examples/notifications/build/windows/nsis/wails_tools.nsh @@ -0,0 +1,212 @@ +# DO NOT EDIT - Generated automatically by `wails build` + +!include "x64.nsh" +!include "WinVer.nsh" +!include "FileFunc.nsh" + +!ifndef INFO_PROJECTNAME + !define INFO_PROJECTNAME "notifications" +!endif +!ifndef INFO_COMPANYNAME + !define INFO_COMPANYNAME "My Company" +!endif +!ifndef INFO_PRODUCTNAME + !define INFO_PRODUCTNAME "My Product" +!endif +!ifndef INFO_PRODUCTVERSION + !define INFO_PRODUCTVERSION "0.1.0" +!endif +!ifndef INFO_COPYRIGHT + !define INFO_COPYRIGHT "© now, My Company" +!endif +!ifndef PRODUCT_EXECUTABLE + !define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe" +!endif +!ifndef UNINST_KEY_NAME + !define UNINST_KEY_NAME "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" +!endif +!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}" + +!ifndef REQUEST_EXECUTION_LEVEL + !define REQUEST_EXECUTION_LEVEL "admin" +!endif + +RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}" + +!ifdef ARG_WAILS_AMD64_BINARY + !define SUPPORTS_AMD64 +!endif + +!ifdef ARG_WAILS_ARM64_BINARY + !define SUPPORTS_ARM64 +!endif + +!ifdef SUPPORTS_AMD64 + !ifdef SUPPORTS_ARM64 + !define ARCH "amd64_arm64" + !else + !define ARCH "amd64" + !endif +!else + !ifdef SUPPORTS_ARM64 + !define ARCH "arm64" + !else + !error "Wails: Undefined ARCH, please provide at least one of ARG_WAILS_AMD64_BINARY or ARG_WAILS_ARM64_BINARY" + !endif +!endif + +!macro wails.checkArchitecture + !ifndef WAILS_WIN10_REQUIRED + !define WAILS_WIN10_REQUIRED "This product is only supported on Windows 10 (Server 2016) and later." + !endif + + !ifndef WAILS_ARCHITECTURE_NOT_SUPPORTED + !define WAILS_ARCHITECTURE_NOT_SUPPORTED "This product can't be installed on the current Windows architecture. Supports: ${ARCH}" + !endif + + ${If} ${AtLeastWin10} + !ifdef SUPPORTS_AMD64 + ${if} ${IsNativeAMD64} + Goto ok + ${EndIf} + !endif + + !ifdef SUPPORTS_ARM64 + ${if} ${IsNativeARM64} + Goto ok + ${EndIf} + !endif + + IfSilent silentArch notSilentArch + silentArch: + SetErrorLevel 65 + Abort + notSilentArch: + MessageBox MB_OK "${WAILS_ARCHITECTURE_NOT_SUPPORTED}" + Quit + ${else} + IfSilent silentWin notSilentWin + silentWin: + SetErrorLevel 64 + Abort + notSilentWin: + MessageBox MB_OK "${WAILS_WIN10_REQUIRED}" + Quit + ${EndIf} + + ok: +!macroend + +!macro wails.files + !ifdef SUPPORTS_AMD64 + ${if} ${IsNativeAMD64} + File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}" + ${EndIf} + !endif + + !ifdef SUPPORTS_ARM64 + ${if} ${IsNativeARM64} + File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_ARM64_BINARY}" + ${EndIf} + !endif +!macroend + +!macro wails.writeUninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + + SetRegView 64 + WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}" + WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + IntFmt $0 "0x%08X" $0 + WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0" +!macroend + +!macro wails.deleteUninstaller + Delete "$INSTDIR\uninstall.exe" + + SetRegView 64 + DeleteRegKey HKLM "${UNINST_KEY}" +!macroend + +!macro wails.setShellContext + ${If} ${REQUEST_EXECUTION_LEVEL} == "admin" + SetShellVarContext all + ${else} + SetShellVarContext current + ${EndIf} +!macroend + +# Install webview2 by launching the bootstrapper +# See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment +!macro wails.webview2runtime + !ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT + !define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime" + !endif + + SetRegView 64 + # If the admin key exists and is not empty then webview2 is already installed + ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${If} $0 != "" + Goto ok + ${EndIf} + + ${If} ${REQUEST_EXECUTION_LEVEL} == "user" + # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed + ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${If} $0 != "" + Goto ok + ${EndIf} + ${EndIf} + + SetDetailsPrint both + DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}" + SetDetailsPrint listonly + + InitPluginsDir + CreateDirectory "$pluginsdir\webview2bootstrapper" + SetOutPath "$pluginsdir\webview2bootstrapper" + File "MicrosoftEdgeWebview2Setup.exe" + ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' + + SetDetailsPrint both + ok: +!macroend + +# Copy of APP_ASSOCIATE and APP_UNASSOCIATE macros from here https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b +!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND + ; Backup the previously associated file class + ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" "" + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0" + + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}" + + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open" + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}` +!macroend + +!macro APP_UNASSOCIATE EXT FILECLASS + ; Backup the previously associated file class + ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup` + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0" + + DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}` +!macroend + +!macro wails.associateFiles + ; Create file associations + +!macroend + +!macro wails.unassociateFiles + ; Delete app associations + +!macroend \ No newline at end of file diff --git a/v3/examples/notifications/build/windows/wails.exe.manifest b/v3/examples/notifications/build/windows/wails.exe.manifest new file mode 100644 index 000000000..0299e62ca --- /dev/null +++ b/v3/examples/notifications/build/windows/wails.exe.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + true/pm + permonitorv2,permonitor + + + \ No newline at end of file diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js deleted file mode 100644 index eb8893845..000000000 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.js +++ /dev/null @@ -1,25 +0,0 @@ -// @ts-check -// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL -// This file is automatically generated. DO NOT EDIT - -import * as Service from "./service.js"; -export { - Service -}; - -import * as $models from "./models.js"; - -/** - * NotificationAction represents an action button for a notification - * @typedef {$models.NotificationAction} NotificationAction - */ - -/** - * NotificationCategory groups actions for notifications - * @typedef {$models.NotificationCategory} NotificationCategory - */ - -/** - * NotificationOptions contains configuration for a notification - * @typedef {$models.NotificationOptions} NotificationOptions - */ diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.ts b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.ts new file mode 100644 index 000000000..bbdce6579 --- /dev/null +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.ts @@ -0,0 +1,13 @@ +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +import * as Service from "./service.js"; +export { + Service +}; + +export { + NotificationAction, + NotificationCategory, + NotificationOptions +} from "./models.js"; diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js deleted file mode 100644 index 1b53de966..000000000 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.js +++ /dev/null @@ -1,36 +0,0 @@ -// @ts-check -// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL -// This file is automatically generated. DO NOT EDIT - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore: Unused imports -import {Create as $Create} from "@wailsio/runtime"; - -/** - * NotificationAction represents an action button for a notification - * @typedef {Object} NotificationAction - * @property {string} [id] - * @property {string} [title] - * @property {boolean} [destructive] - (macOS-specific) - */ - -/** - * NotificationCategory groups actions for notifications - * @typedef {Object} NotificationCategory - * @property {string} [id] - * @property {NotificationAction[]} [actions] - * @property {boolean} [hasReplyField] - * @property {string} [replyPlaceholder] - * @property {string} [replyButtonTitle] - */ - -/** - * NotificationOptions contains configuration for a notification - * @typedef {Object} NotificationOptions - * @property {string} [id] - * @property {string} [title] - * @property {string} [subtitle] - (macOS-specific) - * @property {string} [body] - * @property {string} [categoryId] - * @property {{ [_: string]: any }} [data] - */ diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.ts b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.ts new file mode 100644 index 000000000..d7f48edfe --- /dev/null +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.ts @@ -0,0 +1,107 @@ +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: Unused imports +import { Create as $Create } from "@wailsio/runtime"; + +/** + * NotificationAction represents an action button for a notification. + */ +export class NotificationAction { + "id"?: string; + "title"?: string; + + /** + * (macOS-specific) + */ + "destructive"?: boolean; + + /** Creates a new NotificationAction instance. */ + constructor($$source: Partial = {}) { + + Object.assign(this, $$source); + } + + /** + * Creates a new NotificationAction instance from a string or object. + */ + static createFrom($$source: any = {}): NotificationAction { + let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; + return new NotificationAction($$parsedSource as Partial); + } +} + +/** + * NotificationCategory groups actions for notifications. + */ +export class NotificationCategory { + "id"?: string; + "actions"?: NotificationAction[]; + "hasReplyField"?: boolean; + "replyPlaceholder"?: string; + "replyButtonTitle"?: string; + + /** Creates a new NotificationCategory instance. */ + constructor($$source: Partial = {}) { + + Object.assign(this, $$source); + } + + /** + * Creates a new NotificationCategory instance from a string or object. + */ + static createFrom($$source: any = {}): NotificationCategory { + const $$createField1_0 = $$createType1; + let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; + if ("actions" in $$parsedSource) { + $$parsedSource["actions"] = $$createField1_0($$parsedSource["actions"]); + } + return new NotificationCategory($$parsedSource as Partial); + } +} + +/** + * NotificationOptions contains configuration for a notification + */ +export class NotificationOptions { + "id": string; + "title": string; + + /** + * (macOS and Linux only) + */ + "subtitle"?: string; + "body"?: string; + "categoryId"?: string; + "data"?: { [_: string]: any }; + + /** Creates a new NotificationOptions instance. */ + constructor($$source: Partial = {}) { + if (!("id" in $$source)) { + this["id"] = ""; + } + if (!("title" in $$source)) { + this["title"] = ""; + } + + Object.assign(this, $$source); + } + + /** + * Creates a new NotificationOptions instance from a string or object. + */ + static createFrom($$source: any = {}): NotificationOptions { + const $$createField5_0 = $$createType2; + let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; + if ("data" in $$parsedSource) { + $$parsedSource["data"] = $$createField5_0($$parsedSource["data"]); + } + return new NotificationOptions($$parsedSource as Partial); + } +} + +// Private type creation functions +const $$createType0 = NotificationAction.createFrom; +const $$createType1 = $Create.Array($$createType0); +const $$createType2 = $Create.Map($Create.Any, $Create.Any); diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js deleted file mode 100644 index 40c55b4a9..000000000 --- a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.js +++ /dev/null @@ -1,131 +0,0 @@ -// @ts-check -// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL -// This file is automatically generated. DO NOT EDIT - -/** - * Service represents the notifications service - * @module - */ - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore: Unused imports -import {Call as $Call, Create as $Create} from "@wailsio/runtime"; - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore: Unused imports -import * as $models from "./models.js"; - -/** - * CheckNotificationAuthorization checks current notification permission status. - * @returns {Promise & { cancel(): void }} - */ -export function CheckNotificationAuthorization() { - let $resultPromise = /** @type {any} */($Call.ByID(2789931702)); - return $resultPromise; -} - -/** - * RegisterNotificationCategory registers a new NotificationCategory to be used with SendNotificationWithActions. - * Registering a category with the same name as a previously registered NotificationCategory will override it. - * @param {$models.NotificationCategory} category - * @returns {Promise & { cancel(): void }} - */ -export function RegisterNotificationCategory(category) { - let $resultPromise = /** @type {any} */($Call.ByID(2679064664, category)); - return $resultPromise; -} - -/** - * RemoveAllDeliveredNotifications removes all delivered notifications. - * @returns {Promise & { cancel(): void }} - */ -export function RemoveAllDeliveredNotifications() { - let $resultPromise = /** @type {any} */($Call.ByID(384520397)); - return $resultPromise; -} - -/** - * RemoveAllPendingNotifications removes all pending notifications. - * @returns {Promise & { cancel(): void }} - */ -export function RemoveAllPendingNotifications() { - let $resultPromise = /** @type {any} */($Call.ByID(1423986276)); - return $resultPromise; -} - -/** - * RemoveDeliveredNotification removes a delivered notification matching the unique identifier. - * @param {string} identifier - * @returns {Promise & { cancel(): void }} - */ -export function RemoveDeliveredNotification(identifier) { - let $resultPromise = /** @type {any} */($Call.ByID(149440045, identifier)); - return $resultPromise; -} - -/** - * RemoveNotification is a macOS stub that always returns nil. - * Use one of the following instead: - * RemoveAllPendingNotifications - * RemovePendingNotification - * RemoveAllDeliveredNotifications - * RemoveDeliveredNotification - * (Linux-specific) - * @param {string} identifier - * @returns {Promise & { cancel(): void }} - */ -export function RemoveNotification(identifier) { - let $resultPromise = /** @type {any} */($Call.ByID(3702062929, identifier)); - return $resultPromise; -} - -/** - * RemoveNotificationCategory remove a previously registered NotificationCategory. - * @param {string} categoryId - * @returns {Promise & { cancel(): void }} - */ -export function RemoveNotificationCategory(categoryId) { - let $resultPromise = /** @type {any} */($Call.ByID(229511469, categoryId)); - return $resultPromise; -} - -/** - * RemovePendingNotification removes a pending notification matching the unique identifier. - * @param {string} identifier - * @returns {Promise & { cancel(): void }} - */ -export function RemovePendingNotification(identifier) { - let $resultPromise = /** @type {any} */($Call.ByID(3872412470, identifier)); - return $resultPromise; -} - -/** - * RequestNotificationAuthorization requests permission for notifications. - * @returns {Promise & { cancel(): void }} - */ -export function RequestNotificationAuthorization() { - let $resultPromise = /** @type {any} */($Call.ByID(729898933)); - return $resultPromise; -} - -/** - * SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. - * @param {$models.NotificationOptions} options - * @returns {Promise & { cancel(): void }} - */ -export function SendNotification(options) { - let $resultPromise = /** @type {any} */($Call.ByID(2246903123, options)); - return $resultPromise; -} - -/** - * SendNotificationWithActions sends a notification with additional actions and inputs. - * A NotificationCategory must be registered with RegisterNotificationCategory first. The `CategoryID` must match the registered category. - * If a NotificationCategory is not registered a basic notification will be sent. - * @param {$models.NotificationOptions} options - * @returns {Promise & { cancel(): void }} - */ -export function SendNotificationWithActions(options) { - let $resultPromise = /** @type {any} */($Call.ByID(1615199806, options)); - return $resultPromise; -} diff --git a/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.ts b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.ts new file mode 100644 index 000000000..28f1cb3b2 --- /dev/null +++ b/v3/examples/notifications/frontend/bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/service.ts @@ -0,0 +1,62 @@ +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +/** + * Service represents the notifications service + * @module + */ + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: Unused imports +import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Create } from "@wailsio/runtime"; + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: Unused imports +import * as $models from "./models.js"; + +export function CheckNotificationAuthorization(): $CancellablePromise { + return $Call.ByID(2789931702); +} + +export function RegisterNotificationCategory(category: $models.NotificationCategory): $CancellablePromise { + return $Call.ByID(2679064664, category); +} + +export function RemoveAllDeliveredNotifications(): $CancellablePromise { + return $Call.ByID(384520397); +} + +export function RemoveAllPendingNotifications(): $CancellablePromise { + return $Call.ByID(1423986276); +} + +export function RemoveDeliveredNotification(identifier: string): $CancellablePromise { + return $Call.ByID(149440045, identifier); +} + +export function RemoveNotification(identifier: string): $CancellablePromise { + return $Call.ByID(3702062929, identifier); +} + +export function RemoveNotificationCategory(categoryID: string): $CancellablePromise { + return $Call.ByID(229511469, categoryID); +} + +export function RemovePendingNotification(identifier: string): $CancellablePromise { + return $Call.ByID(3872412470, identifier); +} + +/** + * Public methods that delegate to the implementation. + */ +export function RequestNotificationAuthorization(): $CancellablePromise { + return $Call.ByID(729898933); +} + +export function SendNotification(options: $models.NotificationOptions): $CancellablePromise { + return $Call.ByID(2246903123, options); +} + +export function SendNotificationWithActions(options: $models.NotificationOptions): $CancellablePromise { + return $Call.ByID(1615199806, options); +} diff --git a/v3/examples/notifications/frontend/index.html b/v3/examples/notifications/frontend/index.html index 3c0d45f85..ae067c8a2 100644 --- a/v3/examples/notifications/frontend/index.html +++ b/v3/examples/notifications/frontend/index.html @@ -13,17 +13,18 @@ - - + +

-

Wails + Javascript

- - + diff --git a/v3/examples/notifications/frontend/main.js b/v3/examples/notifications/frontend/main.js deleted file mode 100644 index 781f8983e..000000000 --- a/v3/examples/notifications/frontend/main.js +++ /dev/null @@ -1,67 +0,0 @@ -import * as Notifications from "./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications"; -import { Events } from "@wailsio/runtime"; - -const notificationsElement = document.getElementById('notifications'); - -window.sendNotification = async () => { - const granted = await Notifications.Service.RequestNotificationAuthorization(); - if (granted) { - await Notifications.Service.SendNotification({ - id: crypto.randomUUID(), - title: "Title", - body: "Body!", - data: { - messageId: "msg-123", - senderId: "user-123", - timestamp: Date.now(), - } - }); - } -} - -window.sendComplexNotification = async () => { - const granted = await Notifications.Service.RequestNotificationAuthorization(); - if (granted) { - await Notifications.Service.RegisterNotificationCategory({ - id: "FRONTEND_NOTIF", - actions: [ - { id: "VIEW_ACTION", title: "View" }, - { id: "MARK_READ_ACTION", title: "Mark as Read" }, - ], - hasReplyField: true, - replyButtonTitle: "Reply", - replyPlaceholder: "Reply to frontend...", - }); - - await Notifications.Service.SendNotificationWithActions({ - id: crypto.randomUUID(), - title: "Complex Frontend Notification", - subtitle: "From: Jane Doe", - body: "Is it rainging today where you are?", - categoryId: "FRONTEND_NOTIF", - data: { - messageId: "msg-456", - senderId: "user-456", - timestamp: Date.now(), - } - }); - } -} - -window.removeNotification = async (id) => { - const granted = await Notifications.Service.RequestNotificationAuthorization(); - if (granted) { - await Notifications.Service.RemoveDeliveredNotification(id); - } -} - -window.removeAllNotifications = async (id) => { - const granted = await Notifications.Service.RequestNotificationAuthorization(); - if (granted) { - await Notifications.Service.RemoveAllDeliveredNotifications(); - } -} - -Events.On("notification:response", (response) => { - notificationsElement.innerText = JSON.stringify(response.data[0]); -}); \ No newline at end of file diff --git a/v3/examples/notifications/frontend/package-lock.json b/v3/examples/notifications/frontend/package-lock.json new file mode 100644 index 000000000..cdd50c49d --- /dev/null +++ b/v3/examples/notifications/frontend/package-lock.json @@ -0,0 +1,935 @@ +{ + "name": "frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.0", + "devDependencies": { + "@wailsio/runtime": "latest", + "typescript": "^4.9.3", + "vite": "^5.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.37.0.tgz", + "integrity": "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.37.0.tgz", + "integrity": "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.37.0.tgz", + "integrity": "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.37.0.tgz", + "integrity": "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.37.0.tgz", + "integrity": "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.37.0.tgz", + "integrity": "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.37.0.tgz", + "integrity": "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.37.0.tgz", + "integrity": "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.37.0.tgz", + "integrity": "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.37.0.tgz", + "integrity": "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.37.0.tgz", + "integrity": "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.37.0.tgz", + "integrity": "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.37.0.tgz", + "integrity": "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.37.0.tgz", + "integrity": "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.37.0.tgz", + "integrity": "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.37.0.tgz", + "integrity": "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.37.0.tgz", + "integrity": "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.37.0.tgz", + "integrity": "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.37.0.tgz", + "integrity": "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.37.0.tgz", + "integrity": "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wailsio/runtime": { + "version": "3.0.0-alpha.66", + "resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.66.tgz", + "integrity": "sha512-ENLu8rn1griL1gFHJqkq1i+BVxrrA0JPJHYneUJYuf/s54kjuQViW0RKDEe/WTDo56ABpfykrd/T8OYpPUyXUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.37.0.tgz", + "integrity": "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.37.0", + "@rollup/rollup-android-arm64": "4.37.0", + "@rollup/rollup-darwin-arm64": "4.37.0", + "@rollup/rollup-darwin-x64": "4.37.0", + "@rollup/rollup-freebsd-arm64": "4.37.0", + "@rollup/rollup-freebsd-x64": "4.37.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", + "@rollup/rollup-linux-arm-musleabihf": "4.37.0", + "@rollup/rollup-linux-arm64-gnu": "4.37.0", + "@rollup/rollup-linux-arm64-musl": "4.37.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", + "@rollup/rollup-linux-riscv64-gnu": "4.37.0", + "@rollup/rollup-linux-riscv64-musl": "4.37.0", + "@rollup/rollup-linux-s390x-gnu": "4.37.0", + "@rollup/rollup-linux-x64-gnu": "4.37.0", + "@rollup/rollup-linux-x64-musl": "4.37.0", + "@rollup/rollup-win32-arm64-msvc": "4.37.0", + "@rollup/rollup-win32-ia32-msvc": "4.37.0", + "@rollup/rollup-win32-x64-msvc": "4.37.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/vite": { + "version": "5.4.15", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.15.tgz", + "integrity": "sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + } + } +} diff --git a/v3/examples/notifications/frontend/package.json b/v3/examples/notifications/frontend/package.json index 9ae87549e..4d675f189 100644 --- a/v3/examples/notifications/frontend/package.json +++ b/v3/examples/notifications/frontend/package.json @@ -5,11 +5,12 @@ "type": "module", "scripts": { "dev": "vite", - "build:dev": "vite build --minify false --mode development", - "build": "vite build --mode production", + "build:dev": "tsc && vite build --minify false --mode development", + "build": "tsc && vite build --mode production", "preview": "vite preview" }, "devDependencies": { + "typescript": "^4.9.3", "vite": "^5.0.0", "@wailsio/runtime": "latest" } diff --git a/v3/examples/notifications/frontend/public/javascript.svg b/v3/examples/notifications/frontend/public/javascript.svg deleted file mode 100644 index f9abb2b72..000000000 --- a/v3/examples/notifications/frontend/public/javascript.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/style.css b/v3/examples/notifications/frontend/public/style.css index 127799eda..074717bca 100644 --- a/v3/examples/notifications/frontend/public/style.css +++ b/v3/examples/notifications/frontend/public/style.css @@ -30,11 +30,6 @@ url("./Inter-Medium.ttf") format("truetype"); } -h3 { - font-size: 3em; - line-height: 1.1; -} - a { font-weight: 500; color: #646cff; @@ -45,8 +40,12 @@ a:hover { color: #535bf2; } +.controls { + display: flex; + gap: 1em; +} + button { - /* width: 60px; */ height: 30px; line-height: 30px; border-radius: 3px; @@ -56,11 +55,6 @@ button { cursor: pointer; } -.result { - height: 20px; - line-height: 20px; -} - body { margin: 0; display: flex; @@ -75,11 +69,12 @@ body { flex-direction: column; align-items: center; justify-content: center; + padding: 3em; } -h1 { - font-size: 3.2em; +h1, h3 { line-height: 1.1; + text-align: center; } #app { @@ -103,19 +98,23 @@ h1 { filter: drop-shadow(0 0 2em #f7df1eaa); } -.result { - height: 20px; - line-height: 20px; - margin: 1.5rem auto; - text-align: center; -} - .footer { margin-top: 1rem; align-content: center; text-align: center; } +.footer table { + font-size: 12px; + border-collapse: collapse; + margin: 0 auto; +} + +.footer table, th, td { + border: 1px solid #ddd; + padding: 0.5em; +} + @media (prefers-color-scheme: light) { :root { color: #213547; @@ -129,32 +128,4 @@ h1 { button { background-color: #f9f9f9; } -} - - -.input-box .btn:hover { - background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); - color: #333333; -} - -.input-box .input { - border: none; - border-radius: 3px; - outline: none; - height: 30px; - line-height: 30px; - padding: 0 10px; - color: black; - background-color: rgba(240, 240, 240, 1); - -webkit-font-smoothing: antialiased; -} - -.input-box .input:hover { - border: none; - background-color: rgba(255, 255, 255, 1); -} - -.input-box .input:focus { - border: none; - background-color: rgba(255, 255, 255, 1); } \ No newline at end of file diff --git a/v3/examples/notifications/frontend/public/typescript.svg b/v3/examples/notifications/frontend/public/typescript.svg new file mode 100644 index 000000000..d91c910cc --- /dev/null +++ b/v3/examples/notifications/frontend/public/typescript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/examples/notifications/frontend/src/main.ts b/v3/examples/notifications/frontend/src/main.ts new file mode 100644 index 000000000..437fb8c94 --- /dev/null +++ b/v3/examples/notifications/frontend/src/main.ts @@ -0,0 +1,95 @@ +import { Events } from "@wailsio/runtime"; +import * as Notifications from "../bindings/github.com/wailsapp/wails/v3/pkg/services/notifications"; + +document.querySelector("#basic")?.addEventListener("click", async () => { + try { + const authorized = await Notifications.Service.CheckNotificationAuthorization(); + if (authorized) { + await Notifications.Service.SendNotification({ + id: crypto.randomUUID(), + title: "Notification Title", + subtitle: "Subtitle on macOS and Linux", + body: "Body text of notification.", + data: { + "user-id": "user-123", + "message-id": "msg-123", + "timestamp": Date.now(), + }, + }); + } else { + console.warn("Notifications are not authorized.\n You can attempt to request again or let the user know in the UI.\n"); + } + } catch (error) { + console.error(error); + } +}); +document.querySelector("#complex")?.addEventListener("click", async () => { + try { + const authorized = await Notifications.Service.CheckNotificationAuthorization(); + if (authorized) { + const CategoryID = "frontend-notification-id"; + + await Notifications.Service.RegisterNotificationCategory({ + id: CategoryID, + actions: [ + { id: "VIEW", title: "View" }, + { id: "MARK_READ", title: "Mark as read" }, + { id: "DELETE", title: "Delete", destructive: true }, + ], + hasReplyField: true, + replyPlaceholder: "Message...", + replyButtonTitle: "Reply", + }); + + await Notifications.Service.SendNotificationWithActions({ + id: crypto.randomUUID(), + title: "Notification Title", + subtitle: "Subtitle on macOS and Linux", + body: "Body text of notification.", + categoryId: CategoryID, + data: { + "user-id": "user-123", + "message-id": "msg-123", + "timestamp": Date.now(), + }, + }); + } else { + console.warn("Notifications are not authorized.\n You can attempt to request again or let the user know in the UI.\n"); + } + } catch (error) { + console.error(error); + } +}); + +const unlisten = Events.On("notification:action", (response) => { + console.info(`Recieved a ${response.name} event`); + const { userInfo, ...base } = response.data[0]; + console.info("Notification Response:"); + console.table(base); + console.info("Notification Response Metadata:"); + console.table(userInfo); + const table = ` +
Notification Response
+ + + ${Object.keys(base).map(key => ``).join("")} + + + ${Object.values(base).map(value => ``).join("")} + +
${key}
${value}
+
Notification Metadata
+ + + ${Object.keys(userInfo).map(key => ``).join("")} + + + ${Object.values(userInfo).map(value => ``).join("")} + +
${key}
${value}
+ `; + const footer = document.querySelector("#response"); + if (footer) footer.innerHTML = table; +}); + +window.onbeforeunload = () => unlisten(); \ No newline at end of file diff --git a/v3/examples/notifications/frontend/src/vite-env.d.ts b/v3/examples/notifications/frontend/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/v3/examples/notifications/frontend/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/v3/examples/notifications/frontend/tsconfig.json b/v3/examples/notifications/frontend/tsconfig.json new file mode 100644 index 000000000..c267ecf24 --- /dev/null +++ b/v3/examples/notifications/frontend/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "Node", + "strict": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "noEmit": true, + "noUnusedLocals": true, + "noUnusedParameters": false, + "noImplicitAny": false, + "noImplicitReturns": true, + "skipLibCheck": true + }, + "include": ["src"] +} diff --git a/v3/examples/notifications/go.mod b/v3/examples/notifications/go.mod new file mode 100644 index 000000000..39537e938 --- /dev/null +++ b/v3/examples/notifications/go.mod @@ -0,0 +1,53 @@ +module notifications + +go 1.24.0 + +toolchain go1.24.1 + +require github.com/wailsapp/wails/v3 v3.0.0-dev + +require ( + dario.cat/mergo v1.0.1 // indirect + git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v1.1.6 // indirect + github.com/adrg/xdg v0.5.3 // indirect + github.com/bep/debounce v1.2.1 // indirect + github.com/cloudflare/circl v1.6.0 // indirect + github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/ebitengine/purego v0.8.2 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.6.2 // indirect + github.com/go-git/go-git/v5 v5.13.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/leaanthony/go-ansi-parser v1.6.1 // indirect + github.com/leaanthony/u v1.1.1 // indirect + github.com/lmittmann/tint v1.0.7 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/samber/lo v1.49.1 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.3.1 // indirect + github.com/wailsapp/go-webview2 v1.0.21 // indirect + github.com/wailsapp/mimetype v1.4.1 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.37.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect +) + +replace github.com/wailsapp/wails/v3 => ../wails/v3 diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index c2a2502a3..aae1bf2f0 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -3,7 +3,6 @@ package main import ( "embed" _ "embed" - "encoding/json" "fmt" "log" "time" @@ -12,17 +11,31 @@ import ( "github.com/wailsapp/wails/v3/pkg/services/notifications" ) +// Wails uses Go's `embed` package to embed the frontend files into the binary. +// Any files in the frontend/dist folder will be embedded into the binary and +// made available to the frontend. +// See https://pkg.go.dev/embed for more information. + //go:embed all:frontend/dist var assets embed.FS +// main function serves as the application's entry point. It initializes the application, creates a window, +// and starts a goroutine that emits a time-based event every second. It subsequently runs the application and +// logs any error that might occur. func main() { - notificationService := notifications.New() + // Create a new Notification Service + ns := notifications.New() + // Create a new Wails application by providing the necessary options. + // Variables 'Name' and 'Description' are for application metadata. + // 'Assets' configures the asset server with the 'FS' variable pointing to the frontend files. + // 'Bind' is a list of Go struct instances. The frontend has access to the methods of these instances. + // 'Mac' options tailor the application when running an macOS. app := application.New(application.Options{ - Name: "Notifications", - Description: "A demo of using raw HTML & CSS", + Name: "Notifications Demo", + Description: "A demo of using desktop notifications with Wails", Services: []application.Service{ - application.NewService(notificationService), + application.NewService(ns), }, Assets: application.AssetOptions{ Handler: application.AssetFileServerFS(assets), @@ -30,13 +43,15 @@ func main() { Mac: application.MacOptions{ ApplicationShouldTerminateAfterLastWindowClosed: true, }, - Windows: application.WindowsOptions{ - WndClass: "Notifications", - }, }) + // Create a new window with the necessary options. + // 'Title' is the title of the window. + // 'Mac' options tailor the window when running on macOS. + // 'BackgroundColour' is the background colour of the window. + // 'URL' is the URL that will be loaded into the webview. app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ - Title: "Notifications", + Title: "Window 1", Mac: application.MacWindow{ InvisibleTitleBarHeight: 50, Backdrop: application.MacBackdropTranslucent, @@ -46,67 +61,90 @@ func main() { URL: "/", }) + // Create a goroutine that spawns desktop notifications from Go go func() { - granted, err := notificationService.RequestNotificationAuthorization() + var authorized bool + var err error + authorized, err = ns.CheckNotificationAuthorization() if err != nil { - log.Default().Printf("WARNING: %s\n", err) - return + println(fmt.Errorf("checking app notification authorization failed: %s", err)) } - if granted { - notificationService.OnNotificationResponse(func(result notifications.NotificationResult) { - if result.Error != nil { - fmt.Printf("notification response error: %s", result.Error) - return - } - data, _ := json.Marshal(result.Response) - fmt.Printf("%s\n", string(data)) - app.EmitEvent("notification:response", result.Response) - }) - time.Sleep(time.Second * 2) + if !authorized { + authorized, err = ns.RequestNotificationAuthorization() + if err != nil { + println(fmt.Errorf("requesting app notification authorization failed: %s", err)) + } + } - notificationService.SendNotification(notifications.NotificationOptions{ - ID: "uuid1", - Title: "Title!", - Body: "Body!", + if authorized { + ns.OnNotificationResponse(func(result notifications.NotificationResult) { + if result.Error != nil { + println(fmt.Errorf("parsing notification result failed: %s", result.Error)) + } else { + fmt.Printf("Response: %+v\n", result.Response) + println("Sending response to frontend...") + app.EmitEvent("notification:action", result.Response) + } + }) + + err = ns.SendNotification(notifications.NotificationOptions{ + ID: "uuid-basic-1", + Title: "Notification Title", + Subtitle: "Subtitle on macOS and Linux", + Body: "Body text of notification.", Data: map[string]interface{}{ - "messageId": "msg-123", - "senderId": "user-123", - "timestamp": time.Now().Unix(), + "user-id": "user-123", + "message-id": "msg-123", + "timestamp": time.Now().Unix(), }, }) + if err != nil { + println(fmt.Errorf("sending basic notification failed: %s", err)) + } + // Delay before sending next notification time.Sleep(time.Second * 2) - notificationService.RegisterNotificationCategory(notifications.NotificationCategory{ - ID: "BACKEND_NOTIF", + const CategoryID = "backend-notification-id" + + err = ns.RegisterNotificationCategory(notifications.NotificationCategory{ + ID: CategoryID, Actions: []notifications.NotificationAction{ - {ID: "VIEW_ACTION", Title: "View"}, - {ID: "MARK_READ_ACTION", Title: "Mark as Read"}, - {ID: "DELETE_ACTION", Title: "Delete", Destructive: true}, + {ID: "VIEW", Title: "View"}, + {ID: "MARK_READ", Title: "Mark as read"}, + {ID: "DELETE", Title: "Delete", Destructive: true}, }, HasReplyField: true, + ReplyPlaceholder: "Message...", ReplyButtonTitle: "Reply", - ReplyPlaceholder: "Reply to backend...", }) + if err != nil { + println(fmt.Errorf("creating notification category failed: %s", err)) + } - notificationService.SendNotificationWithActions(notifications.NotificationOptions{ - ID: "uuid2", - Title: "Complex Backend Notification", - Subtitle: "From: Jane Doe", - Body: "Is it raining today where you are?", - CategoryID: "BACKEND_NOTIF", + err = ns.SendNotificationWithActions(notifications.NotificationOptions{ + ID: "uuid-with-actions-1", + Title: "Actions Notification Title", + Subtitle: "Subtitle on macOS and Linux", + Body: "Body text of notification with actions.", + CategoryID: CategoryID, Data: map[string]interface{}{ - "messageId": "msg-456", - "senderId": "user-456", - "timestamp": time.Now().Unix(), + "user-id": "user-123", + "message-id": "msg-123", + "timestamp": time.Now().Unix(), }, }) + if err != nil { + println(fmt.Errorf("sending notification with actions failed: %s", err)) + } } }() + // Run the application. This blocks until the application has been exited. err := app.Run() + // If an error occurred while running the application, log it and exit. if err != nil { log.Fatal(err) } From d25f9237215964831effeceac8b4dbc61db715fe Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Mar 2025 20:07:31 -0700 Subject: [PATCH 106/136] wait on dbus --- .../notifications/notifications_linux.go | 72 +++++++++++++++++-- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index bdc8312ff..3be587ac0 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "sync" + "time" "github.com/godbus/dbus/v5" "github.com/wailsapp/wails/v3/pkg/application" @@ -48,6 +49,29 @@ func New() *Service { notifications: make(map[uint32]*notificationData), } + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + conn, err := dbus.ConnectSessionBus() + if err != nil { + fmt.Printf("Warning: Failed to connect to D-Bus session bus: %v\n", err) + fmt.Printf("Notifications will be unavailable\n") + } else { + impl.conn = conn + + obj := conn.Object(dbusNotificationInterface, dbusNotificationPath) + call := obj.CallWithContext(ctx, dbusNotificationInterface+".GetCapabilities", 0) + + var capabilities []string + err := call.Store(&capabilities) + + if err != nil { + fmt.Printf("Warning: D-Bus notification service not ready: %v\n", err) + } else { + fmt.Printf("D-Bus notification service is ready with capabilities: %v\n", capabilities) + } + } + NotificationService = &Service{ impl: impl, } @@ -56,15 +80,29 @@ func New() *Service { return NotificationService } +// Helper method to check if D-Bus connection is available +func (ln *linuxNotifier) checkConnection() error { + if ln.conn == nil { + return fmt.Errorf("D-Bus connection is not initialized, notifications are unavailable") + } + + return nil +} + // Startup is called when the service is loaded. func (ln *linuxNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { ln.appName = application.Get().Config().Name - conn, err := dbus.ConnectSessionBus() - if err != nil { - return fmt.Errorf("failed to connect to session bus: %w", err) + if ln.conn == nil { + conn, err := dbus.ConnectSessionBus() + if err != nil { + fmt.Printf("Warning: Failed to connect to D-Bus session bus: %v\n", err) + fmt.Printf("Notifications will be unavailable\n") + + return nil + } + ln.conn = conn } - ln.conn = conn if err := ln.loadCategories(); err != nil { fmt.Printf("Failed to load notification categories: %v\n", err) @@ -74,7 +112,7 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic signalCtx, ln.cancel = context.WithCancel(context.Background()) if err := ln.setupSignalHandling(signalCtx); err != nil { - return fmt.Errorf("failed to set up notification signal handling: %w", err) + fmt.Printf("Warning: Failed to set up notification signal handling: %v\n", err) } return nil @@ -110,6 +148,10 @@ func (ln *linuxNotifier) CheckNotificationAuthorization() (bool, error) { // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { + if err := ln.checkConnection(); err != nil { + return err + } + hints := map[string]dbus.Variant{} body := options.Body @@ -176,6 +218,10 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { // SendNotificationWithActions sends a notification with additional actions. func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions) error { + if err := ln.checkConnection(); err != nil { + return err + } + ln.categoriesLock.RLock() category, exists := ln.categories[options.CategoryID] ln.categoriesLock.RUnlock() @@ -284,6 +330,10 @@ func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error { // RemoveAllPendingNotifications attempts to remove all active notifications. func (ln *linuxNotifier) RemoveAllPendingNotifications() error { + if err := ln.checkConnection(); err != nil { + return err + } + ln.notificationsLock.Lock() dbusIDs := make([]uint32, 0, len(ln.notifications)) for id := range ln.notifications { @@ -300,6 +350,10 @@ func (ln *linuxNotifier) RemoveAllPendingNotifications() error { // RemovePendingNotification removes a pending notification. func (ln *linuxNotifier) RemovePendingNotification(identifier string) error { + if err := ln.checkConnection(); err != nil { + return err + } + var dbusID uint32 found := false @@ -337,6 +391,10 @@ func (ln *linuxNotifier) RemoveNotification(identifier string) error { // Helper method to close a notification. func (ln *linuxNotifier) closeNotification(id uint32) error { + if err := ln.checkConnection(); err != nil { + return err + } + obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) call := obj.Call(dbusNotificationInterface+".CloseNotification", 0, id) @@ -417,6 +475,10 @@ func (ln *linuxNotifier) loadCategories() error { // Setup signal handling for notification actions. func (ln *linuxNotifier) setupSignalHandling(ctx context.Context) error { + if err := ln.checkConnection(); err != nil { + return err + } + if err := ln.conn.AddMatchSignal( dbus.WithMatchInterface(dbusNotificationInterface), dbus.WithMatchMember("ActionInvoked"), From 276c653b1df4db017fd7120faef302853c8af2b1 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Mar 2025 20:22:29 -0700 Subject: [PATCH 107/136] update example --- v3/examples/notifications/build/windows/Taskfile.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/examples/notifications/build/windows/Taskfile.yml b/v3/examples/notifications/build/windows/Taskfile.yml index 534f4fb31..be6e4125e 100644 --- a/v3/examples/notifications/build/windows/Taskfile.yml +++ b/v3/examples/notifications/build/windows/Taskfile.yml @@ -60,4 +60,4 @@ tasks: run: cmds: - - '{{.BIN_DIR}}/{{.APP_NAME}}.exe' + - '{{.BIN_DIR}}\\{{.APP_NAME}}.exe' From 7d0f7f4652b6efeafaaa381c91bba35f4f357339 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Mar 2025 21:26:02 -0700 Subject: [PATCH 108/136] revert linux wait and update payload on win --- .../notifications/notifications_linux.go | 72 ++----------------- .../notifications/notifications_windows.go | 68 ++++++++---------- 2 files changed, 33 insertions(+), 107 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_linux.go b/v3/pkg/services/notifications/notifications_linux.go index 3be587ac0..bdc8312ff 100644 --- a/v3/pkg/services/notifications/notifications_linux.go +++ b/v3/pkg/services/notifications/notifications_linux.go @@ -9,7 +9,6 @@ import ( "os" "path/filepath" "sync" - "time" "github.com/godbus/dbus/v5" "github.com/wailsapp/wails/v3/pkg/application" @@ -49,29 +48,6 @@ func New() *Service { notifications: make(map[uint32]*notificationData), } - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - - conn, err := dbus.ConnectSessionBus() - if err != nil { - fmt.Printf("Warning: Failed to connect to D-Bus session bus: %v\n", err) - fmt.Printf("Notifications will be unavailable\n") - } else { - impl.conn = conn - - obj := conn.Object(dbusNotificationInterface, dbusNotificationPath) - call := obj.CallWithContext(ctx, dbusNotificationInterface+".GetCapabilities", 0) - - var capabilities []string - err := call.Store(&capabilities) - - if err != nil { - fmt.Printf("Warning: D-Bus notification service not ready: %v\n", err) - } else { - fmt.Printf("D-Bus notification service is ready with capabilities: %v\n", capabilities) - } - } - NotificationService = &Service{ impl: impl, } @@ -80,29 +56,15 @@ func New() *Service { return NotificationService } -// Helper method to check if D-Bus connection is available -func (ln *linuxNotifier) checkConnection() error { - if ln.conn == nil { - return fmt.Errorf("D-Bus connection is not initialized, notifications are unavailable") - } - - return nil -} - // Startup is called when the service is loaded. func (ln *linuxNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { ln.appName = application.Get().Config().Name - if ln.conn == nil { - conn, err := dbus.ConnectSessionBus() - if err != nil { - fmt.Printf("Warning: Failed to connect to D-Bus session bus: %v\n", err) - fmt.Printf("Notifications will be unavailable\n") - - return nil - } - ln.conn = conn + conn, err := dbus.ConnectSessionBus() + if err != nil { + return fmt.Errorf("failed to connect to session bus: %w", err) } + ln.conn = conn if err := ln.loadCategories(); err != nil { fmt.Printf("Failed to load notification categories: %v\n", err) @@ -112,7 +74,7 @@ func (ln *linuxNotifier) Startup(ctx context.Context, options application.Servic signalCtx, ln.cancel = context.WithCancel(context.Background()) if err := ln.setupSignalHandling(signalCtx); err != nil { - fmt.Printf("Warning: Failed to set up notification signal handling: %v\n", err) + return fmt.Errorf("failed to set up notification signal handling: %w", err) } return nil @@ -148,10 +110,6 @@ func (ln *linuxNotifier) CheckNotificationAuthorization() (bool, error) { // SendNotification sends a basic notification with a unique identifier, title, subtitle, and body. func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { - if err := ln.checkConnection(); err != nil { - return err - } - hints := map[string]dbus.Variant{} body := options.Body @@ -218,10 +176,6 @@ func (ln *linuxNotifier) SendNotification(options NotificationOptions) error { // SendNotificationWithActions sends a notification with additional actions. func (ln *linuxNotifier) SendNotificationWithActions(options NotificationOptions) error { - if err := ln.checkConnection(); err != nil { - return err - } - ln.categoriesLock.RLock() category, exists := ln.categories[options.CategoryID] ln.categoriesLock.RUnlock() @@ -330,10 +284,6 @@ func (ln *linuxNotifier) RemoveNotificationCategory(categoryId string) error { // RemoveAllPendingNotifications attempts to remove all active notifications. func (ln *linuxNotifier) RemoveAllPendingNotifications() error { - if err := ln.checkConnection(); err != nil { - return err - } - ln.notificationsLock.Lock() dbusIDs := make([]uint32, 0, len(ln.notifications)) for id := range ln.notifications { @@ -350,10 +300,6 @@ func (ln *linuxNotifier) RemoveAllPendingNotifications() error { // RemovePendingNotification removes a pending notification. func (ln *linuxNotifier) RemovePendingNotification(identifier string) error { - if err := ln.checkConnection(); err != nil { - return err - } - var dbusID uint32 found := false @@ -391,10 +337,6 @@ func (ln *linuxNotifier) RemoveNotification(identifier string) error { // Helper method to close a notification. func (ln *linuxNotifier) closeNotification(id uint32) error { - if err := ln.checkConnection(); err != nil { - return err - } - obj := ln.conn.Object(dbusNotificationInterface, dbusNotificationPath) call := obj.Call(dbusNotificationInterface+".CloseNotification", 0, id) @@ -475,10 +417,6 @@ func (ln *linuxNotifier) loadCategories() error { // Setup signal handling for notification actions. func (ln *linuxNotifier) setupSignalHandling(ctx context.Context) error { - if err := ln.checkConnection(); err != nil { - return err - } - if err := ln.conn.AddMatchSignal( dbus.WithMatchInterface(dbusNotificationInterface), dbus.WithMatchMember("ActionInvoked"), diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index d792d6949..e22fe01b6 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -36,8 +36,8 @@ const ( // NotificationPayload combines the action ID and user data into a single structure type NotificationPayload struct { - Action string `json:"action"` - Data map[string]interface{} `json:"data,omitempty"` + Action string `json:"action"` + Options NotificationOptions `json:"payload,omitempty"` } // Creates a new Notifications Service. @@ -79,7 +79,8 @@ func (wn *windowsNotifier) Startup(ctx context.Context, options application.Serv toast.SetActivationCallback(func(args string, data []toast.UserData) { result := NotificationResult{} - actionIdentifier, userInfo, err := parseNotificationResponse(args) + + actionIdentifier, options, err := parseNotificationResponse(args) if err != nil { result.Error = err @@ -90,21 +91,15 @@ func (wn *windowsNotifier) Startup(ctx context.Context, options application.Serv return } + // Subtitle is retained but was not shown with the notification response := NotificationResponse{ + ID: options.ID, ActionIdentifier: actionIdentifier, - } - - if userInfo != "" { - var userInfoMap map[string]interface{} - if err := json.Unmarshal([]byte(userInfo), &userInfoMap); err != nil { - result.Error = fmt.Errorf("failed to unmarshal notification response: %w", err) - - if ns := getNotificationService(); ns != nil { - ns.handleNotificationResult(result) - } - return - } - response.UserInfo = userInfoMap + Title: options.Title, + Subtitle: options.Subtitle, + Body: options.Body, + CategoryID: options.CategoryID, + UserInfo: options.Data, } if userText, found := wn.getUserText(data); found { @@ -154,9 +149,9 @@ func (wn *windowsNotifier) SendNotification(options NotificationOptions) error { } if options.Data != nil { - encodedPayload, err := wn.encodePayload(DefaultActionIdentifier, options.Data) + encodedPayload, err := wn.encodePayload(DefaultActionIdentifier, options) if err != nil { - return fmt.Errorf("failed to encode notification data: %w", err) + return fmt.Errorf("failed to encode notification payload: %w", err) } n.ActivationArguments = encodedPayload } @@ -208,16 +203,16 @@ func (wn *windowsNotifier) SendNotificationWithActions(options NotificationOptio } if options.Data != nil { - encodedPayload, err := wn.encodePayload(n.ActivationArguments, options.Data) + encodedPayload, err := wn.encodePayload(n.ActivationArguments, options) if err != nil { - return fmt.Errorf("failed to encode notification data: %w", err) + return fmt.Errorf("failed to encode notification payload: %w", err) } n.ActivationArguments = encodedPayload for index := range n.Actions { - encodedPayload, err := wn.encodePayload(n.Actions[index].Arguments, options.Data) + encodedPayload, err := wn.encodePayload(n.Actions[index].Arguments, options) if err != nil { - return fmt.Errorf("failed to encode notification data: %w", err) + return fmt.Errorf("failed to encode notification payload: %w", err) } n.Actions[index].Arguments = encodedPayload } @@ -284,10 +279,10 @@ func (wn *windowsNotifier) RemoveNotification(identifier string) error { } // encodePayload combines an action ID and user data into a single encoded string -func (wn *windowsNotifier) encodePayload(actionID string, data map[string]interface{}) (string, error) { +func (wn *windowsNotifier) encodePayload(actionID string, options NotificationOptions) (string, error) { payload := NotificationPayload{ - Action: actionID, - Data: data, + Action: actionID, + Options: options, } jsonData, err := json.Marshal(payload) @@ -300,37 +295,30 @@ func (wn *windowsNotifier) encodePayload(actionID string, data map[string]interf } // decodePayload extracts the action ID and user data from an encoded payload -func decodePayload(encodedString string) (string, map[string]interface{}, error) { +func decodePayload(encodedString string) (string, NotificationOptions, error) { jsonData, err := base64.StdEncoding.DecodeString(encodedString) if err != nil { - return encodedString, nil, fmt.Errorf("failed to decode base64 payload: %w", err) + return encodedString, NotificationOptions{}, fmt.Errorf("failed to decode base64 payload: %w", err) } var payload NotificationPayload if err := json.Unmarshal(jsonData, &payload); err != nil { - return encodedString, nil, fmt.Errorf("failed to unmarshal notification payload: %w", err) + return encodedString, NotificationOptions{}, fmt.Errorf("failed to unmarshal notification payload: %w", err) } - return payload.Action, payload.Data, nil + return payload.Action, payload.Options, nil } // parseNotificationResponse updated to use structured payload decoding -func parseNotificationResponse(response string) (action string, data string, err error) { - actionID, userData, err := decodePayload(response) +func parseNotificationResponse(response string) (action string, options NotificationOptions, err error) { + actionID, options, err := decodePayload(response) if err != nil { fmt.Printf("Warning: Failed to decode notification response: %v\n", err) - return response, "", err + return response, NotificationOptions{}, err } - if userData != nil { - userDataJSON, err := json.Marshal(userData) - if err == nil { - return actionID, string(userDataJSON), nil - } - } - - return actionID, "", nil + return actionID, options, nil } func (wn *windowsNotifier) saveIconToDir() error { From af5abda8b1693fb391d22a0a20a6fddfa2edd296 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Mon, 24 Mar 2025 21:34:10 -0700 Subject: [PATCH 109/136] update example --- v3/examples/notifications/main.go | 143 +++++++++++++++--------------- 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/v3/examples/notifications/main.go b/v3/examples/notifications/main.go index aae1bf2f0..264e7273e 100644 --- a/v3/examples/notifications/main.go +++ b/v3/examples/notifications/main.go @@ -8,6 +8,7 @@ import ( "time" "github.com/wailsapp/wails/v3/pkg/application" + "github.com/wailsapp/wails/v3/pkg/events" "github.com/wailsapp/wails/v3/pkg/services/notifications" ) @@ -61,85 +62,87 @@ func main() { URL: "/", }) - // Create a goroutine that spawns desktop notifications from Go - go func() { - var authorized bool - var err error - authorized, err = ns.CheckNotificationAuthorization() - if err != nil { - println(fmt.Errorf("checking app notification authorization failed: %s", err)) - } - - if !authorized { - authorized, err = ns.RequestNotificationAuthorization() + app.OnApplicationEvent(events.Common.ApplicationStarted, func(event *application.ApplicationEvent) { + // Create a goroutine that spawns desktop notifications from Go + go func() { + var authorized bool + var err error + authorized, err = ns.CheckNotificationAuthorization() if err != nil { - println(fmt.Errorf("requesting app notification authorization failed: %s", err)) + println(fmt.Errorf("checking app notification authorization failed: %s", err)) } - } - if authorized { - ns.OnNotificationResponse(func(result notifications.NotificationResult) { - if result.Error != nil { - println(fmt.Errorf("parsing notification result failed: %s", result.Error)) - } else { - fmt.Printf("Response: %+v\n", result.Response) - println("Sending response to frontend...") - app.EmitEvent("notification:action", result.Response) + if !authorized { + authorized, err = ns.RequestNotificationAuthorization() + if err != nil { + println(fmt.Errorf("requesting app notification authorization failed: %s", err)) } - }) - - err = ns.SendNotification(notifications.NotificationOptions{ - ID: "uuid-basic-1", - Title: "Notification Title", - Subtitle: "Subtitle on macOS and Linux", - Body: "Body text of notification.", - Data: map[string]interface{}{ - "user-id": "user-123", - "message-id": "msg-123", - "timestamp": time.Now().Unix(), - }, - }) - if err != nil { - println(fmt.Errorf("sending basic notification failed: %s", err)) } - // Delay before sending next notification - time.Sleep(time.Second * 2) + if authorized { + ns.OnNotificationResponse(func(result notifications.NotificationResult) { + if result.Error != nil { + println(fmt.Errorf("parsing notification result failed: %s", result.Error)) + } else { + fmt.Printf("Response: %+v\n", result.Response) + println("Sending response to frontend...") + app.EmitEvent("notification:action", result.Response) + } + }) - const CategoryID = "backend-notification-id" + err = ns.SendNotification(notifications.NotificationOptions{ + ID: "uuid-basic-1", + Title: "Notification Title", + Subtitle: "Subtitle on macOS and Linux", + Body: "Body text of notification.", + Data: map[string]interface{}{ + "user-id": "user-123", + "message-id": "msg-123", + "timestamp": time.Now().Unix(), + }, + }) + if err != nil { + println(fmt.Errorf("sending basic notification failed: %s", err)) + } - err = ns.RegisterNotificationCategory(notifications.NotificationCategory{ - ID: CategoryID, - Actions: []notifications.NotificationAction{ - {ID: "VIEW", Title: "View"}, - {ID: "MARK_READ", Title: "Mark as read"}, - {ID: "DELETE", Title: "Delete", Destructive: true}, - }, - HasReplyField: true, - ReplyPlaceholder: "Message...", - ReplyButtonTitle: "Reply", - }) - if err != nil { - println(fmt.Errorf("creating notification category failed: %s", err)) + // Delay before sending next notification + time.Sleep(time.Second * 2) + + const CategoryID = "backend-notification-id" + + err = ns.RegisterNotificationCategory(notifications.NotificationCategory{ + ID: CategoryID, + Actions: []notifications.NotificationAction{ + {ID: "VIEW", Title: "View"}, + {ID: "MARK_READ", Title: "Mark as read"}, + {ID: "DELETE", Title: "Delete", Destructive: true}, + }, + HasReplyField: true, + ReplyPlaceholder: "Message...", + ReplyButtonTitle: "Reply", + }) + if err != nil { + println(fmt.Errorf("creating notification category failed: %s", err)) + } + + err = ns.SendNotificationWithActions(notifications.NotificationOptions{ + ID: "uuid-with-actions-1", + Title: "Actions Notification Title", + Subtitle: "Subtitle on macOS and Linux", + Body: "Body text of notification with actions.", + CategoryID: CategoryID, + Data: map[string]interface{}{ + "user-id": "user-123", + "message-id": "msg-123", + "timestamp": time.Now().Unix(), + }, + }) + if err != nil { + println(fmt.Errorf("sending notification with actions failed: %s", err)) + } } - - err = ns.SendNotificationWithActions(notifications.NotificationOptions{ - ID: "uuid-with-actions-1", - Title: "Actions Notification Title", - Subtitle: "Subtitle on macOS and Linux", - Body: "Body text of notification with actions.", - CategoryID: CategoryID, - Data: map[string]interface{}{ - "user-id": "user-123", - "message-id": "msg-123", - "timestamp": time.Now().Unix(), - }, - }) - if err != nil { - println(fmt.Errorf("sending notification with actions failed: %s", err)) - } - } - }() + }() + }) // Run the application. This blocks until the application has been exited. err := app.Run() From 1db65a84c34684ac2713ed55e6da9199999ad9aa Mon Sep 17 00:00:00 2001 From: popaprozac Date: Wed, 26 Mar 2025 23:12:46 -0700 Subject: [PATCH 110/136] stage docs --- docs/src/content/docs/learn/notifications.mdx | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/src/content/docs/learn/notifications.mdx diff --git a/docs/src/content/docs/learn/notifications.mdx b/docs/src/content/docs/learn/notifications.mdx new file mode 100644 index 000000000..e69de29bb From 38ac5f799b57ad7545e2f2a400ddfc066d3e8675 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 27 Mar 2025 11:24:13 -0700 Subject: [PATCH 111/136] sign all things --- .../commands/build_assets/darwin/Taskfile.yml | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/v3/internal/commands/build_assets/darwin/Taskfile.yml b/v3/internal/commands/build_assets/darwin/Taskfile.yml index 30e7da823..3dd73a042 100644 --- a/v3/internal/commands/build_assets/darwin/Taskfile.yml +++ b/v3/internal/commands/build_assets/darwin/Taskfile.yml @@ -19,7 +19,7 @@ tasks: - go build {{.BUILD_FLAGS}} -o {{.OUTPUT}} vars: BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}' - DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}' + DEFAULT_OUTPUT: '{{.BIN_DIR}}/build/{{.APP_NAME}}' OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}' env: GOOS: darwin @@ -36,14 +36,14 @@ tasks: - task: build vars: ARCH: amd64 - OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" + OUTPUT: "{{.BIN_DIR}}/build/{{.APP_NAME}}-amd64" - task: build vars: ARCH: arm64 - OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" + OUTPUT: "{{.BIN_DIR}}/build/{{.APP_NAME}}-arm64" cmds: - - lipo -create -output "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" - - rm "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" + - lipo -create -output "{{.BIN_DIR}}/build/{{.APP_NAME}}" "{{.BIN_DIR}}/build/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/build/{{.APP_NAME}}-arm64" + - rm "{{.BIN_DIR}}/build/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/build/{{.APP_NAME}}-arm64" package: summary: Packages a production build of the application into a `.app` bundle @@ -65,11 +65,17 @@ tasks: create:app:bundle: summary: Creates an `.app` bundle cmds: - - mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/{MacOS,Resources} - - cp build/darwin/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources - - cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS - - cp build/darwin/Info.plist {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents + - mkdir -p {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents/{MacOS,Resources} + - cp build/darwin/icons.icns {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents/Resources + - cp {{.BIN_DIR}}/build/{{.APP_NAME}} {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents/MacOS + - cp build/darwin/Info.plist {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents + - codesign --force --deep --sign - {{.BIN_DIR}}/release/{{.APP_NAME}}.app run: cmds: - - '{{.BIN_DIR}}/{{.APP_NAME}}' + - mkdir -p {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/{MacOS,Resources} + - cp build/darwin/icons.icns {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/Resources + - cp {{.BIN_DIR}}/build/{{.APP_NAME}} {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/MacOS + - cp build/darwin/Info.dev.plist {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/Info.plist + - codesign --force --deep --sign - {{.BIN_DIR}}/dev/{{.APP_NAME}}.app + - '{{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/MacOS/{{.APP_NAME}}' From 9db28ec5fda336b3bd2e20c8c56919f9c733eca4 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 27 Mar 2025 11:24:13 -0700 Subject: [PATCH 112/136] update docs/changelog --- docs/src/content/docs/changelog.mdx | 1 + docs/src/content/docs/guides/signing.mdx | 2 +- docs/src/content/docs/learn/build.mdx | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 75dbf824b..89af3efeb 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -139,6 +139,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Built-in service types are now consistently called `Service` by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Built-in service creation functions with options are now consistently called `NewWithConfig` by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - `Select` method on `sqlite` service is now named `Query` for consistency with Go APIs by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) +- Creates and ad-hoc signs app bundles in dev to enable certain macOS APIs by [@popaprozac] in [#4171](https://github.com/wailsapp/wails/pull/4171) ## v3.0.0-alpha.9 - 2025-01-13 diff --git a/docs/src/content/docs/guides/signing.mdx b/docs/src/content/docs/guides/signing.mdx index b5de768c9..68b9aabed 100644 --- a/docs/src/content/docs/guides/signing.mdx +++ b/docs/src/content/docs/guides/signing.mdx @@ -86,7 +86,7 @@ This guide covers how to sign your Wails applications for both macOS and Windows 3. **Configure Notarization** ```json title="gon-sign.json" { - "source": ["./build/bin/app"], + "source": ["./build/bin/release/app"], "bundle_id": "com.company.app", "apple_id": { "username": "dev@company.com", diff --git a/docs/src/content/docs/learn/build.mdx b/docs/src/content/docs/learn/build.mdx index aeb5804af..e45c6e3b9 100644 --- a/docs/src/content/docs/learn/build.mdx +++ b/docs/src/content/docs/learn/build.mdx @@ -123,6 +123,7 @@ the application on macOS. Key features include: - Building binaries for amd64, arm64 and universal (both) architectures - Generating `.icns` icon file - Creating an `.app` bundle for distributing +- Ad-hoc signing `.app` bundles - Setting macOS-specific build flags and environment variables ## Task Execution and Command Aliases From 743882a9b9cb7ae8706da31347a431f0da16fb84 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 27 Mar 2025 13:10:45 -0700 Subject: [PATCH 113/136] update docs/changelog --- docs/src/content/docs/changelog.mdx | 1 + docs/src/content/docs/learn/notifications.mdx | 304 ++++++++++++++++++ 2 files changed, 305 insertions(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 75dbf824b..cfded500e 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -76,6 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add `SetMenu()` on window to allow for setting a menu on a window by [@leaanthony](https://github.com/leaanthony) +- Add Notification support by [@popaprozac] in [#4098](https://github.com/wailsapp/wails/pull/4098) ### Fixed diff --git a/docs/src/content/docs/learn/notifications.mdx b/docs/src/content/docs/learn/notifications.mdx index e69de29bb..6a8e9c7a8 100644 --- a/docs/src/content/docs/learn/notifications.mdx +++ b/docs/src/content/docs/learn/notifications.mdx @@ -0,0 +1,304 @@ +--- +title: Notifications +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; + +## Introduction + +Wails provides a comprehensive cross-platform notification system for desktop applications. This service allows you to display native system notifications, with support for interactive elements like action buttons and text input fields. + +## Basic Usage + +### Creating the Service + +First, initialize the notifications service: + +```go +import "github.com/wailsapp/wails/v3/pkg/application" +import "github.com/wailsapp/wails/v3/services/notifications" + +// Create a new notification service +notifier := notifications.New() + +//Register the service with the application +app := application.New(application.Options{ + Services: []application.Service{ + application.NewService(notifier), + }, +}) +``` + +## Notification Authorization + +Notifications on macOS require user authorization. Request and check authorization: + +```go +authorized, err := notifier.CheckNotificationAuthorization() +if err != nil { + // Handle authorization error +} +if authorized { + // Send notifications +} else { + // Request authorization + authorized, err = notifier.RequestNotificationAuthorization() +} +``` +On Windows and Linux this always returns `true`. + +## Notification Types + +### Basic Notifications + +Send a basic notification with a unique id, title, optional subtitle (macOS and Linux), and body text to users: + +```go +notifier.SendNotification(notifications.NotificaionOptions{ + ID: "unique-id", + Title: "New Calendar Invite", + Subtitle: "From: Jane Doe", // Optional + Body: "Tap to view the event" +}) + +``` + +### Interactive Notifications +Send a notification with action buttons and text inputs. These notifications require a notification category to be resgistered first: + +```go +// Define a unique category id +categoryID := "unique-category-id" + +// Define a category with actions +category := notifications.NotificationCategory{ + ID: categoryID, + Actions: []notifications.NotificationAction{ + { + ID: "OPEN", + Title: "Open", + }, + { + ID: "ARCHIVE", + Title: "Archive", + Destructive: true, /* macOS-specific */ + }, + }, + HasReplyField: true, + ReplyPlaceholder: "message...", + ReplyButtonTitle: "Reply", +} + +// Register the category +notifier.RegisterNotificationCategory(category) + +// Send an interactive notification with the actions registered in the provided category +notifier.SendNotificationWithActions(notifications.NotificationOptions{ + ID: "unique-id", + Title: "New Message", + Subtitle: "From: Jane Doe", + Body: "Are you able to make it?", + CategoryID: categoryID, +}) +``` + +## Notification Responses + +Process user interactions with notifications: + +```go +notifier.OnNotificationResponse(func(result notifications.NotificationResult) { + response := result.Response + fmt.Printf("Notification %s was actioned with: %s\n", response.ID, response.ActionIdentifier) + + if response.ActionIdentifier == "TEXT_REPLY" { + fmt.Printf("User replied: %s\n", response.UserText) + } + + if data, ok := response.UserInfo["sender"].(string); ok { + fmt.Printf("Original sender: %s\n", data) + } + + // Emit an event to the frontend + app.EmitEvent("notification", result.Response) +}) +``` + +## Notification Customisation + +### Custom Metadata + +Basic and interactive notifications can include custom data: + +```go +notifier.SendNotification(notifications.NotificaionOptions{ + ID: "unique-id", + Title: "New Calendar Invite", + Subtitle: "From: Jane Doe", // Optional + Body: "Tap to view the event" + Data: map[string]interface{}{ + sender: "jane.doe@example.com", + timestamp: "2025-03-10T15:30:00Z", + } +}) + +``` + +## Platform Considerations + + + + + On macOS, notifications: + + - Require user authorization + - Require the app to be notorized for distribution + - Use system-standard notification appearances + - Support `subtitle` + - Support user text input + - Support the `Destructive` action option + - Automatically handle dark/light mode + + + + + + On Windows, notifications: + + - Use Windows system toast styles + - Adapt to Windows theme settings + - Support user text input + - Support high DPI displays + - Do not support `subtitle` + + + + + + On Linux, dialog behaviour depends on the desktop environment: + + - Use native notifications when available + - Follow desktop environment theme + - Position according to desktop environment rules + - Support `subtitle` + - Do not support user text input + + + + +## Best Practices + +1. Check and request for authorization: + - macOS requires user authorization + +2. Provide clear and concise notifications: + - Use descriptive titles, subtitles, text, and action titles + +3. Handle dialog responses appropriately: + - Check for errors in notification responses + - Provide feedback for user actions + +4. Consider platform conventions: + - Follow platform-specific notification patterns + - Respect system settings + +## Examples + +Explore this example: + +- [Notifications](/examples/notifications) + +## API Reference + +### Service Management +| Method | Description | +|--------------------------------------------|-------------------------------------------------------| +| `New()` | Creates a new notifications service | + +### Notification Authorization +| Method | Description | +|----------------------------------------------|------------------------------------------------------------| +| `RequestNotificationAuthorization()` | Requests permission to display notifications (macOS) | +| `CheckNotificationAuthorization()` | Checks current notification authorization status (macOS) | + +### Sending Notifications +| Method | Description | +|------------------------------------------------------------|---------------------------------------------------| +| `SendNotification(options NotificationOptions)` | Sends a basic notification | +| `SendNotificationWithActions(options NotificationOptions)` | Sends an interactive notification with actions | + +### Notification Categories +| Method | Description | +|---------------------------------------------------------------|---------------------------------------------------| +| `RegisterNotificationCategory(category NotificationCategory)` | Registers a reusable notification category | +| `RemoveNotificationCategory(categoryID string)` | Removes a previously registered category | + +### Managing Notifications +| Method | Description | +|-------------------------------------------------|---------------------------------------------------------------------| +| `RemoveAllPendingNotifications()` | Removes all pending notifications (macOS and Linux only) | +| `RemovePendingNotification(identifier string)` | Removes a specific pending notification (macOS and Linux only) | +| `RemoveAllDeliveredNotifications()` | Removes all delivered notifications (macOS and Linux only) | +| `RemoveDeliveredNotification(identifier string)`| Removes a specific delivered notification (macOS and Linux only) | +| `RemoveNotification(identifier string)` | Removes a notification (Linux-specific) | + +### Event Handling +| Method | Description | +|--------------------------------------------------------------------|-------------------------------------------------| +| `OnNotificationResponse(callback func(result NotificationResult))` | Registers a callback for notification responses | + +### Structs and Types + +#### NotificationOptions +```go +type NotificationOptions struct { + ID string // Unique identifier for the notification + Title string // Main notification title + Subtitle string // Subtitle text (macOS and Linux only) + Body string // Main notification content + CategoryID string // Category identifier for interactive notifications + Data map[string]interface{} // Custom data to associate with the notification +} +``` + +#### NotificationCategory +```go +type NotificationCategory struct { + ID string // Unique identifier for the category + Actions []NotificationAction // Button actions for the notification + HasReplyField bool // Whether to include a text input field + ReplyPlaceholder string // Placeholder text for the input field + ReplyButtonTitle string // Text for the reply button +} +``` + +#### NotificationAction +```go +type NotificationAction struct { + ID string // Unique identifier for the action + Title string // Button text + Destructive bool // Whether the action is destructive (macOS-specific) +} +``` + +#### NotificationResponse +```go +type NotificationResponse struct { + ID string // Notification identifier + ActionIdentifier string // Action that was triggered + CategoryID string // Category of the notification + Title string // Title of the notification + Subtitle string // Subtitle of the notification + Body string // Body text of the notification + UserText string // Text entered by the user + UserInfo map[string]interface{} // Custom data from the notification +} +``` + +#### NotificationResult +```go +type NotificationResult struct { + Response NotificationResponse // Response data + Error error // Any error that occurred +} +``` \ No newline at end of file From 1022f47f142aff0eb915a28b3808bbba15ed486c Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 27 Mar 2025 13:27:39 -0700 Subject: [PATCH 114/136] fix docs --- docs/src/content/docs/learn/notifications.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/content/docs/learn/notifications.mdx b/docs/src/content/docs/learn/notifications.mdx index 6a8e9c7a8..393c563aa 100644 --- a/docs/src/content/docs/learn/notifications.mdx +++ b/docs/src/content/docs/learn/notifications.mdx @@ -54,7 +54,7 @@ On Windows and Linux this always returns `true`. Send a basic notification with a unique id, title, optional subtitle (macOS and Linux), and body text to users: ```go -notifier.SendNotification(notifications.NotificaionOptions{ +notifier.SendNotification(notifications.NotificationOptions{ ID: "unique-id", Title: "New Calendar Invite", Subtitle: "From: Jane Doe", // Optional @@ -137,8 +137,8 @@ notifier.SendNotification(notifications.NotificaionOptions{ Subtitle: "From: Jane Doe", // Optional Body: "Tap to view the event" Data: map[string]interface{}{ - sender: "jane.doe@example.com", - timestamp: "2025-03-10T15:30:00Z", + "sender": "jane.doe@example.com", + "timestamp": "2025-03-10T15:30:00Z", } }) From bd5c82ef351c5c240ae6a02c01f27b812cfb63c0 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 27 Mar 2025 14:12:53 -0700 Subject: [PATCH 115/136] fix docs --- docs/src/content/docs/learn/notifications.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/learn/notifications.mdx b/docs/src/content/docs/learn/notifications.mdx index 393c563aa..851e56228 100644 --- a/docs/src/content/docs/learn/notifications.mdx +++ b/docs/src/content/docs/learn/notifications.mdx @@ -131,7 +131,7 @@ notifier.OnNotificationResponse(func(result notifications.NotificationResult) { Basic and interactive notifications can include custom data: ```go -notifier.SendNotification(notifications.NotificaionOptions{ +notifier.SendNotification(notifications.NotificationOptions{ ID: "unique-id", Title: "New Calendar Invite", Subtitle: "From: Jane Doe", // Optional From b313f2cee137dc6148c89c598a5dae472e3ba0ae Mon Sep 17 00:00:00 2001 From: popaprozac Date: Thu, 27 Mar 2025 14:43:23 -0700 Subject: [PATCH 116/136] fix docs --- docs/src/content/docs/learn/notifications.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/content/docs/learn/notifications.mdx b/docs/src/content/docs/learn/notifications.mdx index 851e56228..5a59f5e2a 100644 --- a/docs/src/content/docs/learn/notifications.mdx +++ b/docs/src/content/docs/learn/notifications.mdx @@ -58,7 +58,7 @@ notifier.SendNotification(notifications.NotificationOptions{ ID: "unique-id", Title: "New Calendar Invite", Subtitle: "From: Jane Doe", // Optional - Body: "Tap to view the event" + Body: "Tap to view the event", }) ``` @@ -135,7 +135,7 @@ notifier.SendNotification(notifications.NotificationOptions{ ID: "unique-id", Title: "New Calendar Invite", Subtitle: "From: Jane Doe", // Optional - Body: "Tap to view the event" + Body: "Tap to view the event", Data: map[string]interface{}{ "sender": "jane.doe@example.com", "timestamp": "2025-03-10T15:30:00Z", From 8c3ee8f1bd9fd92df2f99773dec2a27871ebe611 Mon Sep 17 00:00:00 2001 From: Wilko Date: Sat, 29 Mar 2025 21:06:53 +0100 Subject: [PATCH 117/136] Support for File-Associations on macOS --- docs/src/content/docs/changelog.mdx | 1 + .../content/docs/guides/file-associations.mdx | 3 ++ v3/internal/commands/build-assets.go | 6 ++- v3/internal/commands/build_assets/config.yml | 1 + .../darwin/Info.dev.plist.tmpl | 45 ++++++++++++++----- .../darwin/Info.plist.tmpl | 45 ++++++++++++++----- 6 files changed, 77 insertions(+), 24 deletions(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 75dbf824b..291d33a42 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -76,6 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add `SetMenu()` on window to allow for setting a menu on a window by [@leaanthony](https://github.com/leaanthony) +-  Add File Association support for mac by [@wimaha] ### Fixed diff --git a/docs/src/content/docs/guides/file-associations.mdx b/docs/src/content/docs/guides/file-associations.mdx index 3394b576f..eebc29364 100644 --- a/docs/src/content/docs/guides/file-associations.mdx +++ b/docs/src/content/docs/guides/file-associations.mdx @@ -62,6 +62,7 @@ fileAssociations: | description | Description shown in file properties | Windows | | iconName | Name of the icon file (without extension) in the build folder | All | | role | Application's role for this file type (e.g., `Editor`, `Viewer`) | macOS | +| mimeType | MIME type for the file (e.g., `image/jpeg`) | macOS | ## Listening for File Open Events @@ -105,6 +106,8 @@ Let's walk through setting up file associations for a simple text editor: Run `wails3 generate icons --help` for more information. ::: + - For macOS add copy statement like `cp build/darwin/documenticon.icns {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources` in the `create:app:bundle:` task. + 2. ### Configure File Associations Edit the `build/config.yml` file to add your file associations: diff --git a/v3/internal/commands/build-assets.go b/v3/internal/commands/build-assets.go index 12b5694fd..1fa9138f5 100644 --- a/v3/internal/commands/build-assets.go +++ b/v3/internal/commands/build-assets.go @@ -4,14 +4,15 @@ import ( "embed" _ "embed" "fmt" - "github.com/leaanthony/gosod" - "gopkg.in/yaml.v3" "io/fs" "os" "path/filepath" "runtime" "strings" "time" + + "github.com/leaanthony/gosod" + "gopkg.in/yaml.v3" ) //go:embed build_assets @@ -121,6 +122,7 @@ type FileAssociation struct { Description string `yaml:"description"` IconName string `yaml:"iconName"` Role string `yaml:"role"` + MimeType string `yaml:"mimeType"` } type UpdateConfig struct { diff --git a/v3/internal/commands/build_assets/config.yml b/v3/internal/commands/build_assets/config.yml index bc09a6d28..8a5e2f4c8 100644 --- a/v3/internal/commands/build_assets/config.yml +++ b/v3/internal/commands/build_assets/config.yml @@ -56,6 +56,7 @@ fileAssociations: # description: Image File # iconName: jpegFileIcon # role: Editor +# mimeType: image/jpeg # (optional) # Other data other: diff --git a/v3/internal/commands/updatable_build_assets/darwin/Info.dev.plist.tmpl b/v3/internal/commands/updatable_build_assets/darwin/Info.dev.plist.tmpl index 47f39f537..e44a679d2 100644 --- a/v3/internal/commands/updatable_build_assets/darwin/Info.dev.plist.tmpl +++ b/v3/internal/commands/updatable_build_assets/darwin/Info.dev.plist.tmpl @@ -2,27 +2,50 @@ CFBundlePackageType - APPL + APPL CFBundleName - {{.ProductName}} + {{.ProductName}} CFBundleExecutable - {{.BinaryName}} + {{.BinaryName}} CFBundleIdentifier - {{.ProductIdentifier}} + {{.ProductIdentifier}} CFBundleVersion - {{.ProductVersion}} + {{.ProductVersion}} CFBundleGetInfoString - {{.ProductComments}} + {{.ProductComments}} CFBundleShortVersionString - {{.ProductVersion}} + {{.ProductVersion}} CFBundleIconFile - icons + icons LSMinimumSystemVersion - 10.15.0 + 10.15.0 NSHighResolutionCapable - true + true NSHumanReadableCopyright - {{.ProductCopyright}} + {{.ProductCopyright}} + {{- if .FileAssociations}} + CFBundleDocumentTypes + + {{- range .FileAssociations}} + + CFBundleTypeExtensions + + {{.Ext}} + + CFBundleTypeName + {{.Name}} + CFBundleTypeRole + {{.Role}} + CFBundleTypeIconFile + {{.IconName}} + {{- if .MimeType}} + CFBundleTypeMimeType + {{.MimeType}} + {{- end}} + + {{- end}} + + {{- end}} NSAppTransportSecurity NSAllowsLocalNetworking diff --git a/v3/internal/commands/updatable_build_assets/darwin/Info.plist.tmpl b/v3/internal/commands/updatable_build_assets/darwin/Info.plist.tmpl index 3dce3676c..c20032556 100644 --- a/v3/internal/commands/updatable_build_assets/darwin/Info.plist.tmpl +++ b/v3/internal/commands/updatable_build_assets/darwin/Info.plist.tmpl @@ -2,26 +2,49 @@ CFBundlePackageType - APPL + APPL CFBundleName - {{.ProductName}} + {{.ProductName}} CFBundleExecutable - {{.BinaryName}} + {{.BinaryName}} CFBundleIdentifier - {{.ProductIdentifier}} + {{.ProductIdentifier}} CFBundleVersion - {{.ProductVersion}} + {{.ProductVersion}} CFBundleGetInfoString - {{.ProductComments}} + {{.ProductComments}} CFBundleShortVersionString - {{.ProductVersion}} + {{.ProductVersion}} CFBundleIconFile - icons + icons LSMinimumSystemVersion - 10.15.0 + 10.15.0 NSHighResolutionCapable - true + true NSHumanReadableCopyright - {{.ProductCopyright}} + {{.ProductCopyright}} + {{- if .FileAssociations}} + CFBundleDocumentTypes + + {{- range .FileAssociations}} + + CFBundleTypeExtensions + + {{.Ext}} + + CFBundleTypeName + {{.Name}} + CFBundleTypeRole + {{.Role}} + CFBundleTypeIconFile + {{.IconName}} + {{- if .MimeType}} + CFBundleTypeMimeType + {{.MimeType}} + {{- end}} + + {{- end}} + + {{- end}} \ No newline at end of file From 5f8a858aa9a42ede5e39346b29fd2887af07b7ae Mon Sep 17 00:00:00 2001 From: Wilko Date: Sat, 29 Mar 2025 21:40:50 +0100 Subject: [PATCH 118/136] Update changelog.mdx --- docs/src/content/docs/changelog.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 291d33a42..79e020b66 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -76,7 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add `SetMenu()` on window to allow for setting a menu on a window by [@leaanthony](https://github.com/leaanthony) --  Add File Association support for mac by [@wimaha] +-  Add File Association support for mac by [@wimaha](https://github.com/wimaha) in [#4177](https://github.com/wailsapp/wails/pull/4177) ### Fixed From 9a41b0ce9f9a2e4d5d62e717491ec7a37615b53b Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 29 Mar 2025 23:36:25 -0700 Subject: [PATCH 119/136] move icon method, impl interface, check compat, don't panic! --- .../notifications/notifications_darwin.go | 43 +++-- .../notifications/notifications_darwin.h | 1 + .../notifications/notifications_darwin.m | 39 ++-- .../notifications/notifications_windows.go | 2 +- .../notifications_windows_icon.go | 173 ------------------ v3/pkg/w32/icon.go | 118 ++++++++++++ 6 files changed, 176 insertions(+), 200 deletions(-) delete mode 100644 v3/pkg/services/notifications/notifications_windows_icon.go diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 1a64cbb9e..02dc4fc95 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -3,8 +3,13 @@ package notifications /* -#cgo CFLAGS: -mmacosx-version-min=11.0 -x objective-c -#cgo LDFLAGS: -framework Cocoa -mmacosx-version-min=11 -framework UserNotifications +#cgo CFLAGS:-x objective-c +#cgo LDFLAGS: -framework Foundation -framework Cocoa + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 +#cgo LDFLAGS: -framework UserNotifications +#endif + #import "./notifications_darwin.h" */ import "C" @@ -30,21 +35,18 @@ type notificationChannel struct { Error error } +type ChannelHandler interface { + GetChannel(id int) (chan notificationChannel, bool) +} + +var _ ChannelHandler = (*darwinNotifier)(nil) + const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" // Creates a new Notifications Service. // Your app must be packaged and signed for this feature to work. func New() *Service { notificationServiceOnce.Do(func() { - if !CheckBundleIdentifier() { - panic("\nError: Cannot use the notification API in development mode on macOS.\n" + - "Notifications require the app to be properly bundled with a bundle identifier and signed.\n" + - "To use the notification API on macOS:\n" + - " 1. Build and package your app using 'wails3 package'\n" + - " 2. Sign the packaged .app\n" + - " 3. Run the signed .app bundle") - } - impl := &darwinNotifier{ channels: make(map[int]chan notificationChannel), nextChannelID: 0, @@ -59,6 +61,12 @@ func New() *Service { } func (dn *darwinNotifier) Startup(ctx context.Context, options application.ServiceOptions) error { + if !isNotificationAvailable() { + return fmt.Errorf("notifications are not available on this system") + } + if !checkBundleIdentifier() { + return fmt.Errorf("notifications require a valid bundle identifier") + } return nil } @@ -66,7 +74,12 @@ func (dn *darwinNotifier) Shutdown() error { return nil } -func CheckBundleIdentifier() bool { +// isNotificationAvailable checks if notifications are available on the system. +func isNotificationAvailable() bool { + return bool(C.isNotificationAvailable()) +} + +func checkBundleIdentifier() bool { return bool(C.checkBundleIdentifier()) } @@ -310,12 +323,12 @@ func captureResult(channelID C.int, success C.bool, errorMsg *C.char) { return } - dn, ok := ns.impl.(*darwinNotifier) + handler, ok := ns.impl.(ChannelHandler) if !ok { return } - resultCh, exists := dn.getChannel(int(channelID)) + resultCh, exists := handler.GetChannel(int(channelID)) if !exists { return } @@ -390,7 +403,7 @@ func (dn *darwinNotifier) registerChannel() (int, chan notificationChannel) { return id, resultCh } -func (dn *darwinNotifier) getChannel(id int) (chan notificationChannel, bool) { +func (dn *darwinNotifier) GetChannel(id int) (chan notificationChannel, bool) { dn.channelsLock.Lock() defer dn.channelsLock.Unlock() diff --git a/v3/pkg/services/notifications/notifications_darwin.h b/v3/pkg/services/notifications/notifications_darwin.h index f7acf6d1a..7cd505240 100644 --- a/v3/pkg/services/notifications/notifications_darwin.h +++ b/v3/pkg/services/notifications/notifications_darwin.h @@ -6,6 +6,7 @@ #import bool checkBundleIdentifier(void); +bool isNotificationAvailable(void); void requestNotificationAuthorization(int channelID); void checkNotificationAuthorization(int channelID); void sendNotification(int channelID, const char *identifier, const char *title, const char *subtitle, const char *body, const char *data_json); diff --git a/v3/pkg/services/notifications/notifications_darwin.m b/v3/pkg/services/notifications/notifications_darwin.m index 4ea4918ae..6c2048b74 100644 --- a/v3/pkg/services/notifications/notifications_darwin.m +++ b/v3/pkg/services/notifications/notifications_darwin.m @@ -1,7 +1,26 @@ #import "notifications_darwin.h" #include #import + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 #import +#endif + +bool isNotificationAvailable(void) { + if (@available(macOS 11.0, *)) { + return YES; + } else { + return NO; + } +} + +bool checkBundleIdentifier(void) { + NSBundle *main = [NSBundle mainBundle]; + if (main.bundleIdentifier == nil) { + return NO; + } + return YES; +} extern void captureResult(int channelID, bool success, const char* error); extern void didReceiveNotificationResponse(const char *jsonPayload, const char* error); @@ -14,9 +33,15 @@ extern void didReceiveNotificationResponse(const char *jsonPayload, const char* - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { - UNNotificationPresentationOptions options = UNNotificationPresentationOptionList | - UNNotificationPresentationOptionBanner | - UNNotificationPresentationOptionSound; + UNNotificationPresentationOptions options = 0; + + if (@available(macOS 11.0, *)) { + // These options are only available in macOS 11.0+ + options = UNNotificationPresentationOptionList | + UNNotificationPresentationOptionBanner | + UNNotificationPresentationOptionSound; + } + completionHandler(options); } @@ -82,14 +107,6 @@ static BOOL ensureDelegateInitialized(void) { return success; } -bool checkBundleIdentifier(void) { - NSBundle *main = [NSBundle mainBundle]; - if (main.bundleIdentifier == nil) { - return false; - } - return true; -} - void requestNotificationAuthorization(int channelID) { if (!ensureDelegateInitialized()) { NSString *errorMsg = @"Notification delegate has been lost. Reinitialize the notification service."; diff --git a/v3/pkg/services/notifications/notifications_windows.go b/v3/pkg/services/notifications/notifications_windows.go index e22fe01b6..b7a16decc 100644 --- a/v3/pkg/services/notifications/notifications_windows.go +++ b/v3/pkg/services/notifications/notifications_windows.go @@ -327,7 +327,7 @@ func (wn *windowsNotifier) saveIconToDir() error { return fmt.Errorf("failed to retrieve application icon: %w", err) } - return saveHIconAsPNG(icon, wn.iconPath) + return w32.SaveHIconAsPNG(icon, wn.iconPath) } func (wn *windowsNotifier) saveCategoriesToRegistry() error { diff --git a/v3/pkg/services/notifications/notifications_windows_icon.go b/v3/pkg/services/notifications/notifications_windows_icon.go deleted file mode 100644 index aed560594..000000000 --- a/v3/pkg/services/notifications/notifications_windows_icon.go +++ /dev/null @@ -1,173 +0,0 @@ -//go:build windows - -package notifications - -import ( - "image" - "image/color" - "image/png" - "os" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v3/pkg/w32" -) - -// Windows API constants -const ( - SRCCOPY = 0x00CC0020 - BI_RGB = 0 - DIB_RGB_COLORS = 0 -) - -// Windows structures -type ICONINFO struct { - FIcon int32 - XHotspot int32 - YHotspot int32 - HbmMask syscall.Handle - HbmColor syscall.Handle -} - -type BITMAP struct { - BmType int32 - BmWidth int32 - BmHeight int32 - BmWidthBytes int32 - BmPlanes uint16 - BmBitsPixel uint16 - BmBits uintptr -} - -type BITMAPINFOHEADER struct { - BiSize uint32 - BiWidth int32 - BiHeight int32 - BiPlanes uint16 - BiBitCount uint16 - BiCompression uint32 - BiSizeImage uint32 - BiXPelsPerMeter int32 - BiYPelsPerMeter int32 - BiClrUsed uint32 - BiClrImportant uint32 -} - -type RGBQUAD struct { - RgbBlue byte - RgbGreen byte - RgbRed byte - RgbReserved byte -} - -type BITMAPINFO struct { - BmiHeader BITMAPINFOHEADER - BmiColors [1]RGBQUAD -} - -func saveHIconAsPNG(hIcon w32.HICON, filePath string) error { - // Load necessary DLLs - user32 := syscall.NewLazyDLL("user32.dll") - gdi32 := syscall.NewLazyDLL("gdi32.dll") - - // Get procedures - getIconInfo := user32.NewProc("GetIconInfo") - getObject := gdi32.NewProc("GetObjectW") - createCompatibleDC := gdi32.NewProc("CreateCompatibleDC") - selectObject := gdi32.NewProc("SelectObject") - getDIBits := gdi32.NewProc("GetDIBits") - deleteObject := gdi32.NewProc("DeleteObject") - deleteDC := gdi32.NewProc("DeleteDC") - - // Get icon info - var iconInfo ICONINFO - ret, _, err := getIconInfo.Call( - uintptr(hIcon), - uintptr(unsafe.Pointer(&iconInfo)), - ) - if ret == 0 { - return err - } - defer deleteObject.Call(uintptr(iconInfo.HbmMask)) - defer deleteObject.Call(uintptr(iconInfo.HbmColor)) - - // Get bitmap info - var bmp BITMAP - ret, _, err = getObject.Call( - uintptr(iconInfo.HbmColor), - unsafe.Sizeof(bmp), - uintptr(unsafe.Pointer(&bmp)), - ) - if ret == 0 { - return err - } - - // Create DC - hdc, _, _ := createCompatibleDC.Call(0) - if hdc == 0 { - return syscall.EINVAL - } - defer deleteDC.Call(hdc) - - // Select bitmap into DC - oldBitmap, _, _ := selectObject.Call(hdc, uintptr(iconInfo.HbmColor)) - defer selectObject.Call(hdc, oldBitmap) - - // Prepare bitmap info header - var bi BITMAPINFO - bi.BmiHeader.BiSize = uint32(unsafe.Sizeof(bi.BmiHeader)) - bi.BmiHeader.BiWidth = bmp.BmWidth - bi.BmiHeader.BiHeight = bmp.BmHeight - bi.BmiHeader.BiPlanes = 1 - bi.BmiHeader.BiBitCount = 32 - bi.BmiHeader.BiCompression = BI_RGB - - // Allocate memory for bitmap bits - width, height := int(bmp.BmWidth), int(bmp.BmHeight) - bufferSize := width * height * 4 - bits := make([]byte, bufferSize) - - // Get bitmap bits - ret, _, err = getDIBits.Call( - hdc, - uintptr(iconInfo.HbmColor), - 0, - uintptr(bmp.BmHeight), - uintptr(unsafe.Pointer(&bits[0])), - uintptr(unsafe.Pointer(&bi)), - DIB_RGB_COLORS, - ) - if ret == 0 { - return err - } - - // Create Go image - img := image.NewRGBA(image.Rect(0, 0, width, height)) - - // Convert DIB to RGBA - for y := 0; y < height; y++ { - for x := 0; x < width; x++ { - // DIB is bottom-up, so we need to invert Y - dibIndex := ((height-1-y)*width + x) * 4 - - // BGRA to RGBA - b := bits[dibIndex] - g := bits[dibIndex+1] - r := bits[dibIndex+2] - a := bits[dibIndex+3] - - // Set pixel in the image - img.Set(x, y, color.RGBA{R: r, G: g, B: b, A: a}) - } - } - - // Create output file - outFile, err := os.Create(filePath) - if err != nil { - return err - } - defer outFile.Close() - - // Encode and save the image - return png.Encode(outFile, img) -} diff --git a/v3/pkg/w32/icon.go b/v3/pkg/w32/icon.go index 009479323..97d4ad854 100644 --- a/v3/pkg/w32/icon.go +++ b/v3/pkg/w32/icon.go @@ -6,8 +6,11 @@ import ( "bytes" "fmt" "image" + "image/color" "image/draw" "image/png" + "os" + "syscall" "unsafe" ) @@ -90,6 +93,121 @@ func CreateLargeHIconFromImage(fileData []byte) (HICON, error) { return HICON(icon), err } +type ICONINFO struct { + FIcon int32 + XHotspot int32 + YHotspot int32 + HbmMask syscall.Handle + HbmColor syscall.Handle +} + +func SaveHIconAsPNG(hIcon HICON, filePath string) error { + // Load necessary DLLs + user32 := syscall.NewLazyDLL("user32.dll") + gdi32 := syscall.NewLazyDLL("gdi32.dll") + + // Get procedures + getIconInfo := user32.NewProc("GetIconInfo") + getObject := gdi32.NewProc("GetObjectW") + createCompatibleDC := gdi32.NewProc("CreateCompatibleDC") + selectObject := gdi32.NewProc("SelectObject") + getDIBits := gdi32.NewProc("GetDIBits") + deleteObject := gdi32.NewProc("DeleteObject") + deleteDC := gdi32.NewProc("DeleteDC") + + // Get icon info + var iconInfo ICONINFO + ret, _, err := getIconInfo.Call( + uintptr(hIcon), + uintptr(unsafe.Pointer(&iconInfo)), + ) + if ret == 0 { + return err + } + defer deleteObject.Call(uintptr(iconInfo.HbmMask)) + defer deleteObject.Call(uintptr(iconInfo.HbmColor)) + + // Get bitmap info + var bmp BITMAP + ret, _, err = getObject.Call( + uintptr(iconInfo.HbmColor), + unsafe.Sizeof(bmp), + uintptr(unsafe.Pointer(&bmp)), + ) + if ret == 0 { + return err + } + + // Create DC + hdc, _, _ := createCompatibleDC.Call(0) + if hdc == 0 { + return syscall.EINVAL + } + defer deleteDC.Call(hdc) + + // Select bitmap into DC + oldBitmap, _, _ := selectObject.Call(hdc, uintptr(iconInfo.HbmColor)) + defer selectObject.Call(hdc, oldBitmap) + + // Prepare bitmap info header + var bi BITMAPINFO + bi.BmiHeader.BiSize = uint32(unsafe.Sizeof(bi.BmiHeader)) + bi.BmiHeader.BiWidth = bmp.BmWidth + bi.BmiHeader.BiHeight = bmp.BmHeight + bi.BmiHeader.BiPlanes = 1 + bi.BmiHeader.BiBitCount = 32 + bi.BmiHeader.BiCompression = BI_RGB + + // Allocate memory for bitmap bits + width, height := int(bmp.BmWidth), int(bmp.BmHeight) + bufferSize := width * height * 4 + bits := make([]byte, bufferSize) + + // Get bitmap bits + ret, _, err = getDIBits.Call( + hdc, + uintptr(iconInfo.HbmColor), + 0, + uintptr(bmp.BmHeight), + uintptr(unsafe.Pointer(&bits[0])), + uintptr(unsafe.Pointer(&bi)), + DIB_RGB_COLORS, + ) + if ret == 0 { + return err + } + + // Create Go image + img := image.NewRGBA(image.Rect(0, 0, width, height)) + + // Convert DIB to RGBA + for y := 0; y < height; y++ { + for x := 0; x < width; x++ { + // DIB is bottom-up, so we need to invert Y + dibIndex := ((height-1-y)*width + x) * 4 + + // BGRA to RGBA + b := bits[dibIndex] + g := bits[dibIndex+1] + r := bits[dibIndex+2] + a := bits[dibIndex+3] + + // Set pixel in the image + img.Set(x, y, color.RGBA{R: r, G: g, B: b, A: a}) + } + } + + // Create output file + outFile, err := os.Create(filePath) + if err != nil { + return err + } + defer outFile.Close() + + // Encode and save the image + return png.Encode(outFile, img) +} + func SetWindowIcon(hwnd HWND, icon HICON) { SendMessage(hwnd, WM_SETICON, ICON_SMALL, uintptr(icon)) } From 75dbe85ad699c5bc6f71f38c2d0de87f0d53c48b Mon Sep 17 00:00:00 2001 From: popaprozac Date: Sat, 29 Mar 2025 23:39:50 -0700 Subject: [PATCH 120/136] remove comptime check --- v3/pkg/services/notifications/notifications_darwin.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/v3/pkg/services/notifications/notifications_darwin.go b/v3/pkg/services/notifications/notifications_darwin.go index 02dc4fc95..2c8f33d15 100644 --- a/v3/pkg/services/notifications/notifications_darwin.go +++ b/v3/pkg/services/notifications/notifications_darwin.go @@ -39,8 +39,6 @@ type ChannelHandler interface { GetChannel(id int) (chan notificationChannel, bool) } -var _ ChannelHandler = (*darwinNotifier)(nil) - const AppleDefaultActionIdentifier = "com.apple.UNNotificationDefaultActionIdentifier" // Creates a new Notifications Service. From 3f22e1fe0ca39e3ca5825f8e7f2960aa56a60139 Mon Sep 17 00:00:00 2001 From: Gabriel Lima <39922116+TheGB0077@users.noreply.github.com> Date: Sun, 6 Apr 2025 22:36:22 -0300 Subject: [PATCH 121/136] Normalize Windows paths by default JS code ends up escaping Windows paths when data gets passed around from backend to the frontend, so those should be normalized beforehand. --- v3/pkg/application/dialogs_windows.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/v3/pkg/application/dialogs_windows.go b/v3/pkg/application/dialogs_windows.go index 36e153141..04b9e96b8 100644 --- a/v3/pkg/application/dialogs_windows.go +++ b/v3/pkg/application/dialogs_windows.go @@ -234,6 +234,10 @@ func convertFilters(filters []FileFilter) []cfd.FileFilter { return result } +func normalizeWindowsPath(path string) string { + return strings.ReplaceAll(path, "\\", "/") +} + func showCfdDialog(newDlg func() (cfd.Dialog, error), isMultiSelect bool) (any, error) { dlg, err := newDlg() if err != nil { @@ -247,7 +251,20 @@ func showCfdDialog(newDlg func() (cfd.Dialog, error), isMultiSelect bool) (any, }() if multi, _ := dlg.(cfd.OpenMultipleFilesDialog); multi != nil && isMultiSelect { - return multi.ShowAndGetResults() + paths, err := multi.ShowAndGetResults() + if err != nil { + return nil, err + } + + for i, path := range paths { + paths[i] = normalizeWindowsPath(path) + } + return paths, nil } - return dlg.ShowAndGetResult() + + path, err := dlg.ShowAndGetResult() + if err != nil { + return nil, err + } + return normalizeWindowsPath(path), nil } From f6750c3a481b759e45c4d6c9d9055fd061ad0239 Mon Sep 17 00:00:00 2001 From: Gabriel Lima <39922116+TheGB0077@users.noreply.github.com> Date: Mon, 7 Apr 2025 13:35:37 -0300 Subject: [PATCH 122/136] delete redundant method --- v3/pkg/application/dialogs_windows.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/v3/pkg/application/dialogs_windows.go b/v3/pkg/application/dialogs_windows.go index 04b9e96b8..ef5b625fc 100644 --- a/v3/pkg/application/dialogs_windows.go +++ b/v3/pkg/application/dialogs_windows.go @@ -234,10 +234,6 @@ func convertFilters(filters []FileFilter) []cfd.FileFilter { return result } -func normalizeWindowsPath(path string) string { - return strings.ReplaceAll(path, "\\", "/") -} - func showCfdDialog(newDlg func() (cfd.Dialog, error), isMultiSelect bool) (any, error) { dlg, err := newDlg() if err != nil { @@ -257,7 +253,7 @@ func showCfdDialog(newDlg func() (cfd.Dialog, error), isMultiSelect bool) (any, } for i, path := range paths { - paths[i] = normalizeWindowsPath(path) + paths[i] = filepath.Clean(path) } return paths, nil } @@ -266,5 +262,5 @@ func showCfdDialog(newDlg func() (cfd.Dialog, error), isMultiSelect bool) (any, if err != nil { return nil, err } - return normalizeWindowsPath(path), nil + return filepath.Clean(path), nil } From e62c0b0b80f00701efb29dc8390ecd3958344e1a Mon Sep 17 00:00:00 2001 From: Gabriel Lima <39922116+TheGB0077@users.noreply.github.com> Date: Mon, 7 Apr 2025 20:27:11 -0300 Subject: [PATCH 123/136] Add fix to changelog [skip ci] --- docs/src/content/docs/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 75dbf824b..e0cc919ea 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -111,6 +111,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed initially-hidden menu items by [@IanVS](https://github.com/IanVS) in [#4116](https://github.com/wailsapp/wails/pull/4116) - Fixed assetFileServer not serving `.html` files when non-extension request when `[request]` doesn't exist but `[request].html` does - Fixed icon generation paths by [@robin-samuel](https://github.com/robin-samuel) in [#4125](https://github.com/wailsapp/wails/pull/4125) +- Fixed Dialogs rutime function returning escaped paths on Windows by [TheGB0077](https://github.com/TheGB0077) in [#4188](https://github.com/wailsapp/wails/pull/4188) ### Changed From 1b00dc9ac7fa380452a280d6a1b279626c39d209 Mon Sep 17 00:00:00 2001 From: Gabriel Lima <39922116+TheGB0077@users.noreply.github.com> Date: Mon, 7 Apr 2025 20:30:01 -0300 Subject: [PATCH 124/136] small typo --- docs/src/content/docs/changelog.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index e0cc919ea..ef003acf3 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -111,7 +111,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed initially-hidden menu items by [@IanVS](https://github.com/IanVS) in [#4116](https://github.com/wailsapp/wails/pull/4116) - Fixed assetFileServer not serving `.html` files when non-extension request when `[request]` doesn't exist but `[request].html` does - Fixed icon generation paths by [@robin-samuel](https://github.com/robin-samuel) in [#4125](https://github.com/wailsapp/wails/pull/4125) -- Fixed Dialogs rutime function returning escaped paths on Windows by [TheGB0077](https://github.com/TheGB0077) in [#4188](https://github.com/wailsapp/wails/pull/4188) +- Fixed Dialogs runtime function returning escaped paths on Windows by [TheGB0077](https://github.com/TheGB0077) in [#4188](https://github.com/wailsapp/wails/pull/4188) ### Changed From f46352dbe1d64e53abdb3a9a010b1779badcd37a Mon Sep 17 00:00:00 2001 From: Gabriel Lima <39922116+TheGB0077@users.noreply.github.com> Date: Wed, 9 Apr 2025 16:21:59 -0300 Subject: [PATCH 125/136] Create dialogs_windows_test.go --- v3/pkg/application/dialogs_windows_test.go | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 v3/pkg/application/dialogs_windows_test.go diff --git a/v3/pkg/application/dialogs_windows_test.go b/v3/pkg/application/dialogs_windows_test.go new file mode 100644 index 000000000..af4dabf75 --- /dev/null +++ b/v3/pkg/application/dialogs_windows_test.go @@ -0,0 +1,57 @@ +//go:build windows + +package application_test + +import ( + "path/filepath" + "testing" + + "github.com/matryer/is" +) + +func TestCleanPath(t *testing.T) { + i := is.New(t) + tests := []struct { + name string + inputPath string + expected string + }{ + { + name: "path with double separators", + inputPath: `C:\\temp\\folder`, + expected: `C:\temp\folder`, + }, + { + name: "path with forward slashes", + inputPath: `C://temp//folder`, + expected: `C:\temp\folder`, + }, + { + name: "path with trailing separator", + inputPath: `C:\\temp\\folder\\`, + expected: `C:\temp\folder`, + }, + { + name: "path with escaped tab character", + inputPath: `C:\\Users\\test\\tab.txt`, + expected: `C:\Users\test\tab.txt`, + }, + { + name: "newline character", + inputPath: `C:\\Users\\test\\newline\\n.txt`, + expected: `C:\Users\test\newline\n.txt`, + }, + { + name: "UNC path with multiple separators", + inputPath: `\\\\\\\\host\\share\\test.txt`, + expected: `\\\\host\share\test.txt`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cleaned := filepath.Clean(tt.inputPath) + i.Equal(cleaned, tt.expected) + }) + } +} From c482c85c7b3885438c2b1dd8b20ae4998ee37131 Mon Sep 17 00:00:00 2001 From: popaprozac Date: Wed, 9 Apr 2025 15:48:52 -0700 Subject: [PATCH 126/136] revert and append .dev --- docs/src/content/docs/guides/signing.mdx | 2 +- .../commands/build_assets/darwin/Taskfile.yml | 32 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/src/content/docs/guides/signing.mdx b/docs/src/content/docs/guides/signing.mdx index 68b9aabed..b5de768c9 100644 --- a/docs/src/content/docs/guides/signing.mdx +++ b/docs/src/content/docs/guides/signing.mdx @@ -86,7 +86,7 @@ This guide covers how to sign your Wails applications for both macOS and Windows 3. **Configure Notarization** ```json title="gon-sign.json" { - "source": ["./build/bin/release/app"], + "source": ["./build/bin/app"], "bundle_id": "com.company.app", "apple_id": { "username": "dev@company.com", diff --git a/v3/internal/commands/build_assets/darwin/Taskfile.yml b/v3/internal/commands/build_assets/darwin/Taskfile.yml index 3dd73a042..f0791fea9 100644 --- a/v3/internal/commands/build_assets/darwin/Taskfile.yml +++ b/v3/internal/commands/build_assets/darwin/Taskfile.yml @@ -19,7 +19,7 @@ tasks: - go build {{.BUILD_FLAGS}} -o {{.OUTPUT}} vars: BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}' - DEFAULT_OUTPUT: '{{.BIN_DIR}}/build/{{.APP_NAME}}' + DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}' OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}' env: GOOS: darwin @@ -36,14 +36,14 @@ tasks: - task: build vars: ARCH: amd64 - OUTPUT: "{{.BIN_DIR}}/build/{{.APP_NAME}}-amd64" + OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" - task: build vars: ARCH: arm64 - OUTPUT: "{{.BIN_DIR}}/build/{{.APP_NAME}}-arm64" + OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" cmds: - - lipo -create -output "{{.BIN_DIR}}/build/{{.APP_NAME}}" "{{.BIN_DIR}}/build/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/build/{{.APP_NAME}}-arm64" - - rm "{{.BIN_DIR}}/build/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/build/{{.APP_NAME}}-arm64" + - lipo -create -output "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" + - rm "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64" package: summary: Packages a production build of the application into a `.app` bundle @@ -65,17 +65,17 @@ tasks: create:app:bundle: summary: Creates an `.app` bundle cmds: - - mkdir -p {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents/{MacOS,Resources} - - cp build/darwin/icons.icns {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents/Resources - - cp {{.BIN_DIR}}/build/{{.APP_NAME}} {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents/MacOS - - cp build/darwin/Info.plist {{.BIN_DIR}}/release/{{.APP_NAME}}.app/Contents - - codesign --force --deep --sign - {{.BIN_DIR}}/release/{{.APP_NAME}}.app + - mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/{MacOS,Resources} + - cp build/darwin/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources + - cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS + - cp build/darwin/Info.plist {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents + - codesign --force --deep --sign - {{.BIN_DIR}}/{{.APP_NAME}}.app run: cmds: - - mkdir -p {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/{MacOS,Resources} - - cp build/darwin/icons.icns {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/Resources - - cp {{.BIN_DIR}}/build/{{.APP_NAME}} {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/MacOS - - cp build/darwin/Info.dev.plist {{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/Info.plist - - codesign --force --deep --sign - {{.BIN_DIR}}/dev/{{.APP_NAME}}.app - - '{{.BIN_DIR}}/dev/{{.APP_NAME}}.app/Contents/MacOS/{{.APP_NAME}}' + - mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/{MacOS,Resources} + - cp build/darwin/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Resources + - cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/MacOS + - cp build/darwin/Info.dev.plist {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Info.plist + - codesign --force --deep --sign - {{.BIN_DIR}}/{{.APP_NAME}}.dev.app + - '{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/MacOS/{{.APP_NAME}}' From be1d500974a7bd27f9a635792e7e7088cb4d945c Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 12 Apr 2025 13:21:58 +1000 Subject: [PATCH 127/136] Update v3/examples/notifications/build/windows/nsis/wails_tools.nsh Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- v3/examples/notifications/build/windows/nsis/wails_tools.nsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/examples/notifications/build/windows/nsis/wails_tools.nsh b/v3/examples/notifications/build/windows/nsis/wails_tools.nsh index ee4c8ca1a..c47c784a4 100644 --- a/v3/examples/notifications/build/windows/nsis/wails_tools.nsh +++ b/v3/examples/notifications/build/windows/nsis/wails_tools.nsh @@ -158,7 +158,7 @@ RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}" ${If} ${REQUEST_EXECUTION_LEVEL} == "user" # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed - ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" ${If} $0 != "" Goto ok ${EndIf} From f891096d974594f9186915ac08a346541debcaad Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 12 Apr 2025 13:24:36 +1000 Subject: [PATCH 128/136] Fix for webview2 detection --- docs/src/content/docs/changelog.mdx | 1 + .../updatable_build_assets/windows/nsis/wails_tools.nsh.tmpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index d289b3030..6b9c5f152 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -113,6 +113,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed assetFileServer not serving `.html` files when non-extension request when `[request]` doesn't exist but `[request].html` does - Fixed icon generation paths by [@robin-samuel](https://github.com/robin-samuel) in [#4125](https://github.com/wailsapp/wails/pull/4125) - Fixed Dialogs runtime function returning escaped paths on Windows by [TheGB0077](https://github.com/TheGB0077) in [#4188](https://github.com/wailsapp/wails/pull/4188) +- Fixed Webview2 detection path in HKCU by [@leaanthony](https://github.com/leaanthony). ### Changed diff --git a/v3/internal/commands/updatable_build_assets/windows/nsis/wails_tools.nsh.tmpl b/v3/internal/commands/updatable_build_assets/windows/nsis/wails_tools.nsh.tmpl index ca5c11ccc..aae481317 100644 --- a/v3/internal/commands/updatable_build_assets/windows/nsis/wails_tools.nsh.tmpl +++ b/v3/internal/commands/updatable_build_assets/windows/nsis/wails_tools.nsh.tmpl @@ -158,7 +158,7 @@ RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}" ${If} ${REQUEST_EXECUTION_LEVEL} == "user" # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed - ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" ${If} $0 != "" Goto ok ${EndIf} From a9c031155a4b524e5309c539c1e28d2f033faa82 Mon Sep 17 00:00:00 2001 From: yulesxoxo <189644144+yulesxoxo@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:22:05 +0200 Subject: [PATCH 129/136] fix: correct Windows filename in generate:icons task --- v3/cmd/wails3/README.md | 12 ++++++------ .../file-association/build/Taskfile.common.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/v3/cmd/wails3/README.md b/v3/cmd/wails3/README.md index 91ecdafeb..8924153dd 100644 --- a/v3/cmd/wails3/README.md +++ b/v3/cmd/wails3/README.md @@ -21,13 +21,13 @@ It can be used to generate many things including: The `icon` command generates icons for your project. -| Flag | Type | Description | Default | -|--------------------|--------|------------------------------------------------------|-----------------------| -| `-example` | bool | Generates example icon file (appicon.png) | | -| `-input` | string | The input image file | | +| Flag | Type | Description | Default | +|--------------------|--------|------------------------------------------------------|----------------------| +| `-example` | bool | Generates example icon file (appicon.png) | | +| `-input` | string | The input image file | | | `-sizes` | string | The sizes to generate in .ico file (comma separated) | "256,128,64,48,32,16" | -| `-windowsFilename` | string | The output filename for the Windows icon | icons.ico | -| `-macFilename` | string | The output filename for the Mac icon bundle | icons.icns | +| `-windowsFilename` | string | The output filename for the Windows icon | icon.ico | +| `-macFilename` | string | The output filename for the Mac icon bundle | icons.icns | ```bash wails3 generate icon -input myicon.png -sizes "32,64,128" -windowsFilename myicon.ico -macFilename myicon.icns diff --git a/v3/examples/file-association/build/Taskfile.common.yml b/v3/examples/file-association/build/Taskfile.common.yml index 2b8a4d26d..650c8ea83 100644 --- a/v3/examples/file-association/build/Taskfile.common.yml +++ b/v3/examples/file-association/build/Taskfile.common.yml @@ -56,7 +56,7 @@ tasks: - "appicon.png" generates: - "icons.icns" - - "icons.ico" + - "icon.ico" cmds: - wails3 generate icons -input appicon.png From b3cd25cb4abf9dceabc151ad01dcdc86294ecc0a Mon Sep 17 00:00:00 2001 From: yulesxoxo <189644144+yulesxoxo@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:27:05 +0200 Subject: [PATCH 130/136] feat: update changelog --- docs/src/content/docs/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 681e3715f..4b399a8db 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -115,6 +115,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed icon generation paths by [@robin-samuel](https://github.com/robin-samuel) in [#4125](https://github.com/wailsapp/wails/pull/4125) - Fixed Dialogs runtime function returning escaped paths on Windows by [TheGB0077](https://github.com/TheGB0077) in [#4188](https://github.com/wailsapp/wails/pull/4188) - Fixed Webview2 detection path in HKCU by [@leaanthony](https://github.com/leaanthony). +- Fixed Windows icon generation task file name by [@yulesxoxo](https://github.com/yulesxoxo) in [#4219](https://github.com/wailsapp/wails/pull/4219). ### Changed From e97c390f12bf36d241de703431452f951d3b031a Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 18 Apr 2025 15:47:59 +1000 Subject: [PATCH 131/136] Update v3/examples/gin-service/README.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- v3/examples/gin-service/README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/v3/examples/gin-service/README.md b/v3/examples/gin-service/README.md index ed9c2b908..89e5019d7 100644 --- a/v3/examples/gin-service/README.md +++ b/v3/examples/gin-service/README.md @@ -14,11 +14,6 @@ This example shows how to: ## Running the Example -```bash -cd v3/examples/gin-routing -go mod tidy -go run . -``` ## Documentation From 1f5e9852e48144df57a3948e24d5f552b9d3e35b Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 18 Apr 2025 15:49:41 +1000 Subject: [PATCH 132/136] Update v3/examples/gin-service/services/gin_service.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../gin-service/services/gin_service.go | 65 +++++++++++++------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/v3/examples/gin-service/services/gin_service.go b/v3/examples/gin-service/services/gin_service.go index 6c3ef9f70..a67a0f575 100644 --- a/v3/examples/gin-service/services/gin_service.go +++ b/v3/examples/gin-service/services/gin_service.go @@ -137,30 +137,57 @@ func (s *GinService) setupRoutes() { c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) }) - // Create a new user - users.POST("", func(c *gin.Context) { - var newUser User - if err := c.ShouldBindJSON(&newUser); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } +// import block (ensure this exists in your file) +import ( + "context" + "net/http" + "strconv" + "strings" + "sync" + "time" +) - s.mu.Lock() - defer s.mu.Unlock() +// ... - // Set the ID and creation time - newUser.ID = s.nextID - newUser.CreatedAt = time.Now() - s.nextID++ +// Create a new user +users.POST("", func(c *gin.Context) { + var newUser User + if err := c.ShouldBindJSON(&newUser); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } - // Add to the users slice - s.users = append(s.users, newUser) + // Validate required fields + if newUser.Name == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "Name is required"}) + return + } + if newUser.Email == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "Email is required"}) + return + } + // Basic email validation (consider using a proper validator library in production) + if !strings.Contains(newUser.Email, "@") { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid email format"}) + return + } - c.JSON(http.StatusCreated, newUser) + s.mu.Lock() + defer s.mu.Unlock() - // Emit an event to notify about the new user - s.app.EmitEvent("user-created", newUser) - }) + // Set the ID and creation time + newUser.ID = s.nextID + newUser.CreatedAt = time.Now() + s.nextID++ + + // Add to the users slice + s.users = append(s.users, newUser) + + c.JSON(http.StatusCreated, newUser) + + // Emit an event to notify about the new user + s.app.EmitEvent("user-created", newUser) +}) // Delete a user users.DELETE("/:id", func(c *gin.Context) { From eb8a1b53d204c412f017b1cb92afa2170ea33ed0 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 18 Apr 2025 16:11:14 +1000 Subject: [PATCH 133/136] Fix for input on mac --- v3/internal/templates/lit-ts/frontend/public/style.css | 3 --- v3/internal/templates/lit/frontend/public/style.css | 3 --- v3/internal/templates/preact-ts/frontend/public/style.css | 3 --- v3/internal/templates/preact/frontend/public/style.css | 3 --- v3/internal/templates/qwik-ts/frontend/public/style.css | 3 --- v3/internal/templates/qwik/frontend/public/style.css | 3 --- .../templates/react-swc-ts/frontend/public/style.css | 3 --- v3/internal/templates/react-swc/frontend/public/style.css | 3 --- v3/internal/templates/react-ts/frontend/public/style.css | 3 --- v3/internal/templates/react/frontend/public/style.css | 3 --- v3/internal/templates/solid-ts/frontend/public/style.css | 3 --- v3/internal/templates/solid/frontend/public/style.css | 3 --- v3/internal/templates/svelte-ts/frontend/public/style.css | 3 --- v3/internal/templates/svelte/frontend/public/style.css | 3 --- .../templates/sveltekit-ts/frontend/static/style.css | 3 --- v3/internal/templates/sveltekit/frontend/frontend/style.css | 3 --- v3/internal/templates/sveltekit/frontend/static/style.css | 3 --- v3/internal/templates/vanilla-ts/frontend/public/style.css | 6 +++--- v3/internal/templates/vanilla/frontend/public/style.css | 3 --- 19 files changed, 3 insertions(+), 57 deletions(-) diff --git a/v3/internal/templates/lit-ts/frontend/public/style.css b/v3/internal/templates/lit-ts/frontend/public/style.css index 8403ee0fd..10550a378 100644 --- a/v3/internal/templates/lit-ts/frontend/public/style.css +++ b/v3/internal/templates/lit-ts/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/lit/frontend/public/style.css b/v3/internal/templates/lit/frontend/public/style.css index 8403ee0fd..10550a378 100644 --- a/v3/internal/templates/lit/frontend/public/style.css +++ b/v3/internal/templates/lit/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/preact-ts/frontend/public/style.css b/v3/internal/templates/preact-ts/frontend/public/style.css index 5d7b7e09c..c4f073382 100644 --- a/v3/internal/templates/preact-ts/frontend/public/style.css +++ b/v3/internal/templates/preact-ts/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/preact/frontend/public/style.css b/v3/internal/templates/preact/frontend/public/style.css index 5d7b7e09c..c4f073382 100644 --- a/v3/internal/templates/preact/frontend/public/style.css +++ b/v3/internal/templates/preact/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/qwik-ts/frontend/public/style.css b/v3/internal/templates/qwik-ts/frontend/public/style.css index 2b447c0b6..c1d8d1a2e 100644 --- a/v3/internal/templates/qwik-ts/frontend/public/style.css +++ b/v3/internal/templates/qwik-ts/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/qwik/frontend/public/style.css b/v3/internal/templates/qwik/frontend/public/style.css index 2b447c0b6..c1d8d1a2e 100644 --- a/v3/internal/templates/qwik/frontend/public/style.css +++ b/v3/internal/templates/qwik/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/react-swc-ts/frontend/public/style.css b/v3/internal/templates/react-swc-ts/frontend/public/style.css index a36cce4f8..0ba9cf5cc 100644 --- a/v3/internal/templates/react-swc-ts/frontend/public/style.css +++ b/v3/internal/templates/react-swc-ts/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/react-swc/frontend/public/style.css b/v3/internal/templates/react-swc/frontend/public/style.css index a36cce4f8..0ba9cf5cc 100644 --- a/v3/internal/templates/react-swc/frontend/public/style.css +++ b/v3/internal/templates/react-swc/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/react-ts/frontend/public/style.css b/v3/internal/templates/react-ts/frontend/public/style.css index a36cce4f8..0ba9cf5cc 100644 --- a/v3/internal/templates/react-ts/frontend/public/style.css +++ b/v3/internal/templates/react-ts/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/react/frontend/public/style.css b/v3/internal/templates/react/frontend/public/style.css index a36cce4f8..0ba9cf5cc 100644 --- a/v3/internal/templates/react/frontend/public/style.css +++ b/v3/internal/templates/react/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/solid-ts/frontend/public/style.css b/v3/internal/templates/solid-ts/frontend/public/style.css index 2b7547eb4..892241249 100644 --- a/v3/internal/templates/solid-ts/frontend/public/style.css +++ b/v3/internal/templates/solid-ts/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/solid/frontend/public/style.css b/v3/internal/templates/solid/frontend/public/style.css index 2b7547eb4..892241249 100644 --- a/v3/internal/templates/solid/frontend/public/style.css +++ b/v3/internal/templates/solid/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/svelte-ts/frontend/public/style.css b/v3/internal/templates/svelte-ts/frontend/public/style.css index 259397254..0b9c58279 100644 --- a/v3/internal/templates/svelte-ts/frontend/public/style.css +++ b/v3/internal/templates/svelte-ts/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/svelte/frontend/public/style.css b/v3/internal/templates/svelte/frontend/public/style.css index 259397254..0b9c58279 100644 --- a/v3/internal/templates/svelte/frontend/public/style.css +++ b/v3/internal/templates/svelte/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/sveltekit-ts/frontend/static/style.css b/v3/internal/templates/sveltekit-ts/frontend/static/style.css index 259397254..0b9c58279 100644 --- a/v3/internal/templates/sveltekit-ts/frontend/static/style.css +++ b/v3/internal/templates/sveltekit-ts/frontend/static/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/sveltekit/frontend/frontend/style.css b/v3/internal/templates/sveltekit/frontend/frontend/style.css index 259397254..0b9c58279 100644 --- a/v3/internal/templates/sveltekit/frontend/frontend/style.css +++ b/v3/internal/templates/sveltekit/frontend/frontend/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/sveltekit/frontend/static/style.css b/v3/internal/templates/sveltekit/frontend/static/style.css index 259397254..0b9c58279 100644 --- a/v3/internal/templates/sveltekit/frontend/static/style.css +++ b/v3/internal/templates/sveltekit/frontend/static/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/v3/internal/templates/vanilla-ts/frontend/public/style.css b/v3/internal/templates/vanilla-ts/frontend/public/style.css index 259397254..fda46232a 100644 --- a/v3/internal/templates/vanilla-ts/frontend/public/style.css +++ b/v3/internal/templates/vanilla-ts/frontend/public/style.css @@ -13,15 +13,15 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } +* { +} + @font-face { font-family: "Inter"; font-style: normal; diff --git a/v3/internal/templates/vanilla/frontend/public/style.css b/v3/internal/templates/vanilla/frontend/public/style.css index 259397254..0b9c58279 100644 --- a/v3/internal/templates/vanilla/frontend/public/style.css +++ b/v3/internal/templates/vanilla/frontend/public/style.css @@ -13,9 +13,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -} - -* { user-select: none; -webkit-user-select: none; -moz-user-select: none; From f59798ef1dc42407355b0d466f7749fbd54e9536 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 18 Apr 2025 16:15:39 +1000 Subject: [PATCH 134/136] Update changelog --- docs/src/content/docs/changelog.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 681e3715f..fd584c975 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -115,6 +115,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed icon generation paths by [@robin-samuel](https://github.com/robin-samuel) in [#4125](https://github.com/wailsapp/wails/pull/4125) - Fixed Dialogs runtime function returning escaped paths on Windows by [TheGB0077](https://github.com/TheGB0077) in [#4188](https://github.com/wailsapp/wails/pull/4188) - Fixed Webview2 detection path in HKCU by [@leaanthony](https://github.com/leaanthony). +- Fixed input issue with macOS by [@leaanthony](https://github.com/leaanthony). ### Changed From 0222bfa728fb1b04d972fd2f7677f36035c21542 Mon Sep 17 00:00:00 2001 From: Fabio Massaioli Date: Fri, 18 Apr 2025 10:32:18 +0200 Subject: [PATCH 135/136] Fix empty selector --- v3/internal/templates/vanilla-ts/frontend/public/style.css | 3 --- 1 file changed, 3 deletions(-) diff --git a/v3/internal/templates/vanilla-ts/frontend/public/style.css b/v3/internal/templates/vanilla-ts/frontend/public/style.css index fda46232a..0b9c58279 100644 --- a/v3/internal/templates/vanilla-ts/frontend/public/style.css +++ b/v3/internal/templates/vanilla-ts/frontend/public/style.css @@ -19,9 +19,6 @@ -ms-user-select: none; } -* { -} - @font-face { font-family: "Inter"; font-style: normal; From 421b75ef21f09a5e303e167abdbe31495e57a3e2 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 19 Apr 2025 10:27:25 +1000 Subject: [PATCH 136/136] Multiple fixes. Thanks @kron! --- docs/src/content/docs/changelog.mdx | 3 +++ v3/pkg/application/application_windows.go | 28 ++++++++++++++++++++ v3/pkg/application/systemtray_windows.go | 16 +++++++++++ v3/pkg/application/webview_window_windows.go | 20 ++++++++++++-- v3/pkg/w32/user32.go | 6 ++--- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 74eba67d9..3670469f9 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -121,6 +121,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed Webview2 detection path in HKCU by [@leaanthony](https://github.com/leaanthony). - Fixed input issue with macOS by [@leaanthony](https://github.com/leaanthony). - Fixed Windows icon generation task file name by [@yulesxoxo](https://github.com/yulesxoxo) in [#4219](https://github.com/wailsapp/wails/pull/4219). +- Fixed transparency issue for frameless windows by [@leaanthony](https://github.com/leaanthony) based on work by @kron. +- Fixed focus calls when window is disabled or minimised by [@leaanthony](https://github.com/leaanthony) based on work by @kron. +- Fixed system trays not showing after taskbar restarts by [@leaanthony](https://github.com/leaanthony) based on work by @kron. ### Changed diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 2279e16c7..bc8428be1 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -8,7 +8,9 @@ import ( "path/filepath" "slices" "sync" + "sync/atomic" "syscall" + "time" "unsafe" "github.com/wailsapp/go-webview2/webviewloader" @@ -18,6 +20,10 @@ import ( "github.com/wailsapp/wails/v3/pkg/w32" ) +var ( + wmTaskbarCreated = w32.RegisterWindowMessage(w32.MustStringToUTF16Ptr("TaskbarCreated")) +) + type windowsApp struct { parent *App @@ -40,6 +46,9 @@ type windowsApp struct { // system theme isCurrentlyDarkMode bool currentWindowID uint + + // Restart taskbar flag + restartingTaskbar atomic.Bool } func (m *windowsApp) isDarkMode() bool { @@ -221,6 +230,17 @@ func (m *windowsApp) wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) } switch msg { + case wmTaskbarCreated: + if m.restartingTaskbar.Load() { + break + } + m.restartingTaskbar.Store(true) + m.reshowSystrays() + go func() { + // 1 second debounce + time.Sleep(1000) + m.restartingTaskbar.Store(false) + }() case w32.WM_SETTINGCHANGE: settingChanged := w32.UTF16PtrToString((*uint16)(unsafe.Pointer(lParam))) if settingChanged == "ImmersiveColorSet" { @@ -297,6 +317,14 @@ func (m *windowsApp) unregisterWindow(w *windowsWebviewWindow) { } } +func (m *windowsApp) reshowSystrays() { + m.systrayMapLock.Lock() + defer m.systrayMapLock.Unlock() + for _, systray := range m.systrayMap { + systray.reshow() + } +} + func setupDPIAwareness() error { // https://learn.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process // https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows diff --git a/v3/pkg/application/systemtray_windows.go b/v3/pkg/application/systemtray_windows.go index e227a6f0d..2f92eb056 100644 --- a/v3/pkg/application/systemtray_windows.go +++ b/v3/pkg/application/systemtray_windows.go @@ -431,3 +431,19 @@ func (s *windowsSystemTray) Show() { func (s *windowsSystemTray) Hide() { // No-op } + +func (s *windowsSystemTray) reshow() { + // Add icons back to systray + nid := w32.NOTIFYICONDATA{ + HWnd: s.hwnd, + UID: uint32(s.parent.id), + UFlags: w32.NIF_ICON | w32.NIF_MESSAGE, + HIcon: s.currentIcon, + UCallbackMessage: WM_USER_SYSTRAY, + } + nid.CbSize = uint32(unsafe.Sizeof(nid)) + // Show the icon + if !w32.ShellNotifyIcon(w32.NIM_ADD, &nid) { + panic(syscall.GetLastError()) + } +} diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 587154a11..a49255dd5 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -273,9 +273,12 @@ func (w *windowsWebviewWindow) run() { exStyle := w32.WS_EX_CONTROLPARENT if options.BackgroundType != BackgroundTypeSolid { - exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP - if w.parent.options.IgnoreMouseEvents { + if (options.Frameless && options.BackgroundType == BackgroundTypeTransparent) || w.parent.options.IgnoreMouseEvents { + // Always if transparent and frameless exStyle |= w32.WS_EX_TRANSPARENT | w32.WS_EX_LAYERED + } else { + // Only WS_EX_NOREDIRECTIONBITMAP if not (and not solid) + exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP } } if options.AlwaysOnTop { @@ -788,6 +791,14 @@ func (w *windowsWebviewWindow) setFullscreenButtonEnabled(_ bool) { func (w *windowsWebviewWindow) focus() { w32.SetForegroundWindow(w.hwnd) + + if w.isDisabled() { + return + } + if w.isMinimised() { + w.unminimise() + } + w.focusingChromium = true w.chromium.Focus() w.focusingChromium = false @@ -1041,6 +1052,11 @@ func (w *windowsWebviewWindow) disableIcon() { ) } +func (w *windowsWebviewWindow) isDisabled() bool { + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_DISABLED != 0 +} + func (w *windowsWebviewWindow) updateTheme(isDarkMode bool) { if w32.IsCurrentlyHighContrastMode() { diff --git a/v3/pkg/w32/user32.go b/v3/pkg/w32/user32.go index 96701dffb..4117afd2e 100644 --- a/v3/pkg/w32/user32.go +++ b/v3/pkg/w32/user32.go @@ -178,6 +178,8 @@ var ( procRedrawWindow = moduser32.NewProc("RedrawWindow") + procRegisterWindowMessageW = moduser32.NewProc("RegisterWindowMessageW") + mainThread HANDLE ) @@ -299,9 +301,7 @@ func PostThreadMessage(threadID HANDLE, msg int, wp, lp uintptr) { } func RegisterWindowMessage(name *uint16) uint32 { - ret, _, _ := procRegisterWindowMessageA.Call( - uintptr(unsafe.Pointer(name))) - + ret, _, _ := procRegisterWindowMessageW.Call(uintptr(unsafe.Pointer(name))) return uint32(ret) }
- -

Wails + Javascript

- -
+ +

Wails + Javascript

+ +
- -

Wails + Javascript

- -