├── .gitignore ├── .travis.yml ├── README.md ├── element └── element.go ├── handlers ├── error.go ├── find.go ├── gettext.go ├── index.go ├── screenshot.go ├── source.go └── static.go ├── main.go ├── resources ├── static │ ├── bootstrap │ │ ├── config.json │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ └── bootstrap.min.js │ ├── jquery │ │ └── jquery.color-2.1.2.min.js │ └── wda-inspector │ │ ├── main.css │ │ └── main.js ├── templates │ └── index.html └── wda-inspector │ ├── readme.md │ └── src │ ├── .gitignore │ ├── Info │ ├── Info.js │ ├── main.css │ └── tpl │ │ ├── error.html │ │ └── info.html │ ├── Screen │ ├── Screen.js │ ├── main.css │ └── tpl │ │ ├── error.html │ │ ├── highlight.html │ │ └── lockOverlay.html │ ├── Search │ ├── Search.js │ └── tpl │ │ └── form.html │ ├── Tree │ ├── Tree.js │ ├── main.css │ └── tpl │ │ ├── error.html │ │ ├── item.html │ │ └── lockOverlay.html │ ├── build.sh │ ├── main.css │ ├── main.js │ └── package.json ├── vendor └── github.com │ └── qa-dev │ └── go-core │ ├── .gitignore │ ├── color │ └── color.go │ ├── log │ └── log.go │ ├── middleware │ ├── base.go │ └── response_writer.go │ └── response │ └── json.go └── wda ├── client.go ├── find.go ├── gettext.go ├── gettype.go ├── rect.go ├── screenshot.go ├── session.go ├── source.go └── status.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | main 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go: 4 | - 1.7 5 | - 1.8 6 | - tip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WDA-inspector [![Build Status](https://travis-ci.org/qa-dev/wda-inspector.png?branch=master)](https://travis-ci.org/qa-dev/wda-inspector) 2 | ============= 3 | 4 | **wda-inspector** is a useful inspector of [qa-dev/WebDriverAgent](https://github.com/qa-dev/WebDriverAgent) (forked from [facebook/WebDriverAgent](https://github.com/facebook/WebDriverAgent)) 5 | written in Go. 6 | 7 | ## Build 8 | Clone wda-inspector to `$GOPATH` according to [Golang code organization rules](https://golang.org/doc/code.html#Organization) 9 | 10 | ``` 11 | $ cd $GOPATH/src/github.com/qa-dev/wda-inspector 12 | $ go build 13 | ``` 14 | 15 | 16 | ## Usage 17 | 18 | ``` 19 | $ ./wda-inspector -h=127.0.0.1 -bundleId=com.apple.mobilesafari 20 | ``` 21 | _After run of wda-inspector, use link [http://127.0.0.1:8888] for open inspector in web browser._ 22 | 23 | 24 | ### Flags: 25 | 26 | | Name | Type | Required | Default | Description | 27 | | ----------------- | ------ |--------- | --------|--------------------------------- | 28 | | -bundleId | string | true | |Bundle Id | 29 | | -h | string | true | |WDA host | 30 | | -p | string | false | "8100" |WDA port | 31 | | -l | string | false | "8888" |Port for handling | 32 | -------------------------------------------------------------------------------- /element/element.go: -------------------------------------------------------------------------------- 1 | package element 2 | 3 | const ( 4 | TypeOther = "XCUIElementTypeOther" 5 | ) 6 | -------------------------------------------------------------------------------- /handlers/error.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | type JsonError struct { 4 | Message string `json:"message"` 5 | } 6 | 7 | func NewJsonError(m string) *JsonError { 8 | return &JsonError{Message: m} 9 | } 10 | -------------------------------------------------------------------------------- /handlers/find.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "errors" 5 | "github.com/qa-dev/go-core/response" 6 | "github.com/qa-dev/wda-inspector/element" 7 | "github.com/qa-dev/wda-inspector/wda" 8 | "log" 9 | "net/http" 10 | "strings" 11 | ) 12 | 13 | type FindHandler struct { 14 | WdaClient *wda.Client 15 | } 16 | 17 | type FindResponse struct { 18 | *wda.RectResponse 19 | } 20 | 21 | type TypeResponse struct { 22 | *wda.GetTypeResponse 23 | } 24 | 25 | type Response struct { 26 | Value struct { 27 | X float32 `json:"x"` 28 | Y float32 `json:"y"` 29 | Width float32 `json:"width"` 30 | Height float32 `json:"height"` 31 | } `json:"value"` 32 | Type string `json:"type"` 33 | Status int `json:"status"` 34 | } 35 | 36 | func NewFindHandler(c *wda.Client) *FindHandler { 37 | return &FindHandler{WdaClient: c} 38 | } 39 | 40 | func (h *FindHandler) find(using string, value string) (*wda.FindSuccessResponse, error) { 41 | res, err := h.WdaClient.Find(using, value) 42 | if err != nil { 43 | return nil, err 44 | } 45 | if res.Status != wda.StatusOK { 46 | return nil, errors.New("Bad status from inspector") 47 | } 48 | return res, err 49 | } 50 | 51 | func (h *FindHandler) rect(elId string) (*wda.RectResponse, error) { 52 | res, err := h.WdaClient.Rect(elId) 53 | if err != nil { 54 | return nil, err 55 | } 56 | if res.Status != wda.StatusOK { 57 | return nil, errors.New("Bad status from inspector") 58 | } 59 | return res, err 60 | } 61 | 62 | func (h *FindHandler) typ(elId string) (*wda.GetTypeResponse, error) { 63 | typ, err := h.WdaClient.GetType(elId) 64 | if err != nil { 65 | return nil, err 66 | } 67 | if typ.Status != wda.StatusOK { 68 | return nil, errors.New("Bad status from inspector") 69 | } 70 | return typ, err 71 | } 72 | 73 | func (h *FindHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 74 | f, err := h.find(req.FormValue("using"), req.FormValue("value")) 75 | if err != nil { 76 | log.Printf(err.Error()) 77 | response.Json(resp, NewJsonError(err.Error()), http.StatusInternalServerError) 78 | return 79 | } 80 | 81 | r, err := h.rect(f.Value.ElementId) 82 | if err != nil { 83 | log.Printf(err.Error()) 84 | response.Json(resp, NewJsonError(err.Error()), http.StatusInternalServerError) 85 | return 86 | } 87 | 88 | t, err := h.typ(f.Value.ElementId) 89 | if err != nil { 90 | log.Printf(err.Error()) 91 | response.Json(resp, NewJsonError(err.Error()), http.StatusInternalServerError) 92 | return 93 | } 94 | 95 | var res Response 96 | res.Type = strings.Replace(t.Value, "XCUIElementType", "", -1) 97 | res.Value.Height = r.Value.Height 98 | res.Value.Width = r.Value.Width 99 | res.Value.X = r.Value.X 100 | res.Value.Y = r.Value.Y 101 | res.Status = res.Status 102 | 103 | if res.Type == element.TypeOther && r.IsInvalid() { 104 | response.Json(resp, NewJsonError("Element not found on page"), http.StatusBadRequest) 105 | return 106 | } 107 | response.Json(resp, res, http.StatusOK) 108 | } 109 | -------------------------------------------------------------------------------- /handlers/gettext.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "errors" 5 | "github.com/qa-dev/go-core/response" 6 | "github.com/qa-dev/wda-inspector/wda" 7 | "log" 8 | "net/http" 9 | ) 10 | 11 | type GetTextHandler struct { 12 | WdaClient *wda.Client 13 | } 14 | 15 | type GetTextResponse struct { 16 | Text string 17 | } 18 | 19 | func NewGetTextHandler(c *wda.Client) *GetTextHandler { 20 | return &GetTextHandler{WdaClient: c} 21 | } 22 | 23 | func (h *GetTextHandler) getTextResponse(elementId string) (*wda.GetTextResponse, error) { 24 | res, err := h.WdaClient.GetText(elementId) 25 | if err != nil { 26 | return nil, err 27 | } 28 | if res.Status != wda.StatusOK { 29 | return nil, errors.New("Bad status from inspector") 30 | } 31 | return res, err 32 | } 33 | 34 | func (h *GetTextHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 35 | elementId := req.FormValue("elementId") 36 | if elementId == "" { 37 | response.Json(resp, NewJsonError("Blank element id"), http.StatusInternalServerError) 38 | return 39 | } 40 | s, err := h.getTextResponse(elementId) 41 | if err != nil { 42 | log.Printf(err.Error()) 43 | response.Json(resp, NewJsonError(err.Error()), http.StatusInternalServerError) 44 | return 45 | } 46 | response.Json(resp, s, http.StatusOK) 47 | } 48 | -------------------------------------------------------------------------------- /handlers/index.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "html/template" 5 | "log" 6 | "net/http" 7 | ) 8 | 9 | type IndexPageHandler struct { 10 | } 11 | 12 | func NewIndexPage() *IndexPageHandler { 13 | return &IndexPageHandler{} 14 | } 15 | 16 | func (h *IndexPageHandler) index() (*template.Template, error) { 17 | t := template.New("index.html") 18 | return t.ParseFiles("resources/templates/index.html") 19 | } 20 | 21 | func (h *IndexPageHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 22 | t, err := h.index() 23 | if err != nil { 24 | log.Printf(err.Error()) 25 | } 26 | var data interface{} 27 | err = t.Execute(resp, data) 28 | if err != nil { 29 | log.Printf(err.Error()) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /handlers/screenshot.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "errors" 5 | "github.com/qa-dev/go-core/response" 6 | "github.com/qa-dev/wda-inspector/wda" 7 | "log" 8 | "net/http" 9 | ) 10 | 11 | type ScreenshotHandler struct { 12 | WdaClient *wda.Client 13 | } 14 | 15 | type ScreenshotResponse struct { 16 | Img string `json:"img"` 17 | } 18 | 19 | func NewScreenshotHandler(c *wda.Client) *ScreenshotHandler { 20 | return &ScreenshotHandler{WdaClient: c} 21 | } 22 | 23 | func (h *ScreenshotHandler) screenshot() (*wda.Screenshot, error) { 24 | sc, err := h.WdaClient.Screenshot() 25 | if err != nil { 26 | return nil, err 27 | } 28 | if sc.Status != wda.StatusOK { 29 | return nil, errors.New("Bad status from inspector") 30 | } 31 | return sc, err 32 | } 33 | 34 | func (h *ScreenshotHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 35 | sc, err := h.screenshot() 36 | if err == nil { 37 | data := &ScreenshotResponse{Img: sc.Value} 38 | response.Json(resp, data, http.StatusOK) 39 | } else { 40 | log.Printf(err.Error()) 41 | response.Json(resp, NewJsonError(err.Error()), http.StatusInternalServerError) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /handlers/source.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "errors" 5 | "github.com/qa-dev/go-core/response" 6 | "github.com/qa-dev/wda-inspector/wda" 7 | "log" 8 | "net/http" 9 | ) 10 | 11 | type SourceHandler struct { 12 | WdaClient *wda.Client 13 | } 14 | 15 | type SourceResponse struct { 16 | Tree *wda.ElementSource `json:"tree"` 17 | } 18 | 19 | func NewSourceHandler(c *wda.Client) *SourceHandler { 20 | return &SourceHandler{WdaClient: c} 21 | } 22 | 23 | func (h *SourceHandler) source() (*wda.Source, error) { 24 | sc, err := h.WdaClient.Source() 25 | if err != nil { 26 | return nil, err 27 | } 28 | if sc.Status != wda.StatusOK { 29 | return nil, errors.New("Bad status from inspector") 30 | } 31 | return sc, err 32 | } 33 | 34 | func (h *SourceHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 35 | s, err := h.source() 36 | if err == nil { 37 | data := &SourceResponse{Tree: s.Value} 38 | response.Json(resp, data, http.StatusOK) 39 | } else { 40 | log.Printf(err.Error()) 41 | response.Json(resp, NewJsonError(err.Error()), http.StatusInternalServerError) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /handlers/static.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | type StaticHandler struct { 8 | } 9 | 10 | func NewStaticHandler() *StaticHandler { 11 | return &StaticHandler{} 12 | } 13 | 14 | func (h *StaticHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 15 | path := "./resources" + req.URL.Path 16 | http.ServeFile(resp, req, path) 17 | } 18 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "github.com/qa-dev/go-core/middleware" 6 | "github.com/qa-dev/wda-inspector/handlers" 7 | "github.com/qa-dev/wda-inspector/wda" 8 | "log" 9 | "net" 10 | "net/http" 11 | ) 12 | 13 | func main() { 14 | var iHost, iPort, listenPort, bundleId string 15 | flag.StringVar(&iHost, "h", "", "WDA host") 16 | flag.StringVar(&iPort, "p", "8100", "WDA port, 8100 by default") 17 | flag.StringVar(&listenPort, "l", "8888", "Port to listen by inspector, 8888 by default") 18 | flag.StringVar(&bundleId, "bundleId", "", "Bundle Id, default 'ru.avito.services.dev'") 19 | flag.Parse() 20 | if iHost == "" { 21 | log.Fatal("PLease set inspectors host, for example '-h=10.10.10.48'") 22 | } 23 | if bundleId == "" { 24 | log.Fatal("Please set bundle id, for example '-bundleId=com.apple.mobilesafari'") 25 | } 26 | iClient := wda.NewClient(iHost, iPort, bundleId) 27 | mux := http.NewServeMux() 28 | setHandlers(mux, iClient) 29 | 30 | log.Fatal(http.ListenAndServe(net.JoinHostPort("", listenPort), mux)) 31 | } 32 | 33 | func setHandlers(mux *http.ServeMux, iClient *wda.Client) { 34 | mux.Handle("/static/", handlers.NewStaticHandler()) 35 | mux.Handle("/screenshot", middleware.New(handlers.NewScreenshotHandler(iClient))) 36 | mux.Handle("/source", middleware.New(handlers.NewSourceHandler(iClient))) 37 | mux.Handle("/find", middleware.New(handlers.NewFindHandler(iClient))) 38 | mux.Handle("/getText", middleware.New(handlers.NewGetTextHandler(iClient))) 39 | mux.Handle("/", middleware.New(handlers.NewIndexPage())) 40 | } 41 | -------------------------------------------------------------------------------- /resources/static/bootstrap/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "vars": { 3 | "@gray-base": "#000", 4 | "@gray-darker": "lighten(@gray-base, 13.5%)", 5 | "@gray-dark": "lighten(@gray-base, 20%)", 6 | "@gray": "lighten(@gray-base, 33.5%)", 7 | "@gray-light": "lighten(@gray-base, 46.7%)", 8 | "@gray-lighter": "lighten(@gray-base, 93.5%)", 9 | "@brand-primary": "darken(#428bca, 6.5%)", 10 | "@brand-success": "#5cb85c", 11 | "@brand-info": "#5bc0de", 12 | "@brand-warning": "#f0ad4e", 13 | "@brand-danger": "#d9534f", 14 | "@body-bg": "#fff", 15 | "@text-color": "@gray-dark", 16 | "@link-color": "@brand-primary", 17 | "@link-hover-color": "darken(@link-color, 15%)", 18 | "@link-hover-decoration": "underline", 19 | "@font-family-sans-serif": "\"Helvetica Neue\", Helvetica, Arial, sans-serif", 20 | "@font-family-serif": "Georgia, \"Times New Roman\", Times, serif", 21 | "@font-family-monospace": "Menlo, Monaco, Consolas, \"Courier New\", monospace", 22 | "@font-family-base": "@font-family-sans-serif", 23 | "@font-size-base": "14px", 24 | "@font-size-large": "ceil((@font-size-base * 1.25))", 25 | "@font-size-small": "ceil((@font-size-base * 0.85))", 26 | "@font-size-h1": "floor((@font-size-base * 2.6))", 27 | "@font-size-h2": "floor((@font-size-base * 2.15))", 28 | "@font-size-h3": "ceil((@font-size-base * 1.7))", 29 | "@font-size-h4": "ceil((@font-size-base * 1.25))", 30 | "@font-size-h5": "@font-size-base", 31 | "@font-size-h6": "ceil((@font-size-base * 0.85))", 32 | "@line-height-base": "1.428571429", 33 | "@line-height-computed": "floor((@font-size-base * @line-height-base))", 34 | "@headings-font-family": "inherit", 35 | "@headings-font-weight": "500", 36 | "@headings-line-height": "1.1", 37 | "@headings-color": "inherit", 38 | "@icon-font-path": "\"../fonts/\"", 39 | "@icon-font-name": "\"glyphicons-halflings-regular\"", 40 | "@icon-font-svg-id": "\"glyphicons_halflingsregular\"", 41 | "@padding-base-vertical": "6px", 42 | "@padding-base-horizontal": "12px", 43 | "@padding-large-vertical": "10px", 44 | "@padding-large-horizontal": "16px", 45 | "@padding-small-vertical": "5px", 46 | "@padding-small-horizontal": "10px", 47 | "@padding-xs-vertical": "1px", 48 | "@padding-xs-horizontal": "5px", 49 | "@line-height-large": "1.3333333", 50 | "@line-height-small": "1.5", 51 | "@border-radius-base": "4px", 52 | "@border-radius-large": "6px", 53 | "@border-radius-small": "3px", 54 | "@component-active-color": "#fff", 55 | "@component-active-bg": "@brand-primary", 56 | "@caret-width-base": "4px", 57 | "@caret-width-large": "5px", 58 | "@table-cell-padding": "8px", 59 | "@table-condensed-cell-padding": "5px", 60 | "@table-bg": "transparent", 61 | "@table-bg-accent": "#f9f9f9", 62 | "@table-bg-hover": "#f5f5f5", 63 | "@table-bg-active": "@table-bg-hover", 64 | "@table-border-color": "#ddd", 65 | "@btn-font-weight": "normal", 66 | "@btn-default-color": "#333", 67 | "@btn-default-bg": "#fff", 68 | "@btn-default-border": "#ccc", 69 | "@btn-primary-color": "#fff", 70 | "@btn-primary-bg": "@brand-primary", 71 | "@btn-primary-border": "darken(@btn-primary-bg, 5%)", 72 | "@btn-success-color": "#fff", 73 | "@btn-success-bg": "@brand-success", 74 | "@btn-success-border": "darken(@btn-success-bg, 5%)", 75 | "@btn-info-color": "#fff", 76 | "@btn-info-bg": "@brand-info", 77 | "@btn-info-border": "darken(@btn-info-bg, 5%)", 78 | "@btn-warning-color": "#fff", 79 | "@btn-warning-bg": "@brand-warning", 80 | "@btn-warning-border": "darken(@btn-warning-bg, 5%)", 81 | "@btn-danger-color": "#fff", 82 | "@btn-danger-bg": "@brand-danger", 83 | "@btn-danger-border": "darken(@btn-danger-bg, 5%)", 84 | "@btn-link-disabled-color": "@gray-light", 85 | "@btn-border-radius-base": "@border-radius-base", 86 | "@btn-border-radius-large": "@border-radius-large", 87 | "@btn-border-radius-small": "@border-radius-small", 88 | "@input-bg": "#fff", 89 | "@input-bg-disabled": "@gray-lighter", 90 | "@input-color": "@gray", 91 | "@input-border": "#ccc", 92 | "@input-border-radius": "@border-radius-base", 93 | "@input-border-radius-large": "@border-radius-large", 94 | "@input-border-radius-small": "@border-radius-small", 95 | "@input-border-focus": "#66afe9", 96 | "@input-color-placeholder": "#999", 97 | "@input-height-base": "(@line-height-computed + (@padding-base-vertical * 2) + 2)", 98 | "@input-height-large": "(ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2)", 99 | "@input-height-small": "(floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2)", 100 | "@form-group-margin-bottom": "15px", 101 | "@legend-color": "@gray-dark", 102 | "@legend-border-color": "#e5e5e5", 103 | "@input-group-addon-bg": "@gray-lighter", 104 | "@input-group-addon-border-color": "@input-border", 105 | "@cursor-disabled": "not-allowed", 106 | "@dropdown-bg": "#fff", 107 | "@dropdown-border": "rgba(0,0,0,.15)", 108 | "@dropdown-fallback-border": "#ccc", 109 | "@dropdown-divider-bg": "#e5e5e5", 110 | "@dropdown-link-color": "@gray-dark", 111 | "@dropdown-link-hover-color": "darken(@gray-dark, 5%)", 112 | "@dropdown-link-hover-bg": "#f5f5f5", 113 | "@dropdown-link-active-color": "@component-active-color", 114 | "@dropdown-link-active-bg": "@component-active-bg", 115 | "@dropdown-link-disabled-color": "@gray-light", 116 | "@dropdown-header-color": "@gray-light", 117 | "@dropdown-caret-color": "#000", 118 | "@screen-xs": "480px", 119 | "@screen-xs-min": "@screen-xs", 120 | "@screen-phone": "@screen-xs-min", 121 | "@screen-sm": "768px", 122 | "@screen-sm-min": "@screen-sm", 123 | "@screen-tablet": "@screen-sm-min", 124 | "@screen-md": "992px", 125 | "@screen-md-min": "@screen-md", 126 | "@screen-desktop": "@screen-md-min", 127 | "@screen-lg": "1200px", 128 | "@screen-lg-min": "@screen-lg", 129 | "@screen-lg-desktop": "@screen-lg-min", 130 | "@screen-xs-max": "(@screen-sm-min - 1)", 131 | "@screen-sm-max": "(@screen-md-min - 1)", 132 | "@screen-md-max": "(@screen-lg-min - 1)", 133 | "@grid-columns": "12", 134 | "@grid-gutter-width": "30px", 135 | "@grid-float-breakpoint": "@screen-sm-min", 136 | "@grid-float-breakpoint-max": "(@grid-float-breakpoint - 1)", 137 | "@container-tablet": "100%", 138 | "@container-sm": "100%", 139 | "@container-desktop": "100%", 140 | "@container-md": "100%", 141 | "@container-large-desktop": "100%", 142 | "@container-lg": "100%", 143 | "@navbar-height": "50px", 144 | "@navbar-margin-bottom": "@line-height-computed", 145 | "@navbar-border-radius": "@border-radius-base", 146 | "@navbar-padding-horizontal": "floor((@grid-gutter-width / 2))", 147 | "@navbar-padding-vertical": "((@navbar-height - @line-height-computed) / 2)", 148 | "@navbar-collapse-max-height": "340px", 149 | "@navbar-default-color": "#777", 150 | "@navbar-default-bg": "#f8f8f8", 151 | "@navbar-default-border": "darken(@navbar-default-bg, 6.5%)", 152 | "@navbar-default-link-color": "#777", 153 | "@navbar-default-link-hover-color": "#333", 154 | "@navbar-default-link-hover-bg": "transparent", 155 | "@navbar-default-link-active-color": "#555", 156 | "@navbar-default-link-active-bg": "darken(@navbar-default-bg, 6.5%)", 157 | "@navbar-default-link-disabled-color": "#ccc", 158 | "@navbar-default-link-disabled-bg": "transparent", 159 | "@navbar-default-brand-color": "@navbar-default-link-color", 160 | "@navbar-default-brand-hover-color": "darken(@navbar-default-brand-color, 10%)", 161 | "@navbar-default-brand-hover-bg": "transparent", 162 | "@navbar-default-toggle-hover-bg": "#ddd", 163 | "@navbar-default-toggle-icon-bar-bg": "#888", 164 | "@navbar-default-toggle-border-color": "#ddd", 165 | "@navbar-inverse-color": "lighten(@gray-light, 15%)", 166 | "@navbar-inverse-bg": "#222", 167 | "@navbar-inverse-border": "darken(@navbar-inverse-bg, 10%)", 168 | "@navbar-inverse-link-color": "lighten(@gray-light, 15%)", 169 | "@navbar-inverse-link-hover-color": "#fff", 170 | "@navbar-inverse-link-hover-bg": "transparent", 171 | "@navbar-inverse-link-active-color": "@navbar-inverse-link-hover-color", 172 | "@navbar-inverse-link-active-bg": "darken(@navbar-inverse-bg, 10%)", 173 | "@navbar-inverse-link-disabled-color": "#444", 174 | "@navbar-inverse-link-disabled-bg": "transparent", 175 | "@navbar-inverse-brand-color": "@navbar-inverse-link-color", 176 | "@navbar-inverse-brand-hover-color": "#fff", 177 | "@navbar-inverse-brand-hover-bg": "transparent", 178 | "@navbar-inverse-toggle-hover-bg": "#333", 179 | "@navbar-inverse-toggle-icon-bar-bg": "#fff", 180 | "@navbar-inverse-toggle-border-color": "#333", 181 | "@nav-link-padding": "10px 15px", 182 | "@nav-link-hover-bg": "@gray-lighter", 183 | "@nav-disabled-link-color": "@gray-light", 184 | "@nav-disabled-link-hover-color": "@gray-light", 185 | "@nav-tabs-border-color": "#ddd", 186 | "@nav-tabs-link-hover-border-color": "@gray-lighter", 187 | "@nav-tabs-active-link-hover-bg": "@body-bg", 188 | "@nav-tabs-active-link-hover-color": "@gray", 189 | "@nav-tabs-active-link-hover-border-color": "#ddd", 190 | "@nav-tabs-justified-link-border-color": "#ddd", 191 | "@nav-tabs-justified-active-link-border-color": "@body-bg", 192 | "@nav-pills-border-radius": "@border-radius-base", 193 | "@nav-pills-active-link-hover-bg": "@component-active-bg", 194 | "@nav-pills-active-link-hover-color": "@component-active-color", 195 | "@pagination-color": "@link-color", 196 | "@pagination-bg": "#fff", 197 | "@pagination-border": "#ddd", 198 | "@pagination-hover-color": "@link-hover-color", 199 | "@pagination-hover-bg": "@gray-lighter", 200 | "@pagination-hover-border": "#ddd", 201 | "@pagination-active-color": "#fff", 202 | "@pagination-active-bg": "@brand-primary", 203 | "@pagination-active-border": "@brand-primary", 204 | "@pagination-disabled-color": "@gray-light", 205 | "@pagination-disabled-bg": "#fff", 206 | "@pagination-disabled-border": "#ddd", 207 | "@pager-bg": "@pagination-bg", 208 | "@pager-border": "@pagination-border", 209 | "@pager-border-radius": "15px", 210 | "@pager-hover-bg": "@pagination-hover-bg", 211 | "@pager-active-bg": "@pagination-active-bg", 212 | "@pager-active-color": "@pagination-active-color", 213 | "@pager-disabled-color": "@pagination-disabled-color", 214 | "@jumbotron-padding": "30px", 215 | "@jumbotron-color": "inherit", 216 | "@jumbotron-bg": "@gray-lighter", 217 | "@jumbotron-heading-color": "inherit", 218 | "@jumbotron-font-size": "ceil((@font-size-base * 1.5))", 219 | "@jumbotron-heading-font-size": "ceil((@font-size-base * 4.5))", 220 | "@state-success-text": "#3c763d", 221 | "@state-success-bg": "#dff0d8", 222 | "@state-success-border": "darken(spin(@state-success-bg, -10), 5%)", 223 | "@state-info-text": "#31708f", 224 | "@state-info-bg": "#d9edf7", 225 | "@state-info-border": "darken(spin(@state-info-bg, -10), 7%)", 226 | "@state-warning-text": "#8a6d3b", 227 | "@state-warning-bg": "#fcf8e3", 228 | "@state-warning-border": "darken(spin(@state-warning-bg, -10), 5%)", 229 | "@state-danger-text": "#a94442", 230 | "@state-danger-bg": "#f2dede", 231 | "@state-danger-border": "darken(spin(@state-danger-bg, -10), 5%)", 232 | "@tooltip-max-width": "200px", 233 | "@tooltip-color": "#fff", 234 | "@tooltip-bg": "#000", 235 | "@tooltip-opacity": ".9", 236 | "@tooltip-arrow-width": "5px", 237 | "@tooltip-arrow-color": "@tooltip-bg", 238 | "@popover-bg": "#fff", 239 | "@popover-max-width": "276px", 240 | "@popover-border-color": "rgba(0,0,0,.2)", 241 | "@popover-fallback-border-color": "#ccc", 242 | "@popover-title-bg": "darken(@popover-bg, 3%)", 243 | "@popover-arrow-width": "10px", 244 | "@popover-arrow-color": "@popover-bg", 245 | "@popover-arrow-outer-width": "(@popover-arrow-width + 1)", 246 | "@popover-arrow-outer-color": "fadein(@popover-border-color, 5%)", 247 | "@popover-arrow-outer-fallback-color": "darken(@popover-fallback-border-color, 20%)", 248 | "@label-default-bg": "@gray-light", 249 | "@label-primary-bg": "@brand-primary", 250 | "@label-success-bg": "@brand-success", 251 | "@label-info-bg": "@brand-info", 252 | "@label-warning-bg": "@brand-warning", 253 | "@label-danger-bg": "@brand-danger", 254 | "@label-color": "#fff", 255 | "@label-link-hover-color": "#fff", 256 | "@modal-inner-padding": "15px", 257 | "@modal-title-padding": "15px", 258 | "@modal-title-line-height": "@line-height-base", 259 | "@modal-content-bg": "#fff", 260 | "@modal-content-border-color": "rgba(0,0,0,.2)", 261 | "@modal-content-fallback-border-color": "#999", 262 | "@modal-backdrop-bg": "#000", 263 | "@modal-backdrop-opacity": ".5", 264 | "@modal-header-border-color": "#e5e5e5", 265 | "@modal-footer-border-color": "@modal-header-border-color", 266 | "@modal-lg": "900px", 267 | "@modal-md": "600px", 268 | "@modal-sm": "300px", 269 | "@alert-padding": "15px", 270 | "@alert-border-radius": "@border-radius-base", 271 | "@alert-link-font-weight": "bold", 272 | "@alert-success-bg": "@state-success-bg", 273 | "@alert-success-text": "@state-success-text", 274 | "@alert-success-border": "@state-success-border", 275 | "@alert-info-bg": "@state-info-bg", 276 | "@alert-info-text": "@state-info-text", 277 | "@alert-info-border": "@state-info-border", 278 | "@alert-warning-bg": "@state-warning-bg", 279 | "@alert-warning-text": "@state-warning-text", 280 | "@alert-warning-border": "@state-warning-border", 281 | "@alert-danger-bg": "@state-danger-bg", 282 | "@alert-danger-text": "@state-danger-text", 283 | "@alert-danger-border": "@state-danger-border", 284 | "@progress-bg": "#f5f5f5", 285 | "@progress-bar-color": "#fff", 286 | "@progress-border-radius": "@border-radius-base", 287 | "@progress-bar-bg": "@brand-primary", 288 | "@progress-bar-success-bg": "@brand-success", 289 | "@progress-bar-warning-bg": "@brand-warning", 290 | "@progress-bar-danger-bg": "@brand-danger", 291 | "@progress-bar-info-bg": "@brand-info", 292 | "@list-group-bg": "#fff", 293 | "@list-group-border": "#ddd", 294 | "@list-group-border-radius": "@border-radius-base", 295 | "@list-group-hover-bg": "#f5f5f5", 296 | "@list-group-active-color": "@component-active-color", 297 | "@list-group-active-bg": "@component-active-bg", 298 | "@list-group-active-border": "@list-group-active-bg", 299 | "@list-group-active-text-color": "lighten(@list-group-active-bg, 40%)", 300 | "@list-group-disabled-color": "@gray-light", 301 | "@list-group-disabled-bg": "@gray-lighter", 302 | "@list-group-disabled-text-color": "@list-group-disabled-color", 303 | "@list-group-link-color": "#555", 304 | "@list-group-link-hover-color": "@list-group-link-color", 305 | "@list-group-link-heading-color": "#333", 306 | "@panel-bg": "#fff", 307 | "@panel-body-padding": "15px", 308 | "@panel-heading-padding": "10px 15px", 309 | "@panel-footer-padding": "@panel-heading-padding", 310 | "@panel-border-radius": "@border-radius-base", 311 | "@panel-inner-border": "#ddd", 312 | "@panel-footer-bg": "#f5f5f5", 313 | "@panel-default-text": "@gray-dark", 314 | "@panel-default-border": "#ddd", 315 | "@panel-default-heading-bg": "#f5f5f5", 316 | "@panel-primary-text": "#fff", 317 | "@panel-primary-border": "@brand-primary", 318 | "@panel-primary-heading-bg": "@brand-primary", 319 | "@panel-success-text": "@state-success-text", 320 | "@panel-success-border": "@state-success-border", 321 | "@panel-success-heading-bg": "@state-success-bg", 322 | "@panel-info-text": "@state-info-text", 323 | "@panel-info-border": "@state-info-border", 324 | "@panel-info-heading-bg": "@state-info-bg", 325 | "@panel-warning-text": "@state-warning-text", 326 | "@panel-warning-border": "@state-warning-border", 327 | "@panel-warning-heading-bg": "@state-warning-bg", 328 | "@panel-danger-text": "@state-danger-text", 329 | "@panel-danger-border": "@state-danger-border", 330 | "@panel-danger-heading-bg": "@state-danger-bg", 331 | "@thumbnail-padding": "4px", 332 | "@thumbnail-bg": "@body-bg", 333 | "@thumbnail-border": "#ddd", 334 | "@thumbnail-border-radius": "@border-radius-base", 335 | "@thumbnail-caption-color": "@text-color", 336 | "@thumbnail-caption-padding": "9px", 337 | "@well-bg": "#f5f5f5", 338 | "@well-border": "darken(@well-bg, 7%)", 339 | "@badge-color": "#fff", 340 | "@badge-link-hover-color": "#fff", 341 | "@badge-bg": "@gray-light", 342 | "@badge-active-color": "@link-color", 343 | "@badge-active-bg": "#fff", 344 | "@badge-font-weight": "bold", 345 | "@badge-line-height": "1", 346 | "@badge-border-radius": "10px", 347 | "@breadcrumb-padding-vertical": "8px", 348 | "@breadcrumb-padding-horizontal": "15px", 349 | "@breadcrumb-bg": "#f5f5f5", 350 | "@breadcrumb-color": "#ccc", 351 | "@breadcrumb-active-color": "@gray-light", 352 | "@breadcrumb-separator": "\"/\"", 353 | "@carousel-text-shadow": "0 1px 2px rgba(0,0,0,.6)", 354 | "@carousel-control-color": "#fff", 355 | "@carousel-control-width": "15%", 356 | "@carousel-control-opacity": ".5", 357 | "@carousel-control-font-size": "20px", 358 | "@carousel-indicator-active-bg": "#fff", 359 | "@carousel-indicator-border-color": "#fff", 360 | "@carousel-caption-color": "#fff", 361 | "@close-font-weight": "bold", 362 | "@close-color": "#000", 363 | "@close-text-shadow": "0 1px 0 #fff", 364 | "@code-color": "#c7254e", 365 | "@code-bg": "#f9f2f4", 366 | "@kbd-color": "#fff", 367 | "@kbd-bg": "#333", 368 | "@pre-bg": "#f5f5f5", 369 | "@pre-color": "@gray-dark", 370 | "@pre-border-color": "#ccc", 371 | "@pre-scrollable-max-height": "340px", 372 | "@component-offset-horizontal": "180px", 373 | "@text-muted": "@gray-light", 374 | "@abbr-border-color": "@gray-light", 375 | "@headings-small-color": "@gray-light", 376 | "@blockquote-small-color": "@gray-light", 377 | "@blockquote-font-size": "(@font-size-base * 1.25)", 378 | "@blockquote-border-color": "@gray-lighter", 379 | "@page-header-border-color": "@gray-lighter", 380 | "@dl-horizontal-offset": "@component-offset-horizontal", 381 | "@dl-horizontal-breakpoint": "@grid-float-breakpoint", 382 | "@hr-border": "@gray-lighter" 383 | }, 384 | "css": [ 385 | "print.less", 386 | "type.less", 387 | "code.less", 388 | "grid.less", 389 | "tables.less", 390 | "forms.less", 391 | "buttons.less", 392 | "responsive-utilities.less", 393 | "glyphicons.less", 394 | "button-groups.less", 395 | "input-groups.less", 396 | "navs.less", 397 | "navbar.less", 398 | "breadcrumbs.less", 399 | "pagination.less", 400 | "pager.less", 401 | "labels.less", 402 | "badges.less", 403 | "jumbotron.less", 404 | "thumbnails.less", 405 | "alerts.less", 406 | "progress-bars.less", 407 | "media.less", 408 | "list-group.less", 409 | "panels.less", 410 | "responsive-embed.less", 411 | "wells.less", 412 | "close.less", 413 | "component-animations.less", 414 | "dropdowns.less", 415 | "tooltip.less", 416 | "popovers.less", 417 | "modals.less", 418 | "carousel.less" 419 | ], 420 | "js": [ 421 | "alert.js", 422 | "button.js", 423 | "carousel.js", 424 | "dropdown.js", 425 | "modal.js", 426 | "tooltip.js", 427 | "popover.js", 428 | "tab.js", 429 | "affix.js", 430 | "collapse.js", 431 | "scrollspy.js", 432 | "transition.js" 433 | ], 434 | "customizerUrl": "http://getbootstrap.com/customize/?id=f6a05bdcc5c74ffbf35a182aa6d619db" 435 | } -------------------------------------------------------------------------------- /resources/static/bootstrap/css/bootstrap-theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | /*! 8 | * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f6a05bdcc5c74ffbf35a182aa6d619db) 9 | * Config saved to config.json and https://gist.github.com/f6a05bdcc5c74ffbf35a182aa6d619db 10 | */ 11 | /*! 12 | * Bootstrap v3.3.7 (http://getbootstrap.com) 13 | * Copyright 2011-2016 Twitter, Inc. 14 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 15 | */ 16 | .btn-default, 17 | .btn-primary, 18 | .btn-success, 19 | .btn-info, 20 | .btn-warning, 21 | .btn-danger { 22 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); 23 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); 24 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); 25 | } 26 | .btn-default:active, 27 | .btn-primary:active, 28 | .btn-success:active, 29 | .btn-info:active, 30 | .btn-warning:active, 31 | .btn-danger:active, 32 | .btn-default.active, 33 | .btn-primary.active, 34 | .btn-success.active, 35 | .btn-info.active, 36 | .btn-warning.active, 37 | .btn-danger.active { 38 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 39 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 40 | } 41 | .btn-default.disabled, 42 | .btn-primary.disabled, 43 | .btn-success.disabled, 44 | .btn-info.disabled, 45 | .btn-warning.disabled, 46 | .btn-danger.disabled, 47 | .btn-default[disabled], 48 | .btn-primary[disabled], 49 | .btn-success[disabled], 50 | .btn-info[disabled], 51 | .btn-warning[disabled], 52 | .btn-danger[disabled], 53 | fieldset[disabled] .btn-default, 54 | fieldset[disabled] .btn-primary, 55 | fieldset[disabled] .btn-success, 56 | fieldset[disabled] .btn-info, 57 | fieldset[disabled] .btn-warning, 58 | fieldset[disabled] .btn-danger { 59 | -webkit-box-shadow: none; 60 | box-shadow: none; 61 | } 62 | .btn-default .badge, 63 | .btn-primary .badge, 64 | .btn-success .badge, 65 | .btn-info .badge, 66 | .btn-warning .badge, 67 | .btn-danger .badge { 68 | text-shadow: none; 69 | } 70 | .btn:active, 71 | .btn.active { 72 | background-image: none; 73 | } 74 | .btn-default { 75 | background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%); 76 | background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%); 77 | background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e0e0e0)); 78 | background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%); 79 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); 80 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 81 | background-repeat: repeat-x; 82 | border-color: #dbdbdb; 83 | text-shadow: 0 1px 0 #fff; 84 | border-color: #ccc; 85 | } 86 | .btn-default:hover, 87 | .btn-default:focus { 88 | background-color: #e0e0e0; 89 | background-position: 0 -15px; 90 | } 91 | .btn-default:active, 92 | .btn-default.active { 93 | background-color: #e0e0e0; 94 | border-color: #dbdbdb; 95 | } 96 | .btn-default.disabled, 97 | .btn-default[disabled], 98 | fieldset[disabled] .btn-default, 99 | .btn-default.disabled:hover, 100 | .btn-default[disabled]:hover, 101 | fieldset[disabled] .btn-default:hover, 102 | .btn-default.disabled:focus, 103 | .btn-default[disabled]:focus, 104 | fieldset[disabled] .btn-default:focus, 105 | .btn-default.disabled.focus, 106 | .btn-default[disabled].focus, 107 | fieldset[disabled] .btn-default.focus, 108 | .btn-default.disabled:active, 109 | .btn-default[disabled]:active, 110 | fieldset[disabled] .btn-default:active, 111 | .btn-default.disabled.active, 112 | .btn-default[disabled].active, 113 | fieldset[disabled] .btn-default.active { 114 | background-color: #e0e0e0; 115 | background-image: none; 116 | } 117 | .btn-primary { 118 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); 119 | background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); 120 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); 121 | background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); 122 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); 123 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 124 | background-repeat: repeat-x; 125 | border-color: #245580; 126 | } 127 | .btn-primary:hover, 128 | .btn-primary:focus { 129 | background-color: #265a88; 130 | background-position: 0 -15px; 131 | } 132 | .btn-primary:active, 133 | .btn-primary.active { 134 | background-color: #265a88; 135 | border-color: #245580; 136 | } 137 | .btn-primary.disabled, 138 | .btn-primary[disabled], 139 | fieldset[disabled] .btn-primary, 140 | .btn-primary.disabled:hover, 141 | .btn-primary[disabled]:hover, 142 | fieldset[disabled] .btn-primary:hover, 143 | .btn-primary.disabled:focus, 144 | .btn-primary[disabled]:focus, 145 | fieldset[disabled] .btn-primary:focus, 146 | .btn-primary.disabled.focus, 147 | .btn-primary[disabled].focus, 148 | fieldset[disabled] .btn-primary.focus, 149 | .btn-primary.disabled:active, 150 | .btn-primary[disabled]:active, 151 | fieldset[disabled] .btn-primary:active, 152 | .btn-primary.disabled.active, 153 | .btn-primary[disabled].active, 154 | fieldset[disabled] .btn-primary.active { 155 | background-color: #265a88; 156 | background-image: none; 157 | } 158 | .btn-success { 159 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); 160 | background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); 161 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); 162 | background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); 163 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); 164 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 165 | background-repeat: repeat-x; 166 | border-color: #3e8f3e; 167 | } 168 | .btn-success:hover, 169 | .btn-success:focus { 170 | background-color: #419641; 171 | background-position: 0 -15px; 172 | } 173 | .btn-success:active, 174 | .btn-success.active { 175 | background-color: #419641; 176 | border-color: #3e8f3e; 177 | } 178 | .btn-success.disabled, 179 | .btn-success[disabled], 180 | fieldset[disabled] .btn-success, 181 | .btn-success.disabled:hover, 182 | .btn-success[disabled]:hover, 183 | fieldset[disabled] .btn-success:hover, 184 | .btn-success.disabled:focus, 185 | .btn-success[disabled]:focus, 186 | fieldset[disabled] .btn-success:focus, 187 | .btn-success.disabled.focus, 188 | .btn-success[disabled].focus, 189 | fieldset[disabled] .btn-success.focus, 190 | .btn-success.disabled:active, 191 | .btn-success[disabled]:active, 192 | fieldset[disabled] .btn-success:active, 193 | .btn-success.disabled.active, 194 | .btn-success[disabled].active, 195 | fieldset[disabled] .btn-success.active { 196 | background-color: #419641; 197 | background-image: none; 198 | } 199 | .btn-info { 200 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 201 | background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 202 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); 203 | background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); 204 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); 205 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 206 | background-repeat: repeat-x; 207 | border-color: #28a4c9; 208 | } 209 | .btn-info:hover, 210 | .btn-info:focus { 211 | background-color: #2aabd2; 212 | background-position: 0 -15px; 213 | } 214 | .btn-info:active, 215 | .btn-info.active { 216 | background-color: #2aabd2; 217 | border-color: #28a4c9; 218 | } 219 | .btn-info.disabled, 220 | .btn-info[disabled], 221 | fieldset[disabled] .btn-info, 222 | .btn-info.disabled:hover, 223 | .btn-info[disabled]:hover, 224 | fieldset[disabled] .btn-info:hover, 225 | .btn-info.disabled:focus, 226 | .btn-info[disabled]:focus, 227 | fieldset[disabled] .btn-info:focus, 228 | .btn-info.disabled.focus, 229 | .btn-info[disabled].focus, 230 | fieldset[disabled] .btn-info.focus, 231 | .btn-info.disabled:active, 232 | .btn-info[disabled]:active, 233 | fieldset[disabled] .btn-info:active, 234 | .btn-info.disabled.active, 235 | .btn-info[disabled].active, 236 | fieldset[disabled] .btn-info.active { 237 | background-color: #2aabd2; 238 | background-image: none; 239 | } 240 | .btn-warning { 241 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 242 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 243 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); 244 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); 245 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); 246 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 247 | background-repeat: repeat-x; 248 | border-color: #e38d13; 249 | } 250 | .btn-warning:hover, 251 | .btn-warning:focus { 252 | background-color: #eb9316; 253 | background-position: 0 -15px; 254 | } 255 | .btn-warning:active, 256 | .btn-warning.active { 257 | background-color: #eb9316; 258 | border-color: #e38d13; 259 | } 260 | .btn-warning.disabled, 261 | .btn-warning[disabled], 262 | fieldset[disabled] .btn-warning, 263 | .btn-warning.disabled:hover, 264 | .btn-warning[disabled]:hover, 265 | fieldset[disabled] .btn-warning:hover, 266 | .btn-warning.disabled:focus, 267 | .btn-warning[disabled]:focus, 268 | fieldset[disabled] .btn-warning:focus, 269 | .btn-warning.disabled.focus, 270 | .btn-warning[disabled].focus, 271 | fieldset[disabled] .btn-warning.focus, 272 | .btn-warning.disabled:active, 273 | .btn-warning[disabled]:active, 274 | fieldset[disabled] .btn-warning:active, 275 | .btn-warning.disabled.active, 276 | .btn-warning[disabled].active, 277 | fieldset[disabled] .btn-warning.active { 278 | background-color: #eb9316; 279 | background-image: none; 280 | } 281 | .btn-danger { 282 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 283 | background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 284 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); 285 | background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); 286 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); 287 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 288 | background-repeat: repeat-x; 289 | border-color: #b92c28; 290 | } 291 | .btn-danger:hover, 292 | .btn-danger:focus { 293 | background-color: #c12e2a; 294 | background-position: 0 -15px; 295 | } 296 | .btn-danger:active, 297 | .btn-danger.active { 298 | background-color: #c12e2a; 299 | border-color: #b92c28; 300 | } 301 | .btn-danger.disabled, 302 | .btn-danger[disabled], 303 | fieldset[disabled] .btn-danger, 304 | .btn-danger.disabled:hover, 305 | .btn-danger[disabled]:hover, 306 | fieldset[disabled] .btn-danger:hover, 307 | .btn-danger.disabled:focus, 308 | .btn-danger[disabled]:focus, 309 | fieldset[disabled] .btn-danger:focus, 310 | .btn-danger.disabled.focus, 311 | .btn-danger[disabled].focus, 312 | fieldset[disabled] .btn-danger.focus, 313 | .btn-danger.disabled:active, 314 | .btn-danger[disabled]:active, 315 | fieldset[disabled] .btn-danger:active, 316 | .btn-danger.disabled.active, 317 | .btn-danger[disabled].active, 318 | fieldset[disabled] .btn-danger.active { 319 | background-color: #c12e2a; 320 | background-image: none; 321 | } 322 | .thumbnail, 323 | .img-thumbnail { 324 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 325 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 326 | } 327 | .dropdown-menu > li > a:hover, 328 | .dropdown-menu > li > a:focus { 329 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 330 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 331 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 332 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 333 | background-repeat: repeat-x; 334 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 335 | background-color: #e8e8e8; 336 | } 337 | .dropdown-menu > .active > a, 338 | .dropdown-menu > .active > a:hover, 339 | .dropdown-menu > .active > a:focus { 340 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 341 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 342 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 343 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 344 | background-repeat: repeat-x; 345 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 346 | background-color: #2e6da4; 347 | } 348 | .navbar-default { 349 | background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%); 350 | background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%); 351 | background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#f8f8f8)); 352 | background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%); 353 | background-repeat: repeat-x; 354 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); 355 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 356 | border-radius: 4px; 357 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); 358 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); 359 | } 360 | .navbar-default .navbar-nav > .open > a, 361 | .navbar-default .navbar-nav > .active > a { 362 | background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 363 | background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 364 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); 365 | background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); 366 | background-repeat: repeat-x; 367 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); 368 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075); 369 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075); 370 | } 371 | .navbar-brand, 372 | .navbar-nav > li > a { 373 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); 374 | } 375 | .navbar-inverse { 376 | background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%); 377 | background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%); 378 | background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222222)); 379 | background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%); 380 | background-repeat: repeat-x; 381 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); 382 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 383 | border-radius: 4px; 384 | } 385 | .navbar-inverse .navbar-nav > .open > a, 386 | .navbar-inverse .navbar-nav > .active > a { 387 | background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); 388 | background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); 389 | background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); 390 | background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); 391 | background-repeat: repeat-x; 392 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); 393 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25); 394 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25); 395 | } 396 | .navbar-inverse .navbar-brand, 397 | .navbar-inverse .navbar-nav > li > a { 398 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 399 | } 400 | .navbar-static-top, 401 | .navbar-fixed-top, 402 | .navbar-fixed-bottom { 403 | border-radius: 0; 404 | } 405 | @media (max-width: 767px) { 406 | .navbar .navbar-nav .open .dropdown-menu > .active > a, 407 | .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, 408 | .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { 409 | color: #fff; 410 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 411 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 412 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 413 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 414 | background-repeat: repeat-x; 415 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 416 | } 417 | } 418 | .alert { 419 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2); 420 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); 421 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); 422 | } 423 | .alert-success { 424 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 425 | background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 426 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); 427 | background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); 428 | background-repeat: repeat-x; 429 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); 430 | border-color: #b2dba1; 431 | } 432 | .alert-info { 433 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 434 | background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 435 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); 436 | background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); 437 | background-repeat: repeat-x; 438 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); 439 | border-color: #9acfea; 440 | } 441 | .alert-warning { 442 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 443 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 444 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); 445 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); 446 | background-repeat: repeat-x; 447 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); 448 | border-color: #f5e79e; 449 | } 450 | .alert-danger { 451 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 452 | background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 453 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); 454 | background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); 455 | background-repeat: repeat-x; 456 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); 457 | border-color: #dca7a7; 458 | } 459 | .progress { 460 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 461 | background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 462 | background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); 463 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); 464 | background-repeat: repeat-x; 465 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); 466 | } 467 | .progress-bar { 468 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); 469 | background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); 470 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); 471 | background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); 472 | background-repeat: repeat-x; 473 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); 474 | } 475 | .progress-bar-success { 476 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); 477 | background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); 478 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); 479 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); 480 | background-repeat: repeat-x; 481 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); 482 | } 483 | .progress-bar-info { 484 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 485 | background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 486 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); 487 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); 488 | background-repeat: repeat-x; 489 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); 490 | } 491 | .progress-bar-warning { 492 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 493 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 494 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); 495 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); 496 | background-repeat: repeat-x; 497 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); 498 | } 499 | .progress-bar-danger { 500 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); 501 | background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); 502 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); 503 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); 504 | background-repeat: repeat-x; 505 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); 506 | } 507 | .progress-bar-striped { 508 | background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); 509 | background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); 510 | background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); 511 | } 512 | .list-group { 513 | border-radius: 4px; 514 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 515 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 516 | } 517 | .list-group-item.active, 518 | .list-group-item.active:hover, 519 | .list-group-item.active:focus { 520 | text-shadow: 0 -1px 0 #286090; 521 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); 522 | background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); 523 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); 524 | background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); 525 | background-repeat: repeat-x; 526 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); 527 | border-color: #2b669a; 528 | } 529 | .list-group-item.active .badge, 530 | .list-group-item.active:hover .badge, 531 | .list-group-item.active:focus .badge { 532 | text-shadow: none; 533 | } 534 | .panel { 535 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); 536 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); 537 | } 538 | .panel-default > .panel-heading { 539 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 540 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 541 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 542 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 543 | background-repeat: repeat-x; 544 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 545 | } 546 | .panel-primary > .panel-heading { 547 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 548 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 549 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 550 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 551 | background-repeat: repeat-x; 552 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 553 | } 554 | .panel-success > .panel-heading { 555 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 556 | background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 557 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); 558 | background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); 559 | background-repeat: repeat-x; 560 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); 561 | } 562 | .panel-info > .panel-heading { 563 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 564 | background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 565 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); 566 | background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); 567 | background-repeat: repeat-x; 568 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); 569 | } 570 | .panel-warning > .panel-heading { 571 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 572 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 573 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); 574 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); 575 | background-repeat: repeat-x; 576 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); 577 | } 578 | .panel-danger > .panel-heading { 579 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 580 | background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 581 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); 582 | background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); 583 | background-repeat: repeat-x; 584 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); 585 | } 586 | .well { 587 | background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 588 | background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 589 | background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); 590 | background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); 591 | background-repeat: repeat-x; 592 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); 593 | border-color: #dcdcdc; 594 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); 595 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); 596 | } 597 | -------------------------------------------------------------------------------- /resources/static/bootstrap/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | /*! 8 | * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f6a05bdcc5c74ffbf35a182aa6d619db) 9 | * Config saved to config.json and https://gist.github.com/f6a05bdcc5c74ffbf35a182aa6d619db 10 | *//*! 11 | * Bootstrap v3.3.7 (http://getbootstrap.com) 12 | * Copyright 2011-2016 Twitter, Inc. 13 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 14 | */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-default.disabled,.btn-primary.disabled,.btn-success.disabled,.btn-info.disabled,.btn-warning.disabled,.btn-danger.disabled,.btn-default[disabled],.btn-primary[disabled],.btn-success[disabled],.btn-info[disabled],.btn-warning[disabled],.btn-danger[disabled],fieldset[disabled] .btn-default,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-info,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-danger{-webkit-box-shadow:none;box-shadow:none}.btn-default .badge,.btn-primary .badge,.btn-success .badge,.btn-info .badge,.btn-warning .badge,.btn-danger .badge{text-shadow:none}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:-o-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), to(#e0e0e0));background-image:linear-gradient(to bottom, #fff 0, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top, #337ab7 0, #265a88 100%);background-image:-o-linear-gradient(top, #337ab7 0, #265a88 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #337ab7), to(#265a88));background-image:linear-gradient(to bottom, #337ab7 0, #265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#245580}.btn-primary:hover,.btn-primary:focus{background-color:#265a88;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:-o-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5cb85c), to(#419641));background-image:linear-gradient(to bottom, #5cb85c 0, #419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:-o-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5bc0de), to(#2aabd2));background-image:linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #eb9316 100%);background-image:-o-linear-gradient(top, #f0ad4e 0, #eb9316 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f0ad4e), to(#eb9316));background-image:linear-gradient(to bottom, #f0ad4e 0, #eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c12e2a 100%);background-image:-o-linear-gradient(top, #d9534f 0, #c12e2a 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9534f), to(#c12e2a));background-image:linear-gradient(to bottom, #d9534f 0, #c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-o-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f5f5f5), to(#e8e8e8));background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top, #337ab7 0, #2e6da4 100%);background-image:-o-linear-gradient(top, #337ab7 0, #2e6da4 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #337ab7), to(#2e6da4));background-image:linear-gradient(to bottom, #337ab7 0, #2e6da4 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-color:#2e6da4}.navbar-default{background-image:-webkit-linear-gradient(top, #fff 0, #f8f8f8 100%);background-image:-o-linear-gradient(top, #fff 0, #f8f8f8 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), to(#f8f8f8));background-image:linear-gradient(to bottom, #fff 0, #f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #dbdbdb 0, #e2e2e2 100%);background-image:-o-linear-gradient(top, #dbdbdb 0, #e2e2e2 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #dbdbdb), to(#e2e2e2));background-image:linear-gradient(to bottom, #dbdbdb 0, #e2e2e2 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.075);box-shadow:inset 0 3px 9px rgba(0,0,0,0.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top, #3c3c3c 0, #222 100%);background-image:-o-linear-gradient(top, #3c3c3c 0, #222 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #3c3c3c), to(#222));background-image:linear-gradient(to bottom, #3c3c3c 0, #222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border-radius:4px}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #080808 0, #0f0f0f 100%);background-image:-o-linear-gradient(top, #080808 0, #0f0f0f 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #080808), to(#0f0f0f));background-image:linear-gradient(to bottom, #080808 0, #0f0f0f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.25);box-shadow:inset 0 3px 9px rgba(0,0,0,0.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-image:-webkit-linear-gradient(top, #337ab7 0, #2e6da4 100%);background-image:-o-linear-gradient(top, #337ab7 0, #2e6da4 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #337ab7), to(#2e6da4));background-image:linear-gradient(to bottom, #337ab7 0, #2e6da4 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0)}}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);background-image:-o-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #dff0d8), to(#c8e5bc));background-image:linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top, #d9edf7 0, #b9def0 100%);background-image:-o-linear-gradient(top, #d9edf7 0, #b9def0 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9edf7), to(#b9def0));background-image:linear-gradient(to bottom, #d9edf7 0, #b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);background-image:-o-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fcf8e3), to(#f8efc0));background-image:linear-gradient(to bottom, #fcf8e3 0, #f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top, #f2dede 0, #e7c3c3 100%);background-image:-o-linear-gradient(top, #f2dede 0, #e7c3c3 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f2dede), to(#e7c3c3));background-image:linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);background-image:-o-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #ebebeb), to(#f5f5f5));background-image:linear-gradient(to bottom, #ebebeb 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top, #337ab7 0, #286090 100%);background-image:-o-linear-gradient(top, #337ab7 0, #286090 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #337ab7), to(#286090));background-image:linear-gradient(to bottom, #337ab7 0, #286090 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #449d44 100%);background-image:-o-linear-gradient(top, #5cb85c 0, #449d44 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5cb85c), to(#449d44));background-image:linear-gradient(to bottom, #5cb85c 0, #449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #31b0d5 100%);background-image:-o-linear-gradient(top, #5bc0de 0, #31b0d5 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5bc0de), to(#31b0d5));background-image:linear-gradient(to bottom, #5bc0de 0, #31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #ec971f 100%);background-image:-o-linear-gradient(top, #f0ad4e 0, #ec971f 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f0ad4e), to(#ec971f));background-image:linear-gradient(to bottom, #f0ad4e 0, #ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c9302c 100%);background-image:-o-linear-gradient(top, #d9534f 0, #c9302c 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9534f), to(#c9302c));background-image:linear-gradient(to bottom, #d9534f 0, #c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top, #337ab7 0, #2b669a 100%);background-image:-o-linear-gradient(top, #337ab7 0, #2b669a 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #337ab7), to(#2b669a));background-image:linear-gradient(to bottom, #337ab7 0, #2b669a 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:hover .badge,.list-group-item.active:focus .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-o-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f5f5f5), to(#e8e8e8));background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top, #337ab7 0, #2e6da4 100%);background-image:-o-linear-gradient(top, #337ab7 0, #2e6da4 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #337ab7), to(#2e6da4));background-image:linear-gradient(to bottom, #337ab7 0, #2e6da4 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);background-image:-o-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #dff0d8), to(#d0e9c6));background-image:linear-gradient(to bottom, #dff0d8 0, #d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);background-image:-o-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9edf7), to(#c4e3f3));background-image:linear-gradient(to bottom, #d9edf7 0, #c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);background-image:-o-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fcf8e3), to(#faf2cc));background-image:linear-gradient(to bottom, #fcf8e3 0, #faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top, #f2dede 0, #ebcccc 100%);background-image:-o-linear-gradient(top, #f2dede 0, #ebcccc 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f2dede), to(#ebcccc));background-image:linear-gradient(to bottom, #f2dede 0, #ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);background-image:-o-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #e8e8e8), to(#f5f5f5));background-image:linear-gradient(to bottom, #e8e8e8 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)} -------------------------------------------------------------------------------- /resources/static/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qa-dev/wda-inspector/90701505ea2f1b1301bc1121052c99c8db1afa6f/resources/static/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /resources/static/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qa-dev/wda-inspector/90701505ea2f1b1301bc1121052c99c8db1afa6f/resources/static/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qa-dev/wda-inspector/90701505ea2f1b1301bc1121052c99c8db1afa6f/resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qa-dev/wda-inspector/90701505ea2f1b1301bc1121052c99c8db1afa6f/resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /resources/static/bootstrap/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | /*! 8 | * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f6a05bdcc5c74ffbf35a182aa6d619db) 9 | * Config saved to config.json and https://gist.github.com/f6a05bdcc5c74ffbf35a182aa6d619db 10 | */ 11 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(t){"use strict";var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||e[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),n=i.data("bs.alert");n||i.data("bs.alert",n=new o(this)),"string"==typeof e&&n[e].call(i)})}var i='[data-dismiss="alert"]',o=function(e){t(e).on("click",i,this.close)};o.VERSION="3.3.7",o.TRANSITION_DURATION=150,o.prototype.close=function(e){function i(){a.detach().trigger("closed.bs.alert").remove()}var n=t(this),s=n.attr("data-target");s||(s=n.attr("href"),s=s&&s.replace(/.*(?=#[^\s]*$)/,""));var a=t("#"===s?[]:s);e&&e.preventDefault(),a.length||(a=n.closest(".alert")),a.trigger(e=t.Event("close.bs.alert")),e.isDefaultPrevented()||(a.removeClass("in"),t.support.transition&&a.hasClass("fade")?a.one("bsTransitionEnd",i).emulateTransitionEnd(o.TRANSITION_DURATION):i())};var n=t.fn.alert;t.fn.alert=e,t.fn.alert.Constructor=o,t.fn.alert.noConflict=function(){return t.fn.alert=n,this},t(document).on("click.bs.alert.data-api",i,o.prototype.close)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.button"),s="object"==typeof e&&e;n||o.data("bs.button",n=new i(this,s)),"toggle"==e?n.toggle():e&&n.setState(e)})}var i=function(e,o){this.$element=t(e),this.options=t.extend({},i.DEFAULTS,o),this.isLoading=!1};i.VERSION="3.3.7",i.DEFAULTS={loadingText:"loading..."},i.prototype.setState=function(e){var i="disabled",o=this.$element,n=o.is("input")?"val":"html",s=o.data();e+="Text",null==s.resetText&&o.data("resetText",o[n]()),setTimeout(t.proxy(function(){o[n](null==s[e]?this.options[e]:s[e]),"loadingText"==e?(this.isLoading=!0,o.addClass(i).attr(i,i).prop(i,!0)):this.isLoading&&(this.isLoading=!1,o.removeClass(i).removeAttr(i).prop(i,!1))},this),0)},i.prototype.toggle=function(){var t=!0,e=this.$element.closest('[data-toggle="buttons"]');if(e.length){var i=this.$element.find("input");"radio"==i.prop("type")?(i.prop("checked")&&(t=!1),e.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==i.prop("type")&&(i.prop("checked")!==this.$element.hasClass("active")&&(t=!1),this.$element.toggleClass("active")),i.prop("checked",this.$element.hasClass("active")),t&&i.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var o=t.fn.button;t.fn.button=e,t.fn.button.Constructor=i,t.fn.button.noConflict=function(){return t.fn.button=o,this},t(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(i){var o=t(i.target).closest(".btn");e.call(o,"toggle"),t(i.target).is('input[type="radio"], input[type="checkbox"]')||(i.preventDefault(),o.is("input,button")?o.trigger("focus"):o.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(e){t(e.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(e.type))})}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.carousel"),s=t.extend({},i.DEFAULTS,o.data(),"object"==typeof e&&e),a="string"==typeof e?e:s.slide;n||o.data("bs.carousel",n=new i(this,s)),"number"==typeof e?n.to(e):a?n[a]():s.interval&&n.pause().cycle()})}var i=function(e,i){this.$element=t(e),this.$indicators=this.$element.find(".carousel-indicators"),this.options=i,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",t.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",t.proxy(this.pause,this)).on("mouseleave.bs.carousel",t.proxy(this.cycle,this))};i.VERSION="3.3.7",i.TRANSITION_DURATION=600,i.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},i.prototype.keydown=function(t){if(!/input|textarea/i.test(t.target.tagName)){switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}t.preventDefault()}},i.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(t.proxy(this.next,this),this.options.interval)),this},i.prototype.getItemIndex=function(t){return this.$items=t.parent().children(".item"),this.$items.index(t||this.$active)},i.prototype.getItemForDirection=function(t,e){var i=this.getItemIndex(e),o="prev"==t&&0===i||"next"==t&&i==this.$items.length-1;if(o&&!this.options.wrap)return e;var n="prev"==t?-1:1,s=(i+n)%this.$items.length;return this.$items.eq(s)},i.prototype.to=function(t){var e=this,i=this.getItemIndex(this.$active=this.$element.find(".item.active"));return t>this.$items.length-1||0>t?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",this.$items.eq(t))},i.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&t.support.transition&&(this.$element.trigger(t.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},i.prototype.next=function(){return this.sliding?void 0:this.slide("next")},i.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},i.prototype.slide=function(e,o){var n=this.$element.find(".item.active"),s=o||this.getItemForDirection(e,n),a=this.interval,r="next"==e?"left":"right",l=this;if(s.hasClass("active"))return this.sliding=!1;var h=s[0],d=t.Event("slide.bs.carousel",{relatedTarget:h,direction:r});if(this.$element.trigger(d),!d.isDefaultPrevented()){if(this.sliding=!0,a&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var p=t(this.$indicators.children()[this.getItemIndex(s)]);p&&p.addClass("active")}var c=t.Event("slid.bs.carousel",{relatedTarget:h,direction:r});return t.support.transition&&this.$element.hasClass("slide")?(s.addClass(e),s[0].offsetWidth,n.addClass(r),s.addClass(r),n.one("bsTransitionEnd",function(){s.removeClass([e,r].join(" ")).addClass("active"),n.removeClass(["active",r].join(" ")),l.sliding=!1,setTimeout(function(){l.$element.trigger(c)},0)}).emulateTransitionEnd(i.TRANSITION_DURATION)):(n.removeClass("active"),s.addClass("active"),this.sliding=!1,this.$element.trigger(c)),a&&this.cycle(),this}};var o=t.fn.carousel;t.fn.carousel=e,t.fn.carousel.Constructor=i,t.fn.carousel.noConflict=function(){return t.fn.carousel=o,this};var n=function(i){var o,n=t(this),s=t(n.attr("data-target")||(o=n.attr("href"))&&o.replace(/.*(?=#[^\s]+$)/,""));if(s.hasClass("carousel")){var a=t.extend({},s.data(),n.data()),r=n.attr("data-slide-to");r&&(a.interval=!1),e.call(s,a),r&&s.data("bs.carousel").to(r),i.preventDefault()}};t(document).on("click.bs.carousel.data-api","[data-slide]",n).on("click.bs.carousel.data-api","[data-slide-to]",n),t(window).on("load",function(){t('[data-ride="carousel"]').each(function(){var i=t(this);e.call(i,i.data())})})}(jQuery),+function(t){"use strict";function e(e){var i=e.attr("data-target");i||(i=e.attr("href"),i=i&&/#[A-Za-z]/.test(i)&&i.replace(/.*(?=#[^\s]*$)/,""));var o=i&&t(i);return o&&o.length?o:e.parent()}function i(i){i&&3===i.which||(t(n).remove(),t(s).each(function(){var o=t(this),n=e(o),s={relatedTarget:this};n.hasClass("open")&&(i&&"click"==i.type&&/input|textarea/i.test(i.target.tagName)&&t.contains(n[0],i.target)||(n.trigger(i=t.Event("hide.bs.dropdown",s)),i.isDefaultPrevented()||(o.attr("aria-expanded","false"),n.removeClass("open").trigger(t.Event("hidden.bs.dropdown",s)))))}))}function o(e){return this.each(function(){var i=t(this),o=i.data("bs.dropdown");o||i.data("bs.dropdown",o=new a(this)),"string"==typeof e&&o[e].call(i)})}var n=".dropdown-backdrop",s='[data-toggle="dropdown"]',a=function(e){t(e).on("click.bs.dropdown",this.toggle)};a.VERSION="3.3.7",a.prototype.toggle=function(o){var n=t(this);if(!n.is(".disabled, :disabled")){var s=e(n),a=s.hasClass("open");if(i(),!a){"ontouchstart"in document.documentElement&&!s.closest(".navbar-nav").length&&t(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(t(this)).on("click",i);var r={relatedTarget:this};if(s.trigger(o=t.Event("show.bs.dropdown",r)),o.isDefaultPrevented())return;n.trigger("focus").attr("aria-expanded","true"),s.toggleClass("open").trigger(t.Event("shown.bs.dropdown",r))}return!1}},a.prototype.keydown=function(i){if(/(38|40|27|32)/.test(i.which)&&!/input|textarea/i.test(i.target.tagName)){var o=t(this);if(i.preventDefault(),i.stopPropagation(),!o.is(".disabled, :disabled")){var n=e(o),a=n.hasClass("open");if(!a&&27!=i.which||a&&27==i.which)return 27==i.which&&n.find(s).trigger("focus"),o.trigger("click");var r=" li:not(.disabled):visible a",l=n.find(".dropdown-menu"+r);if(l.length){var h=l.index(i.target);38==i.which&&h>0&&h--,40==i.which&&hdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},i.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},i.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},i.prototype.init=function(e,i,o){if(this.enabled=!0,this.type=e,this.$element=t(i),this.options=this.getOptions(o),this.$viewport=this.options.viewport&&t(t.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var n=this.options.trigger.split(" "),s=n.length;s--;){var a=n[s];if("click"==a)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=a){var r="hover"==a?"mouseenter":"focusin",l="hover"==a?"mouseleave":"focusout";this.$element.on(r+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(l+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.getOptions=function(e){return e=t.extend({},this.getDefaults(),this.$element.data(),e),e.delay&&"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),e},i.prototype.getDelegateOptions=function(){var e={},i=this.getDefaults();return this._options&&t.each(this._options,function(t,o){i[t]!=o&&(e[t]=o)}),e},i.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),e instanceof t.Event&&(i.inState["focusin"==e.type?"focus":"hover"]=!0),i.tip().hasClass("in")||"in"==i.hoverState?void(i.hoverState="in"):(clearTimeout(i.timeout),i.hoverState="in",i.options.delay&&i.options.delay.show?void(i.timeout=setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show)):i.show())},i.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},i.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),e instanceof t.Event&&(i.inState["focusout"==e.type?"focus":"hover"]=!1),i.isInStateTrue()?void 0:(clearTimeout(i.timeout),i.hoverState="out",i.options.delay&&i.options.delay.hide?void(i.timeout=setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide)):i.hide())},i.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var o=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!o)return;var n=this,s=this.tip(),a=this.getUID(this.type);this.setContent(),s.attr("id",a),this.$element.attr("aria-describedby",a),this.options.animation&&s.addClass("fade");var r="function"==typeof this.options.placement?this.options.placement.call(this,s[0],this.$element[0]):this.options.placement,l=/\s?auto?\s?/i,h=l.test(r);h&&(r=r.replace(l,"")||"top"),s.detach().css({top:0,left:0,display:"block"}).addClass(r).data("bs."+this.type,this),this.options.container?s.appendTo(this.options.container):s.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var d=this.getPosition(),p=s[0].offsetWidth,c=s[0].offsetHeight;if(h){var f=r,u=this.getPosition(this.$viewport);r="bottom"==r&&d.bottom+c>u.bottom?"top":"top"==r&&d.top-cu.width?"left":"left"==r&&d.left-pa.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.right&&(n.left=a.left+a.width-d)}return n},i.prototype.getTitle=function(){var t,e=this.$element,i=this.options;return t=e.attr("data-original-title")||("function"==typeof i.title?i.title.call(e[0]):i.title)},i.prototype.getUID=function(t){do t+=~~(1e6*Math.random());while(document.getElementById(t));return t},i.prototype.tip=function(){if(!this.$tip&&(this.$tip=t(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},i.prototype.enable=function(){this.enabled=!0},i.prototype.disable=function(){this.enabled=!1},i.prototype.toggleEnabled=function(){this.enabled=!this.enabled},i.prototype.toggle=function(e){var i=this;e&&(i=t(e.currentTarget).data("bs."+this.type),i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i))),e?(i.inState.click=!i.inState.click,i.isInStateTrue()?i.enter(i):i.leave(i)):i.tip().hasClass("in")?i.leave(i):i.enter(i)},i.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null})};var o=t.fn.tooltip;t.fn.tooltip=e,t.fn.tooltip.Constructor=i,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.popover"),s="object"==typeof e&&e;!n&&/destroy|hide/.test(e)||(n||o.data("bs.popover",n=new i(this,s)),"string"==typeof e&&n[e]())})}var i=function(t,e){this.init("popover",t,e)};if(!t.fn.tooltip)throw new Error("Popover requires tooltip.js");i.VERSION="3.3.7",i.DEFAULTS=t.extend({},t.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),i.prototype=t.extend({},t.fn.tooltip.Constructor.prototype),i.prototype.constructor=i,i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof i?"html":"append":"text"](i),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},i.prototype.hasContent=function(){return this.getTitle()||this.getContent()},i.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var o=t.fn.popover;t.fn.popover=e,t.fn.popover.Constructor=i,t.fn.popover.noConflict=function(){return t.fn.popover=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.tab");n||o.data("bs.tab",n=new i(this)),"string"==typeof e&&n[e]()})}var i=function(e){this.element=t(e)};i.VERSION="3.3.7",i.TRANSITION_DURATION=150,i.prototype.show=function(){var e=this.element,i=e.closest("ul:not(.dropdown-menu)"),o=e.data("target");if(o||(o=e.attr("href"),o=o&&o.replace(/.*(?=#[^\s]*$)/,"")),!e.parent("li").hasClass("active")){var n=i.find(".active:last a"),s=t.Event("hide.bs.tab",{relatedTarget:e[0]}),a=t.Event("show.bs.tab",{relatedTarget:n[0]});if(n.trigger(s),e.trigger(a),!a.isDefaultPrevented()&&!s.isDefaultPrevented()){var r=t(o);this.activate(e.closest("li"),i),this.activate(r,r.parent(),function(){n.trigger({type:"hidden.bs.tab",relatedTarget:e[0]}),e.trigger({type:"shown.bs.tab",relatedTarget:n[0]})})}}},i.prototype.activate=function(e,o,n){function s(){a.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),e.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),r?(e[0].offsetWidth,e.addClass("in")):e.removeClass("fade"),e.parent(".dropdown-menu").length&&e.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),n&&n()}var a=o.find("> .active"),r=n&&t.support.transition&&(a.length&&a.hasClass("fade")||!!o.find("> .fade").length);a.length&&r?a.one("bsTransitionEnd",s).emulateTransitionEnd(i.TRANSITION_DURATION):s(),a.removeClass("in")};var o=t.fn.tab;t.fn.tab=e,t.fn.tab.Constructor=i,t.fn.tab.noConflict=function(){return t.fn.tab=o,this};var n=function(i){i.preventDefault(),e.call(t(this),"show")};t(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',n).on("click.bs.tab.data-api",'[data-toggle="pill"]',n)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.affix"),s="object"==typeof e&&e;n||o.data("bs.affix",n=new i(this,s)),"string"==typeof e&&n[e]()})}var i=function(e,o){this.options=t.extend({},i.DEFAULTS,o),this.$target=t(this.options.target).on("scroll.bs.affix.data-api",t.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",t.proxy(this.checkPositionWithEventLoop,this)),this.$element=t(e),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};i.VERSION="3.3.7",i.RESET="affix affix-top affix-bottom",i.DEFAULTS={offset:0,target:window},i.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return i>n?"top":!1;if("bottom"==this.affixed)return null!=i?n+this.unpin<=s.top?!1:"bottom":t-o>=n+a?!1:"bottom";var r=null==this.affixed,l=r?n:s.top,h=r?a:e;return null!=i&&i>=n?"top":null!=o&&l+h>=t-o?"bottom":!1},i.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(i.RESET).addClass("affix");var t=this.$target.scrollTop(),e=this.$element.offset();return this.pinnedOffset=e.top-t},i.prototype.checkPositionWithEventLoop=function(){setTimeout(t.proxy(this.checkPosition,this),1)},i.prototype.checkPosition=function(){if(this.$element.is(":visible")){var e=this.$element.height(),o=this.options.offset,n=o.top,s=o.bottom,a=Math.max(t(document).height(),t(document.body).height());"object"!=typeof o&&(s=n=o),"function"==typeof n&&(n=o.top(this.$element)),"function"==typeof s&&(s=o.bottom(this.$element));var r=this.getState(a,e,n,s);if(this.affixed!=r){null!=this.unpin&&this.$element.css("top","");var l="affix"+(r?"-"+r:""),h=t.Event(l+".bs.affix");if(this.$element.trigger(h),h.isDefaultPrevented())return;this.affixed=r,this.unpin="bottom"==r?this.getPinnedOffset():null,this.$element.removeClass(i.RESET).addClass(l).trigger(l.replace("affix","affixed")+".bs.affix")}"bottom"==r&&this.$element.offset({top:a-e-s})}};var o=t.fn.affix;t.fn.affix=e,t.fn.affix.Constructor=i,t.fn.affix.noConflict=function(){return t.fn.affix=o,this},t(window).on("load",function(){t('[data-spy="affix"]').each(function(){var i=t(this),o=i.data();o.offset=o.offset||{},null!=o.offsetBottom&&(o.offset.bottom=o.offsetBottom),null!=o.offsetTop&&(o.offset.top=o.offsetTop),e.call(i,o)})})}(jQuery),+function(t){"use strict";function e(e){var i,o=e.attr("data-target")||(i=e.attr("href"))&&i.replace(/.*(?=#[^\s]+$)/,"");return t(o)}function i(e){return this.each(function(){var i=t(this),n=i.data("bs.collapse"),s=t.extend({},o.DEFAULTS,i.data(),"object"==typeof e&&e);!n&&s.toggle&&/show|hide/.test(e)&&(s.toggle=!1),n||i.data("bs.collapse",n=new o(this,s)),"string"==typeof e&&n[e]()})}var o=function(e,i){this.$element=t(e),this.options=t.extend({},o.DEFAULTS,i),this.$trigger=t('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};o.VERSION="3.3.7",o.TRANSITION_DURATION=350,o.DEFAULTS={toggle:!0},o.prototype.dimension=function(){var t=this.$element.hasClass("width");return t?"width":"height"},o.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var e,n=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(n&&n.length&&(e=n.data("bs.collapse"),e&&e.transitioning))){var s=t.Event("show.bs.collapse");if(this.$element.trigger(s),!s.isDefaultPrevented()){n&&n.length&&(i.call(n,"hide"),e||n.data("bs.collapse",null));var a=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[a](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var r=function(){this.$element.removeClass("collapsing").addClass("collapse in")[a](""),this.transitioning=0, 12 | this.$element.trigger("shown.bs.collapse")};if(!t.support.transition)return r.call(this);var l=t.camelCase(["scroll",a].join("-"));this.$element.one("bsTransitionEnd",t.proxy(r,this)).emulateTransitionEnd(o.TRANSITION_DURATION)[a](this.$element[0][l])}}}},o.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var e=t.Event("hide.bs.collapse");if(this.$element.trigger(e),!e.isDefaultPrevented()){var i=this.dimension();this.$element[i](this.$element[i]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var n=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return t.support.transition?void this.$element[i](0).one("bsTransitionEnd",t.proxy(n,this)).emulateTransitionEnd(o.TRANSITION_DURATION):n.call(this)}}},o.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},o.prototype.getParent=function(){return t(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(t.proxy(function(i,o){var n=t(o);this.addAriaAndCollapsedClass(e(n),n)},this)).end()},o.prototype.addAriaAndCollapsedClass=function(t,e){var i=t.hasClass("in");t.attr("aria-expanded",i),e.toggleClass("collapsed",!i).attr("aria-expanded",i)};var n=t.fn.collapse;t.fn.collapse=i,t.fn.collapse.Constructor=o,t.fn.collapse.noConflict=function(){return t.fn.collapse=n,this},t(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(o){var n=t(this);n.attr("data-target")||o.preventDefault();var s=e(n),a=s.data("bs.collapse"),r=a?"toggle":n.data();i.call(s,r)})}(jQuery),+function(t){"use strict";function e(i,o){this.$body=t(document.body),this.$scrollElement=t(t(i).is(document.body)?window:i),this.options=t.extend({},e.DEFAULTS,o),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",t.proxy(this.process,this)),this.refresh(),this.process()}function i(i){return this.each(function(){var o=t(this),n=o.data("bs.scrollspy"),s="object"==typeof i&&i;n||o.data("bs.scrollspy",n=new e(this,s)),"string"==typeof i&&n[i]()})}e.VERSION="3.3.7",e.DEFAULTS={offset:10},e.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},e.prototype.refresh=function(){var e=this,i="offset",o=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),t.isWindow(this.$scrollElement[0])||(i="position",o=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var e=t(this),n=e.data("target")||e.attr("href"),s=/^#./.test(n)&&t(n);return s&&s.length&&s.is(":visible")&&[[s[i]().top+o,n]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){e.offsets.push(this[0]),e.targets.push(this[1])})},e.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),e>=o)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(void 0===n[t+1]||ea?0:d.max")[0],k,l=a.each;j.style.cssText="background-color:rgba(1,1,1,.5)",i.rgba=j.style.backgroundColor.indexOf("rgba")>-1,l(g,function(a,b){b.cache="_"+a,b.props.alpha={idx:3,type:"percent",def:1}}),f.fn=a.extend(f.prototype,{parse:function(c,d,e,h){if(c===b)return this._rgba=[null,null,null,null],this;if(c.jquery||c.nodeType)c=a(c).css(d),d=b;var i=this,j=a.type(c),o=this._rgba=[];d!==b&&(c=[c,d,e,h],j="array");if(j==="string")return this.parse(n(c)||k._default);if(j==="array")return l(g.rgba.props,function(a,b){o[b.idx]=m(c[b.idx],b)}),this;if(j==="object")return c instanceof f?l(g,function(a,b){c[b.cache]&&(i[b.cache]=c[b.cache].slice())}):l(g,function(b,d){var e=d.cache;l(d.props,function(a,b){if(!i[e]&&d.to){if(a==="alpha"||c[a]==null)return;i[e]=d.to(i._rgba)}i[e][b.idx]=m(c[a],b,!0)}),i[e]&&a.inArray(null,i[e].slice(0,3))<0&&(i[e][3]=1,d.from&&(i._rgba=d.from(i[e])))}),this},is:function(a){var b=f(a),c=!0,d=this;return l(g,function(a,e){var f,g=b[e.cache];return g&&(f=d[e.cache]||e.to&&e.to(d._rgba)||[],l(e.props,function(a,b){if(g[b.idx]!=null)return c=g[b.idx]===f[b.idx],c})),c}),c},_space:function(){var a=[],b=this;return l(g,function(c,d){b[d.cache]&&a.push(c)}),a.pop()},transition:function(a,b){var c=f(a),d=c._space(),e=g[d],i=this.alpha()===0?f("transparent"):this,j=i[e.cache]||e.to(i._rgba),k=j.slice();return c=c[e.cache],l(e.props,function(a,d){var e=d.idx,f=j[e],g=c[e],i=h[d.type]||{};if(g===null)return;f===null?k[e]=g:(i.mod&&(g-f>i.mod/2?f+=i.mod:f-g>i.mod/2&&(f-=i.mod)),k[e]=m((g-f)*b+f,d))}),this[d](k)},blend:function(b){if(this._rgba[3]===1)return this;var c=this._rgba.slice(),d=c.pop(),e=f(b)._rgba;return f(a.map(c,function(a,b){return(1-d)*e[b]+d*a}))},toRgbaString:function(){var b="rgba(",c=a.map(this._rgba,function(a,b){return a==null?b>2?1:0:a});return c[3]===1&&(c.pop(),b="rgb("),b+c.join()+")"},toHslaString:function(){var b="hsla(",c=a.map(this.hsla(),function(a,b){return a==null&&(a=b>2?1:0),b&&b<3&&(a=Math.round(a*100)+"%"),a});return c[3]===1&&(c.pop(),b="hsl("),b+c.join()+")"},toHexString:function(b){var c=this._rgba.slice(),d=c.pop();return b&&c.push(~~(d*255)),"#"+a.map(c,function(a){return a=(a||0).toString(16),a.length===1?"0"+a:a}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),f.fn.parse.prototype=f.fn,g.hsla.to=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/255,c=a[1]/255,d=a[2]/255,e=a[3],f=Math.max(b,c,d),g=Math.min(b,c,d),h=f-g,i=f+g,j=i*.5,k,l;return g===f?k=0:b===f?k=60*(c-d)/h+360:c===f?k=60*(d-b)/h+120:k=60*(b-c)/h+240,h===0?l=0:j<=.5?l=h/i:l=h/(2-i),[Math.round(k)%360,l,j,e==null?1:e]},g.hsla.from=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],e=a[3],f=d<=.5?d*(1+c):d+c-d*c,g=2*d-f;return[Math.round(o(g,f,b+1/3)*255),Math.round(o(g,f,b)*255),Math.round(o(g,f,b-1/3)*255),e]},l(g,function(c,e){var g=e.props,h=e.cache,i=e.to,j=e.from;f.fn[c]=function(c){i&&!this[h]&&(this[h]=i(this._rgba));if(c===b)return this[h].slice();var d,e=a.type(c),k=e==="array"||e==="object"?c:arguments,n=this[h].slice();return l(g,function(a,b){var c=k[e==="object"?a:b.idx];c==null&&(c=n[b.idx]),n[b.idx]=m(c,b)}),j?(d=f(j(n)),d[h]=n,d):f(n)},l(g,function(b,e){if(f.fn[b])return;f.fn[b]=function(f){var g=a.type(f),h=b==="alpha"?this._hsla?"hsla":"rgba":c,i=this[h](),j=i[e.idx],k;return g==="undefined"?j:(g==="function"&&(f=f.call(this,j),g=a.type(f)),f==null&&e.empty?this:(g==="string"&&(k=d.exec(f),k&&(f=j+parseFloat(k[2])*(k[1]==="+"?1:-1))),i[e.idx]=f,this[h](i)))}})}),f.hook=function(b){var c=b.split(" ");l(c,function(b,c){a.cssHooks[c]={set:function(b,d){var e,g,h="";if(d!=="transparent"&&(a.type(d)!=="string"||(e=n(d)))){d=f(e||d);if(!i.rgba&&d._rgba[3]!==1){g=c==="backgroundColor"?b.parentNode:b;while((h===""||h==="transparent")&&g&&g.style)try{h=a.css(g,"backgroundColor"),g=g.parentNode}catch(j){}d=d.blend(h&&h!=="transparent"?h:"_default")}d=d.toRgbaString()}try{b.style[c]=d}catch(j){}}},a.fx.step[c]=function(b){b.colorInit||(b.start=f(b.elem,c),b.end=f(b.end),b.colorInit=!0),a.cssHooks[c].set(b.elem,b.start.transition(b.end,b.pos))}})},f.hook(c),a.cssHooks.borderColor={expand:function(a){var b={};return l(["Top","Right","Bottom","Left"],function(c,d){b["border"+d+"Color"]=a}),b}},k=a.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery); -------------------------------------------------------------------------------- /resources/static/wda-inspector/main.css: -------------------------------------------------------------------------------- 1 | .wda_info_content { 2 | max-width: 300px; 3 | overflow: auto; 4 | } 5 | .wda_screen_highlight { 6 | background-color: rgba(255, 0, 0, 0.3); 7 | position: absolute; 8 | } 9 | .wda_tree ul { 10 | list-style: none; 11 | padding: 0 0 0 20px; 12 | margin: 0 0 10px 10px; 13 | } 14 | .wda_tree ul ul { 15 | border-left: dotted 1px #ccc; 16 | } 17 | .wda_container { 18 | padding: 60px 0 0; 19 | position: relative; 20 | } 21 | .wda_info { 22 | padding: 60px 0 0; 23 | position: absolute; 24 | top: 0; 25 | right: 0; 26 | } 27 | .wda_info_container { 28 | padding: 10px; 29 | min-height: 200px; 30 | min-width: 200px; 31 | text-align: center; 32 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 33 | background-color: rgba(255, 255, 255, 0.8); 34 | } 35 | .wda_screen { 36 | padding: 10px; 37 | min-width: 300px; 38 | min-height: 500px; 39 | float: left; 40 | } 41 | .wda_screen_container { 42 | position: relative; 43 | } 44 | .wda_tree { 45 | padding: 10px; 46 | overflow: hidden; 47 | } 48 | .wda_tree_container { 49 | height: 500px; 50 | overflow: auto; 51 | } -------------------------------------------------------------------------------- /resources/static/wda-inspector/main.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o\n Class {{info.type}}
\n Name {{info.name}}
\n Label {{info.label}}
\n Value {{info.value}}
\n Rect {{info.frame}}
\n isEnabled {{info.isEnabled}}
\n isVisible {{info.isVisible}}
\n\n"; 54 | 55 | },{}],4:[function(require,module,exports){ 56 | var Mustache = require('mustache'); 57 | var tpl = { 58 | highlight: require('./tpl/highlight.html'), 59 | lockOverlay: require('./tpl/lockOverlay.html'), 60 | error: require('./tpl/error.html') 61 | }; 62 | 63 | var Screen = function($el) { 64 | 65 | var 66 | _this = this, 67 | _selection = { 68 | x: 0, 69 | y: 0, 70 | w: 0, 71 | h: 0 72 | }, 73 | _$highlight, 74 | _$lockOverlay; 75 | 76 | var _render = function($content) { 77 | $el 78 | .empty() 79 | .append($content, _$highlight, _$lockOverlay); 80 | }; 81 | 82 | // Заблокировать 83 | // Например для ожидания загрузки снимка экрана 84 | this.lock = function() { 85 | _$lockOverlay.show(); 86 | }; 87 | 88 | // Разблокировать 89 | this.unlock = function() { 90 | _$lockOverlay.hide(); 91 | }; 92 | 93 | // Обновить изображение 94 | this.update = function(src) { 95 | var img = new Image(); 96 | img.src = 'data:image/png;base64,' + src; 97 | var $content = $(img); 98 | 99 | img.onload = function () { 100 | // когда картинка загрузится, масштабируем её 101 | $content.css({ 102 | width: Math.round(img.width * 0.5) + 'px', 103 | height: Math.round(img.height * 0.5) + 'px' 104 | }); 105 | _render($content); 106 | } 107 | }; 108 | 109 | // Вывести сообщение об ошибке 110 | this.error = function(message) 111 | { 112 | var $content = $(Mustache.render(tpl.error, {message: message})); 113 | _render($content); 114 | }; 115 | 116 | // Подсветить область 117 | this.highlight = function(x, y, w, h) { 118 | _$highlight.css({ 119 | left: x + 'px', 120 | top: y + 'px', 121 | width: w + 'px', 122 | height: h + 'px' 123 | }); 124 | }; 125 | 126 | // Подсветить последнюю выбранную область 127 | this.highlightSelection = function() { 128 | _this.highlight( 129 | _selection.x, 130 | _selection.y, 131 | _selection.w, 132 | _selection.h 133 | ); 134 | }; 135 | 136 | // Выбрать область 137 | this.select = function(x, y, w, h) { 138 | _selection.x = x; 139 | _selection.y = y; 140 | _selection.w = w; 141 | _selection.h = h; 142 | }; 143 | 144 | // INIT 145 | (function() { 146 | _$highlight = $(tpl.highlight); 147 | _$lockOverlay = $(tpl.lockOverlay); 148 | })(); 149 | 150 | }; 151 | 152 | module.exports = Screen; 153 | },{"./tpl/error.html":5,"./tpl/highlight.html":6,"./tpl/lockOverlay.html":7,"mustache":15}],5:[function(require,module,exports){ 154 | module.exports = "
\n {{message}}\n
"; 155 | 156 | },{}],6:[function(require,module,exports){ 157 | module.exports = "
"; 158 | 159 | },{}],7:[function(require,module,exports){ 160 | module.exports = "
\n
\n
"; 161 | 162 | },{}],8:[function(require,module,exports){ 163 | var tpl = { 164 | form: require('./tpl/form.html') 165 | }; 166 | 167 | var Search = function($el, options) { 168 | 169 | var _isLocked = false; 170 | 171 | var _render = function($content) { 172 | $el 173 | .empty() 174 | .append($content); 175 | }; 176 | 177 | var _lock = function() { 178 | if (_isLocked) { 179 | return false; 180 | } 181 | 182 | $el 183 | .find('input') 184 | .attr('readonly', 'readonly'); 185 | _isLocked = true; 186 | 187 | return true; 188 | }; 189 | 190 | var _unlock = function() { 191 | $el 192 | .find('input') 193 | .removeAttr('readonly'); 194 | _isLocked = false; 195 | }; 196 | 197 | // INIT 198 | (function() { 199 | var $form = $(tpl.form); 200 | $form.on('submit', function() { 201 | if (_lock()) { 202 | var locator = $(this).find('input[name="value"]').val(); 203 | $.ajax({ 204 | method: 'POST', 205 | url: options.url, 206 | data: $(this).serialize(), 207 | dataType: 'json', 208 | success: options.success, 209 | error: function(jqXHR) { 210 | if (jqXHR.status === 400) { 211 | options.notFound(locator); 212 | } else { 213 | options.error(locator); 214 | } 215 | }, 216 | complete: function() { 217 | _unlock(); 218 | } 219 | }); 220 | } 221 | 222 | return false; 223 | }); 224 | _render($form); 225 | })(); 226 | 227 | }; 228 | 229 | module.exports = Search; 230 | },{"./tpl/form.html":9}],9:[function(require,module,exports){ 231 | module.exports = "
\n
\n \n
\n
\n \n
\n \n
"; 232 | 233 | },{}],10:[function(require,module,exports){ 234 | var Mustache = require('mustache'); 235 | var tpl = { 236 | item: require('./tpl/item.html'), 237 | lockOverlay: require('./tpl/lockOverlay.html'), 238 | error: require('./tpl/error.html') 239 | }; 240 | 241 | var Tree = function($el) { 242 | 243 | var 244 | _$lockOverlay, 245 | _onElementSelect = function() {}, 246 | _onElementFocus = function() {}, 247 | _onElementBlur = function() {}; 248 | 249 | var _buildList = function(elements) { 250 | var $list = $('
    '); 251 | for (var i = 0; i < elements.length; ++i) { 252 | var item = elements[i]; 253 | item.hasChildren = item.children? true : false; 254 | item.rectStr = JSON.stringify(item.rect); 255 | var 256 | $li = $('
  • '), 257 | $item = $(Mustache.render(tpl.item, item)); 258 | 259 | $li.on('mouseenter.wda-inspector', '.el-type', item.rect, function(e) { 260 | _onElementFocus(e.data); 261 | 262 | return false; 263 | }); 264 | $li.on('mouseleave.wda-inspector', '.el-type', function(e) { 265 | _onElementBlur(e.data); 266 | 267 | return false; 268 | }); 269 | $li.on('click.wda-inspector', '.el-type', item, function(e) { 270 | $el 271 | .find(".el-type.label-primary") 272 | .removeClass("label-primary") 273 | .addClass("label-default"); 274 | $(this) 275 | .removeClass("label-default") 276 | .addClass("label-primary"); 277 | 278 | _onElementSelect(e.data, e.data.rect); 279 | 280 | return false; 281 | }); 282 | 283 | $li.append($item); 284 | 285 | if (item.children) { 286 | $li.append(_buildList(item.children)); 287 | } 288 | 289 | $list.append($li); 290 | } 291 | 292 | $list.on("click", ".element-with-children", function () { 293 | var $this = $(this); 294 | if ($this.hasClass("glyphicon-minus")) { 295 | $this 296 | .removeClass("glyphicon-minus") 297 | .addClass("glyphicon-plus") 298 | .closest("li") 299 | .children("ul") 300 | .css("display", "none"); 301 | } else { 302 | $this 303 | .removeClass("glyphicon-plus") 304 | .addClass("glyphicon-minus") 305 | .closest("li") 306 | .children("ul") 307 | .css("display", "block"); 308 | } 309 | 310 | return false; 311 | }); 312 | 313 | return $list; 314 | }; 315 | 316 | var _render = function($content) { 317 | $el 318 | .empty() 319 | .append($content, _$lockOverlay); 320 | }; 321 | 322 | // Заблокировать 323 | this.lock = function() { 324 | _$lockOverlay.show(); 325 | }; 326 | 327 | // Разблокировать 328 | this.unlock = function() { 329 | _$lockOverlay.hide(); 330 | }; 331 | 332 | // Вывести сообщение об ошибке 333 | this.error = function(message) { 334 | var $content = $(Mustache.render(tpl.error, {message: message})); 335 | _render($content); 336 | }; 337 | 338 | this.update = function(elements) { 339 | var $list = _buildList(elements.children); 340 | _render($list); 341 | }; 342 | 343 | this.select = function(rect, type) { 344 | $el 345 | .find(".el-type[data-rect='" + JSON.stringify(rect) + "'] > :contains('[" + type + "]')") 346 | .click(); 347 | }; 348 | 349 | // Назначить обработчик на фокус элемента 350 | this.onElementFocus = function(handler) { 351 | _onElementFocus = handler; 352 | 353 | }; 354 | 355 | // Назначить обработчик на блюр элемента 356 | this.onElementBlur = function(handler) { 357 | _onElementBlur = handler; 358 | }; 359 | 360 | // Назначить обработчик на выбор элемента 361 | this.onElementSelect = function(handler) { 362 | _onElementSelect = handler; 363 | }; 364 | 365 | // INIT 366 | (function() { 367 | _$lockOverlay = $(tpl.lockOverlay); 368 | })(); 369 | 370 | }; 371 | 372 | module.exports = Tree; 373 | },{"./tpl/error.html":11,"./tpl/item.html":12,"./tpl/lockOverlay.html":13,"mustache":15}],11:[function(require,module,exports){ 374 | module.exports = "
    \n {{message}}\n
    "; 375 | 376 | },{}],12:[function(require,module,exports){ 377 | module.exports = "{{#hasChildren}}\n \n{{/hasChildren}}\n\n [{{type}}]\n\n{{#rawIdentifier}}\n {{rawIdentifier}}\n{{/rawIdentifier}}\n{{label}}"; 378 | 379 | },{}],13:[function(require,module,exports){ 380 | module.exports = "
    \n
    \n
    "; 381 | 382 | },{}],14:[function(require,module,exports){ 383 | var Screen = require('./Screen/Screen.js'); 384 | var Tree = require('./Tree/Tree.js'); 385 | var Info = require('./Info/Info.js'); 386 | var Search = require('./Search/Search.js'); 387 | 388 | $(function () { 389 | 390 | var screen = new Screen($('.wda_screen_container')); 391 | $.ajax({ 392 | method: 'get', 393 | url: '/screenshot', 394 | dataType: 'json', 395 | beforeSend: function() { 396 | screen.lock(); 397 | }, 398 | complete: function() { 399 | screen.unlock(); 400 | }, 401 | success: function(data) { 402 | screen.update(data.img); 403 | }, 404 | error: function() { 405 | screen.error('Не удалось загрузить экран'); 406 | } 407 | }); 408 | 409 | var info = new Info($('.wda_info_container')); 410 | 411 | var tree = new Tree($('.wda_tree_container')); 412 | tree.onElementFocus(function(rect) { 413 | screen.highlight( 414 | rect.x, 415 | rect.y, 416 | rect.width, 417 | rect.height 418 | ); 419 | }); 420 | tree.onElementBlur(screen.highlightSelection); 421 | tree.onElementSelect(function(infoData, rect) { 422 | screen.select( 423 | rect.x, 424 | rect.y, 425 | rect.width, 426 | rect.height 427 | ); 428 | screen.highlightSelection(); 429 | info.update(infoData); 430 | }); 431 | $.ajax({ 432 | method: 'get', 433 | url: '/source', 434 | dataType: 'json', 435 | beforeSend: function() { 436 | tree.lock(); 437 | }, 438 | complete: function() { 439 | tree.unlock(); 440 | }, 441 | success: function(data) { 442 | tree.update(data.tree); 443 | }, 444 | error: function() { 445 | tree.error('Не удалось загрузить дерево элементов'); 446 | } 447 | }); 448 | 449 | var search = new Search($('#navbar'), { 450 | url: '/find', 451 | success: function(data) { 452 | tree.select(data.value, data.type); // todo надо бы id 453 | }, 454 | notFound: function(locator) { 455 | info.error(locator + ' not found!'); 456 | }, 457 | error: function(locator) { 458 | info.error('Wrong locator ' + locator); 459 | } 460 | }); 461 | 462 | }); 463 | 464 | },{"./Info/Info.js":1,"./Screen/Screen.js":4,"./Search/Search.js":8,"./Tree/Tree.js":10}],15:[function(require,module,exports){ 465 | /*! 466 | * mustache.js - Logic-less {{mustache}} templates with JavaScript 467 | * http://github.com/janl/mustache.js 468 | */ 469 | 470 | /*global define: false Mustache: true*/ 471 | 472 | (function defineMustache (global, factory) { 473 | if (typeof exports === 'object' && exports && typeof exports.nodeName !== 'string') { 474 | factory(exports); // CommonJS 475 | } else if (typeof define === 'function' && define.amd) { 476 | define(['exports'], factory); // AMD 477 | } else { 478 | global.Mustache = {}; 479 | factory(global.Mustache); // script, wsh, asp 480 | } 481 | }(this, function mustacheFactory (mustache) { 482 | 483 | var objectToString = Object.prototype.toString; 484 | var isArray = Array.isArray || function isArrayPolyfill (object) { 485 | return objectToString.call(object) === '[object Array]'; 486 | }; 487 | 488 | function isFunction (object) { 489 | return typeof object === 'function'; 490 | } 491 | 492 | /** 493 | * More correct typeof string handling array 494 | * which normally returns typeof 'object' 495 | */ 496 | function typeStr (obj) { 497 | return isArray(obj) ? 'array' : typeof obj; 498 | } 499 | 500 | function escapeRegExp (string) { 501 | return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'); 502 | } 503 | 504 | /** 505 | * Null safe way of checking whether or not an object, 506 | * including its prototype, has a given property 507 | */ 508 | function hasProperty (obj, propName) { 509 | return obj != null && typeof obj === 'object' && (propName in obj); 510 | } 511 | 512 | // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577 513 | // See https://github.com/janl/mustache.js/issues/189 514 | var regExpTest = RegExp.prototype.test; 515 | function testRegExp (re, string) { 516 | return regExpTest.call(re, string); 517 | } 518 | 519 | var nonSpaceRe = /\S/; 520 | function isWhitespace (string) { 521 | return !testRegExp(nonSpaceRe, string); 522 | } 523 | 524 | var entityMap = { 525 | '&': '&', 526 | '<': '<', 527 | '>': '>', 528 | '"': '"', 529 | "'": ''', 530 | '/': '/', 531 | '`': '`', 532 | '=': '=' 533 | }; 534 | 535 | function escapeHtml (string) { 536 | return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) { 537 | return entityMap[s]; 538 | }); 539 | } 540 | 541 | var whiteRe = /\s*/; 542 | var spaceRe = /\s+/; 543 | var equalsRe = /\s*=/; 544 | var curlyRe = /\s*\}/; 545 | var tagRe = /#|\^|\/|>|\{|&|=|!/; 546 | 547 | /** 548 | * Breaks up the given `template` string into a tree of tokens. If the `tags` 549 | * argument is given here it must be an array with two string values: the 550 | * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of 551 | * course, the default is to use mustaches (i.e. mustache.tags). 552 | * 553 | * A token is an array with at least 4 elements. The first element is the 554 | * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag 555 | * did not contain a symbol (i.e. {{myValue}}) this element is "name". For 556 | * all text that appears outside a symbol this element is "text". 557 | * 558 | * The second element of a token is its "value". For mustache tags this is 559 | * whatever else was inside the tag besides the opening symbol. For text tokens 560 | * this is the text itself. 561 | * 562 | * The third and fourth elements of the token are the start and end indices, 563 | * respectively, of the token in the original template. 564 | * 565 | * Tokens that are the root node of a subtree contain two more elements: 1) an 566 | * array of tokens in the subtree and 2) the index in the original template at 567 | * which the closing tag for that section begins. 568 | */ 569 | function parseTemplate (template, tags) { 570 | if (!template) 571 | return []; 572 | 573 | var sections = []; // Stack to hold section tokens 574 | var tokens = []; // Buffer to hold the tokens 575 | var spaces = []; // Indices of whitespace tokens on the current line 576 | var hasTag = false; // Is there a {{tag}} on the current line? 577 | var nonSpace = false; // Is there a non-space char on the current line? 578 | 579 | // Strips all whitespace tokens array for the current line 580 | // if there was a {{#tag}} on it and otherwise only space. 581 | function stripSpace () { 582 | if (hasTag && !nonSpace) { 583 | while (spaces.length) 584 | delete tokens[spaces.pop()]; 585 | } else { 586 | spaces = []; 587 | } 588 | 589 | hasTag = false; 590 | nonSpace = false; 591 | } 592 | 593 | var openingTagRe, closingTagRe, closingCurlyRe; 594 | function compileTags (tagsToCompile) { 595 | if (typeof tagsToCompile === 'string') 596 | tagsToCompile = tagsToCompile.split(spaceRe, 2); 597 | 598 | if (!isArray(tagsToCompile) || tagsToCompile.length !== 2) 599 | throw new Error('Invalid tags: ' + tagsToCompile); 600 | 601 | openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*'); 602 | closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1])); 603 | closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1])); 604 | } 605 | 606 | compileTags(tags || mustache.tags); 607 | 608 | var scanner = new Scanner(template); 609 | 610 | var start, type, value, chr, token, openSection; 611 | while (!scanner.eos()) { 612 | start = scanner.pos; 613 | 614 | // Match any text between tags. 615 | value = scanner.scanUntil(openingTagRe); 616 | 617 | if (value) { 618 | for (var i = 0, valueLength = value.length; i < valueLength; ++i) { 619 | chr = value.charAt(i); 620 | 621 | if (isWhitespace(chr)) { 622 | spaces.push(tokens.length); 623 | } else { 624 | nonSpace = true; 625 | } 626 | 627 | tokens.push([ 'text', chr, start, start + 1 ]); 628 | start += 1; 629 | 630 | // Check for whitespace on the current line. 631 | if (chr === '\n') 632 | stripSpace(); 633 | } 634 | } 635 | 636 | // Match the opening tag. 637 | if (!scanner.scan(openingTagRe)) 638 | break; 639 | 640 | hasTag = true; 641 | 642 | // Get the tag type. 643 | type = scanner.scan(tagRe) || 'name'; 644 | scanner.scan(whiteRe); 645 | 646 | // Get the tag value. 647 | if (type === '=') { 648 | value = scanner.scanUntil(equalsRe); 649 | scanner.scan(equalsRe); 650 | scanner.scanUntil(closingTagRe); 651 | } else if (type === '{') { 652 | value = scanner.scanUntil(closingCurlyRe); 653 | scanner.scan(curlyRe); 654 | scanner.scanUntil(closingTagRe); 655 | type = '&'; 656 | } else { 657 | value = scanner.scanUntil(closingTagRe); 658 | } 659 | 660 | // Match the closing tag. 661 | if (!scanner.scan(closingTagRe)) 662 | throw new Error('Unclosed tag at ' + scanner.pos); 663 | 664 | token = [ type, value, start, scanner.pos ]; 665 | tokens.push(token); 666 | 667 | if (type === '#' || type === '^') { 668 | sections.push(token); 669 | } else if (type === '/') { 670 | // Check section nesting. 671 | openSection = sections.pop(); 672 | 673 | if (!openSection) 674 | throw new Error('Unopened section "' + value + '" at ' + start); 675 | 676 | if (openSection[1] !== value) 677 | throw new Error('Unclosed section "' + openSection[1] + '" at ' + start); 678 | } else if (type === 'name' || type === '{' || type === '&') { 679 | nonSpace = true; 680 | } else if (type === '=') { 681 | // Set the tags for the next time around. 682 | compileTags(value); 683 | } 684 | } 685 | 686 | // Make sure there are no open sections when we're done. 687 | openSection = sections.pop(); 688 | 689 | if (openSection) 690 | throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos); 691 | 692 | return nestTokens(squashTokens(tokens)); 693 | } 694 | 695 | /** 696 | * Combines the values of consecutive text tokens in the given `tokens` array 697 | * to a single token. 698 | */ 699 | function squashTokens (tokens) { 700 | var squashedTokens = []; 701 | 702 | var token, lastToken; 703 | for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 704 | token = tokens[i]; 705 | 706 | if (token) { 707 | if (token[0] === 'text' && lastToken && lastToken[0] === 'text') { 708 | lastToken[1] += token[1]; 709 | lastToken[3] = token[3]; 710 | } else { 711 | squashedTokens.push(token); 712 | lastToken = token; 713 | } 714 | } 715 | } 716 | 717 | return squashedTokens; 718 | } 719 | 720 | /** 721 | * Forms the given array of `tokens` into a nested tree structure where 722 | * tokens that represent a section have two additional items: 1) an array of 723 | * all tokens that appear in that section and 2) the index in the original 724 | * template that represents the end of that section. 725 | */ 726 | function nestTokens (tokens) { 727 | var nestedTokens = []; 728 | var collector = nestedTokens; 729 | var sections = []; 730 | 731 | var token, section; 732 | for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 733 | token = tokens[i]; 734 | 735 | switch (token[0]) { 736 | case '#': 737 | case '^': 738 | collector.push(token); 739 | sections.push(token); 740 | collector = token[4] = []; 741 | break; 742 | case '/': 743 | section = sections.pop(); 744 | section[5] = token[2]; 745 | collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens; 746 | break; 747 | default: 748 | collector.push(token); 749 | } 750 | } 751 | 752 | return nestedTokens; 753 | } 754 | 755 | /** 756 | * A simple string scanner that is used by the template parser to find 757 | * tokens in template strings. 758 | */ 759 | function Scanner (string) { 760 | this.string = string; 761 | this.tail = string; 762 | this.pos = 0; 763 | } 764 | 765 | /** 766 | * Returns `true` if the tail is empty (end of string). 767 | */ 768 | Scanner.prototype.eos = function eos () { 769 | return this.tail === ''; 770 | }; 771 | 772 | /** 773 | * Tries to match the given regular expression at the current position. 774 | * Returns the matched text if it can match, the empty string otherwise. 775 | */ 776 | Scanner.prototype.scan = function scan (re) { 777 | var match = this.tail.match(re); 778 | 779 | if (!match || match.index !== 0) 780 | return ''; 781 | 782 | var string = match[0]; 783 | 784 | this.tail = this.tail.substring(string.length); 785 | this.pos += string.length; 786 | 787 | return string; 788 | }; 789 | 790 | /** 791 | * Skips all text until the given regular expression can be matched. Returns 792 | * the skipped string, which is the entire tail if no match can be made. 793 | */ 794 | Scanner.prototype.scanUntil = function scanUntil (re) { 795 | var index = this.tail.search(re), match; 796 | 797 | switch (index) { 798 | case -1: 799 | match = this.tail; 800 | this.tail = ''; 801 | break; 802 | case 0: 803 | match = ''; 804 | break; 805 | default: 806 | match = this.tail.substring(0, index); 807 | this.tail = this.tail.substring(index); 808 | } 809 | 810 | this.pos += match.length; 811 | 812 | return match; 813 | }; 814 | 815 | /** 816 | * Represents a rendering context by wrapping a view object and 817 | * maintaining a reference to the parent context. 818 | */ 819 | function Context (view, parentContext) { 820 | this.view = view; 821 | this.cache = { '.': this.view }; 822 | this.parent = parentContext; 823 | } 824 | 825 | /** 826 | * Creates a new context using the given view with this context 827 | * as the parent. 828 | */ 829 | Context.prototype.push = function push (view) { 830 | return new Context(view, this); 831 | }; 832 | 833 | /** 834 | * Returns the value of the given name in this context, traversing 835 | * up the context hierarchy if the value is absent in this context's view. 836 | */ 837 | Context.prototype.lookup = function lookup (name) { 838 | var cache = this.cache; 839 | 840 | var value; 841 | if (cache.hasOwnProperty(name)) { 842 | value = cache[name]; 843 | } else { 844 | var context = this, names, index, lookupHit = false; 845 | 846 | while (context) { 847 | if (name.indexOf('.') > 0) { 848 | value = context.view; 849 | names = name.split('.'); 850 | index = 0; 851 | 852 | /** 853 | * Using the dot notion path in `name`, we descend through the 854 | * nested objects. 855 | * 856 | * To be certain that the lookup has been successful, we have to 857 | * check if the last object in the path actually has the property 858 | * we are looking for. We store the result in `lookupHit`. 859 | * 860 | * This is specially necessary for when the value has been set to 861 | * `undefined` and we want to avoid looking up parent contexts. 862 | **/ 863 | while (value != null && index < names.length) { 864 | if (index === names.length - 1) 865 | lookupHit = hasProperty(value, names[index]); 866 | 867 | value = value[names[index++]]; 868 | } 869 | } else { 870 | value = context.view[name]; 871 | lookupHit = hasProperty(context.view, name); 872 | } 873 | 874 | if (lookupHit) 875 | break; 876 | 877 | context = context.parent; 878 | } 879 | 880 | cache[name] = value; 881 | } 882 | 883 | if (isFunction(value)) 884 | value = value.call(this.view); 885 | 886 | return value; 887 | }; 888 | 889 | /** 890 | * A Writer knows how to take a stream of tokens and render them to a 891 | * string, given a context. It also maintains a cache of templates to 892 | * avoid the need to parse the same template twice. 893 | */ 894 | function Writer () { 895 | this.cache = {}; 896 | } 897 | 898 | /** 899 | * Clears all cached templates in this writer. 900 | */ 901 | Writer.prototype.clearCache = function clearCache () { 902 | this.cache = {}; 903 | }; 904 | 905 | /** 906 | * Parses and caches the given `template` and returns the array of tokens 907 | * that is generated from the parse. 908 | */ 909 | Writer.prototype.parse = function parse (template, tags) { 910 | var cache = this.cache; 911 | var tokens = cache[template]; 912 | 913 | if (tokens == null) 914 | tokens = cache[template] = parseTemplate(template, tags); 915 | 916 | return tokens; 917 | }; 918 | 919 | /** 920 | * High-level method that is used to render the given `template` with 921 | * the given `view`. 922 | * 923 | * The optional `partials` argument may be an object that contains the 924 | * names and templates of partials that are used in the template. It may 925 | * also be a function that is used to load partial templates on the fly 926 | * that takes a single argument: the name of the partial. 927 | */ 928 | Writer.prototype.render = function render (template, view, partials) { 929 | var tokens = this.parse(template); 930 | var context = (view instanceof Context) ? view : new Context(view); 931 | return this.renderTokens(tokens, context, partials, template); 932 | }; 933 | 934 | /** 935 | * Low-level method that renders the given array of `tokens` using 936 | * the given `context` and `partials`. 937 | * 938 | * Note: The `originalTemplate` is only ever used to extract the portion 939 | * of the original template that was contained in a higher-order section. 940 | * If the template doesn't use higher-order sections, this argument may 941 | * be omitted. 942 | */ 943 | Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate) { 944 | var buffer = ''; 945 | 946 | var token, symbol, value; 947 | for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 948 | value = undefined; 949 | token = tokens[i]; 950 | symbol = token[0]; 951 | 952 | if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate); 953 | else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate); 954 | else if (symbol === '>') value = this.renderPartial(token, context, partials, originalTemplate); 955 | else if (symbol === '&') value = this.unescapedValue(token, context); 956 | else if (symbol === 'name') value = this.escapedValue(token, context); 957 | else if (symbol === 'text') value = this.rawValue(token); 958 | 959 | if (value !== undefined) 960 | buffer += value; 961 | } 962 | 963 | return buffer; 964 | }; 965 | 966 | Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate) { 967 | var self = this; 968 | var buffer = ''; 969 | var value = context.lookup(token[1]); 970 | 971 | // This function is used to render an arbitrary template 972 | // in the current context by higher-order sections. 973 | function subRender (template) { 974 | return self.render(template, context, partials); 975 | } 976 | 977 | if (!value) return; 978 | 979 | if (isArray(value)) { 980 | for (var j = 0, valueLength = value.length; j < valueLength; ++j) { 981 | buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate); 982 | } 983 | } else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') { 984 | buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate); 985 | } else if (isFunction(value)) { 986 | if (typeof originalTemplate !== 'string') 987 | throw new Error('Cannot use higher-order sections without the original template'); 988 | 989 | // Extract the portion of the original template that the section contains. 990 | value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender); 991 | 992 | if (value != null) 993 | buffer += value; 994 | } else { 995 | buffer += this.renderTokens(token[4], context, partials, originalTemplate); 996 | } 997 | return buffer; 998 | }; 999 | 1000 | Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate) { 1001 | var value = context.lookup(token[1]); 1002 | 1003 | // Use JavaScript's definition of falsy. Include empty arrays. 1004 | // See https://github.com/janl/mustache.js/issues/186 1005 | if (!value || (isArray(value) && value.length === 0)) 1006 | return this.renderTokens(token[4], context, partials, originalTemplate); 1007 | }; 1008 | 1009 | Writer.prototype.renderPartial = function renderPartial (token, context, partials) { 1010 | if (!partials) return; 1011 | 1012 | var value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; 1013 | if (value != null) 1014 | return this.renderTokens(this.parse(value), context, partials, value); 1015 | }; 1016 | 1017 | Writer.prototype.unescapedValue = function unescapedValue (token, context) { 1018 | var value = context.lookup(token[1]); 1019 | if (value != null) 1020 | return value; 1021 | }; 1022 | 1023 | Writer.prototype.escapedValue = function escapedValue (token, context) { 1024 | var value = context.lookup(token[1]); 1025 | if (value != null) 1026 | return mustache.escape(value); 1027 | }; 1028 | 1029 | Writer.prototype.rawValue = function rawValue (token) { 1030 | return token[1]; 1031 | }; 1032 | 1033 | mustache.name = 'mustache.js'; 1034 | mustache.version = '2.2.1'; 1035 | mustache.tags = [ '{{', '}}' ]; 1036 | 1037 | // All high-level mustache.* functions use this writer. 1038 | var defaultWriter = new Writer(); 1039 | 1040 | /** 1041 | * Clears all cached templates in the default writer. 1042 | */ 1043 | mustache.clearCache = function clearCache () { 1044 | return defaultWriter.clearCache(); 1045 | }; 1046 | 1047 | /** 1048 | * Parses and caches the given template in the default writer and returns the 1049 | * array of tokens it contains. Doing this ahead of time avoids the need to 1050 | * parse templates on the fly as they are rendered. 1051 | */ 1052 | mustache.parse = function parse (template, tags) { 1053 | return defaultWriter.parse(template, tags); 1054 | }; 1055 | 1056 | /** 1057 | * Renders the `template` with the given `view` and `partials` using the 1058 | * default writer. 1059 | */ 1060 | mustache.render = function render (template, view, partials) { 1061 | if (typeof template !== 'string') { 1062 | throw new TypeError('Invalid template! Template should be a "string" ' + 1063 | 'but "' + typeStr(template) + '" was given as the first ' + 1064 | 'argument for mustache#render(template, view, partials)'); 1065 | } 1066 | 1067 | return defaultWriter.render(template, view, partials); 1068 | }; 1069 | 1070 | // This is here for backwards compatibility with 0.4.x., 1071 | /*eslint-disable */ // eslint wants camel cased function name 1072 | mustache.to_html = function to_html (template, view, partials, send) { 1073 | /*eslint-enable*/ 1074 | 1075 | var result = mustache.render(template, view, partials); 1076 | 1077 | if (isFunction(send)) { 1078 | send(result); 1079 | } else { 1080 | return result; 1081 | } 1082 | }; 1083 | 1084 | // Export the escaping function so that the user may override it. 1085 | // See https://github.com/janl/mustache.js/issues/244 1086 | mustache.escape = escapeHtml; 1087 | 1088 | // Export these mainly for testing, but also for advanced usage. 1089 | mustache.Scanner = Scanner; 1090 | mustache.Context = Context; 1091 | mustache.Writer = Writer; 1092 | 1093 | })); 1094 | 1095 | },{}]},{},[14]); 1096 | -------------------------------------------------------------------------------- /resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | WDA-Inspector 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 31 | 32 |
    33 |
    34 |
    35 |
    36 |
    37 |
    38 |
    39 |
    40 |
    41 |
    42 |
    43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /resources/wda-inspector/readme.md: -------------------------------------------------------------------------------- 1 | ## Сборка 2 | 3 | Для сборки проекта необходим [npm](https://www.npmjs.com/). 4 | 5 | ``` 6 | resources/wda-inspector/src/build.sh 7 | ``` 8 | -------------------------------------------------------------------------------- /resources/wda-inspector/src/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /resources/wda-inspector/src/Info/Info.js: -------------------------------------------------------------------------------- 1 | var Mustache = require('mustache'); 2 | var tpl = { 3 | info: require('./tpl/info.html'), 4 | error: require('./tpl/error.html') 5 | }; 6 | 7 | var Info = function($el) { 8 | 9 | var _previousColor; 10 | 11 | var _render = function($content) { 12 | $el 13 | .empty() 14 | .append($content); 15 | }; 16 | 17 | var _blink = function(color) { 18 | $el 19 | .stop() 20 | .animate({ 21 | 'background-color': color 22 | }, 100) 23 | .animate({ 24 | 'background-color': _previousColor 25 | }, 500) 26 | }; 27 | 28 | this.update = function(info) { 29 | var $content = $(Mustache.render(tpl.info, {info: info})); 30 | _render($content); 31 | _blink('rgba(250, 255, 189, 0.8)'); 32 | }; 33 | 34 | this.error = function(message) { 35 | var $content = $(Mustache.render(tpl.error, {message: message})); 36 | _render($content); 37 | _blink('rgba(255, 150, 150, 0.8)'); 38 | }; 39 | 40 | // INIT 41 | (function() { 42 | _previousColor = $el.css('background-color'); 43 | })(); 44 | 45 | }; 46 | 47 | module.exports = Info; -------------------------------------------------------------------------------- /resources/wda-inspector/src/Info/main.css: -------------------------------------------------------------------------------- 1 | .wda_info_content { 2 | max-width: 300px; 3 | overflow: auto; 4 | } -------------------------------------------------------------------------------- /resources/wda-inspector/src/Info/tpl/error.html: -------------------------------------------------------------------------------- 1 |
    {{message}}
    -------------------------------------------------------------------------------- /resources/wda-inspector/src/Info/tpl/info.html: -------------------------------------------------------------------------------- 1 |
    2 | Class {{info.type}}
    3 | Name {{info.name}}
    4 | Label {{info.label}}
    5 | Value {{info.value}}
    6 | Rect {{info.frame}}
    7 | isEnabled {{info.isEnabled}}
    8 | isVisible {{info.isVisible}}
    9 |
    10 | -------------------------------------------------------------------------------- /resources/wda-inspector/src/Screen/Screen.js: -------------------------------------------------------------------------------- 1 | var Mustache = require('mustache'); 2 | var tpl = { 3 | highlight: require('./tpl/highlight.html'), 4 | lockOverlay: require('./tpl/lockOverlay.html'), 5 | error: require('./tpl/error.html') 6 | }; 7 | 8 | var Screen = function($el) { 9 | 10 | var 11 | _this = this, 12 | _selection = { 13 | x: 0, 14 | y: 0, 15 | w: 0, 16 | h: 0 17 | }, 18 | _$highlight, 19 | _$lockOverlay; 20 | 21 | var _render = function($content) { 22 | $el 23 | .empty() 24 | .append($content, _$highlight, _$lockOverlay); 25 | }; 26 | 27 | // Заблокировать 28 | // Например для ожидания загрузки снимка экрана 29 | this.lock = function() { 30 | _$lockOverlay.show(); 31 | }; 32 | 33 | // Разблокировать 34 | this.unlock = function() { 35 | _$lockOverlay.hide(); 36 | }; 37 | 38 | // Обновить изображение 39 | this.update = function(src) { 40 | var img = new Image(); 41 | img.src = 'data:image/png;base64,' + src; 42 | var $content = $(img); 43 | 44 | img.onload = function () { 45 | // когда картинка загрузится, масштабируем её 46 | $content.css({ 47 | width: Math.round(img.width * 0.5) + 'px', 48 | height: Math.round(img.height * 0.5) + 'px' 49 | }); 50 | _render($content); 51 | } 52 | }; 53 | 54 | // Вывести сообщение об ошибке 55 | this.error = function(message) 56 | { 57 | var $content = $(Mustache.render(tpl.error, {message: message})); 58 | _render($content); 59 | }; 60 | 61 | // Подсветить область 62 | this.highlight = function(x, y, w, h) { 63 | _$highlight.css({ 64 | left: x + 'px', 65 | top: y + 'px', 66 | width: w + 'px', 67 | height: h + 'px' 68 | }); 69 | }; 70 | 71 | // Подсветить последнюю выбранную область 72 | this.highlightSelection = function() { 73 | _this.highlight( 74 | _selection.x, 75 | _selection.y, 76 | _selection.w, 77 | _selection.h 78 | ); 79 | }; 80 | 81 | // Выбрать область 82 | this.select = function(x, y, w, h) { 83 | _selection.x = x; 84 | _selection.y = y; 85 | _selection.w = w; 86 | _selection.h = h; 87 | }; 88 | 89 | // INIT 90 | (function() { 91 | _$highlight = $(tpl.highlight); 92 | _$lockOverlay = $(tpl.lockOverlay); 93 | })(); 94 | 95 | }; 96 | 97 | module.exports = Screen; -------------------------------------------------------------------------------- /resources/wda-inspector/src/Screen/main.css: -------------------------------------------------------------------------------- 1 | .wda_screen_highlight { 2 | background-color: rgba(255, 0, 0, 0.3); 3 | position: absolute; 4 | } -------------------------------------------------------------------------------- /resources/wda-inspector/src/Screen/tpl/error.html: -------------------------------------------------------------------------------- 1 |
    2 | {{message}} 3 |
    -------------------------------------------------------------------------------- /resources/wda-inspector/src/Screen/tpl/highlight.html: -------------------------------------------------------------------------------- 1 |
    -------------------------------------------------------------------------------- /resources/wda-inspector/src/Screen/tpl/lockOverlay.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    -------------------------------------------------------------------------------- /resources/wda-inspector/src/Search/Search.js: -------------------------------------------------------------------------------- 1 | var tpl = { 2 | form: require('./tpl/form.html') 3 | }; 4 | 5 | var Search = function($el, options) { 6 | 7 | var _isLocked = false; 8 | 9 | var _render = function($content) { 10 | $el 11 | .empty() 12 | .append($content); 13 | }; 14 | 15 | var _lock = function() { 16 | if (_isLocked) { 17 | return false; 18 | } 19 | 20 | $el 21 | .find('input') 22 | .attr('readonly', 'readonly'); 23 | _isLocked = true; 24 | 25 | return true; 26 | }; 27 | 28 | var _unlock = function() { 29 | $el 30 | .find('input') 31 | .removeAttr('readonly'); 32 | _isLocked = false; 33 | }; 34 | 35 | // INIT 36 | (function() { 37 | var $form = $(tpl.form); 38 | $form.on('submit', function() { 39 | if (_lock()) { 40 | var locator = $(this).find('input[name="value"]').val(); 41 | $.ajax({ 42 | method: 'POST', 43 | url: options.url, 44 | data: $(this).serialize(), 45 | dataType: 'json', 46 | success: options.success, 47 | error: function(jqXHR) { 48 | if (jqXHR.status === 400) { 49 | options.notFound(locator); 50 | } else { 51 | options.error(locator); 52 | } 53 | }, 54 | complete: function() { 55 | _unlock(); 56 | } 57 | }); 58 | } 59 | 60 | return false; 61 | }); 62 | _render($form); 63 | })(); 64 | 65 | }; 66 | 67 | module.exports = Search; -------------------------------------------------------------------------------- /resources/wda-inspector/src/Search/tpl/form.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/wda-inspector/src/Tree/Tree.js: -------------------------------------------------------------------------------- 1 | var Mustache = require('mustache'); 2 | var tpl = { 3 | item: require('./tpl/item.html'), 4 | lockOverlay: require('./tpl/lockOverlay.html'), 5 | error: require('./tpl/error.html') 6 | }; 7 | 8 | var Tree = function($el) { 9 | 10 | var 11 | _$lockOverlay, 12 | _onElementSelect = function() {}, 13 | _onElementFocus = function() {}, 14 | _onElementBlur = function() {}; 15 | 16 | var _buildList = function(elements) { 17 | var $list = $('
      '); 18 | for (var i = 0; i < elements.length; ++i) { 19 | var item = elements[i]; 20 | item.hasChildren = item.children? true : false; 21 | item.rectStr = JSON.stringify(item.rect); 22 | var 23 | $li = $('
    • '), 24 | $item = $(Mustache.render(tpl.item, item)); 25 | 26 | $li.on('mouseenter.wda-inspector', '.el-type', item.rect, function(e) { 27 | _onElementFocus(e.data); 28 | 29 | return false; 30 | }); 31 | $li.on('mouseleave.wda-inspector', '.el-type', function(e) { 32 | _onElementBlur(e.data); 33 | 34 | return false; 35 | }); 36 | $li.on('click.wda-inspector', '.el-type', item, function(e) { 37 | $el 38 | .find(".el-type.label-primary") 39 | .removeClass("label-primary") 40 | .addClass("label-default"); 41 | $(this) 42 | .removeClass("label-default") 43 | .addClass("label-primary"); 44 | 45 | _onElementSelect(e.data, e.data.rect); 46 | 47 | return false; 48 | }); 49 | 50 | $li.append($item); 51 | 52 | if (item.children) { 53 | $li.append(_buildList(item.children)); 54 | } 55 | 56 | $list.append($li); 57 | } 58 | 59 | $list.on("click", ".element-with-children", function () { 60 | var $this = $(this); 61 | if ($this.hasClass("glyphicon-minus")) { 62 | $this 63 | .removeClass("glyphicon-minus") 64 | .addClass("glyphicon-plus") 65 | .closest("li") 66 | .children("ul") 67 | .css("display", "none"); 68 | } else { 69 | $this 70 | .removeClass("glyphicon-plus") 71 | .addClass("glyphicon-minus") 72 | .closest("li") 73 | .children("ul") 74 | .css("display", "block"); 75 | } 76 | 77 | return false; 78 | }); 79 | 80 | return $list; 81 | }; 82 | 83 | var _render = function($content) { 84 | $el 85 | .empty() 86 | .append($content, _$lockOverlay); 87 | }; 88 | 89 | // Заблокировать 90 | this.lock = function() { 91 | _$lockOverlay.show(); 92 | }; 93 | 94 | // Разблокировать 95 | this.unlock = function() { 96 | _$lockOverlay.hide(); 97 | }; 98 | 99 | // Вывести сообщение об ошибке 100 | this.error = function(message) { 101 | var $content = $(Mustache.render(tpl.error, {message: message})); 102 | _render($content); 103 | }; 104 | 105 | this.update = function(elements) { 106 | var $list = _buildList(elements.children); 107 | _render($list); 108 | }; 109 | 110 | this.select = function(rect, type) { 111 | $el 112 | .find(".el-type[data-rect='" + JSON.stringify(rect) + "'] > :contains('[" + type + "]')") 113 | .click(); 114 | }; 115 | 116 | // Назначить обработчик на фокус элемента 117 | this.onElementFocus = function(handler) { 118 | _onElementFocus = handler; 119 | 120 | }; 121 | 122 | // Назначить обработчик на блюр элемента 123 | this.onElementBlur = function(handler) { 124 | _onElementBlur = handler; 125 | }; 126 | 127 | // Назначить обработчик на выбор элемента 128 | this.onElementSelect = function(handler) { 129 | _onElementSelect = handler; 130 | }; 131 | 132 | // INIT 133 | (function() { 134 | _$lockOverlay = $(tpl.lockOverlay); 135 | })(); 136 | 137 | }; 138 | 139 | module.exports = Tree; -------------------------------------------------------------------------------- /resources/wda-inspector/src/Tree/main.css: -------------------------------------------------------------------------------- 1 | .wda_tree ul { 2 | list-style: none; 3 | padding: 0 0 0 20px; 4 | margin: 0 0 10px 10px; 5 | } 6 | 7 | .wda_tree ul ul { 8 | border-left: dotted 1px #ccc; 9 | } -------------------------------------------------------------------------------- /resources/wda-inspector/src/Tree/tpl/error.html: -------------------------------------------------------------------------------- 1 |
      2 | {{message}} 3 |
      -------------------------------------------------------------------------------- /resources/wda-inspector/src/Tree/tpl/item.html: -------------------------------------------------------------------------------- 1 | {{#hasChildren}} 2 | 3 | {{/hasChildren}} 4 | 5 | [{{type}}] 6 | 7 | {{#rawIdentifier}} 8 | {{rawIdentifier}} 9 | {{/rawIdentifier}} 10 | {{label}} -------------------------------------------------------------------------------- /resources/wda-inspector/src/Tree/tpl/lockOverlay.html: -------------------------------------------------------------------------------- 1 |
      2 |
      3 |
      -------------------------------------------------------------------------------- /resources/wda-inspector/src/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd "$( dirname "${BASH_SOURCE[0]}" )" 4 | 5 | npm update\ 6 | && node_modules/browserify/bin/cmd.js -t [ stringify ] main.js -o ../../static/wda-inspector/main.js \ 7 | && node_modules/postcss-cli/bin/postcss -u postcss-import main.css > ../../static/wda-inspector/main.css 8 | 9 | echo 'done' -------------------------------------------------------------------------------- /resources/wda-inspector/src/main.css: -------------------------------------------------------------------------------- 1 | @import './Info/main.css'; 2 | @import './Screen/main.css'; 3 | @import './Tree/main.css'; 4 | 5 | .wda_container { 6 | padding: 60px 0 0; 7 | position: relative; 8 | } 9 | .wda_info { 10 | padding: 60px 0 0; 11 | position: absolute; 12 | top: 0; 13 | right: 0; 14 | } 15 | .wda_info_container { 16 | padding: 10px; 17 | min-height: 200px; 18 | min-width: 200px; 19 | text-align: center; 20 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 21 | background-color: rgba(255, 255, 255, 0.8); 22 | } 23 | .wda_screen { 24 | padding: 10px; 25 | min-width: 300px; 26 | min-height: 500px; 27 | float: left; 28 | } 29 | .wda_screen_container { 30 | position: relative; 31 | } 32 | .wda_tree { 33 | padding: 10px; 34 | overflow: hidden; 35 | } 36 | .wda_tree_container { 37 | height: 500px; 38 | overflow: auto; 39 | } -------------------------------------------------------------------------------- /resources/wda-inspector/src/main.js: -------------------------------------------------------------------------------- 1 | var Screen = require('./Screen/Screen.js'); 2 | var Tree = require('./Tree/Tree.js'); 3 | var Info = require('./Info/Info.js'); 4 | var Search = require('./Search/Search.js'); 5 | 6 | $(function () { 7 | 8 | var screen = new Screen($('.wda_screen_container')); 9 | $.ajax({ 10 | method: 'get', 11 | url: '/screenshot', 12 | dataType: 'json', 13 | beforeSend: function() { 14 | screen.lock(); 15 | }, 16 | complete: function() { 17 | screen.unlock(); 18 | }, 19 | success: function(data) { 20 | screen.update(data.img); 21 | }, 22 | error: function() { 23 | screen.error('Не удалось загрузить экран'); 24 | } 25 | }); 26 | 27 | var info = new Info($('.wda_info_container')); 28 | 29 | var tree = new Tree($('.wda_tree_container')); 30 | tree.onElementFocus(function(rect) { 31 | screen.highlight( 32 | rect.x, 33 | rect.y, 34 | rect.width, 35 | rect.height 36 | ); 37 | }); 38 | tree.onElementBlur(screen.highlightSelection); 39 | tree.onElementSelect(function(infoData, rect) { 40 | screen.select( 41 | rect.x, 42 | rect.y, 43 | rect.width, 44 | rect.height 45 | ); 46 | screen.highlightSelection(); 47 | info.update(infoData); 48 | }); 49 | $.ajax({ 50 | method: 'get', 51 | url: '/source', 52 | dataType: 'json', 53 | beforeSend: function() { 54 | tree.lock(); 55 | }, 56 | complete: function() { 57 | tree.unlock(); 58 | }, 59 | success: function(data) { 60 | tree.update(data.tree); 61 | }, 62 | error: function() { 63 | tree.error('Не удалось загрузить дерево элементов'); 64 | } 65 | }); 66 | 67 | var search = new Search($('#navbar'), { 68 | url: '/find', 69 | success: function(data) { 70 | tree.select(data.value, data.type); // todo надо бы id 71 | }, 72 | notFound: function(locator) { 73 | info.error(locator + ' not found!'); 74 | }, 75 | error: function(locator) { 76 | info.error('Wrong locator ' + locator); 77 | } 78 | }); 79 | 80 | }); 81 | -------------------------------------------------------------------------------- /resources/wda-inspector/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wda-inspector", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "main.js", 6 | "devDependencies": { 7 | "browserify": "^13.1.0", 8 | "postcss-cli": "^2.6.0", 9 | "postcss-import": "^8.1.2", 10 | "stringify": "^5.1.0" 11 | }, 12 | "dependencies": { 13 | "mustache": "^2.2.1" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/qa-dev/go-core/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /vendor/github.com/qa-dev/go-core/color/color.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import "fmt" 4 | 5 | type TypeColor string 6 | 7 | const ( 8 | Black TypeColor = "\x1b[30m" 9 | Red TypeColor = "\x1b[31m" 10 | Green TypeColor = "\x1b[32m" 11 | Yellow TypeColor = "\x1b[33m" 12 | Blue TypeColor = "\x1b[34m" 13 | Magenta TypeColor = "\x1b[35m" 14 | Cyan TypeColor = "\x1b[36m" 15 | White TypeColor = "\x1b[37m" 16 | Default TypeColor = "\x1b[39m" 17 | LightGray TypeColor = "\x1b[90m" 18 | LightRed TypeColor = "\x1b[91m" 19 | LightGreen TypeColor = "\x1b[92m" 20 | LightYellow TypeColor = "\x1b[93m" 21 | LightBlue TypeColor = "\x1b[94m" 22 | LightMagenta TypeColor = "\x1b[95m" 23 | LightCyan TypeColor = "\x1b[96m" 24 | LightWhite TypeColor = "\x1b[97m" 25 | ) 26 | 27 | var def TypeColor = Default 28 | 29 | func Color(c TypeColor, s string) string { 30 | return fmt.Sprintf("%s%s%s", c, s, DefColor()) 31 | } 32 | 33 | func ColorN(c TypeColor, s string) string { 34 | return Color(c, s) + "\n" 35 | } 36 | 37 | func SetDefColor(c TypeColor) { 38 | def = c 39 | } 40 | 41 | func DefColor() TypeColor { 42 | return def 43 | } 44 | -------------------------------------------------------------------------------- /vendor/github.com/qa-dev/go-core/log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "github.com/qa-dev/go-core/color" 5 | "log" 6 | ) 7 | 8 | func Info(format string, a ...interface{}) { 9 | format = color.Color(color.Blue, "INFO: ")+format 10 | log.Printf(format, a...) 11 | } 12 | 13 | func Fatal(format string, a ...interface{}) { 14 | format = color.Color(color.Red, "FATAL: ")+format 15 | log.Fatalf(format, a...) 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/qa-dev/go-core/middleware/base.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/qa-dev/go-core/log" 5 | "net/http" 6 | "runtime/debug" 7 | ) 8 | 9 | func New(h http.Handler) http.Handler { 10 | return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { 11 | defer func() { 12 | if err := recover(); err != nil { 13 | log.Fatal("Panic: %+v\n%s", err, debug.Stack()) 14 | } 15 | }() 16 | 17 | lrw := &LoggedResponseWriter{responseWriter: resp} 18 | 19 | h.ServeHTTP(lrw, req) 20 | log.Info("%v %v %v (%v)", 21 | lrw.Status(), req.Method, req.URL.Path, req.RemoteAddr) 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/qa-dev/go-core/middleware/response_writer.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | // LoggedResponseWriter оборачивает http.ResponseWriter 8 | // Поддерживает возможность чтения ранее записанного статуса ответа 9 | type LoggedResponseWriter struct { 10 | responseWriter http.ResponseWriter 11 | status int 12 | } 13 | 14 | // Header возвращает результат вызова метода Header() оборачиваемого http.ResponseWriter 15 | func (lrw *LoggedResponseWriter) Header() http.Header { 16 | return lrw.responseWriter.Header() 17 | } 18 | 19 | // Write возвращает результат вызова метода Write() оборачиваемого http.ResponseWriter 20 | func (lrw *LoggedResponseWriter) Write(data []byte) (int, error) { 21 | return lrw.responseWriter.Write(data) 22 | } 23 | 24 | // WriteHeader возвращает результат вызова метода WriteHeader() оборачиваемого http.ResponseWriter 25 | func (lrw *LoggedResponseWriter) WriteHeader(status int) { 26 | lrw.status = status 27 | lrw.responseWriter.WriteHeader(status) 28 | } 29 | 30 | // Status возвращает ранее записанный статус ответа 31 | func (lrw *LoggedResponseWriter) Status() int { 32 | return lrw.status 33 | } 34 | 35 | // ResponseWriter возвращает оборочиваемый ResponseWriter 36 | func (lrw *LoggedResponseWriter) ResponseWriter() http.ResponseWriter { 37 | return lrw.responseWriter 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/qa-dev/go-core/response/json.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | // Ответ обернутый в json 9 | func Json(w http.ResponseWriter, data interface{}, code int) { 10 | w.Header().Set("Content-Type", "text/json; charset=utf-8") 11 | w.WriteHeader(code) 12 | 13 | body, err := json.Marshal(data) 14 | if err != nil { 15 | body = []byte( 16 | `{"error": "Unknown error in encoding json!"}`) 17 | } 18 | 19 | w.Write(body) 20 | } 21 | -------------------------------------------------------------------------------- /wda/client.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "io/ioutil" 7 | "net/http" 8 | ) 9 | 10 | const ( 11 | StatusOK = 0 12 | ) 13 | 14 | type Client struct { 15 | ip string 16 | port string 17 | bundleId string 18 | } 19 | 20 | func NewClient(ip string, port string, bundleId string) *Client { 21 | return &Client{ip: ip, port: port, bundleId: bundleId} 22 | } 23 | 24 | func (c *Client) BundleId() string { 25 | return c.bundleId 26 | } 27 | 28 | func (c *Client) url(uri string) string { 29 | return "http://" + c.ip + ":" + c.port + uri 30 | } 31 | 32 | func (c *Client) get(uri string) ([]byte, error) { 33 | r, err := http.Get(c.url(uri)) 34 | return c.resonseProcess(r, err) 35 | } 36 | 37 | func (c *Client) post(uri string, data []byte) ([]byte, error) { 38 | r, err := http.Post(c.url(uri), "application/ajax", bytes.NewBuffer(data)) 39 | return c.resonseProcess(r, err) 40 | } 41 | 42 | func (c *Client) resonseProcess(r *http.Response, err error) ([]byte, error) { 43 | if err != nil { 44 | return nil, err 45 | } 46 | defer r.Body.Close() 47 | if r.StatusCode != http.StatusOK { 48 | return nil, errors.New("Bad status from inspector: " + r.Status) 49 | } 50 | res, err := ioutil.ReadAll(r.Body) 51 | if err != nil { 52 | return nil, err 53 | } 54 | return res, nil 55 | } 56 | -------------------------------------------------------------------------------- /wda/find.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type FindSuccessResponse struct { 9 | Value struct { 10 | ElementId string `json:"ELEMENT"` 11 | Type string `json:"type"` 12 | } `json:"value"` 13 | Status int 14 | } 15 | 16 | type FindErrorResponse struct { 17 | Value struct { 18 | Using string `json:"using"` 19 | Value string `json:"value"` 20 | Description string `json:"description"` 21 | } `json:"value"` 22 | Status int 23 | } 24 | 25 | type FindRequest struct { 26 | Using string `json:"using"` 27 | Value string `json:"value"` 28 | } 29 | 30 | func (c *Client) Find(using string, value string) (*FindSuccessResponse, error) { 31 | session, err := c.getSession() 32 | if err != nil { 33 | return nil, err 34 | } 35 | findReq := FindRequest{Using: using, Value: value} 36 | reqBody, err := json.Marshal(findReq) 37 | if err != nil { 38 | return nil, err 39 | } 40 | res, err := c.post("/session/"+session+"/element", reqBody) 41 | if err != nil { 42 | return nil, err 43 | } 44 | var findResp *FindSuccessResponse 45 | err = json.Unmarshal(res, &findResp) 46 | if err != nil { 47 | return nil, err 48 | } 49 | if findResp.Status != StatusOK { 50 | var findErrorResp *FindErrorResponse 51 | findErrorRespErr := json.Unmarshal(res, &findErrorResp) 52 | if findErrorRespErr == nil { 53 | return nil, fmt.Errorf("WDA returns error on finding element: %+v", findErrorResp) 54 | } 55 | } 56 | return findResp, nil 57 | } 58 | -------------------------------------------------------------------------------- /wda/gettext.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | ) 7 | 8 | type GetTextResponse struct { 9 | Value string `json:"value"` 10 | Status int `json:"status"` 11 | } 12 | 13 | func (c *Client) GetText(elementId string) (*GetTextResponse, error) { 14 | if elementId == "" { 15 | return nil, errors.New("Blank element id") 16 | } 17 | session, err := c.getSession() 18 | if err != nil { 19 | return nil, err 20 | } 21 | res, err := c.get("/session/" + session + "/element/" + elementId + "/text") 22 | if err != nil { 23 | return nil, err 24 | } 25 | var textResp GetTextResponse 26 | err = json.Unmarshal(res, &textResp) 27 | if err != nil { 28 | return nil, err 29 | } 30 | return &textResp, nil 31 | } 32 | -------------------------------------------------------------------------------- /wda/gettype.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | ) 7 | 8 | type GetTypeResponse struct { 9 | Value string `json:"value"` 10 | Status int `json:"status"` 11 | } 12 | 13 | func (c *Client) GetType(elementId string) (*GetTypeResponse, error) { 14 | if elementId == "" { 15 | return nil, errors.New("Blank element id") 16 | } 17 | session, err := c.getSession() 18 | if err != nil { 19 | return nil, err 20 | } 21 | res, err := c.get("/session/" + session + "/element/" + elementId + "/attribute/type") 22 | if err != nil { 23 | return nil, err 24 | } 25 | var typeResp GetTypeResponse 26 | err = json.Unmarshal(res, &typeResp) 27 | if err != nil { 28 | return nil, err 29 | } 30 | return &typeResp, nil 31 | } 32 | -------------------------------------------------------------------------------- /wda/rect.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type RectResponse struct { 8 | Value struct { 9 | X float32 `json:"x"` 10 | Y float32 `json:"y"` 11 | Width float32 `json:"width"` 12 | Height float32 `json:"height"` 13 | } `json:"value"` 14 | Status int `json:"status"` 15 | } 16 | 17 | func (c *Client) Rect(elId string) (*RectResponse, error) { 18 | session, err := c.getSession() 19 | if err != nil { 20 | return nil, err 21 | } 22 | res, err := c.get("/session/" + session + "/element/" + elId + "/rect") 23 | if err != nil { 24 | return nil, err 25 | } 26 | var rectResp *RectResponse 27 | err = json.Unmarshal(res, &rectResp) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return rectResp, nil 32 | } 33 | 34 | // IsInvalid проверяет, валидный ли элемент, если вдруг вместо нужного и 35 | // несуществующего элемента вернулся XCUIElementTypeElementOther, проверяя значения его /rect. 36 | // Если все нули – значит элемент не валиден 37 | func (r *RectResponse) IsInvalid() bool { 38 | return r.Value.Height == 0 && r.Value.Width == 0 && r.Value.X == 0 && r.Value.Y == 0 39 | } 40 | -------------------------------------------------------------------------------- /wda/screenshot.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type Screenshot struct { 8 | Value string `json:"value"` 9 | Status int `json:"status"` 10 | } 11 | 12 | func (c *Client) Screenshot() (*Screenshot, error) { 13 | res, err := c.get("/screenshot") 14 | if err != nil { 15 | return nil, err 16 | } 17 | var ss *Screenshot 18 | err = json.Unmarshal(res, &ss) 19 | if err != nil { 20 | return nil, err 21 | } 22 | return ss, nil 23 | } 24 | -------------------------------------------------------------------------------- /wda/session.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | ) 7 | 8 | type SessionResponse struct { 9 | Value struct { 10 | SessionId string `json:"sessionId"` 11 | } `json:"value"` 12 | Status int `json:"status"` 13 | } 14 | 15 | func (c *Client) session() (*SessionResponse, error) { 16 | req := make(map[string]map[string]string, 1) 17 | tmpMap := make(map[string]string, 1) 18 | tmpMap["bundleId"] = c.BundleId() 19 | req["desiredCapabilities"] = tmpMap 20 | reqRaw, err := json.Marshal(req) 21 | log.Printf(string(reqRaw)) 22 | if err != nil { 23 | return nil, err 24 | } 25 | res, err := c.post("/session", reqRaw) 26 | log.Printf(string(res)) 27 | if err != nil { 28 | return nil, err 29 | } 30 | var session *SessionResponse 31 | err = json.Unmarshal(res, &session) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return session, nil 36 | } 37 | 38 | func (c *Client) getSession() (string, error) { 39 | status, err := c.status() 40 | if err != nil { 41 | return "", err 42 | } 43 | if status.SessionId == "" { 44 | res, err := c.session() 45 | if err != nil { 46 | return "", err 47 | } 48 | return res.Value.SessionId, nil 49 | } else { 50 | return status.SessionId, nil 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /wda/source.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type ElementSource struct { 8 | IsEnabled string `json:"isEnabled"` 9 | IsVisible string `json:"isVisible"` 10 | Frame string `json:"frame"` 11 | Children []*ElementSource `json:"children"` 12 | Rect struct { 13 | X float32 `json:"x"` 14 | Y float32 `json:"y"` 15 | Width float32 `json:"width"` 16 | Height float32 `json:"height"` 17 | } `json:"rect"` 18 | Value interface{} `json:"value"` 19 | Label string `json:"label"` 20 | Type string `json:"type"` 21 | Name string `json:"name"` 22 | RawIdentifier string `json:"rawIdentifier"` 23 | } 24 | 25 | type Source struct { 26 | Value *ElementSource `json:"value"` 27 | Status int `json:"status"` 28 | } 29 | 30 | func (c *Client) Source() (*Source, error) { 31 | res, err := c.get("/source?format=json") 32 | if err != nil { 33 | return nil, err 34 | } 35 | var s *Source 36 | err = json.Unmarshal(res, &s) 37 | if err != nil { 38 | return nil, err 39 | } 40 | return s, nil 41 | } 42 | -------------------------------------------------------------------------------- /wda/status.go: -------------------------------------------------------------------------------- 1 | package wda 2 | 3 | import "encoding/json" 4 | 5 | type Status struct { 6 | SessionId string `json:"sessionId,omitempty"` 7 | Status int `json:"status"` 8 | } 9 | 10 | func (c *Client) status() (*Status, error) { 11 | res, err := c.get("/status") 12 | if err != nil { 13 | return nil, err 14 | } 15 | var s *Status 16 | err = json.Unmarshal(res, &s) 17 | if err != nil { 18 | return nil, err 19 | } 20 | return s, nil 21 | } 22 | --------------------------------------------------------------------------------