├── .babelrc ├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── context.go ├── controller.go ├── func_map.go ├── go.mod ├── go.sum ├── package.json ├── render.go ├── scope.go ├── setting.go ├── test └── banner.tmpl ├── views ├── themes │ └── widget │ │ ├── actions │ │ ├── edit │ │ │ └── 4.widget_scopes.tmpl │ │ └── index │ │ │ └── 4.widget_scopes.tmpl │ │ ├── assets │ │ ├── javascripts │ │ │ ├── widget.js │ │ │ ├── widget │ │ │ │ └── widget.js │ │ │ ├── widget_check.js │ │ │ ├── widget_inline_edit.js │ │ │ └── widget_inline_edit │ │ │ │ └── widget_inline_edit.js │ │ └── stylesheets │ │ │ ├── widget.css │ │ │ ├── widget │ │ │ └── widget.scss │ │ │ ├── widget_inline_edit.css │ │ │ └── widget_inline_edit │ │ │ └── widget_inline_edit.scss │ │ ├── edit.tmpl │ │ ├── new.tmpl │ │ ├── preview.tmpl │ │ └── setting.tmpl └── widget │ └── inline_edit.tmpl ├── widget.go ├── widget_test.go └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | .sass-cache/ 15 | *.css.map 16 | *.js.map 17 | 18 | *.cgo1.go 19 | *.cgo2.c 20 | _cgo_defun.c 21 | _cgo_gotypes.go 22 | _cgo_export.* 23 | 24 | _testmain.go 25 | 26 | *.exe 27 | *.test 28 | *.prof 29 | *.swn 30 | .DS_Store 31 | 32 | node_modules/ 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - "1.13" 4 | 5 | services: 6 | - mysql 7 | - postgresql 8 | 9 | env: 10 | - GO111MODULE=on 11 | 12 | before_install: 13 | - mysql -e "CREATE DATABASE IF NOT EXISTS qor_test;" 14 | - mysql -e "GRANT ALL PRIVILEGES ON qor_test.* TO 'qor'@'localhost' IDENTIFIED BY 'qor'" 15 | - psql -c 'create database qor_test;' -U postgres 16 | - psql -c "CREATE USER qor WITH ENCRYPTED PASSWORD 'qor'" -U postgres 17 | - psql -c "GRANT ALL PRIVILEGES ON DATABASE qor_test TO qor" -U postgres 18 | - go get -t -v ./... 19 | 20 | script: 21 | - go get -u github.com/goware/modvendor 22 | - go mod vendor 23 | - modvendor -copy="**/*.html **/*.js **/*.css **/*.tmpl **/*.ttf **/*.woff **/*.woff2" -v 24 | - TEST_DB=postgres go test -v ./... 25 | - TEST_DB=mysql go test -v ./... 26 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) The Plant https://theplant.jp 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Widget 2 | 3 | Widget are defined, customizable, shareable HTML *widgets* that can be used within [QOR Admin](https://github.com/qor/admin) or your own frontend. 4 | 5 | [![Build Status](https://travis-ci.com/qor/widget.svg?branch=master)](https://travis-ci.com/qor/widget) 6 | 7 | ## Getting Started 8 | 9 | ```go 10 | // Initialize widgets container 11 | Widgets := widget.New(&widget.Config{DB: db}) 12 | 13 | // Define widget's setting struct 14 | type bannerArgument struct { 15 | Title string 16 | Link string 17 | BackgroundImage oss.OSS 18 | } 19 | 20 | // Register new widget 21 | Widgets.RegisterWidget(&widget.Widget{ 22 | // Widget's Name 23 | Name: "Banner", 24 | // Widget's available templates 25 | Templates: []string{"banner1", "banner2"}, 26 | // Widget's setting, which is configurable from the place using the widget with inline edit 27 | Setting: Admin.NewResource(&bannerArgument{}), 28 | // InlineEditURL overwrite widget's inline edit's setting URL, usually we don't require do that, Widget will generate setting form based on Widget's setting resource, but in case of you want to fully customize your widget's setting page, you can overwrite it to return setting's URL 29 | InlineEditURL: func(context *Context) string { 30 | return "/different-setting-url" 31 | }, 32 | // Generate a context to render the widget based on the widget's configurations 33 | Context: func(context *widget.Context, setting interface{}) *widget.Context { 34 | context.Options["Setting"] = setting 35 | context.Options["CurrentTime"] = time.Now() 36 | return context 37 | }, 38 | }) 39 | 40 | 41 | type slideImage struct { 42 | Title string 43 | Image oss.OSS 44 | } 45 | 46 | type slideShowArgument struct { 47 | SlideImages []slideImage 48 | } 49 | 50 | slideShowResource := Admin.NewResource(&slideShowArgument{}) 51 | slideShowResource.AddProcessor(func(value interface{}, metaValues *resource.MetaValues, context *qor.Context) error { 52 | if slides, ok := value.(*slideShowArgument); ok { 53 | for _, slide := range slides.SlideImages { 54 | if slide.Title == "" { 55 | return errors.New("slide title is blank") 56 | } 57 | } 58 | } 59 | return nil 60 | }) 61 | 62 | Widgets.RegisterWidget(&widget.Widget{ 63 | Name: "SlideShow", 64 | Templates: []string{"slideshow"}, 65 | Setting: slideShowResource, 66 | Context: func(context *widget.Context, setting interface{}) *widget.Context { 67 | context.Options["Setting"] = setting 68 | return context 69 | }, 70 | }) 71 | 72 | // Define Widget Group 73 | Widgets.RegisterWidgetGroup(&widget.WidgetGroup{ 74 | Name: "HomeBanners", 75 | Widgets: []string{"Banner", "SlideShow"}, 76 | }) 77 | 78 | // Manage widgets from QOR Admin interface 79 | Admin.AddResource(Widgets) 80 | ``` 81 | 82 | ### Render Widget From Controller 83 | 84 | ```go 85 | func Index(request *http.Request, writer http.ResponseWriter) { 86 | // Generate widget context 87 | widgetContext := admin.Widgets.NewContext(&widget.Context{ 88 | DB: DB(request), 89 | Options: map[string]interface{}{"Request": request, "CurrentUser": currentUser}, // those options are accessible from widget views 90 | InlineEdit: true, // enable inline edit mode for widget 91 | }) 92 | 93 | // Render Widget `HomeBanner` based on widget `Banner`'s definition to HTML template 94 | homeBannerContent := widgetContext.Render("HomeBanner", "Banner") 95 | 96 | // Render Widget `CampaignBanner` based on widget `Banner`'s definition to HTML template 97 | campaignBannerContent := widgetContext.Render("CampaignBanner", "Banner") 98 | 99 | // Then you could use the banner's HTML content in your templates 100 | } 101 | ``` 102 | 103 | ### Templates 104 | 105 | Widget's template is Golang HTML template based, and thus quite flexible. 106 | 107 | Continuing on the above *widget* example, we configure it to use templates `banner1`, `banner2`. QOR widget will look up templates from path `$APP_ROOT/app/views/widgets` by default, so you need to put your template in the right folder! 108 | 109 | Once the template is found, QOR Widget will use the widget's generated context and use it to render the template like how Golang template works. 110 | 111 | ```go 112 | // app/views/widgets/banner1.tmpl 113 | 123 | 124 | // app/views/widgets/banner2.tmpl 125 | 134 | ``` 135 | 136 | You could also register other paths like: 137 | 138 | ```go 139 | Widgets.RegisterViewPath("app/views/widgets") 140 | ``` 141 | 142 | ### Register Scopes 143 | 144 | In some cases, you might want to show a different page according to UTM source/medium/campaign or for A/B testing to increase the conversion rate. Using a Widget's Scope you can register some *scopes*, configure your *widget* for each of them, and when a *scope*'s `Visible` condition is matched the *widget* will use its configuration to render the *widget*. 145 | 146 | ```go 147 | Widgets.RegisterScope(&widget.Scope{ 148 | Name: "From Google", 149 | Visible: func(context *widget.Context) bool { 150 | if request, ok := context.Get("Request"); ok { 151 | return strings.Contains(request.(*http.Request).Referer(), "google.com") 152 | } 153 | return false 154 | }, 155 | }) 156 | 157 | Widgets.RegisterScope(&widget.Scope{ 158 | Name: "VIP User", 159 | Visible: func(context *widget.Context) bool { 160 | if user, ok := context.Get("CurrentUser"); ok { 161 | return user.(*User).Role == "vip" 162 | } 163 | return false 164 | }, 165 | }) 166 | ``` 167 | 168 | ## Live Widget Demo 169 | 170 | [Widget Demo](http://demo.getqor.com) 171 | 172 | ## License 173 | 174 | Released under the [MIT License](http://opensource.org/licenses/MIT). 175 | -------------------------------------------------------------------------------- /context.go: -------------------------------------------------------------------------------- 1 | package widget 2 | 3 | import ( 4 | "fmt" 5 | "html/template" 6 | "reflect" 7 | 8 | "github.com/jinzhu/gorm" 9 | "github.com/qor/admin" 10 | "github.com/qor/qor" 11 | "github.com/qor/qor/utils" 12 | ) 13 | 14 | // Context widget context 15 | type Context struct { 16 | Widgets *Widgets 17 | DB *gorm.DB 18 | AvailableWidgets []string 19 | Options map[string]interface{} 20 | Body string 21 | InlineEdit bool 22 | SourceType string 23 | SourceID string 24 | FuncMaps template.FuncMap 25 | WidgetSetting QorWidgetSettingInterface 26 | } 27 | 28 | // Get get option with name 29 | func (context Context) Get(name string) (interface{}, bool) { 30 | if value, ok := context.Options[name]; ok { 31 | return value, true 32 | } 33 | 34 | return nil, false 35 | } 36 | 37 | // Set set option by name 38 | func (context *Context) Set(name string, value interface{}) { 39 | if context.Options == nil { 40 | context.Options = map[string]interface{}{} 41 | } 42 | context.Options[name] = value 43 | } 44 | 45 | // GetDB set option by name 46 | func (context *Context) GetDB() *gorm.DB { 47 | if context.DB != nil { 48 | return context.DB 49 | } 50 | return context.Widgets.Config.DB 51 | } 52 | 53 | // Clone clone a context 54 | func (context *Context) Clone() *Context { 55 | return &Context{ 56 | Widgets: context.Widgets, 57 | DB: context.DB, 58 | AvailableWidgets: context.AvailableWidgets, 59 | Options: context.Options, 60 | InlineEdit: context.InlineEdit, 61 | FuncMaps: context.FuncMaps, 62 | WidgetSetting: context.WidgetSetting, 63 | } 64 | } 65 | 66 | // Render render widget based on context 67 | func (context *Context) Render(widgetName string, widgetGroupName string) template.HTML { 68 | var ( 69 | visibleScopes []string 70 | widgets = context.Widgets 71 | widgetSettingResource = widgets.WidgetSettingResource 72 | clone = context.Clone() 73 | ) 74 | 75 | for _, scope := range registeredScopes { 76 | if scope.Visible(context) { 77 | visibleScopes = append(visibleScopes, scope.ToParam()) 78 | } 79 | } 80 | 81 | if setting := context.findWidgetSetting(widgetName, append(visibleScopes, "default"), widgetGroupName); setting != nil { 82 | clone.WidgetSetting = setting 83 | adminContext := admin.Context{Admin: context.Widgets.Config.Admin, Context: &qor.Context{DB: context.DB}} 84 | 85 | var ( 86 | widgetObj = GetWidget(setting.GetSerializableArgumentKind()) 87 | widgetSetting = widgetObj.Context(clone, setting.GetSerializableArgument(setting)) 88 | ) 89 | 90 | if clone.InlineEdit { 91 | prefix := widgets.Resource.GetAdmin().GetRouter().Prefix 92 | inlineEditURL := adminContext.URLFor(setting, widgetSettingResource) 93 | if widgetObj.InlineEditURL != nil { 94 | inlineEditURL = widgetObj.InlineEditURL(context) 95 | } 96 | 97 | return template.HTML(fmt.Sprintf( 98 | "
\n%v\n
", 99 | prefix, 100 | prefix, 101 | utils.ToParamString(widgetObj.Name), 102 | fmt.Sprintf("%v/%v/inline-edit", prefix, widgets.Resource.ToParam()), 103 | inlineEditURL, 104 | widgetObj.Render(widgetSetting, setting.GetTemplate()), 105 | )) 106 | } 107 | 108 | return widgetObj.Render(widgetSetting, setting.GetTemplate()) 109 | } 110 | 111 | return template.HTML("") 112 | } 113 | 114 | func (context *Context) findWidgetSetting(widgetName string, scopes []string, widgetGroupName string) QorWidgetSettingInterface { 115 | var ( 116 | db = context.GetDB() 117 | widgetSettingResource = context.Widgets.WidgetSettingResource 118 | setting QorWidgetSettingInterface 119 | settings = widgetSettingResource.NewSlice() 120 | ) 121 | 122 | if context.SourceID != "" { 123 | db.Order("source_id DESC").Where("name = ? AND scope IN (?) AND ((shared = ? AND source_type = ?) OR (source_type = ? AND source_id = ?))", widgetName, scopes, true, "", context.SourceType, context.SourceID).Find(settings) 124 | } else { 125 | db.Where("name = ? AND scope IN (?) AND source_type = ?", widgetName, scopes, "").Find(settings) 126 | } 127 | 128 | settingsValue := reflect.Indirect(reflect.ValueOf(settings)) 129 | if settingsValue.Len() > 0 { 130 | OUTTER: 131 | for _, scope := range scopes { 132 | for i := 0; i < settingsValue.Len(); i++ { 133 | s := settingsValue.Index(i).Interface().(QorWidgetSettingInterface) 134 | if s.GetScope() == scope { 135 | setting = s 136 | break OUTTER 137 | } 138 | } 139 | } 140 | } 141 | 142 | if context.SourceType == "" { 143 | if setting == nil { 144 | if widgetGroupName == "" { 145 | utils.ExitWithMsg("Widget: Can't Create Widget Without Widget Type") 146 | return nil 147 | } 148 | setting = widgetSettingResource.NewStruct().(QorWidgetSettingInterface) 149 | setting.SetWidgetName(widgetName) 150 | setting.SetGroupName(widgetGroupName) 151 | setting.SetSerializableArgumentKind(widgetGroupName) 152 | db.Create(setting) 153 | } else if setting.GetGroupName() != widgetGroupName { 154 | setting.SetGroupName(widgetGroupName) 155 | db.Save(setting) 156 | } 157 | } 158 | 159 | return setting 160 | } 161 | -------------------------------------------------------------------------------- /controller.go: -------------------------------------------------------------------------------- 1 | package widget 2 | 3 | import ( 4 | "html/template" 5 | "net/http" 6 | 7 | "github.com/qor/admin" 8 | "github.com/qor/responder" 9 | "github.com/qor/serializable_meta" 10 | ) 11 | 12 | type widgetController struct { 13 | Widgets *Widgets 14 | } 15 | 16 | func (wc widgetController) Index(context *admin.Context) { 17 | context = context.NewResourceContext(wc.Widgets.WidgetSettingResource) 18 | 19 | result, _, err := wc.getWidget(context) 20 | context.AddError(err) 21 | 22 | if context.HasError() { 23 | http.NotFound(context.Writer, context.Request) 24 | } else { 25 | responder.With("html", func() { 26 | context.Execute("index", result) 27 | }).With("json", func() { 28 | context.JSON("index", result) 29 | }).Respond(context.Request) 30 | } 31 | } 32 | 33 | func (wc widgetController) New(context *admin.Context) { 34 | widgetInter := wc.Widgets.WidgetSettingResource.NewStruct().(QorWidgetSettingInterface) 35 | context.Execute("new", widgetInter) 36 | } 37 | 38 | func (wc widgetController) Setting(context *admin.Context) { 39 | widgetInter := wc.Widgets.WidgetSettingResource.NewStruct().(QorWidgetSettingInterface) 40 | widgetType := context.Request.URL.Query().Get("widget_type") 41 | if widgetType != "" { 42 | if serializableMeta, ok := widgetInter.(serializable_meta.SerializableMetaInterface); ok && serializableMeta.GetSerializableArgumentKind() != widgetType { 43 | serializableMeta.SetSerializableArgumentKind(widgetType) 44 | serializableMeta.SetSerializableArgumentValue(nil) 45 | } 46 | } 47 | section := []*admin.Section{{ 48 | Resource: wc.Widgets.WidgetSettingResource, 49 | Title: "Settings", 50 | Rows: [][]string{{"Kind"}, {"SerializableMeta"}}, 51 | }} 52 | content := context.Render("setting", struct { 53 | Widget interface{} 54 | Section []*admin.Section 55 | }{ 56 | Widget: widgetInter, 57 | Section: section, 58 | }) 59 | context.Writer.Write([]byte(content)) 60 | } 61 | 62 | func (wc widgetController) Edit(context *admin.Context) { 63 | context = context.NewResourceContext(wc.Widgets.WidgetSettingResource) 64 | widgetSetting, scopes, err := wc.getWidget(context) 65 | context.AddError(err) 66 | 67 | responder.With("html", func() { 68 | context.Funcs(template.FuncMap{ 69 | "get_widget_scopes": func() []string { return scopes }, 70 | }).Execute("edit", widgetSetting) 71 | }).With("json", func() { 72 | context.JSON("show", widgetSetting) 73 | }).Respond(context.Request) 74 | } 75 | 76 | func (wc widgetController) Preview(context *admin.Context) { 77 | widgetContext := wc.Widgets.NewContext(&Context{ 78 | DB: context.GetDB(), 79 | Options: map[string]interface{}{"Request": context.Request, "AdminContext": context}, 80 | }) 81 | 82 | content := context.Funcs(template.FuncMap{ 83 | "load_preview_assets": wc.Widgets.LoadPreviewAssets, 84 | }).Funcs(widgetContext.FuncMap()).Render("preview", struct { 85 | WidgetName string 86 | }{ 87 | WidgetName: context.ResourceID, 88 | }) 89 | context.Writer.Write([]byte(content)) 90 | } 91 | 92 | func (wc widgetController) Update(context *admin.Context) { 93 | context = context.NewResourceContext(wc.Widgets.WidgetSettingResource) 94 | widgetSetting, scopes, err := wc.getWidget(context) 95 | context.AddError(err) 96 | 97 | if context.AddError(context.Resource.Decode(context.Context, widgetSetting)); !context.HasError() { 98 | context.AddError(context.Resource.CallSave(widgetSetting, context.Context)) 99 | } 100 | 101 | if context.HasError() { 102 | responder.With("html", func() { 103 | context.Writer.WriteHeader(admin.HTTPUnprocessableEntity) 104 | context.Funcs(template.FuncMap{ 105 | "get_widget_scopes": func() []string { return scopes }, 106 | }).Execute("edit", widgetSetting) 107 | }).With([]string{"json", "xml"}, func() { 108 | context.Writer.WriteHeader(admin.HTTPUnprocessableEntity) 109 | context.Encode("index", map[string]interface{}{"errors": context.GetErrors()}) 110 | }).Respond(context.Request) 111 | } else { 112 | responder.With("html", func() { 113 | http.Redirect(context.Writer, context.Request, context.Request.URL.Path, http.StatusFound) 114 | }).With("json", func() { 115 | context.JSON("index", widgetSetting) 116 | }).Respond(context.Request) 117 | } 118 | } 119 | 120 | func (wc widgetController) InlineEdit(context *admin.Context) { 121 | context.Writer.Write([]byte(context.Render("widget/inline_edit"))) 122 | } 123 | 124 | func (wc widgetController) getWidget(context *admin.Context) (interface{}, []string, error) { 125 | var DB = context.GetDB() 126 | 127 | // index page 128 | if context.ResourceID == "" && context.Request.Method == "GET" { 129 | scope := context.Request.URL.Query().Get("widget_scope") 130 | if scope == "" { 131 | scope = "default" 132 | } 133 | 134 | context.SetDB(DB.Where("scope = ?", scope)) 135 | defer context.SetDB(DB) 136 | results, err := context.FindMany() 137 | return results, []string{}, err 138 | } 139 | 140 | // show page 141 | var ( 142 | scopes []string 143 | result = wc.Widgets.WidgetSettingResource.NewStruct() 144 | scope = context.Request.URL.Query().Get("widget_scope") 145 | widgetType = context.Request.URL.Query().Get("widget_type") 146 | ) 147 | 148 | if scope == "" { 149 | scope = context.Request.Form.Get("QorResource.Scope") 150 | if scope == "" { 151 | scope = "default" 152 | } 153 | } 154 | 155 | if widgetType == "" { 156 | widgetType = context.Request.Form.Get("QorResource.Kind") 157 | } 158 | 159 | err := DB.FirstOrInit(result, QorWidgetSetting{Name: context.ResourceID, Scope: scope}).Error 160 | 161 | if widgetType != "" { 162 | if serializableMeta, ok := result.(serializable_meta.SerializableMetaInterface); ok && serializableMeta.GetSerializableArgumentKind() != widgetType { 163 | serializableMeta.SetSerializableArgumentKind(widgetType) 164 | serializableMeta.SetSerializableArgumentValue(nil) 165 | } 166 | } 167 | return result, scopes, err 168 | } 169 | -------------------------------------------------------------------------------- /func_map.go: -------------------------------------------------------------------------------- 1 | package widget 2 | 3 | import ( 4 | "sort" 5 | "strings" 6 | 7 | "github.com/qor/admin" 8 | "github.com/qor/roles" 9 | ) 10 | 11 | type GroupedWidgets struct { 12 | Group string 13 | Widgets []*Widget 14 | } 15 | 16 | var funcMap = map[string]interface{}{ 17 | "widget_available_scopes": func() []*Scope { 18 | if len(registeredScopes) > 0 { 19 | return append([]*Scope{{Name: "Default Visitor", Param: "default"}}, registeredScopes...) 20 | } 21 | return []*Scope{} 22 | }, 23 | "widget_grouped_widgets": func(context *admin.Context) []*GroupedWidgets { 24 | groupedWidgetsSlice := []*GroupedWidgets{} 25 | 26 | OUTER: 27 | for _, w := range registeredWidgets { 28 | var roleNames = []interface{}{} 29 | for _, role := range context.Roles { 30 | roleNames = append(roleNames, role) 31 | } 32 | if w.Permission == nil || w.Permission.HasPermission(roles.Create, roleNames...) { 33 | for _, groupedWidgets := range groupedWidgetsSlice { 34 | if groupedWidgets.Group == w.Group { 35 | groupedWidgets.Widgets = append(groupedWidgets.Widgets, w) 36 | continue OUTER 37 | } 38 | } 39 | 40 | groupedWidgetsSlice = append(groupedWidgetsSlice, &GroupedWidgets{ 41 | Group: w.Group, 42 | Widgets: []*Widget{w}, 43 | }) 44 | } 45 | } 46 | 47 | sort.SliceStable(groupedWidgetsSlice, func(i, j int) bool { 48 | if groupedWidgetsSlice[i].Group == "" { 49 | return false 50 | } 51 | return strings.Compare(groupedWidgetsSlice[i].Group, groupedWidgetsSlice[j].Group) < 0 52 | }) 53 | 54 | return groupedWidgetsSlice 55 | }, 56 | } 57 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/qor/widget 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/fatih/color v1.9.0 7 | github.com/jinzhu/gorm v1.9.16 8 | github.com/qor/admin v0.0.0-20200908023436-0c0a0b041c88 9 | github.com/qor/assetfs v0.0.0-20170713023933-ff57fdc13a14 10 | github.com/qor/qor v0.0.0-20200729071734-d587cffbbb93 11 | github.com/qor/responder v0.0.0-20171031032654-b6def473574f 12 | github.com/qor/roles v0.0.0-20201008080147-dcaf8a4646d8 13 | github.com/qor/serializable_meta v0.0.0-20180510060738-5fd8542db417 14 | ) 15 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= 2 | github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= 3 | github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= 4 | github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= 5 | github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= 6 | github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= 7 | github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= 8 | github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= 9 | github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= 10 | github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= 11 | github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= 12 | github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= 13 | github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= 14 | github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= 15 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 16 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= 17 | github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= 18 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 19 | github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= 20 | github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= 21 | github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= 22 | github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= 23 | github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= 24 | github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= 25 | github.com/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs= 26 | github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg= 27 | github.com/jinzhu/gorm v1.9.15/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= 28 | github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= 29 | github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= 30 | github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= 31 | github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= 32 | github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 33 | github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= 34 | github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 35 | github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 36 | github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= 37 | github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 38 | github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 39 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 40 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 41 | github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= 42 | github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= 43 | github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= 44 | github.com/microcosm-cc/bluemonday v1.0.3 h1:EjVH7OqbU219kdm8acbveoclh2zZFqPJTJw6VUlTLAQ= 45 | github.com/microcosm-cc/bluemonday v1.0.3/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w= 46 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 47 | github.com/qor/admin v0.0.0-20200908023436-0c0a0b041c88 h1:fMtNHN6WgFSfFZ+ZXpnJW62h4kZ+jsk1/WIsnPX9GuE= 48 | github.com/qor/admin v0.0.0-20200908023436-0c0a0b041c88/go.mod h1:TiMo/I9p4pjVFtLI8+ellx2YbeiirVYcoh5UrQc9v9I= 49 | github.com/qor/assetfs v0.0.0-20170713023933-ff57fdc13a14 h1:JRpyNNSRAkwNHd4WgyPcalTAhxOCh3eFNMoQkxWhjSw= 50 | github.com/qor/assetfs v0.0.0-20170713023933-ff57fdc13a14/go.mod h1:GZSCP3jIneuPsav3pXmpmJwz9ES+Fuq4ZPOUC3wwckQ= 51 | github.com/qor/media v0.0.0-20200720100650-60c52edf57cb/go.mod h1:hzx9cTt5MpROMVIhwNhRJETc7e3a1J4bLNYflkcQ1wk= 52 | github.com/qor/middlewares v0.0.0-20170822143614-781378b69454 h1:+WCc1IigwWpWBxMFsmLUsIF230TakGHstDajd8aKDAc= 53 | github.com/qor/middlewares v0.0.0-20170822143614-781378b69454/go.mod h1:PejEyg3hS+Toh5m0AKRv2jK5br8qIoHLqmHrpg0WJYg= 54 | github.com/qor/oss v0.0.0-20191031055114-aef9ba66bf76/go.mod h1:JhtPzUhP5KGtCB2yksmxuYAD4hEWw4qGQJpucjsm3U0= 55 | github.com/qor/qor v0.0.0-20200715033016-13227382be83/go.mod h1:oG+LgDEnsI9avcFFdczoZnBe3rw42s4cG433w6XpEig= 56 | github.com/qor/qor v0.0.0-20200729071734-d587cffbbb93 h1:kxseRCbX7NxSvKYSO1rXQCALzl3YLZvooxhhQdA23fU= 57 | github.com/qor/qor v0.0.0-20200729071734-d587cffbbb93/go.mod h1:i3WqgQWpyNJRB9D3ewgthf5/8fR/ALcvPGUqu5vHZA8= 58 | github.com/qor/responder v0.0.0-20171031032654-b6def473574f h1:sKELSAyL+z5BRHFe97Bx71z197cBEobVJ6rASKTMSqU= 59 | github.com/qor/responder v0.0.0-20171031032654-b6def473574f/go.mod h1:0TL2G+qGDYhHJ6XIJ6UcqkZVN+jp8AGqGU2wDnv2qas= 60 | github.com/qor/roles v0.0.0-20171127035124-d6375609fe3e/go.mod h1:++RicL9Ia/BrQHppwAsMc5CA7mAjnBLNniB46MzUteA= 61 | github.com/qor/roles v0.0.0-20201008080147-dcaf8a4646d8 h1:Yv4gbXvj1JL/G4Ck4HPK7tz7gF42yntoiNINqd85NbU= 62 | github.com/qor/roles v0.0.0-20201008080147-dcaf8a4646d8/go.mod h1:++RicL9Ia/BrQHppwAsMc5CA7mAjnBLNniB46MzUteA= 63 | github.com/qor/serializable_meta v0.0.0-20180510060738-5fd8542db417 h1:dnqlvo4M/uR0KhB6Tyhsv6XbSokcpfwQ4ublD9D/PBQ= 64 | github.com/qor/serializable_meta v0.0.0-20180510060738-5fd8542db417/go.mod h1:ZhRkze6qCgCNNqisHEFTAkndoBtY/XJbA03LJLJrzDY= 65 | github.com/qor/session v0.0.0-20170907035918-8206b0adab70 h1:8l21EEdlZ9R0AA3FbeUAANc5NAx8Y3tn1VKbyAgjYlI= 66 | github.com/qor/session v0.0.0-20170907035918-8206b0adab70/go.mod h1:ldgcaca0ZGx6tFtd/w0ELq5jHD/KLJ1Lbdn8qhr/pQ0= 67 | github.com/qor/validations v0.0.0-20171228122639-f364bca61b46 h1:dRlsVUhwD1pwrasuVbNooGQITYjKzmXK5eYoEEvBGQI= 68 | github.com/qor/validations v0.0.0-20171228122639-f364bca61b46/go.mod h1:UJsA0AuvrKNaWtrb1UzKai10mN3ZBbQkPjUHpxwahTc= 69 | github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ= 70 | github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q= 71 | github.com/theplant/cldr v0.0.0-20190423050709-9f76f7ce4ee8 h1:di0cR5qqo2DllBMwmP75kZpUX6dAXhsn1O2dshQfMaA= 72 | github.com/theplant/cldr v0.0.0-20190423050709-9f76f7ce4ee8/go.mod h1:MIL7SmF8wRAYDn+JexczVRUiJXTCi4VbQavsCKWKwXI= 73 | github.com/theplant/htmltestingutils v0.0.0-20190423050759-0e06de7b6967/go.mod h1:86iN4EAYaQbx1VTW5uPslTIviRkYH8CzslMC//g+BgY= 74 | github.com/theplant/testingutils v0.0.0-20190603093022-26d8b4d95c61/go.mod h1:p22Q3Bg5ML+hdI3QSQkB/pZ2+CjfOnGugoQIoyE2Ub8= 75 | github.com/yosssi/gohtml v0.0.0-20200519115854-476f5b4b8047/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE= 76 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 77 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 78 | golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 79 | golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 80 | golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 81 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 82 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 83 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 84 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= 85 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 86 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 87 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 88 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 89 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 90 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 91 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 92 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qor", 3 | "description": "An enterprise-level open source content management system.", 4 | "version": "0.1.0", 5 | "main": "admin/views/assets/javascripts/app.js", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/qor/qor.git" 10 | }, 11 | "keywords": [ 12 | "qor", 13 | "cms", 14 | "go" 15 | ], 16 | "devDependencies": { 17 | "@babel/core": "^7.25.2", 18 | "@babel/preset-env": "^7.25.2", 19 | "gulp-babel": "^8.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /render.go: -------------------------------------------------------------------------------- 1 | package widget 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "html/template" 7 | "path/filepath" 8 | 9 | "github.com/qor/qor/utils" 10 | ) 11 | 12 | // Render find widget by name, render it based on current context 13 | func (widgets *Widgets) Render(widgetName string, widgetGroupName string) template.HTML { 14 | return widgets.NewContext(nil).Render(widgetName, widgetGroupName) 15 | } 16 | 17 | // NewContext create new context for widgets 18 | func (widgets *Widgets) NewContext(context *Context) *Context { 19 | if context == nil { 20 | context = &Context{} 21 | } 22 | 23 | if context.DB == nil { 24 | context.DB = widgets.Config.DB 25 | } 26 | 27 | if context.Options == nil { 28 | context.Options = map[string]interface{}{} 29 | } 30 | 31 | if context.FuncMaps == nil { 32 | context.FuncMaps = template.FuncMap{} 33 | } 34 | 35 | for key, fc := range widgets.funcMaps { 36 | if _, ok := context.FuncMaps[key]; !ok { 37 | context.FuncMaps[key] = fc 38 | } 39 | } 40 | 41 | context.Widgets = widgets 42 | return context 43 | } 44 | 45 | // Funcs return view functions map 46 | func (context *Context) Funcs(funcMaps template.FuncMap) *Context { 47 | if context.FuncMaps == nil { 48 | context.FuncMaps = template.FuncMap{} 49 | } 50 | 51 | for key, fc := range funcMaps { 52 | context.FuncMaps[key] = fc 53 | } 54 | 55 | return context 56 | } 57 | 58 | // FuncMap return funcmap 59 | func (context *Context) FuncMap() template.FuncMap { 60 | funcMap := template.FuncMap{} 61 | 62 | funcMap["render_widget"] = func(widgetName string, widgetGroupName ...string) template.HTML { 63 | var groupName string 64 | if len(widgetGroupName) == 0 { 65 | groupName = "" 66 | } else { 67 | groupName = widgetGroupName[0] 68 | } 69 | return context.Render(widgetName, groupName) 70 | } 71 | 72 | return funcMap 73 | } 74 | 75 | // Render register widget itself content 76 | func (w *Widget) Render(context *Context, file string) template.HTML { 77 | if len(context.Body) > 0 { 78 | return template.HTML(context.Body) 79 | } 80 | 81 | var ( 82 | err error 83 | content []byte 84 | tmpl *template.Template 85 | ) 86 | 87 | if file == "" && len(w.Templates) > 0 { 88 | file = w.Templates[0] 89 | } 90 | 91 | defer func() { 92 | if r := recover(); r != nil { 93 | err = fmt.Errorf("Get error when render file %v: %v", file, r) 94 | utils.ExitWithMsg(err) 95 | } 96 | }() 97 | 98 | if content, err = context.Widgets.AssetFS.Asset(file + ".tmpl"); err == nil { 99 | if tmpl, err = template.New(filepath.Base(file)).Funcs(context.FuncMaps).Parse(string(content)); err == nil { 100 | var result = bytes.NewBufferString("") 101 | if err = tmpl.Execute(result, context.Options); err == nil { 102 | return template.HTML(result.String()) 103 | } 104 | } 105 | } 106 | 107 | return template.HTML(err.Error()) 108 | } 109 | 110 | // RegisterViewPath register views directory 111 | func (widgets *Widgets) RegisterViewPath(p string) { 112 | if filepath.IsAbs(p) { 113 | viewPaths = append(viewPaths, p) 114 | widgets.AssetFS.RegisterPath(p) 115 | } else { 116 | for _, gopath := range utils.GOPATH() { 117 | viewPaths = append(viewPaths, filepath.Join(gopath, "src", p)) 118 | widgets.AssetFS.RegisterPath(filepath.Join(gopath, "src", p)) 119 | } 120 | } 121 | } 122 | 123 | // LoadPreviewAssets will return assets tag used for Preview 124 | func (widgets *Widgets) LoadPreviewAssets() template.HTML { 125 | tags := "" 126 | for _, asset := range widgets.Config.PreviewAssets { 127 | extension := filepath.Ext(asset) 128 | if extension == ".css" { 129 | tags += fmt.Sprintf("\n", asset) 130 | } else if extension == ".js" { 131 | tags += fmt.Sprintf("\n", asset) 132 | } else { 133 | tags += fmt.Sprintf("%v\n", asset) 134 | } 135 | } 136 | return template.HTML(tags) 137 | } 138 | -------------------------------------------------------------------------------- /scope.go: -------------------------------------------------------------------------------- 1 | package widget 2 | 3 | import "github.com/qor/qor/utils" 4 | 5 | var registeredScopes []*Scope 6 | 7 | // Scope widget scope 8 | type Scope struct { 9 | Name string 10 | Param string 11 | Visible func(*Context) bool 12 | } 13 | 14 | // ToParam generate param for scope 15 | func (scope *Scope) ToParam() string { 16 | if scope.Param != "" { 17 | return scope.Param 18 | } 19 | return utils.ToParamString(scope.Name) 20 | } 21 | 22 | // RegisterScope register scope for widget 23 | func (widgets *Widgets) RegisterScope(scope *Scope) { 24 | registeredScopes = append(registeredScopes, scope) 25 | } 26 | -------------------------------------------------------------------------------- /setting.go: -------------------------------------------------------------------------------- 1 | package widget 2 | 3 | import ( 4 | "fmt" 5 | "html/template" 6 | "time" 7 | 8 | "github.com/jinzhu/gorm" 9 | "github.com/qor/admin" 10 | "github.com/qor/qor" 11 | "github.com/qor/qor/resource" 12 | "github.com/qor/qor/utils" 13 | "github.com/qor/serializable_meta" 14 | ) 15 | 16 | // QorWidgetSettingInterface qor widget setting interface 17 | type QorWidgetSettingInterface interface { 18 | GetWidgetName() string 19 | SetWidgetName(string) 20 | GetGroupName() string 21 | SetGroupName(string) 22 | GetScope() string 23 | SetScope(string) 24 | GetTemplate() string 25 | SetTemplate(string) 26 | GetSourceType() string 27 | SetSourceType(string) 28 | GetSourceID() string 29 | SetSourceID(string) 30 | GetShared() bool 31 | SetShared(bool) 32 | serializable_meta.SerializableMetaInterface 33 | } 34 | 35 | // QorWidgetSetting default qor widget setting struct 36 | type QorWidgetSetting struct { 37 | Name string `gorm:"primary_key;size:100"` 38 | Scope string `gorm:"primary_key;size:128;default:'default'"` 39 | SourceType string `gorm:"primary_key;default:'';size:100"` 40 | SourceID string `gorm:"primary_key;default:'';size:100"` 41 | Description string 42 | Shared bool 43 | WidgetType string 44 | GroupName string 45 | Template string 46 | serializable_meta.SerializableMeta 47 | CreatedAt time.Time 48 | UpdatedAt time.Time 49 | } 50 | 51 | // ResourceName get widget setting's resource name 52 | func (widgetSetting *QorWidgetSetting) ResourceName() string { 53 | return "Widget Content" 54 | } 55 | 56 | // GetSerializableArgumentKind get serializable kind 57 | func (widgetSetting *QorWidgetSetting) GetSerializableArgumentKind() string { 58 | if widgetSetting.WidgetType != "" { 59 | return widgetSetting.WidgetType 60 | } 61 | return widgetSetting.Kind 62 | } 63 | 64 | // SetSerializableArgumentKind set serializable kind 65 | func (widgetSetting *QorWidgetSetting) SetSerializableArgumentKind(name string) { 66 | widgetSetting.WidgetType = name 67 | widgetSetting.Kind = name 68 | } 69 | 70 | // GetWidgetName get widget setting's group name 71 | func (widgetSetting QorWidgetSetting) GetWidgetName() string { 72 | return widgetSetting.Name 73 | } 74 | 75 | // SetWidgetName set widget setting's group name 76 | func (widgetSetting *QorWidgetSetting) SetWidgetName(name string) { 77 | widgetSetting.Name = name 78 | } 79 | 80 | // GetGroupName get widget setting's group name 81 | func (widgetSetting QorWidgetSetting) GetGroupName() string { 82 | return widgetSetting.GroupName 83 | } 84 | 85 | // SetGroupName set widget setting's group name 86 | func (widgetSetting *QorWidgetSetting) SetGroupName(groupName string) { 87 | widgetSetting.GroupName = groupName 88 | } 89 | 90 | // GetScope get widget's scope 91 | func (widgetSetting QorWidgetSetting) GetScope() string { 92 | return widgetSetting.Scope 93 | } 94 | 95 | // SetScope set widget setting's scope 96 | func (widgetSetting *QorWidgetSetting) SetScope(scope string) { 97 | widgetSetting.Scope = scope 98 | } 99 | 100 | // GetSourceType get widget's source type 101 | func (widgetSetting QorWidgetSetting) GetSourceType() string { 102 | return widgetSetting.SourceType 103 | } 104 | 105 | // SetSourceType set widget setting's souce type 106 | func (widgetSetting *QorWidgetSetting) SetSourceType(sourceType string) { 107 | widgetSetting.SourceType = sourceType 108 | } 109 | 110 | // GetSourceID get widget's source ID 111 | func (widgetSetting QorWidgetSetting) GetSourceID() string { 112 | return widgetSetting.SourceID 113 | } 114 | 115 | // SetSourceID set widget setting's source id 116 | func (widgetSetting *QorWidgetSetting) SetSourceID(sourceID string) { 117 | widgetSetting.SourceID = sourceID 118 | } 119 | 120 | // GetShared get widget's source ID 121 | func (widgetSetting QorWidgetSetting) GetShared() bool { 122 | return widgetSetting.Shared 123 | } 124 | 125 | // SetShared set widget setting's source id 126 | func (widgetSetting *QorWidgetSetting) SetShared(shared bool) { 127 | widgetSetting.Shared = shared 128 | } 129 | 130 | // GetTemplate get used widget template 131 | func (widgetSetting QorWidgetSetting) GetTemplate() string { 132 | if widget := GetWidget(widgetSetting.GetSerializableArgumentKind()); widget != nil { 133 | for _, value := range widget.Templates { 134 | if value == widgetSetting.Template { 135 | return value 136 | } 137 | } 138 | 139 | // return first value of defined widget templates 140 | for _, value := range widget.Templates { 141 | return value 142 | } 143 | } 144 | return "" 145 | } 146 | 147 | // SetTemplate set used widget's template 148 | func (widgetSetting *QorWidgetSetting) SetTemplate(template string) { 149 | widgetSetting.Template = template 150 | } 151 | 152 | // GetSerializableArgumentResource get setting's argument's resource 153 | func (widgetSetting *QorWidgetSetting) GetSerializableArgumentResource() *admin.Resource { 154 | widget := GetWidget(widgetSetting.GetSerializableArgumentKind()) 155 | if widget != nil { 156 | return widget.Setting 157 | } 158 | return nil 159 | } 160 | 161 | // ConfigureQorResource a method used to config Widget for qor admin 162 | func (widgetSetting *QorWidgetSetting) ConfigureQorResource(res resource.Resourcer) { 163 | if res, ok := res.(*admin.Resource); ok { 164 | res.Meta(&admin.Meta{Name: "PreviewIcon", Valuer: func(result interface{}, context *qor.Context) interface{} { 165 | if setting, ok := result.(QorWidgetSettingInterface); ok { 166 | if widget := GetWidget(setting.GetSerializableArgumentKind()); widget != nil { 167 | return template.HTML(fmt.Sprintf("", widget.PreviewIcon)) 168 | } 169 | } 170 | return "" 171 | }}) 172 | 173 | res.Meta(&admin.Meta{Name: "Name", Type: "string"}) 174 | res.Meta(&admin.Meta{Name: "DisplayName", Label: "Name", Type: "readonly", FieldName: "Name"}) 175 | res.Meta(&admin.Meta{Name: "Description", Type: "string"}) 176 | 177 | res.Meta(&admin.Meta{ 178 | Name: "Scope", 179 | Type: "hidden", 180 | Valuer: func(result interface{}, context *qor.Context) interface{} { 181 | if scope := context.Request.URL.Query().Get("widget_scope"); scope != "" { 182 | return scope 183 | } 184 | 185 | if setting, ok := result.(QorWidgetSettingInterface); ok { 186 | if scope := setting.GetScope(); scope != "" { 187 | return scope 188 | } 189 | } 190 | 191 | return "default" 192 | }, 193 | Setter: func(result interface{}, metaValue *resource.MetaValue, context *qor.Context) { 194 | if setting, ok := result.(QorWidgetSettingInterface); ok { 195 | setting.SetScope(utils.ToString(metaValue.Value)) 196 | } 197 | }, 198 | }) 199 | 200 | res.Meta(&admin.Meta{ 201 | Name: "SourceType", 202 | Type: "hidden", 203 | Valuer: func(result interface{}, context *qor.Context) interface{} { 204 | if sourceType := context.Request.URL.Query().Get("widget_source_type"); sourceType != "" { 205 | return sourceType 206 | } 207 | 208 | if setting, ok := result.(QorWidgetSettingInterface); ok { 209 | if sourceType := setting.GetSourceType(); sourceType != "" { 210 | return sourceType 211 | } 212 | } 213 | return "" 214 | }, 215 | Setter: func(result interface{}, metaValue *resource.MetaValue, context *qor.Context) { 216 | if setting, ok := result.(QorWidgetSettingInterface); ok { 217 | setting.SetSourceType(utils.ToString(metaValue.Value)) 218 | } 219 | }, 220 | }) 221 | 222 | res.Meta(&admin.Meta{ 223 | Name: "SourceID", 224 | Type: "hidden", 225 | Valuer: func(result interface{}, context *qor.Context) interface{} { 226 | if sourceID := context.Request.URL.Query().Get("widget_source_id"); sourceID != "" { 227 | return sourceID 228 | } 229 | 230 | if setting, ok := result.(QorWidgetSettingInterface); ok { 231 | if sourceID := setting.GetSourceID(); sourceID != "" { 232 | return sourceID 233 | } 234 | } 235 | return "" 236 | }, 237 | Setter: func(result interface{}, metaValue *resource.MetaValue, context *qor.Context) { 238 | if setting, ok := result.(QorWidgetSettingInterface); ok { 239 | setting.SetSourceID(utils.ToString(metaValue.Value)) 240 | } 241 | }, 242 | }) 243 | 244 | res.Meta(&admin.Meta{ 245 | Name: "Widgets", 246 | Type: "select_one", 247 | Valuer: func(result interface{}, context *qor.Context) interface{} { 248 | if typ := context.Request.URL.Query().Get("widget_type"); typ != "" { 249 | return typ 250 | } 251 | 252 | if setting, ok := result.(QorWidgetSettingInterface); ok { 253 | widget := GetWidget(setting.GetSerializableArgumentKind()) 254 | if widget == nil { 255 | return "" 256 | } 257 | return widget.Name 258 | } 259 | 260 | return "" 261 | }, 262 | Collection: func(result interface{}, context *qor.Context) (results [][]string) { 263 | if setting, ok := result.(QorWidgetSettingInterface); ok { 264 | if setting.GetWidgetName() == "" { 265 | for _, widget := range registeredWidgets { 266 | results = append(results, []string{widget.Name, widget.Name}) 267 | } 268 | } else { 269 | groupName := setting.GetGroupName() 270 | for _, group := range registeredWidgetsGroup { 271 | if group.Name == groupName { 272 | for _, widget := range group.Widgets { 273 | results = append(results, []string{widget, widget}) 274 | } 275 | } 276 | } 277 | } 278 | 279 | if len(results) == 0 { 280 | results = append(results, []string{setting.GetSerializableArgumentKind(), setting.GetSerializableArgumentKind()}) 281 | } 282 | } 283 | return 284 | }, 285 | Setter: func(result interface{}, metaValue *resource.MetaValue, context *qor.Context) { 286 | if setting, ok := result.(QorWidgetSettingInterface); ok { 287 | setting.SetSerializableArgumentKind(utils.ToString(metaValue.Value)) 288 | } 289 | }, 290 | }) 291 | 292 | res.Meta(&admin.Meta{ 293 | Name: "Template", 294 | Type: "select_one", 295 | Valuer: func(result interface{}, context *qor.Context) interface{} { 296 | if setting, ok := result.(QorWidgetSettingInterface); ok { 297 | return setting.GetTemplate() 298 | } 299 | return "" 300 | }, 301 | Collection: func(result interface{}, context *qor.Context) (results [][]string) { 302 | if setting, ok := result.(QorWidgetSettingInterface); ok { 303 | if widget := GetWidget(setting.GetSerializableArgumentKind()); widget != nil { 304 | for _, value := range widget.Templates { 305 | results = append(results, []string{value, value}) 306 | } 307 | } 308 | } 309 | return 310 | }, 311 | Setter: func(result interface{}, metaValue *resource.MetaValue, context *qor.Context) { 312 | if setting, ok := result.(QorWidgetSettingInterface); ok { 313 | setting.SetTemplate(utils.ToString(metaValue.Value)) 314 | } 315 | }, 316 | }) 317 | 318 | res.Meta(&admin.Meta{ 319 | Name: "Shared", 320 | Label: "Add to Container Library (can be reused on other pages)", 321 | }) 322 | 323 | res.Action(&admin.Action{ 324 | Name: "Preview", 325 | URL: func(record interface{}, context *admin.Context) string { 326 | return fmt.Sprintf("%v/%v/%v/!preview", context.Admin.GetRouter().Prefix, res.ToParam(), record.(QorWidgetSettingInterface).GetWidgetName()) 327 | }, 328 | Modes: []string{"edit", "menu_item"}, 329 | }) 330 | 331 | res.AddProcessor(&resource.Processor{ 332 | Name: "widget-default-value", 333 | Handler: func(value interface{}, metaValues *resource.MetaValues, context *qor.Context) error { 334 | if widgetSetting, ok := value.(QorWidgetSettingInterface); ok { 335 | if widgetSetting.GetShared() { 336 | widgetSetting.SetSourceType("") 337 | widgetSetting.SetSourceID("") 338 | } 339 | } 340 | return nil 341 | }, 342 | }) 343 | 344 | res.UseTheme("widget") 345 | 346 | res.IndexAttrs("PreviewIcon", "Name", "Description", "CreatedAt", "UpdatedAt") 347 | res.OverrideShowAttrs(func() { 348 | res.ShowAttrs("PreviewIcon", "Name", "Scope", "WidgetType", "Template", "Description", "Value", "CreatedAt", "UpdatedAt") 349 | }) 350 | res.EditAttrs( 351 | "DisplayName", "Description", "Scope", "Widgets", "Template", 352 | &admin.Section{ 353 | Title: "Settings", 354 | Rows: [][]string{{"Kind"}, {"SerializableMeta"}}, 355 | }, 356 | "Shared", "SourceType", "SourceID", 357 | ) 358 | res.NewAttrs("Name", "Description", "Scope", "Widgets", "Template", 359 | &admin.Section{ 360 | Title: "Settings", 361 | Rows: [][]string{{"Kind"}, {"SerializableMeta"}}, 362 | }, 363 | "Shared", "SourceType", "SourceID", 364 | ) 365 | 366 | searchHandler := res.SearchHandler 367 | res.SearchHandler = func(keyword string, context *qor.Context) *gorm.DB { 368 | // don't include widgets have source_type in index page 369 | if context.ResourceID == "" { 370 | context.SetDB(context.GetDB().Where("source_type = ?", "")) 371 | } 372 | return searchHandler(keyword, context) 373 | } 374 | } 375 | } 376 | -------------------------------------------------------------------------------- /test/banner.tmpl: -------------------------------------------------------------------------------- 1 | Hello, {{.CurrentUser}} 2 |

{{.Title}}

3 |

{{.SubTitle}}

4 | -------------------------------------------------------------------------------- /views/themes/widget/actions/edit/4.widget_scopes.tmpl: -------------------------------------------------------------------------------- 1 | {{$resource := .Resource}} 2 | {{$result := .Result}} 3 | {{$availableScopes := widget_available_scopes}} 4 | {{$scopes := get_widget_scopes}} 5 | 6 | {{if $availableScopes}} 7 | {{$widget_scope := .Context.Request.URL.Query.Get "widget_scope"}} 8 |
9 |
10 | {{range $availableScope := $availableScopes}} 11 | 15 | {{$availableScope.Name}} 16 | 17 | {{end}} 18 |
19 |
20 | {{end}} 21 | 22 | -------------------------------------------------------------------------------- /views/themes/widget/actions/index/4.widget_scopes.tmpl: -------------------------------------------------------------------------------- 1 | {{$result := .Result}} 2 | {{$resource := .Resource}} 3 | {{$availableScopes := widget_available_scopes}} 4 | 5 | {{if $availableScopes}} 6 | {{$widget_scope := .Context.Request.URL.Query.Get "widget_scope"}} 7 |
8 | {{range $availableScope := $availableScopes}} 9 | 10 | {{$availableScope.Name}} 11 | 12 | {{end}} 13 |
14 | {{end}} 15 | -------------------------------------------------------------------------------- /views/themes/widget/assets/javascripts/widget.js: -------------------------------------------------------------------------------- 1 | "use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"===("undefined"==typeof exports?"undefined":_typeof(exports))?require("jquery"):jQuery)}(function(e){function t(i,o){this.$element=e(i),this.options=e.extend({},t.DEFAULTS,e.isPlainObject(o)&&o),this.init()}var i=e("body"),o='select[name="QorResource.Widgets"]';return t.prototype={constructor:t,init:function(){this.bind(),this.isNewForm=this.$element.hasClass("qor-layout__widget-new"),!this.isNewForm&&this.$element.find(o).length&&this.addWidgetSlideout(),this.initSelect()},bind:function(){this.$element.on("change.qor.widget","select",this.change.bind(this)).on("click.qor.widget",".qor-widget__new",this.getFormHtml.bind(this)).on("click.qor.widget",".qor-widget__cancel",this.cancelForm.bind(this))},unbind:function(){this.$element.off("change.qor.widget","select",this.change.bind(this)).off("click.qor.widget",".qor-widget__new",this.getFormHtml.bind(this))},initSelect:function(){var t=this.$element,i=t.find("select").filter('[name="QorResource.Widgets"],[name="QorResource.Template"]'),o=e('[name="QorResource.Kind"]'),n=t.data("hint"),r='

'+n+"

";if(i.closest(".qor-form-section").hide(),i.each(function(){e(this).find("option").filter('[value!=""]').length>=2&&e(this).closest(".qor-form-section").show()}),!this.isNewForm&&!t.find(".qor-bannereditor").length){var s=o.parent().next(".qor-form-section-rows"),l=o.closest(".qor-fieldset"),a=o.closest(".qor-form-section");s.children().length&&l.find(".qor-field__label:visible").length||(s.append(r),t.find(".qor-field__label").not(a.find(".qor-field__label")).is(":visible")||(a.hide(),t.append(r).parent().find(".qor-form__actions").remove()))}},addWidgetSlideout:function(){var t,n,r=this.$element.find(o),s=i.data("tabScopeActive"),l=e(".qor-slideout").is(":visible"),a=r.closest("form"),d=a.data("action-url")||a.prop("action"),c=d&&-1!==d.indexOf("?")?"&":"?";r.find("option").each(function(){var i=e(this),o=i.val();o&&(t=""+d+c+"widget_type="+o,s&&(t=t+"&widget_scope="+s),n=l?"'+o+"":"'+o+"",r.after(n))})},change:function(t){var i=e(t.target),n=i.val(),r=e(".qor-slideout").is(":visible"),s=".qor-widget-"+n,l=e(s),a=l.prop("href");if(i.is(o))return e.fn.qorSlideoutBeforeHide=null,window.onbeforeunload=null,this.isNewForm||(r?l.trigger("click"):location.href=a),!1},getFormHtml:function(i){var o=e(i.target).closest("a"),n=o.data("widget-type"),r=this.$element,s=o.attr("href"),l=r.find(".qor-layout__widget-selector"),a=l.find("select"),d=e(".qor-layout__widget-setting"),c=r.find('[data-section-title="Settings"]'),f=e(t.TEMPLATE_LOADING);return c.length&&(d=c),f.appendTo(d).trigger("enable"),r.find(".qor-slideout__lists-item a").hide(),r.find(".qor-slideout__lists-groupname").hide(),r.find(".qor-layout__widget-actions").show(),e.get(s,function(e){l.find(".qor-layout__widget-name").html(o.data("widget-name")),l.show(),a.val(n).closest(".qor-form-section").hide(),d.html(e).trigger("enable")}).fail(function(){window.alert("server error, please try again!")}),!1},cancelForm:function(){var e=this.$element;e.closest(".qor-bottomsheets").length&&e.closest(".qor-bottomsheets").removeClass("qor-bottomsheets__fullscreen"),e.find(".qor-slideout__lists-item a").show(),e.find(".qor-slideout__lists-groupname").show(),e.find(".qor-layout__widget-actions, .qor-layout__widget-selector").hide(),e.find(".qor-layout__widget-setting").html("")},destroy:function(){this.unbind(),this.$element.removeData("qor.widget")}},t.DEFAULTS={},t.TEMPLATE_LOADING='
',t.plugin=function(i){return this.each(function(){var o=e(this),n=o.data("qor.widget"),r=void 0;if(!n){if(/destroy/.test(i))return;o.data("qor.widget",n=new t(this,i))}"string"==typeof i&&e.isFunction(r=n[i])&&r.apply(n)})},e(function(){var i='[data-toggle="qor.widget"]';e(document).on("disable.qor.widget",function(o){t.plugin.call(e(i,o.target),"destroy")}).on("enable.qor.widget",function(o){t.plugin.call(e(i,o.target))}).triggerHandler("enable.qor.widget"),e(".qor-page__header .qor-page-subnav__header").length&&e(".mdl-layout__content").addClass("has-subnav")}),t}); -------------------------------------------------------------------------------- /views/themes/widget/assets/javascripts/widget/widget.js: -------------------------------------------------------------------------------- 1 | (function(factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | // AMD. Register as anonymous module. 4 | define(['jquery'], factory); 5 | } else if (typeof exports === 'object') { 6 | // Node / CommonJS 7 | factory(require('jquery')); 8 | } else { 9 | // Browser globals. 10 | factory(jQuery); 11 | } 12 | })(function($) { 13 | 'use strict'; 14 | 15 | let $body = $('body'), 16 | NAMESPACE = 'qor.widget', 17 | EVENT_ENABLE = 'enable.' + NAMESPACE, 18 | EVENT_DISABLE = 'disable.' + NAMESPACE, 19 | EVENT_CHANGE = 'change.' + NAMESPACE, 20 | EVENT_CLICK = 'click.' + NAMESPACE, 21 | TARGET_WIDGET = 'select[name="QorResource.Widgets"]', 22 | TARGET_WIDGET_KIND = '[name="QorResource.Kind"]', 23 | SELECT_FILTER = '[name="QorResource.Widgets"],[name="QorResource.Template"]', 24 | CLASS_IS_NEW = 'qor-layout__widget-new', 25 | CLASS_FORM_SECTION = '.qor-form-section', 26 | CLASS_LABEL = '.qor-field__label', 27 | CLASS_LABEL_VISIBLE = '.qor-field__label:visible', 28 | CLASS_FORM_SETTING = '.qor-layout__widget-setting'; 29 | 30 | function QorWidget(element, options) { 31 | this.$element = $(element); 32 | this.options = $.extend({}, QorWidget.DEFAULTS, $.isPlainObject(options) && options); 33 | this.init(); 34 | } 35 | 36 | QorWidget.prototype = { 37 | constructor: QorWidget, 38 | 39 | init: function() { 40 | this.bind(); 41 | this.isNewForm = this.$element.hasClass(CLASS_IS_NEW); 42 | if (!this.isNewForm && this.$element.find(TARGET_WIDGET).length) { 43 | this.addWidgetSlideout(); 44 | } 45 | this.initSelect(); 46 | }, 47 | 48 | bind: function() { 49 | this.$element 50 | .on(EVENT_CHANGE, 'select', this.change.bind(this)) 51 | .on(EVENT_CLICK, '.qor-widget__new', this.getFormHtml.bind(this)) 52 | .on(EVENT_CLICK, '.qor-widget__cancel', this.cancelForm.bind(this)); 53 | }, 54 | 55 | unbind: function() { 56 | this.$element.off(EVENT_CHANGE, 'select', this.change.bind(this)).off(EVENT_CLICK, '.qor-widget__new', this.getFormHtml.bind(this)); 57 | }, 58 | 59 | initSelect: function() { 60 | let $element = this.$element, 61 | $select = $element.find('select').filter(SELECT_FILTER), 62 | $kind = $(TARGET_WIDGET_KIND), 63 | hint = $element.data('hint'), 64 | NO_SETTINGS = `

${hint}

`; 65 | 66 | $select.closest(CLASS_FORM_SECTION).hide(); 67 | $select.each(function() { 68 | if ( 69 | $(this) 70 | .find('option') 71 | .filter('[value!=""]').length >= 2 72 | ) { 73 | $(this) 74 | .closest(CLASS_FORM_SECTION) 75 | .show(); 76 | } 77 | }); 78 | 79 | if (!this.isNewForm && !$element.find('.qor-bannereditor').length) { 80 | let $kindNext = $kind.parent().next('.qor-form-section-rows'), 81 | $kindParent = $kind.closest('.qor-fieldset'), 82 | $kindSection = $kind.closest('.qor-form-section'); 83 | 84 | // if settings dont have any field. will show NO SETTING HINT in settings container 85 | if (!$kindNext.children().length || !$kindParent.find(CLASS_LABEL_VISIBLE).length) { 86 | $kindNext.append(NO_SETTINGS); 87 | 88 | // if no other fields, just has empty settings fields, hide all elements and show NO SETTING HINT. 89 | if ( 90 | !$element 91 | .find(CLASS_LABEL) 92 | .not($kindSection.find(CLASS_LABEL)) 93 | .is(':visible') 94 | ) { 95 | $kindSection.hide(); 96 | $element 97 | .append(NO_SETTINGS) 98 | .parent() 99 | .find('.qor-form__actions') 100 | .remove(); 101 | } 102 | } 103 | } 104 | }, 105 | 106 | addWidgetSlideout: function() { 107 | var $select = this.$element.find(TARGET_WIDGET), 108 | tabScopeActive = $body.data('tabScopeActive'), 109 | isInSlideout = $('.qor-slideout').is(':visible'), 110 | $form = $select.closest('form'), 111 | actionUrl = $form.data('action-url') || $form.prop('action'), 112 | separator = actionUrl && actionUrl.indexOf('?') !== -1 ? '&' : '?', 113 | url, 114 | clickTmpl; 115 | 116 | $select.find('option').each(function() { 117 | var $this = $(this), 118 | val = $this.val(); 119 | 120 | if (val) { 121 | url = `${actionUrl}${separator}widget_type=${val}`; 122 | 123 | if (tabScopeActive) { 124 | url = `${url}&widget_scope=${tabScopeActive}`; 125 | } 126 | 127 | if (isInSlideout) { 128 | clickTmpl = ``; 129 | } else { 130 | clickTmpl = ``; 131 | } 132 | 133 | $select.after(clickTmpl); 134 | } 135 | }); 136 | }, 137 | 138 | change: function(e) { 139 | let $target = $(e.target), 140 | widgetValue = $target.val(), 141 | isInSlideout = $('.qor-slideout').is(':visible'), 142 | clickClass = '.qor-widget-' + widgetValue, 143 | $link = $(clickClass), 144 | url = $link.prop('href'); 145 | 146 | if (!$target.is(TARGET_WIDGET)) { 147 | return; 148 | } 149 | 150 | $.fn.qorSlideoutBeforeHide = null; 151 | window.onbeforeunload = null; 152 | 153 | if (!this.isNewForm) { 154 | if (isInSlideout) { 155 | $link.trigger('click'); 156 | } else { 157 | location.href = url; 158 | } 159 | } 160 | 161 | return false; 162 | }, 163 | 164 | getFormHtml: function(e) { 165 | let $target = $(e.target).closest('a'), 166 | widgetType = $target.data('widget-type'), 167 | $element = this.$element, 168 | url = $target.attr('href'), 169 | $title = $element.find('.qor-layout__widget-selector'), 170 | $selector = $title.find('select'), 171 | $setting = $(CLASS_FORM_SETTING), 172 | $sectionSetting = $element.find('[data-section-title="Settings"]'), 173 | $loading = $(QorWidget.TEMPLATE_LOADING); 174 | 175 | if ($sectionSetting.length) { 176 | $setting = $sectionSetting; 177 | } 178 | 179 | $loading.appendTo($setting).trigger('enable'); 180 | 181 | $element.find('.qor-slideout__lists-item a').hide(); 182 | $element.find('.qor-slideout__lists-groupname').hide(); 183 | $element.find('.qor-layout__widget-actions').show(); 184 | 185 | $.get(url, function(html) { 186 | $title.find('.qor-layout__widget-name').html($target.data('widget-name')); 187 | $title.show(); 188 | $selector 189 | .val(widgetType) 190 | .closest('.qor-form-section') 191 | .hide(); 192 | $setting.html(html).trigger('enable'); 193 | }).fail(function() { 194 | window.alert('server error, please try again!'); 195 | }); 196 | 197 | return false; 198 | }, 199 | 200 | cancelForm: function() { 201 | let $element = this.$element; 202 | 203 | if ($element.closest('.qor-bottomsheets').length) { 204 | $element.closest('.qor-bottomsheets').removeClass('qor-bottomsheets__fullscreen'); 205 | } 206 | $element.find('.qor-slideout__lists-item a').show(); 207 | $element.find('.qor-slideout__lists-groupname').show(); 208 | $element.find('.qor-layout__widget-actions, .qor-layout__widget-selector').hide(); 209 | $element.find(CLASS_FORM_SETTING).html(''); 210 | }, 211 | 212 | destroy: function() { 213 | this.unbind(); 214 | this.$element.removeData(NAMESPACE); 215 | } 216 | }; 217 | 218 | QorWidget.DEFAULTS = {}; 219 | 220 | QorWidget.TEMPLATE_LOADING = 221 | '
'; 222 | 223 | QorWidget.plugin = function(options) { 224 | return this.each(function() { 225 | let $this = $(this), 226 | data = $this.data(NAMESPACE), 227 | fn; 228 | 229 | if (!data) { 230 | if (/destroy/.test(options)) { 231 | return; 232 | } 233 | 234 | $this.data(NAMESPACE, (data = new QorWidget(this, options))); 235 | } 236 | 237 | if (typeof options === 'string' && $.isFunction((fn = data[options]))) { 238 | fn.apply(data); 239 | } 240 | }); 241 | }; 242 | 243 | $(function() { 244 | let selector = '[data-toggle="qor.widget"]'; 245 | 246 | $(document) 247 | .on(EVENT_DISABLE, function(e) { 248 | QorWidget.plugin.call($(selector, e.target), 'destroy'); 249 | }) 250 | .on(EVENT_ENABLE, function(e) { 251 | QorWidget.plugin.call($(selector, e.target)); 252 | }) 253 | .triggerHandler(EVENT_ENABLE); 254 | 255 | if ($('.qor-page__header .qor-page-subnav__header').length) { 256 | $('.mdl-layout__content').addClass('has-subnav'); 257 | } 258 | }); 259 | 260 | return QorWidget; 261 | }); 262 | -------------------------------------------------------------------------------- /views/themes/widget/assets/javascripts/widget_check.js: -------------------------------------------------------------------------------- 1 | if(!window.loadedWidgetAsset) { 2 | window.loadjscssfile = function (filename, filetype) { 3 | var fileref; 4 | if (filetype == "js"){ 5 | fileref = document.createElement('script'); 6 | fileref.setAttribute("type", "text/javascript"); 7 | fileref.setAttribute("src", filename); 8 | } else if (filetype == "css"){ 9 | fileref = document.createElement("link"); 10 | fileref.setAttribute("rel", "stylesheet"); 11 | fileref.setAttribute("type", "text/css"); 12 | fileref.setAttribute("href", filename); 13 | } 14 | if (typeof fileref != "undefined") 15 | document.getElementsByTagName("head")[0].appendChild(fileref); 16 | }; 17 | 18 | window.loadedWidgetAsset = true; 19 | var prefix = document.currentScript.getAttribute("data-prefix"); 20 | 21 | if (!window.jQuery) { 22 | loadjscssfile(prefix + "/assets/javascripts/vendors/jquery.min.js", "js"); 23 | } 24 | 25 | loadjscssfile(prefix + "/assets/javascripts/widget_inline_edit.js?theme=widget", "js"); 26 | loadjscssfile(prefix + "/assets/stylesheets/widget_inline_edit.css?theme=widget", "css"); 27 | } 28 | -------------------------------------------------------------------------------- /views/themes/widget/assets/javascripts/widget_inline_edit.js: -------------------------------------------------------------------------------- 1 | "use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("object"===("undefined"==typeof exports?"undefined":_typeof(exports))?require("jquery"):jQuery)}(function(t){function e(i,n){this.$element=t(i),this.options=t.extend({},e.DEFAULTS,t.isPlainObject(n)&&n),this.init()}var i,n=t("body"),o="qor.widget.inlineEdit";return e.prototype={constructor:e,init:function(){this.bind(),this.initStatus()},bind:function(){this.$element.on("click.qor.widget.inlineEdit",".qor-widget-button",this.click),t(document).on("keyup",this.keyup)},initStatus:function(){var e=document.createElement("iframe");e.src=i,e.id="qor-widget-iframe",e.attachEvent?e.attachEvent("onload",function(){t(".qor-widget-button").show()}):e.onload=function(){t(".qor-widget-button").show()},document.body.appendChild(e)},keyup:function(t){var e=document.getElementById("qor-widget-iframe");27===t.keyCode&&e&&e.contentDocument.querySelector(".qor-slideout__close").click()},click:function(){var e=t(this),i=document.getElementById("qor-widget-iframe"),o=i.contentWindow.$,d=i.contentDocument.querySelector(".js-widget-edit-link");if(d)return i.classList.add("show"),o?o(".js-widget-edit-link").data("url",e.data("url")).click():(d.setAttribute("data-url",e.data("url")),d.click()),n.addClass("open-widget-editor"),!1}},e.plugin=function(i){return this.each(function(){var n,d=t(this),r=d.data(o);if(!r){if(/destroy/.test(i))return;d.data(o,r=new e(this,i))}"string"==typeof i&&t.isFunction(n=r[i])&&n.apply(r)})},t(function(){n.attr("data-toggle","qor.widgets"),t(".qor-widget").each(function(){var e=t(this),n=e.children().eq(0);i=e.data("widget-inline-edit-url"),"static"===n.css("position")&&n.css("position","relative"),n.addClass("qor-widget").unwrap(),n.append('
')});var o='[data-toggle="qor.widgets"]';t(document).on("disable.qor.widget.inlineEdit",function(i){e.plugin.call(t(o,i.target),"destroy")}).on("enable.qor.widget.inlineEdit",function(i){e.plugin.call(t(o,i.target))}).triggerHandler("enable.qor.widget.inlineEdit")}),e}); -------------------------------------------------------------------------------- /views/themes/widget/assets/javascripts/widget_inline_edit/widget_inline_edit.js: -------------------------------------------------------------------------------- 1 | (function(factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | // AMD. Register as anonymous module. 4 | define(['jquery'], factory); 5 | } else if (typeof exports === 'object') { 6 | // Node / CommonJS 7 | factory(require('jquery')); 8 | } else { 9 | // Browser globals. 10 | factory(jQuery); 11 | } 12 | })(function($) { 13 | 14 | 'use strict'; 15 | 16 | var $body = $("body"); 17 | var NAMESPACE = 'qor.widget.inlineEdit'; 18 | var EVENT_ENABLE = 'enable.' + NAMESPACE; 19 | var EVENT_DISABLE = 'disable.' + NAMESPACE; 20 | var EVENT_CLICK = 'click.' + NAMESPACE; 21 | var EDIT_WIDGET_BUTTON = '.qor-widget-button'; 22 | var ID_WIDGET = 'qor-widget-iframe'; 23 | var INLINE_EDIT_URL; 24 | 25 | function QorWidgetInlineEdit(element, options) { 26 | this.$element = $(element); 27 | this.options = $.extend({}, QorWidgetInlineEdit.DEFAULTS, $.isPlainObject(options) && options); 28 | this.init(); 29 | } 30 | 31 | QorWidgetInlineEdit.prototype = { 32 | constructor: QorWidgetInlineEdit, 33 | 34 | init: function() { 35 | this.bind(); 36 | this.initStatus(); 37 | }, 38 | 39 | bind: function() { 40 | this.$element.on(EVENT_CLICK, EDIT_WIDGET_BUTTON, this.click); 41 | $(document).on('keyup', this.keyup); 42 | }, 43 | 44 | initStatus: function() { 45 | var iframe = document.createElement("iframe"); 46 | 47 | iframe.src = INLINE_EDIT_URL; 48 | iframe.id = ID_WIDGET; 49 | 50 | // show edit button after iframe totally loaded. 51 | if (iframe.attachEvent) { 52 | iframe.attachEvent("onload", function() { 53 | $('.qor-widget-button').show(); 54 | }); 55 | } else { 56 | iframe.onload = function() { 57 | $('.qor-widget-button').show(); 58 | }; 59 | } 60 | 61 | document.body.appendChild(iframe); 62 | }, 63 | 64 | keyup: function(e) { 65 | var iframe = document.getElementById('qor-widget-iframe'); 66 | if (e.keyCode === 27) { 67 | iframe && iframe.contentDocument.querySelector('.qor-slideout__close').click(); 68 | } 69 | }, 70 | 71 | click: function() { 72 | var $this = $(this); 73 | var iframe = document.getElementById('qor-widget-iframe'); 74 | var $iframe = iframe.contentWindow.$; 75 | var editLink = iframe.contentDocument.querySelector('.js-widget-edit-link'); 76 | 77 | if (!editLink) { 78 | return; 79 | } 80 | 81 | iframe.classList.add('show'); 82 | 83 | if ($iframe) { 84 | $iframe(".js-widget-edit-link").data("url", $this.data("url")).click(); 85 | } else { 86 | editLink.setAttribute("data-url", $this.data("url")); 87 | editLink.click(); 88 | } 89 | 90 | $body.addClass("open-widget-editor"); 91 | 92 | return false; 93 | } 94 | }; 95 | 96 | QorWidgetInlineEdit.plugin = function(options) { 97 | return this.each(function() { 98 | var $this = $(this); 99 | var data = $this.data(NAMESPACE); 100 | var fn; 101 | 102 | if (!data) { 103 | if (/destroy/.test(options)) { 104 | return; 105 | } 106 | $this.data(NAMESPACE, (data = new QorWidgetInlineEdit(this, options))); 107 | } 108 | 109 | if (typeof options === 'string' && $.isFunction(fn = data[options])) { 110 | fn.apply(data); 111 | } 112 | }); 113 | }; 114 | 115 | 116 | $(function() { 117 | $body.attr("data-toggle", "qor.widgets"); 118 | 119 | $(".qor-widget").each(function() { 120 | var $this = $(this); 121 | var $wrap = $this.children().eq(0); 122 | 123 | INLINE_EDIT_URL = $this.data("widget-inline-edit-url"); 124 | 125 | if ($wrap.css("position") === "static") { 126 | $wrap.css("position", "relative"); 127 | } 128 | 129 | $wrap.addClass("qor-widget").unwrap(); 130 | 131 | $wrap.append('
'); 132 | }); 133 | 134 | var selector = '[data-toggle="qor.widgets"]'; 135 | 136 | $(document). 137 | on(EVENT_DISABLE, function(e) { 138 | QorWidgetInlineEdit.plugin.call($(selector, e.target), 'destroy'); 139 | }). 140 | on(EVENT_ENABLE, function(e) { 141 | QorWidgetInlineEdit.plugin.call($(selector, e.target)); 142 | }). 143 | triggerHandler(EVENT_ENABLE); 144 | }); 145 | 146 | 147 | return QorWidgetInlineEdit; 148 | }); 149 | -------------------------------------------------------------------------------- /views/themes/widget/assets/stylesheets/widget.css: -------------------------------------------------------------------------------- 1 | .qor-slideout__lists{margin:24px 0;padding:0}.qor-slideout__lists .qor-slideout__lists-groupname{font-size:16px}.qor-slideout__lists li{list-style:none;padding:0;margin:12px 0}.qor-slideout__lists .qor-slideout__lists-item img{max-width:100%;box-shadow:1px 0 6px rgba(0,0,0,.2);margin:0 auto 8px;display:block}.qor-slideout__lists .qor-slideout__lists-item>a{display:inline-block;vertical-align:top;padding:8px;border-radius:2px;width:27%;color:rgba(0,0,0,.75);margin-right:2%;margin-bottom:24px;text-align:center}.qor-slideout__lists .qor-slideout__lists-item>a:hover{background-color:rgba(0,0,0,.04)}.qor-slideout__lists .qor-slideout__lists-item>a::nth-child(3n){margin-right:0}.qor-layout__widget-new .qor-layout__widget-selector{margin-top:-20px}.qor-layout__widget-new .qor-layout__widget-selector+[data-section-title=Settings]{display:none}.qor-layout__widget-new .qor-layout__widget-selector .qor-layout__widget-name{padding-top:16px;font-size:20px;font-weight:600}.qor-bottomsheets__body .qor-layout__widget-selector .qor-layout__widget-name{padding-top:0;margin:0}.qor-bottomsheets__body .qor-layout__widget-new{padding:0 24px 0 41px}.qor-bottomsheets__body .qor-slideout__lists .qor-slideout__lists-item>a{width:43%}.qor-theme-widget .qor-table__content{max-height:none}.qor-theme-widget .mdl-data-table tbody tr,.qor-theme-widget .mdl-data-table td{height:auto}.qor-theme-widget .qor-table img.qor-preview-icon{height:auto!important;max-height:100px!important;max-width:70px!important} -------------------------------------------------------------------------------- /views/themes/widget/assets/stylesheets/widget/widget.scss: -------------------------------------------------------------------------------- 1 | .qor-slideout__lists { 2 | margin: 24px 0; 3 | padding: 0; 4 | 5 | .qor-slideout__lists-groupname { 6 | font-size: 16px; 7 | } 8 | 9 | li { 10 | list-style: none; 11 | padding: 0; 12 | margin: 12px 0; 13 | } 14 | 15 | .qor-slideout__lists-item { 16 | img { 17 | max-width: 100%; 18 | box-shadow: 1px 0px 6px rgba(0, 0, 0, 0.2); 19 | margin: 0 auto; 20 | display: block; 21 | margin-bottom: 8px; 22 | } 23 | 24 | > a { 25 | display: inline-block; 26 | vertical-align: top; 27 | padding: 8px; 28 | border-radius: 2px; 29 | width: 27%; 30 | color: rgba(0, 0, 0, 0.75); 31 | margin-right: 2%; 32 | margin-bottom: 24px; 33 | text-align: center; 34 | 35 | &:hover { 36 | background-color: rgba(0, 0, 0, 0.04); 37 | } 38 | 39 | &::nth-child(3n) { 40 | margin-right: 0; 41 | } 42 | } 43 | } 44 | } 45 | 46 | .qor-layout__widget-new { 47 | .qor-layout__widget-selector { 48 | margin-top: -20px; 49 | & + [data-section-title='Settings'] { 50 | display: none; 51 | } 52 | .qor-layout__widget-name { 53 | padding-top: 16px; 54 | font-size: 20px; 55 | font-weight: 600; 56 | } 57 | } 58 | } 59 | 60 | .qor-bottomsheets__body { 61 | .qor-layout__widget-selector { 62 | .qor-layout__widget-name { 63 | padding-top: 0; 64 | margin: 0; 65 | } 66 | } 67 | .qor-layout__widget-new { 68 | padding: 0 24px 0 41px; 69 | } 70 | 71 | .qor-slideout__lists { 72 | .qor-slideout__lists-item > a { 73 | width: 43%; 74 | } 75 | } 76 | } 77 | 78 | .qor-theme-widget { 79 | .qor-table__content { 80 | max-height: none; 81 | } 82 | 83 | .mdl-data-table tbody tr, 84 | .mdl-data-table td { 85 | height: auto; 86 | } 87 | 88 | .qor-table img { 89 | &.qor-preview-icon { 90 | height: auto !important; 91 | max-height: 100px !important; 92 | max-width: 70px !important; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /views/themes/widget/assets/stylesheets/widget_inline_edit.css: -------------------------------------------------------------------------------- 1 | #qor-widget-iframe{background-color:transparent;border:none;width:1px;height:1px;position:fixed}#qor-widget-iframe.show{width:100%;height:100%;top:0;left:0;z-index:999;background-color:rgba(0,0,0,.5)}.qor-widget-button{background-color:#2196f3;color:#fff;border:none;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);padding:6px 32px 6px 16px;display:inline-block;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500}.qor-widget-embed-wrapper{position:absolute;top:4px;right:2px}.qor-widget-embed-wrapper button::after{position:absolute;top:4px;right:-1px;display:inline-block;width:32px;color:#fff;font-size:18px;content:"\270E"}body.open-widget-editor{overflow-y:hidden} -------------------------------------------------------------------------------- /views/themes/widget/assets/stylesheets/widget_inline_edit/widget_inline_edit.scss: -------------------------------------------------------------------------------- 1 | #qor-widget-iframe { 2 | background-color: transparent; 3 | border: none; 4 | width: 1px; 5 | height: 1px; 6 | position : fixed; 7 | } 8 | 9 | #qor-widget-iframe.show { 10 | width : 100%; 11 | height: 100%; 12 | top : 0; 13 | left : 0; 14 | z-index : 999; 15 | background-color : rgba(0, 0, 0, 0.5); 16 | } 17 | 18 | .qor-widget-button { 19 | background-color: rgb(33,150,243); 20 | color: white; 21 | border: none; 22 | box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); 23 | padding: 6px 32px 6px 16px; 24 | display: inline-block; 25 | font-family: "Roboto","Helvetica","Arial",sans-serif; 26 | font-size: 14px; 27 | font-weight: 500; 28 | } 29 | 30 | .qor-widget-embed-wrapper { 31 | position: absolute; 32 | top: 4px; 33 | right: 2px; 34 | } 35 | 36 | .qor-widget-embed-wrapper button::after { 37 | position: absolute; 38 | top: 4px; 39 | right: -1px; 40 | display: inline-block; 41 | width: 32px; 42 | color: #fff; 43 | font-size: 18px; 44 | content: "\270E"; 45 | } 46 | 47 | body.open-widget-editor { 48 | overflow-y: hidden; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /views/themes/widget/edit.tmpl: -------------------------------------------------------------------------------- 1 | {{$result := .Result}} 2 | {{$resource := .Resource}} 3 | 4 | {{$actions := load_actions "edit"}} 5 | {{if $actions}} 6 |
{{$actions}}
7 | {{end}} 8 | 9 |
10 | {{render "shared/flashes"}} 11 | {{render "shared/errors"}} 12 | 13 |
14 |
15 | 16 | 17 |
18 | {{render_form $result edit_sections}} 19 |
20 | 21 | {{if has_update_permission $resource}} 22 |
23 | 24 | {{t "qor_admin.form.cancel_edit" "Cancel Edit"}} 25 |
26 | {{end}} 27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /views/themes/widget/new.tmpl: -------------------------------------------------------------------------------- 1 | {{$result := .Result}} 2 | {{$resource := .Resource}} 3 | {{$context := .}} 4 | 5 | {{$actions := load_actions "new"}} 6 | {{if $actions}} 7 |
{{$actions}}
8 | {{end}} 9 | 10 |
11 | {{render "shared/flashes"}} 12 | {{render "shared/errors"}} 13 | 14 |
15 |
16 | 17 |
18 |
    19 | {{$groupWidgets := widget_grouped_widgets $context}} 20 | {{range $groupWidget := $groupWidgets}} 21 |
  • 22 | {{if $groupWidget.Group}} 23 |
    {{t (printf "qor_widgets.group.%v" $groupWidget.Group) $groupWidget.Group}}
    24 | {{else if (gt (len $groupWidgets) 1)}} 25 |
    {{t "qor_widgets.group.other" "Other"}}
    26 | {{end}} 27 | 28 |
    29 | {{range $widget := $groupWidget.Widgets}} 30 | 31 | {{if $widget.PreviewIcon}} 32 | 33 | {{end}} 34 | {{$widget.Name}} 35 | 36 | {{end}} 37 |
    38 |
  • 39 | {{end}} 40 |
41 | 42 | 46 |
47 | 48 | {{if has_update_permission $resource}} 49 | 53 | {{end}} 54 |
55 |
56 |
57 |
58 | -------------------------------------------------------------------------------- /views/themes/widget/preview.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25 | {{ load_preview_assets }} 26 | 27 | 28 | 29 |
30 |

{{ t "qor_admin.widget.preview_by_name" "Preview Widget: {{.WidgetName}}" .Result}}

31 | 32 |
33 | {{render_widget .Result.WidgetName}} 34 |
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /views/themes/widget/setting.tmpl: -------------------------------------------------------------------------------- 1 | {{$result := .Result}} 2 | {{render_form $result.Widget $result.Section }} 3 | -------------------------------------------------------------------------------- /views/widget/inline_edit.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {{stylesheet_tag "qor_admin_default"}} 18 | {{load_admin_stylesheets}} 19 | {{load_theme_stylesheets}} 20 | {{javascript_tag "vendors"}} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 34 | {{javascript_tag "qor_admin_default"}} 35 | {{load_admin_javascripts}} 36 | {{load_theme_javascripts}} 37 | 38 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /widget.go: -------------------------------------------------------------------------------- 1 | package widget 2 | 3 | import ( 4 | "fmt" 5 | "html/template" 6 | "log" 7 | "path/filepath" 8 | 9 | "github.com/jinzhu/gorm" 10 | "github.com/qor/admin" 11 | "github.com/qor/assetfs" 12 | "github.com/qor/qor/resource" 13 | "github.com/qor/qor/utils" 14 | "github.com/qor/roles" 15 | ) 16 | 17 | var ( 18 | viewPaths []string 19 | registeredWidgets []*Widget 20 | registeredWidgetsGroup []*WidgetsGroup 21 | ) 22 | 23 | // Config widget config 24 | type Config struct { 25 | DB *gorm.DB 26 | Admin *admin.Admin 27 | PreviewAssets []string 28 | } 29 | 30 | // New new widgets container 31 | func New(config *Config) *Widgets { 32 | widgets := &Widgets{Config: config, funcMaps: template.FuncMap{}, AssetFS: assetfs.AssetFS().NameSpace("widgets")} 33 | 34 | if utils.AppRoot != "" { 35 | widgets.RegisterViewPath(filepath.Join(utils.AppRoot, "app/views/widgets")) 36 | } 37 | widgets.RegisterViewPath("app/views/widgets") 38 | return widgets 39 | } 40 | 41 | // Widgets widgets container 42 | type Widgets struct { 43 | funcMaps template.FuncMap 44 | Config *Config 45 | Resource *admin.Resource 46 | AssetFS assetfs.Interface 47 | WidgetSettingResource *admin.Resource 48 | } 49 | 50 | // SetAssetFS set asset fs for render 51 | func (widgets *Widgets) SetAssetFS(assetFS assetfs.Interface) { 52 | for _, viewPath := range viewPaths { 53 | assetFS.RegisterPath(viewPath) 54 | } 55 | 56 | widgets.AssetFS = assetFS 57 | } 58 | 59 | // RegisterWidget register a new widget 60 | func (widgets *Widgets) RegisterWidget(w *Widget) { 61 | registeredWidgets = append(registeredWidgets, w) 62 | } 63 | 64 | // RegisterWidgetsGroup register widgets group 65 | func (widgets *Widgets) RegisterWidgetsGroup(group *WidgetsGroup) { 66 | registeredWidgetsGroup = append(registeredWidgetsGroup, group) 67 | } 68 | 69 | // RegisterFuncMap register view funcs, it could be used when render templates 70 | func (widgets *Widgets) RegisterFuncMap(name string, fc interface{}) { 71 | widgets.funcMaps[name] = fc 72 | } 73 | 74 | // ConfigureQorResourceBeforeInitialize a method used to config Widget for qor admin 75 | func (widgets *Widgets) ConfigureQorResourceBeforeInitialize(res resource.Resourcer) { 76 | if res, ok := res.(*admin.Resource); ok { 77 | // register view paths 78 | res.GetAdmin().RegisterViewPath("github.com/qor/widget/views") 79 | 80 | // set resources 81 | widgets.Resource = res 82 | 83 | // set setting resource 84 | if widgets.WidgetSettingResource == nil { 85 | widgets.WidgetSettingResource = res.GetAdmin().NewResource(&QorWidgetSetting{}, &admin.Config{Name: res.Name}) 86 | } 87 | 88 | res.Name = widgets.WidgetSettingResource.Name 89 | 90 | for funcName, fc := range funcMap { 91 | res.GetAdmin().RegisterFuncMap(funcName, fc) 92 | } 93 | 94 | // configure routes 95 | controller := widgetController{Widgets: widgets} 96 | router := res.GetAdmin().GetRouter() 97 | router.Get(widgets.WidgetSettingResource.ToParam(), controller.Index, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 98 | router.Get(fmt.Sprintf("%v/new", widgets.WidgetSettingResource.ToParam()), controller.New, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 99 | router.Get(fmt.Sprintf("%v/!setting", widgets.WidgetSettingResource.ToParam()), controller.Setting, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 100 | router.Get(fmt.Sprintf("%v/%v", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Edit, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 101 | router.Get(fmt.Sprintf("%v/%v/!preview", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Preview, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 102 | router.Get(fmt.Sprintf("%v/%v/edit", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Edit, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 103 | router.Put(fmt.Sprintf("%v/%v", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Update, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 104 | router.Post(widgets.WidgetSettingResource.ToParam(), controller.Update, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 105 | router.Get(fmt.Sprintf("%v/inline-edit", res.ToParam()), controller.InlineEdit, &admin.RouteConfig{Resource: widgets.WidgetSettingResource}) 106 | } 107 | } 108 | 109 | // Widget widget struct 110 | type Widget struct { 111 | Name string 112 | PreviewIcon string 113 | Group string 114 | Templates []string 115 | Setting *admin.Resource 116 | Permission *roles.Permission 117 | InlineEditURL func(*Context) string 118 | Context func(context *Context, setting interface{}) *Context 119 | } 120 | 121 | // WidgetsGroup widgets Group 122 | type WidgetsGroup struct { 123 | Name string 124 | Widgets []string 125 | } 126 | 127 | // GetWidget get widget by name 128 | func GetWidget(name string) *Widget { 129 | for _, w := range registeredWidgets { 130 | if w.Name == name { 131 | return w 132 | } 133 | } 134 | 135 | for _, g := range registeredWidgetsGroup { 136 | if g.Name == name { 137 | for _, widgetName := range g.Widgets { 138 | return GetWidget(widgetName) 139 | } 140 | } 141 | } 142 | 143 | log.Println("widget " + name + " not exists, make sure to register it") 144 | return nil 145 | } 146 | 147 | // GetWidgets GetWidgets return registered widgets 148 | func GetWidgets() []*Widget { 149 | return registeredWidgets 150 | } 151 | -------------------------------------------------------------------------------- /widget_test.go: -------------------------------------------------------------------------------- 1 | package widget_test 2 | 3 | import ( 4 | "fmt" 5 | "html/template" 6 | "net/http" 7 | "net/http/httptest" 8 | "net/url" 9 | "strings" 10 | "testing" 11 | 12 | "github.com/fatih/color" 13 | "github.com/jinzhu/gorm" 14 | "github.com/qor/admin" 15 | "github.com/qor/qor" 16 | "github.com/qor/qor/test/utils" 17 | "github.com/qor/widget" 18 | ) 19 | 20 | var db *gorm.DB 21 | var Widgets *widget.Widgets 22 | var Admin *admin.Admin 23 | var Server *httptest.Server 24 | 25 | type bannerArgument struct { 26 | Title string 27 | SubTitle string 28 | } 29 | 30 | func init() { 31 | db = utils.TestDB() 32 | //db.LogMode(true) 33 | } 34 | 35 | // Runner 36 | func setup() { 37 | if err := db.DropTableIfExists(&widget.QorWidgetSetting{}).Error; err != nil { 38 | panic(err) 39 | } 40 | db.AutoMigrate(&widget.QorWidgetSetting{}) 41 | mux := http.NewServeMux() 42 | Server = httptest.NewServer(mux) 43 | 44 | Widgets = widget.New(&widget.Config{ 45 | DB: db, 46 | }) 47 | Widgets.RegisterViewPath("github.com/qor/widget/test") 48 | 49 | Admin = admin.New(&qor.Config{DB: db}) 50 | Admin.AddResource(Widgets) 51 | Admin.MountTo("/admin", mux) 52 | 53 | Widgets.RegisterWidget(&widget.Widget{ 54 | Name: "Banner", 55 | Templates: []string{"banner"}, 56 | Setting: Admin.NewResource(&bannerArgument{}), 57 | Context: func(context *widget.Context, setting interface{}) *widget.Context { 58 | if setting != nil { 59 | argument := setting.(*bannerArgument) 60 | context.Options["Title"] = argument.Title 61 | context.Options["SubTitle"] = argument.SubTitle 62 | } 63 | return context 64 | }, 65 | }) 66 | 67 | Widgets.RegisterScope(&widget.Scope{ 68 | Name: "From Google", 69 | Visible: func(context *widget.Context) bool { 70 | if request, ok := context.Get("Request"); ok { 71 | _, ok := request.(*http.Request).URL.Query()["from_google"] 72 | return ok 73 | } 74 | return false 75 | }, 76 | }) 77 | 78 | Widgets.RegisterWidget(&widget.Widget{ 79 | Name: "NoTemplate", 80 | Setting: Admin.NewResource(&bannerArgument{}), 81 | Context: func(context *widget.Context, setting interface{}) *widget.Context { 82 | context.Body = "

My html

" 83 | return context 84 | }, 85 | }) 86 | } 87 | 88 | func reset() { 89 | db.DropTable(&widget.QorWidgetSetting{}) 90 | db.AutoMigrate(&widget.QorWidgetSetting{}) 91 | setup() 92 | } 93 | 94 | // Test DB's record after call Render 95 | func TestRenderRecord(t *testing.T) { 96 | reset() 97 | var count int 98 | db.Model(&widget.QorWidgetSetting{}).Where(widget.QorWidgetSetting{Name: "HomeBanner", WidgetType: "Banner", Scope: "default", GroupName: "Banner"}).Count(&count) 99 | if count != 0 { 100 | t.Errorf(color.RedString(fmt.Sprintf("\nWidget Render Record TestCase: should don't exist widget setting"))) 101 | } 102 | 103 | widgetContext := Widgets.NewContext(&widget.Context{}) 104 | widgetContext.Render("HomeBanner", "Banner") 105 | db.Model(&widget.QorWidgetSetting{}).Where(widget.QorWidgetSetting{Name: "HomeBanner", WidgetType: "Banner", Scope: "default", GroupName: "Banner"}).Count(&count) 106 | if count == 0 { 107 | t.Errorf(color.RedString(fmt.Sprintf("\nWidget Render Record TestCase: should have default widget setting"))) 108 | } 109 | 110 | http.PostForm(Server.URL+"/admin/widgets/HomeBanner", 111 | url.Values{"_method": {"PUT"}, 112 | "QorResource.Scope": {"from_google"}, 113 | "QorResource.ActivatedAt": {"2016-07-14 10:10:42.433372925 +0800 CST"}, 114 | "QorResource.Widgets": {"Banner"}, 115 | "QorResource.Template": {"banner"}, 116 | "QorResource.Kind": {"Banner"}, 117 | }) 118 | db.Model(&widget.QorWidgetSetting{}).Where(widget.QorWidgetSetting{Name: "HomeBanner", WidgetType: "Banner", Scope: "from_google"}).Count(&count) 119 | if count == 0 { 120 | t.Errorf(color.RedString(fmt.Sprintf("\nWidget Render Record TestCase: should have from_google widget setting"))) 121 | } 122 | } 123 | 124 | // Runner 125 | func TestRenderContext(t *testing.T) { 126 | reset() 127 | setting := &widget.QorWidgetSetting{} 128 | db.Where(widget.QorWidgetSetting{Name: "HomeBanner", WidgetType: "Banner", Scope: "default"}).FirstOrInit(setting) 129 | db.Create(setting) 130 | 131 | html := Widgets.Render("HomeBanner", "Banner") 132 | if !strings.Contains(string(html), "Hello, \n

\n

\n") { 133 | t.Errorf(color.RedString(fmt.Sprintf("\nWidget Render TestCase #%d: Failure Result:\n %s\n", 1, html))) 134 | } 135 | 136 | widgetContext := Widgets.NewContext(&widget.Context{ 137 | Options: map[string]interface{}{"CurrentUser": "Qortex"}, 138 | }) 139 | html = widgetContext.Render("HomeBanner", "Banner") 140 | if !strings.Contains(string(html), "Hello, Qortex\n

\n

\n") { 141 | t.Errorf(color.RedString(fmt.Sprintf("\nWidget Render TestCase #%d: Failure Result:\n %s\n", 2, html))) 142 | } 143 | 144 | db.Where(widget.QorWidgetSetting{Name: "HomeBanner", WidgetType: "Banner"}).FirstOrInit(setting) 145 | setting.SetSerializableArgumentValue(&bannerArgument{Title: "Title", SubTitle: "SubTitle"}) 146 | err := db.Model(setting).Update(setting).Error 147 | if err != nil { 148 | panic(err) 149 | } 150 | 151 | html = widgetContext.Render("HomeBanner", "Banner") 152 | if !strings.Contains(string(html), "Hello, Qortex\n

Title

\n

SubTitle

\n") { 153 | t.Errorf(color.RedString(fmt.Sprintf("\nWidget Render TestCase #%d: Failure Result:\n %s\n", 3, html))) 154 | } 155 | 156 | } 157 | 158 | func TestRenderNoTemplate(t *testing.T) { 159 | reset() 160 | 161 | html := Widgets.Render("abc", "NoTemplate") 162 | if !strings.Contains(string(html), "

My html

") { 163 | t.Errorf(color.RedString(fmt.Sprintf("\nWidget Render TestCase #%d: Failure Result:\n %s\n", 5, html))) 164 | } 165 | 166 | } 167 | 168 | func TestRegisterFuncMap(t *testing.T) { 169 | func1 := func() {} 170 | Widgets.RegisterFuncMap("func1", func1) 171 | context := Widgets.NewContext(nil) 172 | if _, ok := context.FuncMaps["func1"]; !ok { 173 | t.Errorf("func1 should be assigned to context") 174 | } 175 | 176 | context2 := context.Funcs(template.FuncMap{"func2": func() {}}) 177 | if _, ok := context.FuncMaps["func2"]; !ok { 178 | t.Errorf("func2 should be assigned to context") 179 | } 180 | if _, ok := context2.FuncMaps["func2"]; !ok { 181 | t.Errorf("func2 should be assigned to context") 182 | } 183 | 184 | context3 := Widgets.NewContext(nil) 185 | if _, ok := context3.FuncMaps["func3"]; ok { 186 | t.Errorf("func3 should not be assigned to other contexts") 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ampproject/remapping@^2.2.0": 6 | version "2.3.0" 7 | resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" 8 | integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== 9 | dependencies: 10 | "@jridgewell/gen-mapping" "^0.3.5" 11 | "@jridgewell/trace-mapping" "^0.3.24" 12 | 13 | "@babel/code-frame@^7.24.7": 14 | version "7.24.7" 15 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" 16 | integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== 17 | dependencies: 18 | "@babel/highlight" "^7.24.7" 19 | picocolors "^1.0.0" 20 | 21 | "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2": 22 | version "7.25.2" 23 | resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.2.tgz#e41928bd33475305c586f6acbbb7e3ade7a6f7f5" 24 | integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ== 25 | 26 | "@babel/core@^7.25.2": 27 | version "7.25.2" 28 | resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77" 29 | integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== 30 | dependencies: 31 | "@ampproject/remapping" "^2.2.0" 32 | "@babel/code-frame" "^7.24.7" 33 | "@babel/generator" "^7.25.0" 34 | "@babel/helper-compilation-targets" "^7.25.2" 35 | "@babel/helper-module-transforms" "^7.25.2" 36 | "@babel/helpers" "^7.25.0" 37 | "@babel/parser" "^7.25.0" 38 | "@babel/template" "^7.25.0" 39 | "@babel/traverse" "^7.25.2" 40 | "@babel/types" "^7.25.2" 41 | convert-source-map "^2.0.0" 42 | debug "^4.1.0" 43 | gensync "^1.0.0-beta.2" 44 | json5 "^2.2.3" 45 | semver "^6.3.1" 46 | 47 | "@babel/generator@^7.25.0": 48 | version "7.25.0" 49 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.0.tgz#f858ddfa984350bc3d3b7f125073c9af6988f18e" 50 | integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== 51 | dependencies: 52 | "@babel/types" "^7.25.0" 53 | "@jridgewell/gen-mapping" "^0.3.5" 54 | "@jridgewell/trace-mapping" "^0.3.25" 55 | jsesc "^2.5.1" 56 | 57 | "@babel/helper-annotate-as-pure@^7.24.7": 58 | version "7.24.7" 59 | resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" 60 | integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== 61 | dependencies: 62 | "@babel/types" "^7.24.7" 63 | 64 | "@babel/helper-builder-binary-assignment-operator-visitor@^7.24.7": 65 | version "7.24.7" 66 | resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz#37d66feb012024f2422b762b9b2a7cfe27c7fba3" 67 | integrity sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA== 68 | dependencies: 69 | "@babel/traverse" "^7.24.7" 70 | "@babel/types" "^7.24.7" 71 | 72 | "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.25.2": 73 | version "7.25.2" 74 | resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" 75 | integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== 76 | dependencies: 77 | "@babel/compat-data" "^7.25.2" 78 | "@babel/helper-validator-option" "^7.24.8" 79 | browserslist "^4.23.1" 80 | lru-cache "^5.1.1" 81 | semver "^6.3.1" 82 | 83 | "@babel/helper-create-class-features-plugin@^7.24.7": 84 | version "7.25.0" 85 | resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz#a109bf9c3d58dfed83aaf42e85633c89f43a6253" 86 | integrity sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ== 87 | dependencies: 88 | "@babel/helper-annotate-as-pure" "^7.24.7" 89 | "@babel/helper-member-expression-to-functions" "^7.24.8" 90 | "@babel/helper-optimise-call-expression" "^7.24.7" 91 | "@babel/helper-replace-supers" "^7.25.0" 92 | "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" 93 | "@babel/traverse" "^7.25.0" 94 | semver "^6.3.1" 95 | 96 | "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.7", "@babel/helper-create-regexp-features-plugin@^7.25.0": 97 | version "7.25.2" 98 | resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz#24c75974ed74183797ffd5f134169316cd1808d9" 99 | integrity sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g== 100 | dependencies: 101 | "@babel/helper-annotate-as-pure" "^7.24.7" 102 | regexpu-core "^5.3.1" 103 | semver "^6.3.1" 104 | 105 | "@babel/helper-define-polyfill-provider@^0.6.1", "@babel/helper-define-polyfill-provider@^0.6.2": 106 | version "0.6.2" 107 | resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" 108 | integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== 109 | dependencies: 110 | "@babel/helper-compilation-targets" "^7.22.6" 111 | "@babel/helper-plugin-utils" "^7.22.5" 112 | debug "^4.1.1" 113 | lodash.debounce "^4.0.8" 114 | resolve "^1.14.2" 115 | 116 | "@babel/helper-member-expression-to-functions@^7.24.8": 117 | version "7.24.8" 118 | resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz#6155e079c913357d24a4c20480db7c712a5c3fb6" 119 | integrity sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA== 120 | dependencies: 121 | "@babel/traverse" "^7.24.8" 122 | "@babel/types" "^7.24.8" 123 | 124 | "@babel/helper-module-imports@^7.24.7": 125 | version "7.24.7" 126 | resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" 127 | integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== 128 | dependencies: 129 | "@babel/traverse" "^7.24.7" 130 | "@babel/types" "^7.24.7" 131 | 132 | "@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.25.0", "@babel/helper-module-transforms@^7.25.2": 133 | version "7.25.2" 134 | resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" 135 | integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== 136 | dependencies: 137 | "@babel/helper-module-imports" "^7.24.7" 138 | "@babel/helper-simple-access" "^7.24.7" 139 | "@babel/helper-validator-identifier" "^7.24.7" 140 | "@babel/traverse" "^7.25.2" 141 | 142 | "@babel/helper-optimise-call-expression@^7.24.7": 143 | version "7.24.7" 144 | resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" 145 | integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== 146 | dependencies: 147 | "@babel/types" "^7.24.7" 148 | 149 | "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": 150 | version "7.24.8" 151 | resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" 152 | integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== 153 | 154 | "@babel/helper-remap-async-to-generator@^7.24.7", "@babel/helper-remap-async-to-generator@^7.25.0": 155 | version "7.25.0" 156 | resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz#d2f0fbba059a42d68e5e378feaf181ef6055365e" 157 | integrity sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw== 158 | dependencies: 159 | "@babel/helper-annotate-as-pure" "^7.24.7" 160 | "@babel/helper-wrap-function" "^7.25.0" 161 | "@babel/traverse" "^7.25.0" 162 | 163 | "@babel/helper-replace-supers@^7.24.7", "@babel/helper-replace-supers@^7.25.0": 164 | version "7.25.0" 165 | resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz#ff44deac1c9f619523fe2ca1fd650773792000a9" 166 | integrity sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg== 167 | dependencies: 168 | "@babel/helper-member-expression-to-functions" "^7.24.8" 169 | "@babel/helper-optimise-call-expression" "^7.24.7" 170 | "@babel/traverse" "^7.25.0" 171 | 172 | "@babel/helper-simple-access@^7.24.7": 173 | version "7.24.7" 174 | resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" 175 | integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== 176 | dependencies: 177 | "@babel/traverse" "^7.24.7" 178 | "@babel/types" "^7.24.7" 179 | 180 | "@babel/helper-skip-transparent-expression-wrappers@^7.24.7": 181 | version "7.24.7" 182 | resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" 183 | integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== 184 | dependencies: 185 | "@babel/traverse" "^7.24.7" 186 | "@babel/types" "^7.24.7" 187 | 188 | "@babel/helper-string-parser@^7.24.8": 189 | version "7.24.8" 190 | resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" 191 | integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== 192 | 193 | "@babel/helper-validator-identifier@^7.24.7": 194 | version "7.24.7" 195 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" 196 | integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== 197 | 198 | "@babel/helper-validator-option@^7.24.8": 199 | version "7.24.8" 200 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" 201 | integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== 202 | 203 | "@babel/helper-wrap-function@^7.25.0": 204 | version "7.25.0" 205 | resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz#dab12f0f593d6ca48c0062c28bcfb14ebe812f81" 206 | integrity sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ== 207 | dependencies: 208 | "@babel/template" "^7.25.0" 209 | "@babel/traverse" "^7.25.0" 210 | "@babel/types" "^7.25.0" 211 | 212 | "@babel/helpers@^7.25.0": 213 | version "7.25.0" 214 | resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.0.tgz#e69beb7841cb93a6505531ede34f34e6a073650a" 215 | integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw== 216 | dependencies: 217 | "@babel/template" "^7.25.0" 218 | "@babel/types" "^7.25.0" 219 | 220 | "@babel/highlight@^7.24.7": 221 | version "7.24.7" 222 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" 223 | integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== 224 | dependencies: 225 | "@babel/helper-validator-identifier" "^7.24.7" 226 | chalk "^2.4.2" 227 | js-tokens "^4.0.0" 228 | picocolors "^1.0.0" 229 | 230 | "@babel/parser@^7.25.0": 231 | version "7.25.0" 232 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.0.tgz#9fdc9237504d797b6e7b8f66e78ea7f570d256ad" 233 | integrity sha512-CzdIU9jdP0dg7HdyB+bHvDJGagUv+qtzZt5rYCWwW6tITNqV9odjp6Qu41gkG0ca5UfdDUWrKkiAnHHdGRnOrA== 234 | 235 | "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.0": 236 | version "7.25.0" 237 | resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.0.tgz#328275f22d809b962978d998c6eba22a233ac8aa" 238 | integrity sha512-dG0aApncVQwAUJa8tP1VHTnmU67BeIQvKafd3raEx315H54FfkZSz3B/TT+33ZQAjatGJA79gZqTtqL5QZUKXw== 239 | dependencies: 240 | "@babel/helper-plugin-utils" "^7.24.8" 241 | "@babel/traverse" "^7.25.0" 242 | 243 | "@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.0": 244 | version "7.25.0" 245 | resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz#cd0c583e01369ef51676bdb3d7b603e17d2b3f73" 246 | integrity sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA== 247 | dependencies: 248 | "@babel/helper-plugin-utils" "^7.24.8" 249 | 250 | "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.0": 251 | version "7.25.0" 252 | resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz#749bde80356b295390954643de7635e0dffabe73" 253 | integrity sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA== 254 | dependencies: 255 | "@babel/helper-plugin-utils" "^7.24.8" 256 | 257 | "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.7": 258 | version "7.24.7" 259 | resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz#e4eabdd5109acc399b38d7999b2ef66fc2022f89" 260 | integrity sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ== 261 | dependencies: 262 | "@babel/helper-plugin-utils" "^7.24.7" 263 | "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" 264 | "@babel/plugin-transform-optional-chaining" "^7.24.7" 265 | 266 | "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.0": 267 | version "7.25.0" 268 | resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz#3a82a70e7cb7294ad2559465ebcb871dfbf078fb" 269 | integrity sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw== 270 | dependencies: 271 | "@babel/helper-plugin-utils" "^7.24.8" 272 | "@babel/traverse" "^7.25.0" 273 | 274 | "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": 275 | version "7.21.0-placeholder-for-preset-env.2" 276 | resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" 277 | integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== 278 | 279 | "@babel/plugin-syntax-async-generators@^7.8.4": 280 | version "7.8.4" 281 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" 282 | integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== 283 | dependencies: 284 | "@babel/helper-plugin-utils" "^7.8.0" 285 | 286 | "@babel/plugin-syntax-class-properties@^7.12.13": 287 | version "7.12.13" 288 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" 289 | integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== 290 | dependencies: 291 | "@babel/helper-plugin-utils" "^7.12.13" 292 | 293 | "@babel/plugin-syntax-class-static-block@^7.14.5": 294 | version "7.14.5" 295 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" 296 | integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== 297 | dependencies: 298 | "@babel/helper-plugin-utils" "^7.14.5" 299 | 300 | "@babel/plugin-syntax-dynamic-import@^7.8.3": 301 | version "7.8.3" 302 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" 303 | integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== 304 | dependencies: 305 | "@babel/helper-plugin-utils" "^7.8.0" 306 | 307 | "@babel/plugin-syntax-export-namespace-from@^7.8.3": 308 | version "7.8.3" 309 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" 310 | integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== 311 | dependencies: 312 | "@babel/helper-plugin-utils" "^7.8.3" 313 | 314 | "@babel/plugin-syntax-import-assertions@^7.24.7": 315 | version "7.24.7" 316 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz#2a0b406b5871a20a841240586b1300ce2088a778" 317 | integrity sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg== 318 | dependencies: 319 | "@babel/helper-plugin-utils" "^7.24.7" 320 | 321 | "@babel/plugin-syntax-import-attributes@^7.24.7": 322 | version "7.24.7" 323 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz#b4f9ea95a79e6912480c4b626739f86a076624ca" 324 | integrity sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A== 325 | dependencies: 326 | "@babel/helper-plugin-utils" "^7.24.7" 327 | 328 | "@babel/plugin-syntax-import-meta@^7.10.4": 329 | version "7.10.4" 330 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" 331 | integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== 332 | dependencies: 333 | "@babel/helper-plugin-utils" "^7.10.4" 334 | 335 | "@babel/plugin-syntax-json-strings@^7.8.3": 336 | version "7.8.3" 337 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" 338 | integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== 339 | dependencies: 340 | "@babel/helper-plugin-utils" "^7.8.0" 341 | 342 | "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": 343 | version "7.10.4" 344 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" 345 | integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== 346 | dependencies: 347 | "@babel/helper-plugin-utils" "^7.10.4" 348 | 349 | "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": 350 | version "7.8.3" 351 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" 352 | integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== 353 | dependencies: 354 | "@babel/helper-plugin-utils" "^7.8.0" 355 | 356 | "@babel/plugin-syntax-numeric-separator@^7.10.4": 357 | version "7.10.4" 358 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" 359 | integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== 360 | dependencies: 361 | "@babel/helper-plugin-utils" "^7.10.4" 362 | 363 | "@babel/plugin-syntax-object-rest-spread@^7.8.3": 364 | version "7.8.3" 365 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" 366 | integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== 367 | dependencies: 368 | "@babel/helper-plugin-utils" "^7.8.0" 369 | 370 | "@babel/plugin-syntax-optional-catch-binding@^7.8.3": 371 | version "7.8.3" 372 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" 373 | integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== 374 | dependencies: 375 | "@babel/helper-plugin-utils" "^7.8.0" 376 | 377 | "@babel/plugin-syntax-optional-chaining@^7.8.3": 378 | version "7.8.3" 379 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" 380 | integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== 381 | dependencies: 382 | "@babel/helper-plugin-utils" "^7.8.0" 383 | 384 | "@babel/plugin-syntax-private-property-in-object@^7.14.5": 385 | version "7.14.5" 386 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" 387 | integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== 388 | dependencies: 389 | "@babel/helper-plugin-utils" "^7.14.5" 390 | 391 | "@babel/plugin-syntax-top-level-await@^7.14.5": 392 | version "7.14.5" 393 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" 394 | integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== 395 | dependencies: 396 | "@babel/helper-plugin-utils" "^7.14.5" 397 | 398 | "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": 399 | version "7.18.6" 400 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" 401 | integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== 402 | dependencies: 403 | "@babel/helper-create-regexp-features-plugin" "^7.18.6" 404 | "@babel/helper-plugin-utils" "^7.18.6" 405 | 406 | "@babel/plugin-transform-arrow-functions@^7.24.7": 407 | version "7.24.7" 408 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz#4f6886c11e423bd69f3ce51dbf42424a5f275514" 409 | integrity sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ== 410 | dependencies: 411 | "@babel/helper-plugin-utils" "^7.24.7" 412 | 413 | "@babel/plugin-transform-async-generator-functions@^7.25.0": 414 | version "7.25.0" 415 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz#b785cf35d73437f6276b1e30439a57a50747bddf" 416 | integrity sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q== 417 | dependencies: 418 | "@babel/helper-plugin-utils" "^7.24.8" 419 | "@babel/helper-remap-async-to-generator" "^7.25.0" 420 | "@babel/plugin-syntax-async-generators" "^7.8.4" 421 | "@babel/traverse" "^7.25.0" 422 | 423 | "@babel/plugin-transform-async-to-generator@^7.24.7": 424 | version "7.24.7" 425 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz#72a3af6c451d575842a7e9b5a02863414355bdcc" 426 | integrity sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA== 427 | dependencies: 428 | "@babel/helper-module-imports" "^7.24.7" 429 | "@babel/helper-plugin-utils" "^7.24.7" 430 | "@babel/helper-remap-async-to-generator" "^7.24.7" 431 | 432 | "@babel/plugin-transform-block-scoped-functions@^7.24.7": 433 | version "7.24.7" 434 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz#a4251d98ea0c0f399dafe1a35801eaba455bbf1f" 435 | integrity sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ== 436 | dependencies: 437 | "@babel/helper-plugin-utils" "^7.24.7" 438 | 439 | "@babel/plugin-transform-block-scoping@^7.25.0": 440 | version "7.25.0" 441 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz#23a6ed92e6b006d26b1869b1c91d1b917c2ea2ac" 442 | integrity sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ== 443 | dependencies: 444 | "@babel/helper-plugin-utils" "^7.24.8" 445 | 446 | "@babel/plugin-transform-class-properties@^7.24.7": 447 | version "7.24.7" 448 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz#256879467b57b0b68c7ddfc5b76584f398cd6834" 449 | integrity sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w== 450 | dependencies: 451 | "@babel/helper-create-class-features-plugin" "^7.24.7" 452 | "@babel/helper-plugin-utils" "^7.24.7" 453 | 454 | "@babel/plugin-transform-class-static-block@^7.24.7": 455 | version "7.24.7" 456 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz#c82027ebb7010bc33c116d4b5044fbbf8c05484d" 457 | integrity sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ== 458 | dependencies: 459 | "@babel/helper-create-class-features-plugin" "^7.24.7" 460 | "@babel/helper-plugin-utils" "^7.24.7" 461 | "@babel/plugin-syntax-class-static-block" "^7.14.5" 462 | 463 | "@babel/plugin-transform-classes@^7.25.0": 464 | version "7.25.0" 465 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz#63122366527d88e0ef61b612554fe3f8c793991e" 466 | integrity sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw== 467 | dependencies: 468 | "@babel/helper-annotate-as-pure" "^7.24.7" 469 | "@babel/helper-compilation-targets" "^7.24.8" 470 | "@babel/helper-plugin-utils" "^7.24.8" 471 | "@babel/helper-replace-supers" "^7.25.0" 472 | "@babel/traverse" "^7.25.0" 473 | globals "^11.1.0" 474 | 475 | "@babel/plugin-transform-computed-properties@^7.24.7": 476 | version "7.24.7" 477 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz#4cab3214e80bc71fae3853238d13d097b004c707" 478 | integrity sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ== 479 | dependencies: 480 | "@babel/helper-plugin-utils" "^7.24.7" 481 | "@babel/template" "^7.24.7" 482 | 483 | "@babel/plugin-transform-destructuring@^7.24.8": 484 | version "7.24.8" 485 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz#c828e814dbe42a2718a838c2a2e16a408e055550" 486 | integrity sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ== 487 | dependencies: 488 | "@babel/helper-plugin-utils" "^7.24.8" 489 | 490 | "@babel/plugin-transform-dotall-regex@^7.24.7": 491 | version "7.24.7" 492 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz#5f8bf8a680f2116a7207e16288a5f974ad47a7a0" 493 | integrity sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw== 494 | dependencies: 495 | "@babel/helper-create-regexp-features-plugin" "^7.24.7" 496 | "@babel/helper-plugin-utils" "^7.24.7" 497 | 498 | "@babel/plugin-transform-duplicate-keys@^7.24.7": 499 | version "7.24.7" 500 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz#dd20102897c9a2324e5adfffb67ff3610359a8ee" 501 | integrity sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw== 502 | dependencies: 503 | "@babel/helper-plugin-utils" "^7.24.7" 504 | 505 | "@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.0": 506 | version "7.25.0" 507 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz#809af7e3339466b49c034c683964ee8afb3e2604" 508 | integrity sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g== 509 | dependencies: 510 | "@babel/helper-create-regexp-features-plugin" "^7.25.0" 511 | "@babel/helper-plugin-utils" "^7.24.8" 512 | 513 | "@babel/plugin-transform-dynamic-import@^7.24.7": 514 | version "7.24.7" 515 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz#4d8b95e3bae2b037673091aa09cd33fecd6419f4" 516 | integrity sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg== 517 | dependencies: 518 | "@babel/helper-plugin-utils" "^7.24.7" 519 | "@babel/plugin-syntax-dynamic-import" "^7.8.3" 520 | 521 | "@babel/plugin-transform-exponentiation-operator@^7.24.7": 522 | version "7.24.7" 523 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz#b629ee22645f412024297d5245bce425c31f9b0d" 524 | integrity sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ== 525 | dependencies: 526 | "@babel/helper-builder-binary-assignment-operator-visitor" "^7.24.7" 527 | "@babel/helper-plugin-utils" "^7.24.7" 528 | 529 | "@babel/plugin-transform-export-namespace-from@^7.24.7": 530 | version "7.24.7" 531 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz#176d52d8d8ed516aeae7013ee9556d540c53f197" 532 | integrity sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA== 533 | dependencies: 534 | "@babel/helper-plugin-utils" "^7.24.7" 535 | "@babel/plugin-syntax-export-namespace-from" "^7.8.3" 536 | 537 | "@babel/plugin-transform-for-of@^7.24.7": 538 | version "7.24.7" 539 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz#f25b33f72df1d8be76399e1b8f3f9d366eb5bc70" 540 | integrity sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g== 541 | dependencies: 542 | "@babel/helper-plugin-utils" "^7.24.7" 543 | "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" 544 | 545 | "@babel/plugin-transform-function-name@^7.25.1": 546 | version "7.25.1" 547 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz#b85e773097526c1a4fc4ba27322748643f26fc37" 548 | integrity sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA== 549 | dependencies: 550 | "@babel/helper-compilation-targets" "^7.24.8" 551 | "@babel/helper-plugin-utils" "^7.24.8" 552 | "@babel/traverse" "^7.25.1" 553 | 554 | "@babel/plugin-transform-json-strings@^7.24.7": 555 | version "7.24.7" 556 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz#f3e9c37c0a373fee86e36880d45b3664cedaf73a" 557 | integrity sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw== 558 | dependencies: 559 | "@babel/helper-plugin-utils" "^7.24.7" 560 | "@babel/plugin-syntax-json-strings" "^7.8.3" 561 | 562 | "@babel/plugin-transform-literals@^7.25.2": 563 | version "7.25.2" 564 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz#deb1ad14fc5490b9a65ed830e025bca849d8b5f3" 565 | integrity sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw== 566 | dependencies: 567 | "@babel/helper-plugin-utils" "^7.24.8" 568 | 569 | "@babel/plugin-transform-logical-assignment-operators@^7.24.7": 570 | version "7.24.7" 571 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz#a58fb6eda16c9dc8f9ff1c7b1ba6deb7f4694cb0" 572 | integrity sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw== 573 | dependencies: 574 | "@babel/helper-plugin-utils" "^7.24.7" 575 | "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" 576 | 577 | "@babel/plugin-transform-member-expression-literals@^7.24.7": 578 | version "7.24.7" 579 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz#3b4454fb0e302e18ba4945ba3246acb1248315df" 580 | integrity sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw== 581 | dependencies: 582 | "@babel/helper-plugin-utils" "^7.24.7" 583 | 584 | "@babel/plugin-transform-modules-amd@^7.24.7": 585 | version "7.24.7" 586 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz#65090ed493c4a834976a3ca1cde776e6ccff32d7" 587 | integrity sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg== 588 | dependencies: 589 | "@babel/helper-module-transforms" "^7.24.7" 590 | "@babel/helper-plugin-utils" "^7.24.7" 591 | 592 | "@babel/plugin-transform-modules-commonjs@^7.24.8": 593 | version "7.24.8" 594 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz#ab6421e564b717cb475d6fff70ae7f103536ea3c" 595 | integrity sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA== 596 | dependencies: 597 | "@babel/helper-module-transforms" "^7.24.8" 598 | "@babel/helper-plugin-utils" "^7.24.8" 599 | "@babel/helper-simple-access" "^7.24.7" 600 | 601 | "@babel/plugin-transform-modules-systemjs@^7.25.0": 602 | version "7.25.0" 603 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz#8f46cdc5f9e5af74f3bd019485a6cbe59685ea33" 604 | integrity sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw== 605 | dependencies: 606 | "@babel/helper-module-transforms" "^7.25.0" 607 | "@babel/helper-plugin-utils" "^7.24.8" 608 | "@babel/helper-validator-identifier" "^7.24.7" 609 | "@babel/traverse" "^7.25.0" 610 | 611 | "@babel/plugin-transform-modules-umd@^7.24.7": 612 | version "7.24.7" 613 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz#edd9f43ec549099620df7df24e7ba13b5c76efc8" 614 | integrity sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A== 615 | dependencies: 616 | "@babel/helper-module-transforms" "^7.24.7" 617 | "@babel/helper-plugin-utils" "^7.24.7" 618 | 619 | "@babel/plugin-transform-named-capturing-groups-regex@^7.24.7": 620 | version "7.24.7" 621 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz#9042e9b856bc6b3688c0c2e4060e9e10b1460923" 622 | integrity sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g== 623 | dependencies: 624 | "@babel/helper-create-regexp-features-plugin" "^7.24.7" 625 | "@babel/helper-plugin-utils" "^7.24.7" 626 | 627 | "@babel/plugin-transform-new-target@^7.24.7": 628 | version "7.24.7" 629 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz#31ff54c4e0555cc549d5816e4ab39241dfb6ab00" 630 | integrity sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA== 631 | dependencies: 632 | "@babel/helper-plugin-utils" "^7.24.7" 633 | 634 | "@babel/plugin-transform-nullish-coalescing-operator@^7.24.7": 635 | version "7.24.7" 636 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz#1de4534c590af9596f53d67f52a92f12db984120" 637 | integrity sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ== 638 | dependencies: 639 | "@babel/helper-plugin-utils" "^7.24.7" 640 | "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" 641 | 642 | "@babel/plugin-transform-numeric-separator@^7.24.7": 643 | version "7.24.7" 644 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz#bea62b538c80605d8a0fac9b40f48e97efa7de63" 645 | integrity sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA== 646 | dependencies: 647 | "@babel/helper-plugin-utils" "^7.24.7" 648 | "@babel/plugin-syntax-numeric-separator" "^7.10.4" 649 | 650 | "@babel/plugin-transform-object-rest-spread@^7.24.7": 651 | version "7.24.7" 652 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz#d13a2b93435aeb8a197e115221cab266ba6e55d6" 653 | integrity sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q== 654 | dependencies: 655 | "@babel/helper-compilation-targets" "^7.24.7" 656 | "@babel/helper-plugin-utils" "^7.24.7" 657 | "@babel/plugin-syntax-object-rest-spread" "^7.8.3" 658 | "@babel/plugin-transform-parameters" "^7.24.7" 659 | 660 | "@babel/plugin-transform-object-super@^7.24.7": 661 | version "7.24.7" 662 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz#66eeaff7830bba945dd8989b632a40c04ed625be" 663 | integrity sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg== 664 | dependencies: 665 | "@babel/helper-plugin-utils" "^7.24.7" 666 | "@babel/helper-replace-supers" "^7.24.7" 667 | 668 | "@babel/plugin-transform-optional-catch-binding@^7.24.7": 669 | version "7.24.7" 670 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz#00eabd883d0dd6a60c1c557548785919b6e717b4" 671 | integrity sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA== 672 | dependencies: 673 | "@babel/helper-plugin-utils" "^7.24.7" 674 | "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" 675 | 676 | "@babel/plugin-transform-optional-chaining@^7.24.7", "@babel/plugin-transform-optional-chaining@^7.24.8": 677 | version "7.24.8" 678 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz#bb02a67b60ff0406085c13d104c99a835cdf365d" 679 | integrity sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw== 680 | dependencies: 681 | "@babel/helper-plugin-utils" "^7.24.8" 682 | "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" 683 | "@babel/plugin-syntax-optional-chaining" "^7.8.3" 684 | 685 | "@babel/plugin-transform-parameters@^7.24.7": 686 | version "7.24.7" 687 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" 688 | integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== 689 | dependencies: 690 | "@babel/helper-plugin-utils" "^7.24.7" 691 | 692 | "@babel/plugin-transform-private-methods@^7.24.7": 693 | version "7.24.7" 694 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz#e6318746b2ae70a59d023d5cc1344a2ba7a75f5e" 695 | integrity sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ== 696 | dependencies: 697 | "@babel/helper-create-class-features-plugin" "^7.24.7" 698 | "@babel/helper-plugin-utils" "^7.24.7" 699 | 700 | "@babel/plugin-transform-private-property-in-object@^7.24.7": 701 | version "7.24.7" 702 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz#4eec6bc701288c1fab5f72e6a4bbc9d67faca061" 703 | integrity sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA== 704 | dependencies: 705 | "@babel/helper-annotate-as-pure" "^7.24.7" 706 | "@babel/helper-create-class-features-plugin" "^7.24.7" 707 | "@babel/helper-plugin-utils" "^7.24.7" 708 | "@babel/plugin-syntax-private-property-in-object" "^7.14.5" 709 | 710 | "@babel/plugin-transform-property-literals@^7.24.7": 711 | version "7.24.7" 712 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz#f0d2ed8380dfbed949c42d4d790266525d63bbdc" 713 | integrity sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA== 714 | dependencies: 715 | "@babel/helper-plugin-utils" "^7.24.7" 716 | 717 | "@babel/plugin-transform-regenerator@^7.24.7": 718 | version "7.24.7" 719 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz#021562de4534d8b4b1851759fd7af4e05d2c47f8" 720 | integrity sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA== 721 | dependencies: 722 | "@babel/helper-plugin-utils" "^7.24.7" 723 | regenerator-transform "^0.15.2" 724 | 725 | "@babel/plugin-transform-reserved-words@^7.24.7": 726 | version "7.24.7" 727 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz#80037fe4fbf031fc1125022178ff3938bb3743a4" 728 | integrity sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ== 729 | dependencies: 730 | "@babel/helper-plugin-utils" "^7.24.7" 731 | 732 | "@babel/plugin-transform-shorthand-properties@^7.24.7": 733 | version "7.24.7" 734 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz#85448c6b996e122fa9e289746140aaa99da64e73" 735 | integrity sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA== 736 | dependencies: 737 | "@babel/helper-plugin-utils" "^7.24.7" 738 | 739 | "@babel/plugin-transform-spread@^7.24.7": 740 | version "7.24.7" 741 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz#e8a38c0fde7882e0fb8f160378f74bd885cc7bb3" 742 | integrity sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng== 743 | dependencies: 744 | "@babel/helper-plugin-utils" "^7.24.7" 745 | "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" 746 | 747 | "@babel/plugin-transform-sticky-regex@^7.24.7": 748 | version "7.24.7" 749 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz#96ae80d7a7e5251f657b5cf18f1ea6bf926f5feb" 750 | integrity sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g== 751 | dependencies: 752 | "@babel/helper-plugin-utils" "^7.24.7" 753 | 754 | "@babel/plugin-transform-template-literals@^7.24.7": 755 | version "7.24.7" 756 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz#a05debb4a9072ae8f985bcf77f3f215434c8f8c8" 757 | integrity sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw== 758 | dependencies: 759 | "@babel/helper-plugin-utils" "^7.24.7" 760 | 761 | "@babel/plugin-transform-typeof-symbol@^7.24.8": 762 | version "7.24.8" 763 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz#383dab37fb073f5bfe6e60c654caac309f92ba1c" 764 | integrity sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw== 765 | dependencies: 766 | "@babel/helper-plugin-utils" "^7.24.8" 767 | 768 | "@babel/plugin-transform-unicode-escapes@^7.24.7": 769 | version "7.24.7" 770 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz#2023a82ced1fb4971630a2e079764502c4148e0e" 771 | integrity sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw== 772 | dependencies: 773 | "@babel/helper-plugin-utils" "^7.24.7" 774 | 775 | "@babel/plugin-transform-unicode-property-regex@^7.24.7": 776 | version "7.24.7" 777 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz#9073a4cd13b86ea71c3264659590ac086605bbcd" 778 | integrity sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w== 779 | dependencies: 780 | "@babel/helper-create-regexp-features-plugin" "^7.24.7" 781 | "@babel/helper-plugin-utils" "^7.24.7" 782 | 783 | "@babel/plugin-transform-unicode-regex@^7.24.7": 784 | version "7.24.7" 785 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz#dfc3d4a51127108099b19817c0963be6a2adf19f" 786 | integrity sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg== 787 | dependencies: 788 | "@babel/helper-create-regexp-features-plugin" "^7.24.7" 789 | "@babel/helper-plugin-utils" "^7.24.7" 790 | 791 | "@babel/plugin-transform-unicode-sets-regex@^7.24.7": 792 | version "7.24.7" 793 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz#d40705d67523803a576e29c63cef6e516b858ed9" 794 | integrity sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg== 795 | dependencies: 796 | "@babel/helper-create-regexp-features-plugin" "^7.24.7" 797 | "@babel/helper-plugin-utils" "^7.24.7" 798 | 799 | "@babel/preset-env@^7.25.2": 800 | version "7.25.2" 801 | resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.2.tgz#15918e9d050c4713a2ab8fa2fa82514eaf16676e" 802 | integrity sha512-Y2Vkwy3ITW4id9c6KXshVV/x5yCGK7VdJmKkzOzNsDZMojRKfSA/033rRbLqlRozmhRXCejxWHLSJOg/wUHfzw== 803 | dependencies: 804 | "@babel/compat-data" "^7.25.2" 805 | "@babel/helper-compilation-targets" "^7.25.2" 806 | "@babel/helper-plugin-utils" "^7.24.8" 807 | "@babel/helper-validator-option" "^7.24.8" 808 | "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.0" 809 | "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.0" 810 | "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.0" 811 | "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.7" 812 | "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.0" 813 | "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" 814 | "@babel/plugin-syntax-async-generators" "^7.8.4" 815 | "@babel/plugin-syntax-class-properties" "^7.12.13" 816 | "@babel/plugin-syntax-class-static-block" "^7.14.5" 817 | "@babel/plugin-syntax-dynamic-import" "^7.8.3" 818 | "@babel/plugin-syntax-export-namespace-from" "^7.8.3" 819 | "@babel/plugin-syntax-import-assertions" "^7.24.7" 820 | "@babel/plugin-syntax-import-attributes" "^7.24.7" 821 | "@babel/plugin-syntax-import-meta" "^7.10.4" 822 | "@babel/plugin-syntax-json-strings" "^7.8.3" 823 | "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" 824 | "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" 825 | "@babel/plugin-syntax-numeric-separator" "^7.10.4" 826 | "@babel/plugin-syntax-object-rest-spread" "^7.8.3" 827 | "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" 828 | "@babel/plugin-syntax-optional-chaining" "^7.8.3" 829 | "@babel/plugin-syntax-private-property-in-object" "^7.14.5" 830 | "@babel/plugin-syntax-top-level-await" "^7.14.5" 831 | "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" 832 | "@babel/plugin-transform-arrow-functions" "^7.24.7" 833 | "@babel/plugin-transform-async-generator-functions" "^7.25.0" 834 | "@babel/plugin-transform-async-to-generator" "^7.24.7" 835 | "@babel/plugin-transform-block-scoped-functions" "^7.24.7" 836 | "@babel/plugin-transform-block-scoping" "^7.25.0" 837 | "@babel/plugin-transform-class-properties" "^7.24.7" 838 | "@babel/plugin-transform-class-static-block" "^7.24.7" 839 | "@babel/plugin-transform-classes" "^7.25.0" 840 | "@babel/plugin-transform-computed-properties" "^7.24.7" 841 | "@babel/plugin-transform-destructuring" "^7.24.8" 842 | "@babel/plugin-transform-dotall-regex" "^7.24.7" 843 | "@babel/plugin-transform-duplicate-keys" "^7.24.7" 844 | "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.0" 845 | "@babel/plugin-transform-dynamic-import" "^7.24.7" 846 | "@babel/plugin-transform-exponentiation-operator" "^7.24.7" 847 | "@babel/plugin-transform-export-namespace-from" "^7.24.7" 848 | "@babel/plugin-transform-for-of" "^7.24.7" 849 | "@babel/plugin-transform-function-name" "^7.25.1" 850 | "@babel/plugin-transform-json-strings" "^7.24.7" 851 | "@babel/plugin-transform-literals" "^7.25.2" 852 | "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" 853 | "@babel/plugin-transform-member-expression-literals" "^7.24.7" 854 | "@babel/plugin-transform-modules-amd" "^7.24.7" 855 | "@babel/plugin-transform-modules-commonjs" "^7.24.8" 856 | "@babel/plugin-transform-modules-systemjs" "^7.25.0" 857 | "@babel/plugin-transform-modules-umd" "^7.24.7" 858 | "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" 859 | "@babel/plugin-transform-new-target" "^7.24.7" 860 | "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.7" 861 | "@babel/plugin-transform-numeric-separator" "^7.24.7" 862 | "@babel/plugin-transform-object-rest-spread" "^7.24.7" 863 | "@babel/plugin-transform-object-super" "^7.24.7" 864 | "@babel/plugin-transform-optional-catch-binding" "^7.24.7" 865 | "@babel/plugin-transform-optional-chaining" "^7.24.8" 866 | "@babel/plugin-transform-parameters" "^7.24.7" 867 | "@babel/plugin-transform-private-methods" "^7.24.7" 868 | "@babel/plugin-transform-private-property-in-object" "^7.24.7" 869 | "@babel/plugin-transform-property-literals" "^7.24.7" 870 | "@babel/plugin-transform-regenerator" "^7.24.7" 871 | "@babel/plugin-transform-reserved-words" "^7.24.7" 872 | "@babel/plugin-transform-shorthand-properties" "^7.24.7" 873 | "@babel/plugin-transform-spread" "^7.24.7" 874 | "@babel/plugin-transform-sticky-regex" "^7.24.7" 875 | "@babel/plugin-transform-template-literals" "^7.24.7" 876 | "@babel/plugin-transform-typeof-symbol" "^7.24.8" 877 | "@babel/plugin-transform-unicode-escapes" "^7.24.7" 878 | "@babel/plugin-transform-unicode-property-regex" "^7.24.7" 879 | "@babel/plugin-transform-unicode-regex" "^7.24.7" 880 | "@babel/plugin-transform-unicode-sets-regex" "^7.24.7" 881 | "@babel/preset-modules" "0.1.6-no-external-plugins" 882 | babel-plugin-polyfill-corejs2 "^0.4.10" 883 | babel-plugin-polyfill-corejs3 "^0.10.4" 884 | babel-plugin-polyfill-regenerator "^0.6.1" 885 | core-js-compat "^3.37.1" 886 | semver "^6.3.1" 887 | 888 | "@babel/preset-modules@0.1.6-no-external-plugins": 889 | version "0.1.6-no-external-plugins" 890 | resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" 891 | integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== 892 | dependencies: 893 | "@babel/helper-plugin-utils" "^7.0.0" 894 | "@babel/types" "^7.4.4" 895 | esutils "^2.0.2" 896 | 897 | "@babel/regjsgen@^0.8.0": 898 | version "0.8.0" 899 | resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" 900 | integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== 901 | 902 | "@babel/runtime@^7.8.4": 903 | version "7.25.0" 904 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" 905 | integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== 906 | dependencies: 907 | regenerator-runtime "^0.14.0" 908 | 909 | "@babel/template@^7.24.7", "@babel/template@^7.25.0": 910 | version "7.25.0" 911 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" 912 | integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== 913 | dependencies: 914 | "@babel/code-frame" "^7.24.7" 915 | "@babel/parser" "^7.25.0" 916 | "@babel/types" "^7.25.0" 917 | 918 | "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2": 919 | version "7.25.2" 920 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.2.tgz#1a0a4aef53177bead359ccd0c89f4426c805b2ae" 921 | integrity sha512-s4/r+a7xTnny2O6FcZzqgT6nE4/GHEdcqj4qAeglbUOh0TeglEfmNJFAd/OLoVtGd6ZhAO8GCVvCNUO5t/VJVQ== 922 | dependencies: 923 | "@babel/code-frame" "^7.24.7" 924 | "@babel/generator" "^7.25.0" 925 | "@babel/parser" "^7.25.0" 926 | "@babel/template" "^7.25.0" 927 | "@babel/types" "^7.25.2" 928 | debug "^4.3.1" 929 | globals "^11.1.0" 930 | 931 | "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.4.4": 932 | version "7.25.2" 933 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.2.tgz#55fb231f7dc958cd69ea141a4c2997e819646125" 934 | integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q== 935 | dependencies: 936 | "@babel/helper-string-parser" "^7.24.8" 937 | "@babel/helper-validator-identifier" "^7.24.7" 938 | to-fast-properties "^2.0.0" 939 | 940 | "@jridgewell/gen-mapping@^0.3.5": 941 | version "0.3.5" 942 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" 943 | integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== 944 | dependencies: 945 | "@jridgewell/set-array" "^1.2.1" 946 | "@jridgewell/sourcemap-codec" "^1.4.10" 947 | "@jridgewell/trace-mapping" "^0.3.24" 948 | 949 | "@jridgewell/resolve-uri@^3.1.0": 950 | version "3.1.2" 951 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" 952 | integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== 953 | 954 | "@jridgewell/set-array@^1.2.1": 955 | version "1.2.1" 956 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" 957 | integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== 958 | 959 | "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": 960 | version "1.5.0" 961 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" 962 | integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== 963 | 964 | "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": 965 | version "0.3.25" 966 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" 967 | integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== 968 | dependencies: 969 | "@jridgewell/resolve-uri" "^3.1.0" 970 | "@jridgewell/sourcemap-codec" "^1.4.14" 971 | 972 | ansi-colors@^1.0.1: 973 | version "1.1.0" 974 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" 975 | integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== 976 | dependencies: 977 | ansi-wrap "^0.1.0" 978 | 979 | ansi-styles@^3.2.1: 980 | version "3.2.1" 981 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 982 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 983 | dependencies: 984 | color-convert "^1.9.0" 985 | 986 | ansi-wrap@^0.1.0: 987 | version "0.1.0" 988 | resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" 989 | integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== 990 | 991 | arr-diff@^4.0.0: 992 | version "4.0.0" 993 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" 994 | integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== 995 | 996 | arr-union@^3.1.0: 997 | version "3.1.0" 998 | resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" 999 | integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== 1000 | 1001 | assign-symbols@^1.0.0: 1002 | version "1.0.0" 1003 | resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" 1004 | integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== 1005 | 1006 | babel-plugin-polyfill-corejs2@^0.4.10: 1007 | version "0.4.11" 1008 | resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" 1009 | integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== 1010 | dependencies: 1011 | "@babel/compat-data" "^7.22.6" 1012 | "@babel/helper-define-polyfill-provider" "^0.6.2" 1013 | semver "^6.3.1" 1014 | 1015 | babel-plugin-polyfill-corejs3@^0.10.4: 1016 | version "0.10.4" 1017 | resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz#789ac82405ad664c20476d0233b485281deb9c77" 1018 | integrity sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg== 1019 | dependencies: 1020 | "@babel/helper-define-polyfill-provider" "^0.6.1" 1021 | core-js-compat "^3.36.1" 1022 | 1023 | babel-plugin-polyfill-regenerator@^0.6.1: 1024 | version "0.6.2" 1025 | resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" 1026 | integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== 1027 | dependencies: 1028 | "@babel/helper-define-polyfill-provider" "^0.6.2" 1029 | 1030 | browserslist@^4.23.0, browserslist@^4.23.1: 1031 | version "4.23.2" 1032 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed" 1033 | integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA== 1034 | dependencies: 1035 | caniuse-lite "^1.0.30001640" 1036 | electron-to-chromium "^1.4.820" 1037 | node-releases "^2.0.14" 1038 | update-browserslist-db "^1.1.0" 1039 | 1040 | caniuse-lite@^1.0.30001640: 1041 | version "1.0.30001644" 1042 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001644.tgz#bcd4212a7a03bdedba1ea850b8a72bfe4bec2395" 1043 | integrity sha512-YGvlOZB4QhZuiis+ETS0VXR+MExbFf4fZYYeMTEE0aTQd/RdIjkTyZjLrbYVKnHzppDvnOhritRVv+i7Go6mHw== 1044 | 1045 | chalk@^2.4.2: 1046 | version "2.4.2" 1047 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 1048 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 1049 | dependencies: 1050 | ansi-styles "^3.2.1" 1051 | escape-string-regexp "^1.0.5" 1052 | supports-color "^5.3.0" 1053 | 1054 | color-convert@^1.9.0: 1055 | version "1.9.3" 1056 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 1057 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 1058 | dependencies: 1059 | color-name "1.1.3" 1060 | 1061 | color-name@1.1.3: 1062 | version "1.1.3" 1063 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 1064 | integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== 1065 | 1066 | convert-source-map@^2.0.0: 1067 | version "2.0.0" 1068 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" 1069 | integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== 1070 | 1071 | core-js-compat@^3.36.1, core-js-compat@^3.37.1: 1072 | version "3.37.1" 1073 | resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.37.1.tgz#c844310c7852f4bdf49b8d339730b97e17ff09ee" 1074 | integrity sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg== 1075 | dependencies: 1076 | browserslist "^4.23.0" 1077 | 1078 | core-util-is@~1.0.0: 1079 | version "1.0.3" 1080 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" 1081 | integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== 1082 | 1083 | debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: 1084 | version "4.3.6" 1085 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" 1086 | integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== 1087 | dependencies: 1088 | ms "2.1.2" 1089 | 1090 | electron-to-chromium@^1.4.820: 1091 | version "1.5.3" 1092 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.3.tgz#032bbb8661c0449656fd896e805c8f7150229a0f" 1093 | integrity sha512-QNdYSS5i8D9axWp/6XIezRObRHqaav/ur9z1VzCDUCH1XIFOr9WQk5xmgunhsTpjjgDy3oLxO/WMOVZlpUQrlA== 1094 | 1095 | escalade@^3.1.2: 1096 | version "3.1.2" 1097 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" 1098 | integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== 1099 | 1100 | escape-string-regexp@^1.0.5: 1101 | version "1.0.5" 1102 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 1103 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 1104 | 1105 | esutils@^2.0.2: 1106 | version "2.0.3" 1107 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 1108 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 1109 | 1110 | extend-shallow@^3.0.2: 1111 | version "3.0.2" 1112 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" 1113 | integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== 1114 | dependencies: 1115 | assign-symbols "^1.0.0" 1116 | is-extendable "^1.0.1" 1117 | 1118 | function-bind@^1.1.2: 1119 | version "1.1.2" 1120 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" 1121 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== 1122 | 1123 | gensync@^1.0.0-beta.2: 1124 | version "1.0.0-beta.2" 1125 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" 1126 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== 1127 | 1128 | globals@^11.1.0: 1129 | version "11.12.0" 1130 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 1131 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 1132 | 1133 | gulp-babel@^8.0.0: 1134 | version "8.0.0" 1135 | resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-8.0.0.tgz#e0da96f4f2ec4a88dd3a3030f476e38ab2126d87" 1136 | integrity sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ== 1137 | dependencies: 1138 | plugin-error "^1.0.1" 1139 | replace-ext "^1.0.0" 1140 | through2 "^2.0.0" 1141 | vinyl-sourcemaps-apply "^0.2.0" 1142 | 1143 | has-flag@^3.0.0: 1144 | version "3.0.0" 1145 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 1146 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 1147 | 1148 | hasown@^2.0.2: 1149 | version "2.0.2" 1150 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" 1151 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== 1152 | dependencies: 1153 | function-bind "^1.1.2" 1154 | 1155 | inherits@~2.0.3: 1156 | version "2.0.4" 1157 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 1158 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 1159 | 1160 | is-core-module@^2.13.0: 1161 | version "2.15.0" 1162 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.0.tgz#71c72ec5442ace7e76b306e9d48db361f22699ea" 1163 | integrity sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA== 1164 | dependencies: 1165 | hasown "^2.0.2" 1166 | 1167 | is-extendable@^1.0.1: 1168 | version "1.0.1" 1169 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" 1170 | integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== 1171 | dependencies: 1172 | is-plain-object "^2.0.4" 1173 | 1174 | is-plain-object@^2.0.4: 1175 | version "2.0.4" 1176 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" 1177 | integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== 1178 | dependencies: 1179 | isobject "^3.0.1" 1180 | 1181 | isarray@~1.0.0: 1182 | version "1.0.0" 1183 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 1184 | integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== 1185 | 1186 | isobject@^3.0.1: 1187 | version "3.0.1" 1188 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" 1189 | integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== 1190 | 1191 | js-tokens@^4.0.0: 1192 | version "4.0.0" 1193 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 1194 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 1195 | 1196 | jsesc@^2.5.1: 1197 | version "2.5.2" 1198 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" 1199 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== 1200 | 1201 | jsesc@~0.5.0: 1202 | version "0.5.0" 1203 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 1204 | integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== 1205 | 1206 | json5@^2.2.3: 1207 | version "2.2.3" 1208 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" 1209 | integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== 1210 | 1211 | lodash.debounce@^4.0.8: 1212 | version "4.0.8" 1213 | resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" 1214 | integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== 1215 | 1216 | lru-cache@^5.1.1: 1217 | version "5.1.1" 1218 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" 1219 | integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== 1220 | dependencies: 1221 | yallist "^3.0.2" 1222 | 1223 | ms@2.1.2: 1224 | version "2.1.2" 1225 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1226 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1227 | 1228 | node-releases@^2.0.14: 1229 | version "2.0.18" 1230 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" 1231 | integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== 1232 | 1233 | path-parse@^1.0.7: 1234 | version "1.0.7" 1235 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 1236 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 1237 | 1238 | picocolors@^1.0.0, picocolors@^1.0.1: 1239 | version "1.0.1" 1240 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" 1241 | integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== 1242 | 1243 | plugin-error@^1.0.1: 1244 | version "1.0.1" 1245 | resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" 1246 | integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== 1247 | dependencies: 1248 | ansi-colors "^1.0.1" 1249 | arr-diff "^4.0.0" 1250 | arr-union "^3.1.0" 1251 | extend-shallow "^3.0.2" 1252 | 1253 | process-nextick-args@~2.0.0: 1254 | version "2.0.1" 1255 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 1256 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 1257 | 1258 | readable-stream@~2.3.6: 1259 | version "2.3.8" 1260 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" 1261 | integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== 1262 | dependencies: 1263 | core-util-is "~1.0.0" 1264 | inherits "~2.0.3" 1265 | isarray "~1.0.0" 1266 | process-nextick-args "~2.0.0" 1267 | safe-buffer "~5.1.1" 1268 | string_decoder "~1.1.1" 1269 | util-deprecate "~1.0.1" 1270 | 1271 | regenerate-unicode-properties@^10.1.0: 1272 | version "10.1.1" 1273 | resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" 1274 | integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== 1275 | dependencies: 1276 | regenerate "^1.4.2" 1277 | 1278 | regenerate@^1.4.2: 1279 | version "1.4.2" 1280 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" 1281 | integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== 1282 | 1283 | regenerator-runtime@^0.14.0: 1284 | version "0.14.1" 1285 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" 1286 | integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== 1287 | 1288 | regenerator-transform@^0.15.2: 1289 | version "0.15.2" 1290 | resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" 1291 | integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== 1292 | dependencies: 1293 | "@babel/runtime" "^7.8.4" 1294 | 1295 | regexpu-core@^5.3.1: 1296 | version "5.3.2" 1297 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" 1298 | integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== 1299 | dependencies: 1300 | "@babel/regjsgen" "^0.8.0" 1301 | regenerate "^1.4.2" 1302 | regenerate-unicode-properties "^10.1.0" 1303 | regjsparser "^0.9.1" 1304 | unicode-match-property-ecmascript "^2.0.0" 1305 | unicode-match-property-value-ecmascript "^2.1.0" 1306 | 1307 | regjsparser@^0.9.1: 1308 | version "0.9.1" 1309 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" 1310 | integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== 1311 | dependencies: 1312 | jsesc "~0.5.0" 1313 | 1314 | replace-ext@^1.0.0: 1315 | version "1.0.1" 1316 | resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" 1317 | integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== 1318 | 1319 | resolve@^1.14.2: 1320 | version "1.22.8" 1321 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" 1322 | integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== 1323 | dependencies: 1324 | is-core-module "^2.13.0" 1325 | path-parse "^1.0.7" 1326 | supports-preserve-symlinks-flag "^1.0.0" 1327 | 1328 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 1329 | version "5.1.2" 1330 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1331 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 1332 | 1333 | semver@^6.3.1: 1334 | version "6.3.1" 1335 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" 1336 | integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== 1337 | 1338 | source-map@^0.5.1: 1339 | version "0.5.7" 1340 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 1341 | integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== 1342 | 1343 | string_decoder@~1.1.1: 1344 | version "1.1.1" 1345 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 1346 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 1347 | dependencies: 1348 | safe-buffer "~5.1.0" 1349 | 1350 | supports-color@^5.3.0: 1351 | version "5.5.0" 1352 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1353 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1354 | dependencies: 1355 | has-flag "^3.0.0" 1356 | 1357 | supports-preserve-symlinks-flag@^1.0.0: 1358 | version "1.0.0" 1359 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1360 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1361 | 1362 | through2@^2.0.0: 1363 | version "2.0.5" 1364 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" 1365 | integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== 1366 | dependencies: 1367 | readable-stream "~2.3.6" 1368 | xtend "~4.0.1" 1369 | 1370 | to-fast-properties@^2.0.0: 1371 | version "2.0.0" 1372 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 1373 | integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== 1374 | 1375 | unicode-canonical-property-names-ecmascript@^2.0.0: 1376 | version "2.0.0" 1377 | resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" 1378 | integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== 1379 | 1380 | unicode-match-property-ecmascript@^2.0.0: 1381 | version "2.0.0" 1382 | resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" 1383 | integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== 1384 | dependencies: 1385 | unicode-canonical-property-names-ecmascript "^2.0.0" 1386 | unicode-property-aliases-ecmascript "^2.0.0" 1387 | 1388 | unicode-match-property-value-ecmascript@^2.1.0: 1389 | version "2.1.0" 1390 | resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" 1391 | integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== 1392 | 1393 | unicode-property-aliases-ecmascript@^2.0.0: 1394 | version "2.1.0" 1395 | resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" 1396 | integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== 1397 | 1398 | update-browserslist-db@^1.1.0: 1399 | version "1.1.0" 1400 | resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" 1401 | integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== 1402 | dependencies: 1403 | escalade "^3.1.2" 1404 | picocolors "^1.0.1" 1405 | 1406 | util-deprecate@~1.0.1: 1407 | version "1.0.2" 1408 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1409 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1410 | 1411 | vinyl-sourcemaps-apply@^0.2.0: 1412 | version "0.2.1" 1413 | resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" 1414 | integrity sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw== 1415 | dependencies: 1416 | source-map "^0.5.1" 1417 | 1418 | xtend@~4.0.1: 1419 | version "4.0.2" 1420 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 1421 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 1422 | 1423 | yallist@^3.0.2: 1424 | version "3.1.1" 1425 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" 1426 | integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== 1427 | --------------------------------------------------------------------------------