Repository: cidrblock/td4a Branch: master Commit: 54f992837722 Files: 45 Total size: 597.0 KB Directory structure: gitextract_n5xl74vk/ ├── .gitignore ├── Containerfile ├── LICENSE ├── MANIFEST.in ├── README.md ├── bower.json ├── gcp/ │ └── Dockerfile ├── gulpfile.js ├── my_ansible_inventory/ │ ├── group_vars/ │ │ ├── all/ │ │ │ └── vars.yml │ │ ├── routers/ │ │ │ └── vars.yml │ │ └── servers/ │ │ └── vars.yml │ ├── host_vars/ │ │ ├── router00/ │ │ │ └── vars.yml │ │ ├── server00/ │ │ │ └── vars.yml │ │ └── test00/ │ │ └── vars.yml │ └── inventory.yml ├── my_filter_plugins/ │ └── mask_convert.py ├── package.json ├── requirements.txt ├── setup.py ├── td4a/ │ ├── __init__.py │ ├── controllers/ │ │ ├── __init__.py │ │ ├── config.py │ │ ├── hosts.py │ │ ├── inventory.py │ │ ├── link.py │ │ ├── render.py │ │ ├── retrieve.py │ │ ├── schema.py │ │ └── validate.py │ ├── models/ │ │ ├── __init__.py │ │ ├── exception_handler.py │ │ ├── filters.py │ │ ├── inventory.py │ │ ├── sort_commented_map.py │ │ └── td4ayaml.py │ └── static/ │ ├── css/ │ │ ├── angular-material.css │ │ ├── app.css │ │ ├── codemirror.css │ │ ├── dialog.css │ │ └── material.css │ ├── data.yml │ ├── index.html │ ├── js/ │ │ └── app.js │ └── template.j2 └── td4a-server ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ bower_components node_modules *.pyc venv dist *.egg-info ================================================ FILE: Containerfile ================================================ FROM python:3.8.5-alpine3.12 # Update the packages RUN apk update # Install the ansible dependancies RUN apk add gcc libffi-dev musl-dev openssl-dev sshpass make # RUN apk add py-crypto python-dev # Install td4a RUN pip install td4a==2.0.3 # Clear out extras RUN rm -rf /var/cache/apk/* # Start td4a CMD [ "td4a-server" ] ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 Bradley A. Thornton Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ recursive-include td4a/static * recursive-include td4a/models * recursive-include td4a/controllers * global-exclude *.pyc ================================================ FILE: README.md ================================================ ![screenshot](screenshot.png) ## Template Designer for Automation ### Try it now https://td4a.codethenetwork.com ### Overview TD4A is a visual design aid for building and testing jinja2 templates. It will combine data in yaml format with a jinja2 template and render the output. All jinja2 filters are supported along with the filter plugins from Ansible version 2.9.12 ### Installation: ##### using podman (or docker): ``` podman pull cidrblock/td4a ``` The container registry page can be found here: https://hub.docker.com/r/cidrblock/td4a/ #### using the cli: ``` $ virtualenv venv $ source venv/bin/activate $ pip install td4a ``` The pip package can be found here: https://pypi.python.org/pypi/td4a ### Starting the TD4A server #### Simple ##### using podman (or docker): ``` podman run -p 5000:5000 cidrblock/td4a ``` ##### using the cli: ``` td4a-server ``` ##### open your browser to: http://127.0.0.1:5000 ### Modes TD4A support two different modes of operation. - Templating: Build and render jinja2 templates - Schema: Build and validate a json schema for your data #### Enabling a mode ##### using podman (or docker): ``` podman run -p 5000:5000 \ -it \ cidrblock/td4a \ td4a-server -m mode ``` ##### using the cli: ``` td4a-server -m mode ``` where `mode` is either jinja2 (default) or schema ### Additional configuration options #### Loading custom filter plugins (jinja2 mode only) TD4A supports custom filter plugins within the container. Pass your custom filter_plugins directory as a volume and use the -f option to specify to custom filter plugin directory. ##### using podman (or docker): ``` podman run -p 5000:5000 \ -it \ -v `pwd`/my_filter_plugins:/filter_plugins \ cidrblock/td4a \ td4a-server -f /filter_plugins ``` ##### using the cli: TD4A can load custom filters from a directory specified from the command line: ``` td4a-server -f ./my_filter_plugins ``` #### Loading an ansible inventory (jinja2 and schema mode) Mount the inventory as `/inventory` in the container, and run TD4A with the `-i` option. ##### using podman (or docker): ``` podman run -p 5000:5000 \ -it \ -v '/Users/me/github/ansible_network_inventory:/inventory' \ cidrblock/td4a \ td4a-server -i /inventory -m mode -v 'my_vault_password' ``` If environment variables are needed for a dynamic inventory, they can be passed to the docker container. ``` podman run -p 5000:5000 \ -it \ -v `pwd`/my_filter_plugins:/filter_plugins \ -v '/Users/me/github/ansible_network_inventory:/inventory' \ -e "COUCH_USERNAME=admin" \ -e "COUCH_PASSWORD=password" \ -e "COUCH_URL=http://192.168.1.5:5984/td4a" \ -e "DYNAMIC_INVENTORY_USERNAME=api" \ -e "DYNAMIC_INVENTORY_PASSWORD=password" \ cidrblock/td4a \ td4a-server -f /filter_plugins -m mode -i /inventory -v 'my_vault_password' ``` ##### using the cli: TD4A can load multiple ansible inventories, specifc each with `-i` on the command line: ``` td4a-server -i ./my_ansible_inventory -v 'my_vault_password' ``` #### Enabling storage and links using a couch database (jinja2 and schema mode) TD4A has the ability to store data and templates in a CouchDB. This is disabled by default. The CouchDB needs to previously created. To enable link support, and add the link button to the UI, set the following environ variables: ##### using podman (or docker): ``` podman run -p 5000:5000 \ -v `pwd`/my_filter_plugins:/filter_plugins \ -e "COUCH_USERNAME=admin" \ -e "COUCH_PASSWORD=password" \ -e "COUCH_URL=http://192.168.1.5:5984/td4a" \ cidrblock/td4a \ td4a-server -m mode ``` ##### using the cli: ``` export COUCH_USERNAME=admin export COUCH_PASSWORD=password export COUCH_URL=http://localhost:5984/td4a td4a-server -m mode ``` ### User Interface The interface is browser based and has been tested using Chrome. If your browser did not automatically open when TD4A was started, you can visit http://127.0.0.1:5000 to see the interface. The UI is broken into three sections: 1) DATA, this is where the data in yaml format is provided. 2) TEMPLATE, the jinja2 template to be rendered. 3) RESULT, after clicking the render button, the result pane will be populated with the rendered template. #### Keyboard shortcuts `cmd+r`: Render the template `cmd+s`: Save the data in browser local storage `cmd+b`: Begin new, clear the screen ### Python version To date, this has only been tested with python 3.8.5. ### Development NPM and related packages are required to build the UI. ``` npm install ``` The UI components can be installed for development purposes using bower. ``` bower install ``` The dependancies can be concatenated and minified using gulp. ``` gulp ``` ================================================ FILE: bower.json ================================================ { "name": "jinja_api", "authors": [ "bthornto " ], "description": "", "main": "", "license": "MIT", "homepage": "", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "codemirror": "^5.32.0", "angular": "^1.6.7", "angular-animate": "^1.6.7", "angular-aria": "^1.6.7", "angular-messages": "^1.6.7", "angular-route": "^1.6.7", "Split.js": "^1.3.5", "angular-ui-codemirror": "^0.3.0", "ng-split": "^0.2.0", "angular-material": "^1.1.5", "angular-cookies": "^1.6.7", "angular-local-storage": "^0.7.1" } } ================================================ FILE: gcp/Dockerfile ================================================ FROM cidrblock/td4a:2.0.3 EXPOSE 5000 ================================================ FILE: gulpfile.js ================================================ var gulp = require('gulp'), uglify = require('gulp-uglify'), jshint = require('gulp-jshint'), concat = require('gulp-concat'), notify = require('gulp-notify'), rename = require('gulp-rename'), clean = require('gulp-clean'); var jsDest = 'td4a/static/jsTemp'; var cssDest = 'td4a/static/css'; gulp.task('default', function() { }); gulp.task('codemirror', function(done) { gulp.src("bower_components/codemirror/lib/codemirror.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/mode/jinja2/jinja2.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/mode/yaml/yaml.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/addon/dialog/dialog.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/addon/search/searchcursor.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/addon/search/search.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/addon/search/matchesonscrollbar.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/addon/scroll/annotatescrollbar.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/addon/search/jump-to-line.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/codemirror/lib/codemirror.css") .pipe(gulp.dest(cssDest)); gulp.src("bower_components/codemirror/addon/dialog/dialog.css") .pipe(gulp.dest(cssDest)); gulp.src("bower_components/codemirror/theme/material.css") .pipe(gulp.dest(cssDest)); done(); }); gulp.task('angular', function(done) { gulp.src("bower_components/angular/angular.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/angular-animate/angular-animate.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/angular-aria/angular-aria.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/angular-messages/angular-messages.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/angular-route/angular-route.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/angular-cookies/angular-cookies.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/angular-local-storage/dist/angular-local-storage.js") .pipe(gulp.dest(jsDest)); done(); }); gulp.task('angular-material', function(done) { gulp.src("bower_components/angular-material/angular-material.js") .pipe(gulp.dest(jsDest)); gulp.src("bower_components/angular-material/angular-material.css") .pipe(gulp.dest(cssDest)); done(); }); gulp.task('split', function(done) { gulp.src("bower_components/Split.js/split.js") .pipe(gulp.dest(jsDest)); done(); }); gulp.task('ui-codemirror', function(done) { gulp.src("bower_components/angular-ui-codemirror/ui-codemirror.js") .pipe(gulp.dest(jsDest)); done(); }); gulp.task('ng-split', function(done) { gulp.src("bower_components/ng-split/dist/ng-split.js") .pipe(gulp.dest(jsDest)); done(); }); gulp.task('scripts', function(done) { gulp.src([ 'td4a/static/jsTemp/angular.js', 'td4a/static/jsTemp/codemirror.js', 'td4a/static/jsTemp/*.js' ]) .pipe(concat('main.js')) .pipe(gulp.dest('dist')) .pipe(rename('main.min.js')) .pipe(uglify()) .pipe(gulp.dest('td4a/static/js')) .pipe(notify({ message: 'Scripts task complete' })); done(); }); gulp.task('clean', function (done) { gulp.src(['td4a/static/jsTemp', 'dist' ], {read: false}) .pipe(clean({force: true})); done(); }); gulp.task('default', gulp.series('codemirror', 'angular', 'angular-material', 'split', 'ng-split', 'ui-codemirror', 'scripts')) ================================================ FILE: my_ansible_inventory/group_vars/all/vars.yml ================================================ application_name: td4a ================================================ FILE: my_ansible_inventory/group_vars/routers/vars.yml ================================================ manufacturer: quagga ================================================ FILE: my_ansible_inventory/group_vars/servers/vars.yml ================================================ manufacturer: whitebox ================================================ FILE: my_ansible_inventory/host_vars/router00/vars.yml ================================================ ansible_ssh_pass: "{{ lookup('env', 'ANSIBLE_PASSWORD') }}" interfaces: Ethernet4/10: description: siteassw100-g0/1-siteasrt001-eth4/10 name: Ethernet4/10 shutdown: negate: true switchport: mode: - trunk switchport: true Ethernet4/11: channel_group: id: 31 mode: active description: unity1interface1 mtu: 9216 name: Ethernet4/11 shutdown: negate: true switchport: mode: - trunk switchport: true trunk: allowed_vlans: vlans: 3605,3607 native_vlan: 5 ================================================ FILE: my_ansible_inventory/host_vars/server00/vars.yml ================================================ --- # defaults file for ansible-apache2 # Defines if Apache2 should be configured apache2_config: false # Defines if php.ini should be configured for Apache2 apache2_config_php: false # Defines if Apache2 virtual hosts should be configured apache2_config_virtual_hosts: true # Defines Apache2 default listen port apache2_default_port: 80 # Defines if php-sqlite should be installed apache2_install_php_sqlite: false # Defines if php should be installed apache2_install_php: false apache2_php_max_execution_time: 30 apache2_php_max_input_time: 60 # Defines max memory for Apache php # default is 128M apache2_php_max_memory: 128M apache2_php_post_max_size: 8M apache2_php_timezone: "UTC" apache2_php_upload_max_filesize: 2M apache2_server_admin: webmaster@localhost # Define Apache2 virtual hosts apache2_virtual_hosts: - documentroot: '/var/www/example.com' default_site: false port: 80 serveradmin: '{{ apache2_server_admin }}' servername: 'www.example.com' - documentroot: '/var/www/example.org' default_site: false port: 80 serveradmin: '{{ apache2_server_admin }}' servername: 'www.example.org' - documentroot: '/var/www/html' default_site: true port: 80 serveradmin: '{{ apache2_server_admin }}' servername: '' apache2_web_root: /var/www/html apache2_log_dir: /var/log/apache testVar: testing anotherTestVar: "{{ testVar }}" ================================================ FILE: my_ansible_inventory/host_vars/test00/vars.yml ================================================ a: "{{ b }}" b: c: this d: that foo: "{{ bar }}" bar: - 1 - 2 - 3 ansible_ssh_pass: "{{ lookup('env', 'FOO') }}" cisco_xr_cli: username: "{{ ansible_ssh_user }}" y: "{{ z }}" z: aa: bb: cc: dd: dd f: "{{ bar + bar }}" ================================================ FILE: my_ansible_inventory/inventory.yml ================================================ router[00:03] server[00:03] test[00:03] [routers] router[00:03] [servers] server[00:03] ================================================ FILE: my_filter_plugins/mask_convert.py ================================================ from netaddr import IPNetwork def convert(network, netmask): entry = IPNetwork('%s/%s' % (network, netmask)) answer = {} answer['slashbits'] = '/%s' % getattr(entry, 'prefixlen') answer['bits'] = '%s' % getattr(entry, 'prefixlen') answer['hostmask'] = str(entry.hostmask) answer['netmask'] = str(entry.netmask) answer['network'] = network answer['net_netmask'] = '%s/%s' % (network, answer['netmask']) answer['net_bits'] = '%s/%s' % (network, answer['bits']) answer['net_hostmask'] = '%s/%s' % (network, answer['hostmask']) return answer class FilterModule(object): def filters(self): return { 'convert': convert } ================================================ FILE: package.json ================================================ { "name": "jinja_api", "version": "1.0.0", "description": "", "main": "gulpfile.js", "dependencies": {}, "devDependencies": { "del": "^3.0.0", "gulp": "github:gulpjs/gulp#4.0", "gulp-clean": "^0.3.2", "gulp-concat": "^2.6.1", "gulp-jshint": "^2.0.4", "gulp-notify": "^3.0.0", "gulp-rename": "^1.2.2", "gulp-sass": "^3.1.0", "gulp-uglify": "^3.0.0", "jshint": "^2.9.5" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "MIT" } ================================================ FILE: requirements.txt ================================================ ansible==2.9.12 Flask==1.1.2 netaddr==0.8.0 Twisted==20.3.0 requests==2.24.0 ruamel.yaml==0.16.10 genson==1.2.1 jsonschema==3.2.0 ================================================ FILE: setup.py ================================================ from setuptools import setup setup(name='td4a', version='2.0.3', description='A browser based jinja template renderer', url='http://github.com/cidrblock/td4a', author='Bradley A. Thornton', author_email='brad@thethorntons.net', license='MIT', include_package_data=True, packages=[ 'td4a' ], scripts=['td4a-server'], install_requires=[ 'ansible==2.9.12', 'Flask==1.1.2', 'netaddr==0.8.0', 'Twisted==20.3.0', 'requests==2.24.0', 'ruamel.yaml==0.16.10', 'genson==1.2.1', 'jsonschema==3.2.0' ], zip_safe=False) ================================================ FILE: td4a/__init__.py ================================================ from flask import Flask, request, jsonify from td4a.controllers.config import api_config from td4a.controllers.hosts import api_hosts from td4a.controllers.inventory import api_inventory from td4a.controllers.link import api_link from td4a.controllers.render import api_render from td4a.controllers.retrieve import api_retrieve from td4a.controllers.schema import api_schema from td4a.controllers.validate import api_validate app = Flask(__name__, static_url_path='') # pylint: disable=invalid-name app.register_blueprint(api_config) app.register_blueprint(api_hosts) app.register_blueprint(api_inventory) app.register_blueprint(api_link) app.register_blueprint(api_render) app.register_blueprint(api_retrieve) app.register_blueprint(api_schema) app.register_blueprint(api_validate) @app.route('/') def root(): """ root path """ return app.send_static_file('index.html') ================================================ FILE: td4a/controllers/__init__.py ================================================ ================================================ FILE: td4a/controllers/config.py ================================================ """ /config """ from flask import jsonify, Blueprint from flask import current_app as app api_config = Blueprint('api_config', __name__) # pylint: disable=invalid-name @api_config.route('/config', methods=['GET']) def config(): """ provide some config options to the UI """ if app.args.ui_mode == "jinja": ui_config = { "p1": { "options": { "lineNumbers": True, "theme":"material", "lineWrapping" : True, "mode": "yaml", "indentUnit": 2, "tabSize": 2 }, "title": "DATA", "inventory": bool(app.args.inventory_source), "b1": { "icon": None, "show": False, "text": None, "url": None } }, "p2": { "options": { "lineNumbers": True, "theme": "material", "lineWrapping" : True, "mode": "jinja2" }, "title": "RENDER", "b1": { "icon": "create", "show": True, "text": "Render", "url": "/render" } }, "p3": { "options": { "lineNumbers": True, "theme": "material", "lineWrapping" : True, "mode": 'text' }, "title": "RESULT", "b1": { "icon": "link", "show": bool(app.args.url), "text": "link" } } } elif app.args.ui_mode == "schema": ui_config = { "p1": { "options": { "lineNumbers": True, "theme":"material", "lineWrapping" : True, "mode": "yaml", "indentUnit": 2, "tabSize": 2 }, "title": "DATA", "inventory": bool(app.args.inventory_source), "b1": { "icon": "create", "show": True, "text": "schema", "url": "/schema" } }, "p2": { "options": { "lineNumbers": True, "theme": "material", "lineWrapping" : True, "mode": "yaml" }, "title": "SCHEMA", "b1": { "icon": "check", "show": True, "text": "Validate", "url": "/validate" } }, "p3": { "options": { "lineNumbers": True, "theme": "material", "lineWrapping" : True, "mode": "yaml" }, "title": "VALIDATION SUCCESS/ERRORS", "b1": { "icon": "link", "show": bool(app.args.url), "text": "link" } } } return jsonify(ui_config) ================================================ FILE: td4a/controllers/hosts.py ================================================ """ /hosts """ from flask import jsonify, Blueprint from flask import current_app as app api_hosts = Blueprint('api_hosts', __name__) # pylint: disable=invalid-name @api_hosts.route('/hosts', methods=['GET']) def hosts(): """ check to see if the link button should be enabled """ devices = app.inventory.keys() return jsonify({"hosts": sorted(devices)}) ================================================ FILE: td4a/controllers/inventory.py ================================================ """ /inventory """ from flask import request, jsonify, Blueprint from flask import current_app as app from td4a.models.exception_handler import ExceptionHandler, HandledException from td4a.models.td4ayaml import Td4aYaml import json import collections api_inventory = Blueprint('api_inventory', __name__) # pylint: disable=invalid-name @api_inventory.route('/inventory', methods=['GET']) def rest_inventory(): """ return inventory for host """ yaml = Td4aYaml() inventory = app.inventory.get(request.args.get('host'), "") data = json.loads(json.dumps(inventory)) response_text = '' for section in sorted(data.keys()): response_text += yaml.dump({section: data[section]}) response = {"p1": response_text} return jsonify(response) ================================================ FILE: td4a/controllers/link.py ================================================ from flask import request, jsonify, Blueprint from flask import current_app as app from td4a.models.exception_handler import ExceptionHandler, HandledException import requests api_link = Blueprint('api_link', __name__) @ExceptionHandler def link(payload, args, typ): """ store a doc in the db """ _ = typ auth = (args.username, args.password) url = args.url response = requests.post("%s" % url, json=payload, auth=auth) return {"id": response.json()['id']} @api_link.route('/link', methods=['POST']) def rest_link(): """ Save the documents in a couchdb and returns an id """ try: response = link(payload=request.json, args=app.args, typ="link") return jsonify(response) except HandledException as error: return jsonify(error.json()) ================================================ FILE: td4a/controllers/render.py ================================================ """ /render """ from flask import request, jsonify, Blueprint from flask import current_app as app from jinja2 import meta, Environment, StrictUndefined, Undefined from td4a.models.exception_handler import ExceptionHandler, HandledException from td4a.models.td4ayaml import Td4aYaml from ruamel.yaml import YAML import re api_render = Blueprint('api_render', __name__) # pylint: disable=invalid-name @ExceptionHandler def jinja_unresolved(template, typ): """ Check a jinja template for any unresolved vars """ _ = typ env = Environment() env.trim_blocks = True unresolved = meta.find_undeclared_variables(env.parse(template)) return unresolved def lookup(*args, **kwargs): return "unsupported" @ExceptionHandler def jinja_render(data, template, filters, typ): """ Render a jinja template """ _ = typ if typ == 'p1': env = Environment(undefined=Undefined) else: env = Environment(undefined=StrictUndefined) env.trim_blocks = True for entry in filters: env.filters[entry[0]] = entry[1] env.globals.update(lookup=lookup) result = env.from_string(template).render(data) return result @ExceptionHandler def yaml_parse(string, typ): """ load yaml from string """ _ = typ yaml = YAML() yaml.load(string) @ExceptionHandler def render(payload, filters, typ): """ Given the payload, render the result """ _ = typ try: loader = YAML(typ='unsafe') result = None if payload['p1'] and payload['p2']: # check for error in data yaml_parse(string=payload['p1'], typ="p1") # swap '{{ }}' for "{{ }}" dq_jinja = re.compile(r"'\{\{([^\{\}]+)\}\}'") payload['p1'] = dq_jinja.sub('"{{\\1}}"', payload['p1']) # remove the quotes around dicts put into jinja expose_dicts = re.compile(r'"\{([^\{].*)\}"') # remove the quotes aournd lists put into jinja expose_lists1 = re.compile(r'"\[(.*)\]"') # change '{{ }}' to "{{ }}" dq_jinja = re.compile(r"'\{\{([^\{\}]+)\}\}'") raw_data = None after_jinja = payload['p1'] tvars = loader.load(payload['p1']) if jinja_unresolved(template=after_jinja, typ="p1"): while after_jinja != raw_data: raw_data = after_jinja after_jinja = jinja_render(data=tvars, template=raw_data, filters=filters, typ="p1") yaml_ready = expose_dicts.sub("{\\1}", after_jinja) yaml_ready = expose_lists1.sub("[\\1]", yaml_ready) yaml_ready = dq_jinja.sub('"{{\\1}}"', yaml_ready) tvars = loader.load(yaml_ready) result = jinja_render(data=tvars, template=payload['p2'], filters=filters, typ="p2") return {"p3": result} except HandledException as error: return error.json() @api_render.route('/render', methods=['POST']) def rest_render(): """ render path """ try: print("Checking and parsing data...") response = render(payload=request.json, filters=app.filters, typ="page") print("Done.") return jsonify(response) except HandledException as error: return jsonify(error.json()) ================================================ FILE: td4a/controllers/retrieve.py ================================================ """ /retrieve """ from flask import request, jsonify, Blueprint from flask import current_app as app from td4a.models.exception_handler import ExceptionHandler, HandledException import requests api_retrieve = Blueprint('api_retrieve', __name__) # pylint: disable=invalid-name @ExceptionHandler def retrieve(doc_id, typ): """ get a doc from the db """ _ = typ auth = (app.args.username, app.args.password) url = app.args.url cdoc = requests.get("%s/%s?include_docs=true" % (url, doc_id), auth=auth) doc = cdoc.json() if cdoc.status_code == 200: response = {"panels": doc['panels'], "config": doc['config']} else: response = {"handled_error": { "in": "document retrieval", "title": "Message: Issue loading saved document.", "line_number": None, "details": "Details: %s" % doc['error'], "raw_error": "%s" % cdoc.text } } return response @api_retrieve.route('/retrieve', methods=['GET']) def rest_retrieve(): """ return a doc from the couchdb """ try: response = retrieve(doc_id=request.args.get('id'), typ="link") return jsonify(response) except HandledException as error: return jsonify(error.json()) ================================================ FILE: td4a/controllers/schema.py ================================================ """ /retrieve """ import json from flask import current_app as app from flask import request, jsonify, Blueprint from td4a.models.exception_handler import ExceptionHandler, HandledException from td4a.models.sort_commented_map import sort_commented_map from td4a.models.td4ayaml import Td4aYaml import genson api_schema = Blueprint('api_schema', __name__) # pylint: disable=invalid-name @ExceptionHandler def schema(data, typ): """ Build schema from data """ _ = typ yaml = Td4aYaml() obj_data = yaml.load(data['p1']) json_schema = genson.Schema() json_schema.add_object(obj_data) schema_dict = json_schema.to_dict() schema_yaml = yaml.load(yaml.dump(schema_dict)) sorted_schema_yaml = sort_commented_map(commented_map=schema_yaml) sorted_schema_string = yaml.dump(sorted_schema_yaml) return sorted_schema_string @api_schema.route('/schema', methods=['POST']) def rest_schema(): """ Build a schema for data """ try: payload = request.json response = schema(data=payload, typ="data") return jsonify({"p2": response}) except HandledException as error: return jsonify(error.json()) ================================================ FILE: td4a/controllers/validate.py ================================================ """ /retrieve """ import json from flask import current_app as app from flask import request, jsonify, Blueprint from td4a.models.exception_handler import ExceptionHandler, HandledException from td4a.models.td4ayaml import Td4aYaml from jsonschema import validate from jsonschema import Draft4Validator, FormatChecker from jsonschema.exceptions import UnknownType api_validate = Blueprint('api_validate', __name__) # pylint: disable=invalid-name @ExceptionHandler def parse_yaml(yamul, typ): _ = typ yaml = Td4aYaml() obj = yaml.load(yamul) return obj def validation(payload): """ Validate schema from data """ try: yaml_safe = Td4aYaml(typ='safe') yaml = Td4aYaml() data = yaml_safe.load(payload['p1']) schema = yaml_safe.load(payload['p2']) errors = [] v = Draft4Validator(schema, format_checker=FormatChecker()) for error in sorted(v.iter_errors(data)): errors.append(error.message) if errors: return {"p3": yaml.dump({"messages":errors})} return {"p3": yaml.dump({"messages":["validation passed"]})} except UnknownType as error: error_message = str(error) lines = error_message.splitlines() message = [x for x in lines if x.startswith('Unknown type')] return {"p3": yaml.dump({"messages":message})} @api_validate.route('/validate', methods=['POST']) def rest_validate(): """ Build a schema for data """ try: payload = request.json data = parse_yaml(yamul=payload['p1'], typ='p1') schema = parse_yaml(yamul=payload['p2'], typ='p2') response = validation(payload=payload) return jsonify(response) except HandledException as error: return jsonify(error.json()) ================================================ FILE: td4a/models/__init__.py ================================================ ================================================ FILE: td4a/models/exception_handler.py ================================================ import re import sys import traceback class HandledException(Exception): def __init__(self, value): self.value = value Exception.__init__(self) def __str__(self): return repr(self.value) def json(self): return self.value['json'] class ExceptionHandler(object): """ Handle the expected errors.""" def __init__(self, function): self.function = function self.error = self.typ = self.tback = self.exc_type = self.exc_value = self.exc_traceback = None self.error_map = { "requests.exceptions": self.requests_error, "ruamel.yaml.parser.ParserError": self.parser_error, "ruamel.yaml.constructor.ConstructorError": self.constructor_error, "ruamel.yaml.constructor.DuplicateKeyError": self.duplicate_key_error, "ruamel.yaml.scanner.ScannerError": self.scanner_error, "jinja2.exceptions": self.jinja_error, "TypeError": self.type_error } def __call__(self, *args, **kwargs): try: return self.function(*args, **kwargs) except Exception as error: self.error = error self.exc_type, self.exc_value, self.exc_traceback = sys.exc_info() self.tback = traceback.extract_tb(self.exc_traceback) error_module = getattr(error, '__module__', None) if error_module: full_error = "%s.%s" % (error.__module__, self.exc_type.__name__) else: full_error = self.exc_type.__name__ handler = self.error_map.get(full_error, self.error_map.get(error_module, self.unhandled)) self.typ = kwargs.get('typ') message = handler() raise HandledException({"json": message}) def error_response(self, message, line_number): error_payload = {"handled_error": { "in": self.typ, "title": "Message: Issue found loading %s." % self.typ, "line_number": line_number, "details": "Details: %s" % message, "raw_error": "%s\n%s" % (self.exc_type, self.exc_value) } } return error_payload def constructor_error(self): line_number = self.error.problem_mark.line+1 message = next(x for x in str(self.error).splitlines() if x.startswith('found')) return self.error_response(message=message, line_number=line_number) def duplicate_key_error(self): line_number = self.error.problem_mark.line+1 message = next(x for x in str(self.error).splitlines() if x.startswith('found')).split('with')[0] return self.error_response(message=message, line_number=line_number) def jinja_error(self): message = str(self.error).replace("'ruamel.yaml.comments.CommentedMap object'", 'Object') line_numbers = [x for x in self.tback if re.search('^<.*>$', x[0])] if line_numbers: line_number = line_numbers[0][1] else: line_number = 'unknown' return self.error_response(message=message, line_number=line_number) def parser_error(self): line_number = self.error.problem_mark.line + 1 messages = [x for x in str(self.error).splitlines() if x.startswith('expected')] if messages: message = messages[0] else: message = str(self.error) return self.error_response(message=message, line_number=line_number) def scanner_error(self): line_number = self.error.problem_mark.line + 1 message = str(self.error).splitlines()[0] return self.error_response(message=message, line_number=line_number) def requests_error(self): message = "DB connection problems, see the browser developer tools for the full error." return self.error_response(message=message, line_number=None) def type_error(self): message = str(self.error) line_numbers = [x for x in self.tback if re.search('^<.*>$', x[0])] if line_numbers: line_number = line_numbers[0][1] else: line_number = 'unknown' return self.error_response(message=message, line_number=line_number) def unhandled(self): print(self.exc_type, self.exc_value, self.exc_traceback, self.tback, self.error) line_numbers = [x for x in self.tback if re.search('^<.*>$', x[0])] if line_numbers: line_number = line_numbers[0][1] else: line_number = None message = "Please see the console for details. %s" % str(self.error) return self.error_response(message=message, line_number=line_number) ================================================ FILE: td4a/models/filters.py ================================================ """ filter loader helper """ import os import sys import importlib import ansible.plugins.filter as apf def load_dir(directory): """ Load jinja filters in ansible format """ filter_list = [] sys.path.append(directory) for entry in os.listdir(directory): if entry != '__init__.py' and entry.split('.')[-1] == 'py': filters = importlib.import_module(entry[:-3]).FilterModule().filters() for key, value in filters.items(): filter_list.append((key, value)) return filter_list def filters_load(custom_filters): """ load the filters """ filters = [] filters.extend(load_dir(os.path.dirname(apf.__file__))) if custom_filters: filters.extend(load_dir(custom_filters)) return filters ================================================ FILE: td4a/models/inventory.py ================================================ from ansible.parsing.dataloader import DataLoader from ansible.vars.manager import VariableManager from ansible.inventory.manager import InventoryManager from ansible.module_utils._text import to_bytes from ansible.parsing.vault import VaultSecret class TextVaultSecret(VaultSecret): '''A secret piece of text. ie, a password. Tracks text encoding. The text encoding of the text may not be the default text encoding so we keep track of the encoding so we encode it to the same bytes.''' def __init__(self, text, encoding=None, errors=None, _bytes=None): super(TextVaultSecret, self).__init__() self.text = text self.encoding = encoding or 'utf-8' self._bytes = _bytes self.errors = errors or 'strict' @property def bytes(self): '''The text encoded with encoding, unless we specifically set _bytes.''' return self._bytes or to_bytes(self.text, encoding=self.encoding, errors=self.errors) def inventory_load(inventory_sources, vault_secret): """ Load the inventory """ loader = DataLoader() vault_secrets = [('default', TextVaultSecret(vault_secret))] loader.set_vault_secrets(vault_secrets) inventory = InventoryManager(loader=loader, sources=inventory_sources) result = {} for hostname in inventory.hosts: host = inventory.get_host(hostname) variable_manager = VariableManager(loader=loader, inventory=inventory) magic_vars = ['ansible_playbook_python', 'groups', 'group_names', 'inventory_dir', 'inventory_file', 'inventory_hostname', 'inventory_hostname_short', 'omit', 'playbook_dir'] all_vars = variable_manager.get_vars(host=host, include_hostvars=True) cleaned = ({k: v for (k, v) in all_vars.items() if k not in magic_vars}) result[hostname] = cleaned return result ================================================ FILE: td4a/models/sort_commented_map.py ================================================ from ruamel.yaml.comments import CommentedMap def sort_commented_map(commented_map): """ Sort a ruamel commented map Args: commented_map (CommentedMap): The cm to order Returns: CommentedMap: The sorted commented map """ cmap = CommentedMap() for key, value in sorted(commented_map.iteritems()): if isinstance(value, CommentedMap): cmap[key] = sort_commented_map(value) elif isinstance(value, list): for i in enumerate(value): if isinstance(value[i[0]], CommentedMap): value[i[0]] = sort_commented_map(value[i[0]]) cmap[key] = value else: cmap[key] = value return cmap ================================================ FILE: td4a/models/td4ayaml.py ================================================ from ruamel.yaml import YAML from ruamel.yaml.compat import StringIO class Td4aYaml(YAML): """ Build a string dumper for ruamel """ def dump(self, data, stream=None, **kw): """ dump as string """ inefficient = False if stream is None: inefficient = True stream = StringIO() YAML.dump(self, data, stream, **kw) if inefficient: return stream.getvalue() ================================================ FILE: td4a/static/css/angular-material.css ================================================ /*! * AngularJS Material Design * https://github.com/angular/material * @license MIT * v1.1.5 */ html, body { height: 100%; position: relative; } body { margin: 0; padding: 0; } [tabindex='-1']:focus { outline: none; } .inset { padding: 10px; } a.md-no-style, button.md-no-style { font-weight: normal; background-color: inherit; text-align: left; border: none; padding: 0; margin: 0; } select, button, textarea, input { vertical-align: baseline; } input[type="reset"], input[type="submit"], html input[type="button"], button { cursor: pointer; -webkit-appearance: button; } input[type="reset"][disabled], input[type="submit"][disabled], html input[type="button"][disabled], button[disabled] { cursor: default; } textarea { vertical-align: top; overflow: auto; } input[type="search"] { -webkit-appearance: textfield; box-sizing: content-box; -webkit-box-sizing: content-box; } input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; } input:-webkit-autofill { text-shadow: none; } .md-visually-hidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; text-transform: none; width: 1px; } .md-shadow { position: absolute; top: 0; left: 0; bottom: 0; right: 0; border-radius: inherit; pointer-events: none; } .md-shadow-bottom-z-1 { box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); } .md-shadow-bottom-z-2 { box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4); } .md-shadow-animated.md-shadow { -webkit-transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1); transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1); } /* * A container inside of a rippling element (eg a button), * which contains all of the individual ripples */ .md-ripple-container { pointer-events: none; position: absolute; overflow: hidden; left: 0; top: 0; width: 100%; height: 100%; -webkit-transition: all 0.55s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.55s cubic-bezier(0.25, 0.8, 0.25, 1); } .md-ripple { position: absolute; -webkit-transform: translate(-50%, -50%) scale(0); transform: translate(-50%, -50%) scale(0); -webkit-transform-origin: 50% 50%; transform-origin: 50% 50%; opacity: 0; border-radius: 50%; } .md-ripple.md-ripple-placed { -webkit-transition: margin 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), border 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), width 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), height 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), opacity 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), -webkit-transform 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); transition: margin 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), border 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), width 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), height 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), opacity 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), -webkit-transform 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); transition: margin 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), border 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), width 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), height 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), opacity 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), transform 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); transition: margin 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), border 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), width 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), height 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), opacity 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), transform 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), -webkit-transform 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); } .md-ripple.md-ripple-scaled { -webkit-transform: translate(-50%, -50%) scale(1); transform: translate(-50%, -50%) scale(1); } .md-ripple.md-ripple-active, .md-ripple.md-ripple-full, .md-ripple.md-ripple-visible { opacity: 0.20; } .md-ripple.md-ripple-remove { -webkit-animation: md-remove-ripple 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); animation: md-remove-ripple 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); } @-webkit-keyframes md-remove-ripple { 0% { opacity: .15; } 100% { opacity: 0; } } @keyframes md-remove-ripple { 0% { opacity: .15; } 100% { opacity: 0; } } .md-padding { padding: 8px; } .md-margin { margin: 8px; } .md-scroll-mask { position: absolute; background-color: transparent; top: 0; right: 0; bottom: 0; left: 0; z-index: 50; } .md-scroll-mask > .md-scroll-mask-bar { display: block; position: absolute; background-color: #fafafa; right: 0; top: 0; bottom: 0; z-index: 65; box-shadow: inset 0px 0px 1px rgba(0, 0, 0, 0.3); } .md-no-momentum { -webkit-overflow-scrolling: auto; } .md-no-flicker { -webkit-filter: blur(0px); } @media (min-width: 960px) { .md-padding { padding: 16px; } } html[dir=rtl], html[dir=ltr], body[dir=rtl], body[dir=ltr] { unicode-bidi: embed; } bdo[dir=rtl] { direction: rtl; unicode-bidi: bidi-override; } bdo[dir=ltr] { direction: ltr; unicode-bidi: bidi-override; } html, body { -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; min-height: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /************ * Headings ************/ .md-display-4 { font-size: 112px; font-weight: 300; letter-spacing: -0.010em; line-height: 112px; } .md-display-3 { font-size: 56px; font-weight: 400; letter-spacing: -0.005em; line-height: 56px; } .md-display-2 { font-size: 45px; font-weight: 400; line-height: 64px; } .md-display-1 { font-size: 34px; font-weight: 400; line-height: 40px; } .md-headline { font-size: 24px; font-weight: 400; line-height: 32px; } .md-title { font-size: 20px; font-weight: 500; letter-spacing: 0.005em; } .md-subhead { font-size: 16px; font-weight: 400; letter-spacing: 0.010em; line-height: 24px; } /************ * Body Copy ************/ .md-body-1 { font-size: 14px; font-weight: 400; letter-spacing: 0.010em; line-height: 20px; } .md-body-2 { font-size: 14px; font-weight: 500; letter-spacing: 0.010em; line-height: 24px; } .md-caption { font-size: 12px; letter-spacing: 0.020em; } .md-button { letter-spacing: 0.010em; } /************ * Defaults ************/ button, select, html, textarea, input { font-family: Roboto, "Helvetica Neue", sans-serif; } select, button, textarea, input { font-size: 100%; } /* * * Responsive attributes * * References: * 1) https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties#flex * 2) https://css-tricks.com/almanac/properties/f/flex/ * 3) https://css-tricks.com/snippets/css/a-guide-to-flexbox/ * 4) https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items * 5) http://godban.com.ua/projects/flexgrid * * */ .md-panel-outer-wrapper { height: 100%; left: 0; position: absolute; top: 0; width: 100%; } ._md-panel-hidden { display: none; } ._md-panel-offscreen { left: -9999px; } ._md-panel-fullscreen { border-radius: 0; left: 0; min-height: 100%; min-width: 100%; position: fixed; top: 0; } ._md-panel-shown .md-panel { opacity: 1; -webkit-transition: none; transition: none; } .md-panel { opacity: 0; position: fixed; } .md-panel._md-panel-shown { opacity: 1; -webkit-transition: none; transition: none; } .md-panel._md-panel-animate-enter { opacity: 1; -webkit-transition: all 0.3s cubic-bezier(0, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0, 0, 0.2, 1); } .md-panel._md-panel-animate-leave { opacity: 1; -webkit-transition: all 0.3s cubic-bezier(0.4, 0, 1, 1); transition: all 0.3s cubic-bezier(0.4, 0, 1, 1); } .md-panel._md-panel-animate-scale-out, .md-panel._md-panel-animate-fade-out { opacity: 0; } .md-panel._md-panel-backdrop { height: 100%; position: absolute; width: 100%; } .md-panel._md-opaque-enter { opacity: .48; -webkit-transition: opacity 0.3s cubic-bezier(0, 0, 0.2, 1); transition: opacity 0.3s cubic-bezier(0, 0, 0.2, 1); } .md-panel._md-opaque-leave { -webkit-transition: opacity 0.3s cubic-bezier(0.4, 0, 1, 1); transition: opacity 0.3s cubic-bezier(0.4, 0, 1, 1); } md-autocomplete { border-radius: 2px; display: block; height: 40px; position: relative; overflow: visible; min-width: 190px; } md-autocomplete[disabled] input { cursor: default; } md-autocomplete[md-floating-label] { border-radius: 0; background: transparent; height: auto; } md-autocomplete[md-floating-label] md-input-container { padding-bottom: 0; } md-autocomplete[md-floating-label] md-autocomplete-wrap { height: auto; } md-autocomplete[md-floating-label] .md-show-clear-button button { display: block; position: absolute; right: 0; top: 20px; width: 30px; height: 30px; } md-autocomplete[md-floating-label] .md-show-clear-button input { padding-right: 30px; } [dir=rtl] md-autocomplete[md-floating-label] .md-show-clear-button input { padding-right: 0; padding-left: 30px; } md-autocomplete md-autocomplete-wrap { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; box-sizing: border-box; position: relative; overflow: visible; height: 40px; } md-autocomplete md-autocomplete-wrap.md-menu-showing { z-index: 51; } md-autocomplete md-autocomplete-wrap md-input-container, md-autocomplete md-autocomplete-wrap input { -webkit-box-flex: 1; -webkit-flex: 1 1 0%; flex: 1 1 0%; box-sizing: border-box; min-width: 0; } md-autocomplete md-autocomplete-wrap md-progress-linear { position: absolute; bottom: -2px; left: 0; } md-autocomplete md-autocomplete-wrap md-progress-linear.md-inline { bottom: 40px; right: 2px; left: 2px; width: auto; } md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate { position: absolute; top: 0; left: 0; width: 100%; height: 3px; -webkit-transition: none; transition: none; } md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate .md-container { -webkit-transition: none; transition: none; height: 3px; } md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-enter { -webkit-transition: opacity 0.15s linear; transition: opacity 0.15s linear; } md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-enter.ng-enter-active { opacity: 1; } md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-leave { -webkit-transition: opacity 0.15s linear; transition: opacity 0.15s linear; } md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-leave.ng-leave-active { opacity: 0; } md-autocomplete input:not(.md-input) { font-size: 14px; box-sizing: border-box; border: none; box-shadow: none; outline: none; background: transparent; width: 100%; padding: 0 15px; line-height: 40px; height: 40px; } md-autocomplete input:not(.md-input)::-ms-clear { display: none; } md-autocomplete .md-show-clear-button button { position: relative; line-height: 20px; text-align: center; width: 30px; height: 30px; cursor: pointer; border: none; border-radius: 50%; padding: 0; font-size: 12px; background: transparent; margin: auto 5px; } md-autocomplete .md-show-clear-button button:after { content: ''; position: absolute; top: -6px; right: -6px; bottom: -6px; left: -6px; border-radius: 50%; -webkit-transform: scale(0); transform: scale(0); opacity: 0; -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } md-autocomplete .md-show-clear-button button:focus { outline: none; } md-autocomplete .md-show-clear-button button:focus:after { -webkit-transform: scale(1); transform: scale(1); opacity: 1; } md-autocomplete .md-show-clear-button button md-icon { position: absolute; top: 50%; left: 50%; -webkit-transform: translate3d(-50%, -50%, 0) scale(0.9); transform: translate3d(-50%, -50%, 0) scale(0.9); } md-autocomplete .md-show-clear-button button md-icon path { stroke-width: 0; } md-autocomplete .md-show-clear-button button.ng-enter { -webkit-transform: scale(0); transform: scale(0); -webkit-transition: -webkit-transform 0.15s ease-out; transition: -webkit-transform 0.15s ease-out; transition: transform 0.15s ease-out; transition: transform 0.15s ease-out, -webkit-transform 0.15s ease-out; } md-autocomplete .md-show-clear-button button.ng-enter.ng-enter-active { -webkit-transform: scale(1); transform: scale(1); } md-autocomplete .md-show-clear-button button.ng-leave { -webkit-transition: -webkit-transform 0.15s ease-out; transition: -webkit-transform 0.15s ease-out; transition: transform 0.15s ease-out; transition: transform 0.15s ease-out, -webkit-transform 0.15s ease-out; } md-autocomplete .md-show-clear-button button.ng-leave.ng-leave-active { -webkit-transform: scale(0); transform: scale(0); } @media screen and (-ms-high-contrast: active) { md-autocomplete input { border: 1px solid #fff; } md-autocomplete li:focus { color: #fff; } } .md-virtual-repeat-container.md-autocomplete-suggestions-container { position: absolute; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); z-index: 100; height: 100%; } .md-virtual-repeat-container.md-not-found { height: 48px; } .md-autocomplete-suggestions { margin: 0; list-style: none; padding: 0; } .md-autocomplete-suggestions li { font-size: 14px; overflow: hidden; padding: 0 15px; line-height: 48px; height: 48px; -webkit-transition: background 0.15s linear; transition: background 0.15s linear; margin: 0; white-space: nowrap; text-overflow: ellipsis; } .md-autocomplete-suggestions li:focus { outline: none; } .md-autocomplete-suggestions li:not(.md-not-found-wrapper) { cursor: pointer; } @media screen and (-ms-high-contrast: active) { md-autocomplete, .md-autocomplete-suggestions { border: 1px solid #fff; } } md-backdrop { -webkit-transition: opacity 450ms; transition: opacity 450ms; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 50; } md-backdrop.md-menu-backdrop { position: fixed !important; z-index: 99; } md-backdrop.md-select-backdrop { z-index: 81; -webkit-transition-duration: 0; transition-duration: 0; } md-backdrop.md-dialog-backdrop { z-index: 79; } md-backdrop.md-bottom-sheet-backdrop { z-index: 69; } md-backdrop.md-sidenav-backdrop { z-index: 59; } md-backdrop.md-click-catcher { position: absolute; } md-backdrop.md-opaque { opacity: .48; } md-backdrop.md-opaque.ng-enter { opacity: 0; } md-backdrop.md-opaque.ng-enter.md-opaque.ng-enter-active { opacity: .48; } md-backdrop.md-opaque.ng-leave { opacity: .48; -webkit-transition: opacity 400ms; transition: opacity 400ms; } md-backdrop.md-opaque.ng-leave.md-opaque.ng-leave-active { opacity: 0; } md-bottom-sheet { position: absolute; left: 0; right: 0; bottom: 0; padding: 8px 16px 88px 16px; z-index: 70; border-top-width: 1px; border-top-style: solid; -webkit-transform: translate3d(0, 80px, 0); transform: translate3d(0, 80px, 0); -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); -webkit-transition-property: -webkit-transform; transition-property: -webkit-transform; transition-property: transform; transition-property: transform, -webkit-transform; } md-bottom-sheet.md-has-header { padding-top: 0; } md-bottom-sheet.ng-enter { opacity: 0; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } md-bottom-sheet.ng-enter-active { opacity: 1; display: block; -webkit-transform: translate3d(0, 80px, 0) !important; transform: translate3d(0, 80px, 0) !important; } md-bottom-sheet.ng-leave-active { -webkit-transform: translate3d(0, 100%, 0) !important; transform: translate3d(0, 100%, 0) !important; -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } md-bottom-sheet .md-subheader { background-color: transparent; font-family: Roboto, "Helvetica Neue", sans-serif; line-height: 56px; padding: 0; white-space: nowrap; } md-bottom-sheet md-inline-icon { display: inline-block; height: 24px; width: 24px; fill: #444; } md-bottom-sheet md-list-item { display: -webkit-box; display: -webkit-flex; display: flex; outline: none; } md-bottom-sheet md-list-item:hover { cursor: pointer; } md-bottom-sheet.md-list md-list-item { padding: 0; -webkit-box-align: center; -webkit-align-items: center; align-items: center; height: 48px; } md-bottom-sheet.md-grid { padding-left: 24px; padding-right: 24px; padding-top: 0; } md-bottom-sheet.md-grid md-list { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; -webkit-flex-wrap: wrap; flex-wrap: wrap; -webkit-transition: all 0.5s; transition: all 0.5s; -webkit-box-align: center; -webkit-align-items: center; align-items: center; } md-bottom-sheet.md-grid md-list-item { -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; -webkit-box-align: center; -webkit-align-items: center; align-items: center; -webkit-transition: all 0.5s; transition: all 0.5s; height: 96px; margin-top: 8px; margin-bottom: 8px; /* Mixin for how many grid items to show per row */ } @media (max-width: 960px) { md-bottom-sheet.md-grid md-list-item { -webkit-box-flex: 1; -webkit-flex: 1 1 33.33333%; flex: 1 1 33.33333%; max-width: 33.33333%; } md-bottom-sheet.md-grid md-list-item:nth-of-type(3n + 1) { -webkit-box-align: start; -webkit-align-items: flex-start; align-items: flex-start; } md-bottom-sheet.md-grid md-list-item:nth-of-type(3n) { -webkit-box-align: end; -webkit-align-items: flex-end; align-items: flex-end; } } @media (min-width: 960px) and (max-width: 1279px) { md-bottom-sheet.md-grid md-list-item { -webkit-box-flex: 1; -webkit-flex: 1 1 25%; flex: 1 1 25%; max-width: 25%; } } @media (min-width: 1280px) and (max-width: 1919px) { md-bottom-sheet.md-grid md-list-item { -webkit-box-flex: 1; -webkit-flex: 1 1 16.66667%; flex: 1 1 16.66667%; max-width: 16.66667%; } } @media (min-width: 1920px) { md-bottom-sheet.md-grid md-list-item { -webkit-box-flex: 1; -webkit-flex: 1 1 14.28571%; flex: 1 1 14.28571%; max-width: 14.28571%; } } md-bottom-sheet.md-grid md-list-item::before { display: none; } md-bottom-sheet.md-grid md-list-item .md-list-item-content { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; -webkit-box-align: center; -webkit-align-items: center; align-items: center; width: 48px; padding-bottom: 16px; } md-bottom-sheet.md-grid md-list-item .md-grid-item-content { border: 1px solid transparent; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; -webkit-box-align: center; -webkit-align-items: center; align-items: center; width: 80px; } md-bottom-sheet.md-grid md-list-item .md-grid-text { font-weight: 400; line-height: 16px; font-size: 13px; margin: 0; white-space: nowrap; width: 64px; text-align: center; text-transform: none; padding-top: 8px; } @media screen and (-ms-high-contrast: active) { md-bottom-sheet { border: 1px solid #fff; } } button.md-button::-moz-focus-inner { border: 0; } .md-button { display: inline-block; position: relative; cursor: pointer; /** Alignment adjustments */ min-height: 36px; min-width: 88px; line-height: 36px; vertical-align: middle; -webkit-box-align: center; -webkit-align-items: center; align-items: center; text-align: center; border-radius: 2px; box-sizing: border-box; /* Reset default button appearance */ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; outline: none; border: 0; /** Custom styling for button */ padding: 0 6px; margin: 6px 8px; background: transparent; color: currentColor; white-space: nowrap; /* Uppercase text content */ text-transform: uppercase; font-weight: 500; font-size: 14px; font-style: inherit; font-variant: inherit; font-family: inherit; text-decoration: none; overflow: hidden; -webkit-transition: box-shadow 0.4s cubic-bezier(0.25, 0.8, 0.25, 1), background-color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: box-shadow 0.4s cubic-bezier(0.25, 0.8, 0.25, 1), background-color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } .md-dense > .md-button:not(.md-dense-disabled), .md-dense :not(.md-dense-disabled) .md-button:not(.md-dense-disabled) { min-height: 32px; } .md-dense > .md-button:not(.md-dense-disabled), .md-dense :not(.md-dense-disabled) .md-button:not(.md-dense-disabled) { line-height: 32px; } .md-dense > .md-button:not(.md-dense-disabled), .md-dense :not(.md-dense-disabled) .md-button:not(.md-dense-disabled) { font-size: 13px; } .md-button:focus { outline: none; } .md-button:hover, .md-button:focus { text-decoration: none; } .md-button.ng-hide, .md-button.ng-leave { -webkit-transition: none; transition: none; } .md-button.md-cornered { border-radius: 0; } .md-button.md-icon { padding: 0; background: none; } .md-button.md-raised:not([disabled]) { box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); } .md-button.md-icon-button { margin: 0 6px; height: 40px; min-width: 0; line-height: 24px; padding: 8px; width: 40px; border-radius: 50%; } .md-button.md-icon-button .md-ripple-container { border-radius: 50%; background-clip: padding-box; overflow: hidden; -webkit-mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC"); } .md-button.md-fab { z-index: 20; line-height: 56px; min-width: 0; width: 56px; height: 56px; vertical-align: middle; box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); border-radius: 50%; background-clip: padding-box; overflow: hidden; -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); -webkit-transition-property: background-color, box-shadow, -webkit-transform; transition-property: background-color, box-shadow, -webkit-transform; transition-property: background-color, box-shadow, transform; transition-property: background-color, box-shadow, transform, -webkit-transform; } .md-button.md-fab.md-fab-bottom-right { top: auto; right: 20px; bottom: 20px; left: auto; position: absolute; } .md-button.md-fab.md-fab-bottom-left { top: auto; right: auto; bottom: 20px; left: 20px; position: absolute; } .md-button.md-fab.md-fab-top-right { top: 20px; right: 20px; bottom: auto; left: auto; position: absolute; } .md-button.md-fab.md-fab-top-left { top: 20px; right: auto; bottom: auto; left: 20px; position: absolute; } .md-button.md-fab .md-ripple-container { border-radius: 50%; background-clip: padding-box; overflow: hidden; -webkit-mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC"); } .md-button.md-fab.md-mini { line-height: 40px; width: 40px; height: 40px; } .md-button.md-fab.ng-hide, .md-button.md-fab.ng-leave { -webkit-transition: none; transition: none; } .md-button:not([disabled]).md-raised.md-focused, .md-button:not([disabled]).md-fab.md-focused { box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); } .md-button:not([disabled]).md-raised:active, .md-button:not([disabled]).md-fab:active { box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4); } .md-button .md-ripple-container { border-radius: 2px; background-clip: padding-box; overflow: hidden; -webkit-mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC"); } .md-button.md-icon-button md-icon, button.md-button.md-fab md-icon { display: block; } .md-toast-open-top .md-button.md-fab-top-left, .md-toast-open-top .md-button.md-fab-top-right { -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); -webkit-transform: translate3d(0, 42px, 0); transform: translate3d(0, 42px, 0); } .md-toast-open-top .md-button.md-fab-top-left:not([disabled]).md-focused, .md-toast-open-top .md-button.md-fab-top-left:not([disabled]):hover, .md-toast-open-top .md-button.md-fab-top-right:not([disabled]).md-focused, .md-toast-open-top .md-button.md-fab-top-right:not([disabled]):hover { -webkit-transform: translate3d(0, 41px, 0); transform: translate3d(0, 41px, 0); } .md-toast-open-bottom .md-button.md-fab-bottom-left, .md-toast-open-bottom .md-button.md-fab-bottom-right { -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); -webkit-transform: translate3d(0, -42px, 0); transform: translate3d(0, -42px, 0); } .md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]).md-focused, .md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]):hover, .md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]).md-focused, .md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]):hover { -webkit-transform: translate3d(0, -43px, 0); transform: translate3d(0, -43px, 0); } .md-button-group { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-flex: 1; -webkit-flex: 1; flex: 1; width: 100%; } .md-button-group > .md-button { -webkit-box-flex: 1; -webkit-flex: 1; flex: 1; display: block; overflow: hidden; width: 0; border-width: 1px 0px 1px 1px; border-radius: 0; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .md-button-group > .md-button:first-child { border-radius: 2px 0px 0px 2px; } .md-button-group > .md-button:last-child { border-right-width: 1px; border-radius: 0px 2px 2px 0px; } @media screen and (-ms-high-contrast: active) { .md-button.md-raised, .md-button.md-fab { border: 1px solid #fff; } } md-card { box-sizing: border-box; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; margin: 8px; box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); } md-card md-card-header { padding: 16px; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; } md-card md-card-header:first-child md-card-avatar { margin-right: 12px; } [dir=rtl] md-card md-card-header:first-child md-card-avatar { margin-right: auto; margin-left: 12px; } md-card md-card-header:last-child md-card-avatar { margin-left: 12px; } [dir=rtl] md-card md-card-header:last-child md-card-avatar { margin-left: auto; margin-right: 12px; } md-card md-card-header md-card-avatar { width: 40px; height: 40px; } md-card md-card-header md-card-avatar .md-user-avatar, md-card md-card-header md-card-avatar md-icon { border-radius: 50%; } md-card md-card-header md-card-avatar md-icon { padding: 8px; } md-card md-card-header md-card-avatar md-icon > svg { height: inherit; width: inherit; } md-card md-card-header md-card-avatar + md-card-header-text { max-height: 40px; } md-card md-card-header md-card-avatar + md-card-header-text .md-title { font-size: 14px; } md-card md-card-header md-card-header-text { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-flex: 1; -webkit-flex: 1; flex: 1; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; } md-card md-card-header md-card-header-text .md-subhead { font-size: 14px; } md-card > img, md-card > md-card-header img, md-card md-card-title-media img { box-sizing: border-box; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-flex: 0; -webkit-flex: 0 0 auto; flex: 0 0 auto; width: 100%; height: auto; } md-card md-card-title { padding: 24px 16px 16px; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-flex: 1; -webkit-flex: 1 1 auto; flex: 1 1 auto; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; } md-card md-card-title + md-card-content { padding-top: 0; } md-card md-card-title md-card-title-text { -webkit-box-flex: 1; -webkit-flex: 1; flex: 1; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; display: -webkit-box; display: -webkit-flex; display: flex; } md-card md-card-title md-card-title-text .md-subhead { padding-top: 0; font-size: 14px; } md-card md-card-title md-card-title-text:only-child .md-subhead { padding-top: 12px; } md-card md-card-title md-card-title-media { margin-top: -8px; } md-card md-card-title md-card-title-media .md-media-sm { height: 80px; width: 80px; } md-card md-card-title md-card-title-media .md-media-md { height: 112px; width: 112px; } md-card md-card-title md-card-title-media .md-media-lg { height: 152px; width: 152px; } md-card md-card-content { display: block; padding: 16px; } md-card md-card-content > p:first-child { margin-top: 0; } md-card md-card-content > p:last-child { margin-bottom: 0; } md-card md-card-content .md-media-xl { height: 240px; width: 240px; } md-card .md-actions, md-card md-card-actions { margin: 8px; } md-card .md-actions.layout-column .md-button:not(.md-icon-button), md-card md-card-actions.layout-column .md-button:not(.md-icon-button) { margin: 2px 0; } md-card .md-actions.layout-column .md-button:not(.md-icon-button):first-of-type, md-card md-card-actions.layout-column .md-button:not(.md-icon-button):first-of-type { margin-top: 0; } md-card .md-actions.layout-column .md-button:not(.md-icon-button):last-of-type, md-card md-card-actions.layout-column .md-button:not(.md-icon-button):last-of-type { margin-bottom: 0; } md-card .md-actions.layout-column .md-button.md-icon-button, md-card md-card-actions.layout-column .md-button.md-icon-button { margin-top: 6px; margin-bottom: 6px; } md-card .md-actions md-card-icon-actions, md-card md-card-actions md-card-icon-actions { -webkit-box-flex: 1; -webkit-flex: 1; flex: 1; -webkit-box-pack: start; -webkit-justify-content: flex-start; justify-content: flex-start; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; } md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button), md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button) { margin: 0 4px; } md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button):first-of-type, md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button):first-of-type { margin-left: 0; } [dir=rtl] md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button):first-of-type, [dir=rtl] md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button):first-of-type { margin-left: auto; margin-right: 0; } md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button):last-of-type, md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button):last-of-type { margin-right: 0; } [dir=rtl] md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button):last-of-type, [dir=rtl] md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button):last-of-type { margin-right: auto; margin-left: 0; } md-card .md-actions:not(.layout-column) .md-button.md-icon-button, md-card md-card-actions:not(.layout-column) .md-button.md-icon-button { margin-left: 6px; margin-right: 6px; } md-card .md-actions:not(.layout-column) .md-button.md-icon-button:first-of-type, md-card md-card-actions:not(.layout-column) .md-button.md-icon-button:first-of-type { margin-left: 12px; } [dir=rtl] md-card .md-actions:not(.layout-column) .md-button.md-icon-button:first-of-type, [dir=rtl] md-card md-card-actions:not(.layout-column) .md-button.md-icon-button:first-of-type { margin-left: auto; margin-right: 12px; } md-card .md-actions:not(.layout-column) .md-button.md-icon-button:last-of-type, md-card md-card-actions:not(.layout-column) .md-button.md-icon-button:last-of-type { margin-right: 12px; } [dir=rtl] md-card .md-actions:not(.layout-column) .md-button.md-icon-button:last-of-type, [dir=rtl] md-card md-card-actions:not(.layout-column) .md-button.md-icon-button:last-of-type { margin-right: auto; margin-left: 12px; } md-card .md-actions:not(.layout-column) .md-button + md-card-icon-actions, md-card md-card-actions:not(.layout-column) .md-button + md-card-icon-actions { -webkit-box-flex: 1; -webkit-flex: 1; flex: 1; -webkit-box-pack: end; -webkit-justify-content: flex-end; justify-content: flex-end; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; } md-card md-card-footer { margin-top: auto; padding: 16px; } @media screen and (-ms-high-contrast: active) { md-card { border: 1px solid #fff; } } .md-image-no-fill > img { width: auto; height: auto; } .md-contact-chips .md-chips md-chip { padding: 0 25px 0 0; } [dir=rtl] .md-contact-chips .md-chips md-chip { padding: 0 0 0 25px; } .md-contact-chips .md-chips md-chip .md-contact-avatar { float: left; } [dir=rtl] .md-contact-chips .md-chips md-chip .md-contact-avatar { float: right; } .md-contact-chips .md-chips md-chip .md-contact-avatar img { height: 32px; border-radius: 16px; } .md-contact-chips .md-chips md-chip .md-contact-name { display: inline-block; height: 32px; margin-left: 8px; } [dir=rtl] .md-contact-chips .md-chips md-chip .md-contact-name { margin-left: auto; margin-right: 8px; } .md-contact-suggestion { height: 56px; } .md-contact-suggestion img { height: 40px; border-radius: 20px; margin-top: 8px; } .md-contact-suggestion .md-contact-name { margin-left: 8px; width: 120px; } [dir=rtl] .md-contact-suggestion .md-contact-name { margin-left: auto; margin-right: 8px; } .md-contact-suggestion .md-contact-name, .md-contact-suggestion .md-contact-email { display: inline-block; overflow: hidden; text-overflow: ellipsis; } .md-contact-chips-suggestions li { height: 100%; } .md-chips { display: block; font-family: Roboto, "Helvetica Neue", sans-serif; font-size: 16px; padding: 0 0 8px 3px; vertical-align: middle; } .md-chips:after { content: ''; display: table; clear: both; } [dir=rtl] .md-chips { padding: 0 3px 8px 0; } .md-chips.md-readonly .md-chip-input-container { min-height: 32px; } .md-chips:not(.md-readonly) { cursor: text; } .md-chips.md-removable md-chip { padding-right: 22px; } [dir=rtl] .md-chips.md-removable md-chip { padding-right: 0; padding-left: 22px; } .md-chips.md-removable md-chip .md-chip-content { padding-right: 4px; } [dir=rtl] .md-chips.md-removable md-chip .md-chip-content { padding-right: 0; padding-left: 4px; } .md-chips md-chip { cursor: default; border-radius: 16px; display: block; height: 32px; line-height: 32px; margin: 8px 8px 0 0; padding: 0 12px 0 12px; float: left; box-sizing: border-box; max-width: 100%; position: relative; } [dir=rtl] .md-chips md-chip { margin: 8px 0 0 8px; } [dir=rtl] .md-chips md-chip { float: right; } .md-chips md-chip .md-chip-content { display: block; float: left; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; } [dir=rtl] .md-chips md-chip .md-chip-content { float: right; } .md-chips md-chip .md-chip-content:focus { outline: none; } .md-chips md-chip._md-chip-content-edit-is-enabled { -webkit-user-select: none; /* webkit (safari, chrome) browsers */ -moz-user-select: none; /* mozilla browsers */ -khtml-user-select: none; /* webkit (konqueror) browsers */ -ms-user-select: none; /* IE10+ */ } .md-chips md-chip .md-chip-remove-container { position: absolute; right: 0; line-height: 22px; } [dir=rtl] .md-chips md-chip .md-chip-remove-container { right: auto; left: 0; } .md-chips md-chip .md-chip-remove { text-align: center; width: 32px; height: 32px; min-width: 0; padding: 0; background: transparent; border: none; box-shadow: none; margin: 0; position: relative; } .md-chips md-chip .md-chip-remove md-icon { height: 18px; width: 18px; position: absolute; top: 50%; left: 50%; -webkit-transform: translate3d(-50%, -50%, 0); transform: translate3d(-50%, -50%, 0); } .md-chips .md-chip-input-container { display: block; line-height: 32px; margin: 8px 8px 0 0; padding: 0; float: left; } [dir=rtl] .md-chips .md-chip-input-container { margin: 8px 0 0 8px; } [dir=rtl] .md-chips .md-chip-input-container { float: right; } .md-chips .md-chip-input-container input:not([type]), .md-chips .md-chip-input-container input[type="email"], .md-chips .md-chip-input-container input[type="number"], .md-chips .md-chip-input-container input[type="tel"], .md-chips .md-chip-input-container input[type="url"], .md-chips .md-chip-input-container input[type="text"] { border: 0; height: 32px; line-height: 32px; padding: 0; } .md-chips .md-chip-input-container input:not([type]):focus, .md-chips .md-chip-input-container input[type="email"]:focus, .md-chips .md-chip-input-container input[type="number"]:focus, .md-chips .md-chip-input-container input[type="tel"]:focus, .md-chips .md-chip-input-container input[type="url"]:focus, .md-chips .md-chip-input-container input[type="text"]:focus { outline: none; } .md-chips .md-chip-input-container md-autocomplete, .md-chips .md-chip-input-container md-autocomplete-wrap { background: transparent; height: 32px; } .md-chips .md-chip-input-container md-autocomplete md-autocomplete-wrap { box-shadow: none; } .md-chips .md-chip-input-container md-autocomplete input { position: relative; } .md-chips .md-chip-input-container input { border: 0; height: 32px; line-height: 32px; padding: 0; } .md-chips .md-chip-input-container input:focus { outline: none; } .md-chips .md-chip-input-container md-autocomplete, .md-chips .md-chip-input-container md-autocomplete-wrap { height: 32px; } .md-chips .md-chip-input-container md-autocomplete { box-shadow: none; } .md-chips .md-chip-input-container md-autocomplete input { position: relative; } .md-chips .md-chip-input-container:not(:first-child) { margin: 8px 8px 0 0; } [dir=rtl] .md-chips .md-chip-input-container:not(:first-child) { margin: 8px 0 0 8px; } .md-chips .md-chip-input-container input { background: transparent; border-width: 0; } .md-chips md-autocomplete button { display: none; } @media screen and (-ms-high-contrast: active) { .md-chip-input-container, md-chip { border: 1px solid #fff; } .md-chip-input-container md-autocomplete { border: none; } } .md-inline-form md-checkbox { margin: 19px 0 18px; } md-checkbox { box-sizing: border-box; display: inline-block; margin-bottom: 16px; white-space: nowrap; cursor: pointer; outline: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; position: relative; min-width: 20px; min-height: 20px; margin-left: 0; margin-right: 16px; } [dir=rtl] md-checkbox { margin-left: 16px; } [dir=rtl] md-checkbox { margin-right: 0; } md-checkbox:last-of-type { margin-left: 0; margin-right: 0; } md-checkbox.md-focused:not([disabled]) .md-container:before { left: -8px; top: -8px; right: -8px; bottom: -8px; } md-checkbox.md-focused:not([disabled]):not(.md-checked) .md-container:before { background-color: rgba(0, 0, 0, 0.12); } md-checkbox.md-align-top-left > div.md-container { top: 12px; } md-checkbox .md-container { position: absolute; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); box-sizing: border-box; display: inline-block; width: 20px; height: 20px; left: 0; right: auto; } [dir=rtl] md-checkbox .md-container { left: auto; } [dir=rtl] md-checkbox .md-container { right: 0; } md-checkbox .md-container:before { box-sizing: border-box; background-color: transparent; border-radius: 50%; content: ''; position: absolute; display: block; height: auto; left: 0; top: 0; right: 0; bottom: 0; -webkit-transition: all 0.5s; transition: all 0.5s; width: auto; } md-checkbox .md-container:after { box-sizing: border-box; content: ''; position: absolute; top: -10px; right: -10px; bottom: -10px; left: -10px; } md-checkbox .md-container .md-ripple-container { position: absolute; display: block; width: auto; height: auto; left: -15px; top: -15px; right: -15px; bottom: -15px; } md-checkbox .md-icon { box-sizing: border-box; -webkit-transition: 240ms; transition: 240ms; position: absolute; top: 0; left: 0; width: 20px; height: 20px; border-width: 2px; border-style: solid; border-radius: 2px; } md-checkbox.md-checked .md-icon { border-color: transparent; } md-checkbox.md-checked .md-icon:after { box-sizing: border-box; -webkit-transform: rotate(45deg); transform: rotate(45deg); position: absolute; left: 4.66667px; top: 0.22222px; display: table; width: 6.66667px; height: 13.33333px; border-width: 2px; border-style: solid; border-top: 0; border-left: 0; content: ''; } md-checkbox[disabled] { cursor: default; } md-checkbox.md-indeterminate .md-icon:after { box-sizing: border-box; position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); display: table; width: 12px; height: 2px; border-width: 2px; border-style: solid; border-top: 0; border-left: 0; content: ''; } md-checkbox .md-label { box-sizing: border-box; position: relative; display: inline-block; vertical-align: middle; white-space: normal; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; margin-left: 30px; margin-right: 0; } [dir=rtl] md-checkbox .md-label { margin-left: 0; } [dir=rtl] md-checkbox .md-label { margin-right: 30px; } md-content { display: block; position: relative; overflow: auto; -webkit-overflow-scrolling: touch; } md-content[md-scroll-y] { overflow-y: auto; overflow-x: hidden; } md-content[md-scroll-x] { overflow-x: auto; overflow-y: hidden; } @media print { md-content { overflow: visible !important; } } /** Styles for mdCalendar. */ md-calendar { font-size: 13px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .md-calendar-scroll-mask { display: inline-block; overflow: hidden; height: 308px; } .md-calendar-scroll-mask .md-virtual-repeat-scroller { overflow-y: scroll; -webkit-overflow-scrolling: touch; } .md-calendar-scroll-mask .md-virtual-repeat-scroller::-webkit-scrollbar { display: none; } .md-calendar-scroll-mask .md-virtual-repeat-offsetter { width: 100%; } .md-calendar-scroll-container { box-shadow: inset -3px 3px 6px rgba(0, 0, 0, 0.2); display: inline-block; height: 308px; width: 346px; } .md-calendar-date { height: 44px; width: 44px; text-align: center; padding: 0; border: none; box-sizing: content-box; } .md-calendar-date:first-child { padding-left: 16px; } [dir=rtl] .md-calendar-date:first-child { padding-left: 0; padding-right: 16px; } .md-calendar-date:last-child { padding-right: 16px; } [dir=rtl] .md-calendar-date:last-child { padding-right: 0; padding-left: 16px; } .md-calendar-date.md-calendar-date-disabled { cursor: default; } .md-calendar-date-selection-indicator { -webkit-transition: background-color, color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: background-color, color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); border-radius: 50%; display: inline-block; width: 40px; height: 40px; line-height: 40px; } .md-calendar-date:not(.md-disabled) .md-calendar-date-selection-indicator { cursor: pointer; } .md-calendar-month-label { height: 44px; font-size: 14px; font-weight: 500; padding: 0 0 0 24px; } [dir=rtl] .md-calendar-month-label { padding: 0 24px 0 0; } md-calendar-month .md-calendar-month-label:not(.md-calendar-month-label-disabled) { cursor: pointer; } .md-calendar-month-label md-icon { -webkit-transform: rotate(180deg); transform: rotate(180deg); } [dir=rtl] .md-calendar-month-label md-icon { -webkit-transform: none; transform: none; } .md-calendar-month-label span { vertical-align: middle; } .md-calendar-day-header { table-layout: fixed; border-spacing: 0; border-collapse: collapse; } .md-calendar-day-header th { height: 40px; width: 44px; text-align: center; padding: 0; border: none; box-sizing: content-box; font-weight: normal; } .md-calendar-day-header th:first-child { padding-left: 16px; } [dir=rtl] .md-calendar-day-header th:first-child { padding-left: 0; padding-right: 16px; } .md-calendar-day-header th:last-child { padding-right: 16px; } [dir=rtl] .md-calendar-day-header th:last-child { padding-right: 0; padding-left: 16px; } .md-calendar { table-layout: fixed; border-spacing: 0; border-collapse: collapse; } .md-calendar tr:last-child td { border-bottom-width: 1px; border-bottom-style: solid; } .md-calendar:first-child { border-top: 1px solid transparent; } .md-calendar tbody, .md-calendar td, .md-calendar tr { vertical-align: middle; box-sizing: content-box; } /** Styles for mdDatepicker. */ md-datepicker { white-space: nowrap; overflow: hidden; vertical-align: middle; } .md-inline-form md-datepicker { margin-top: 12px; } .md-datepicker-button { display: inline-block; box-sizing: border-box; background: none; vertical-align: middle; position: relative; } .md-datepicker-button:before { top: 0; left: 0; bottom: 0; right: 0; position: absolute; content: ''; speak: none; } .md-datepicker-input { font-size: 14px; box-sizing: border-box; border: none; box-shadow: none; outline: none; background: transparent; min-width: 120px; max-width: 328px; padding: 0 0 5px; } .md-datepicker-input::-ms-clear { display: none; } ._md-datepicker-floating-label > md-datepicker { overflow: visible; } ._md-datepicker-floating-label > md-datepicker .md-datepicker-input-container { border: none; } ._md-datepicker-floating-label > md-datepicker .md-datepicker-button { float: left; margin-top: -12px; top: 9.5px; } [dir=rtl] ._md-datepicker-floating-label > md-datepicker .md-datepicker-button { float: right; } ._md-datepicker-floating-label .md-input { float: none; } ._md-datepicker-floating-label._md-datepicker-has-calendar-icon > label:not(.md-no-float):not(.md-container-ignore) { right: 18px; left: auto; width: calc(100% - 84px); } [dir=rtl] ._md-datepicker-floating-label._md-datepicker-has-calendar-icon > label:not(.md-no-float):not(.md-container-ignore) { right: auto; } [dir=rtl] ._md-datepicker-floating-label._md-datepicker-has-calendar-icon > label:not(.md-no-float):not(.md-container-ignore) { left: 18px; } ._md-datepicker-floating-label._md-datepicker-has-calendar-icon .md-input-message-animation { margin-left: 64px; } [dir=rtl] ._md-datepicker-floating-label._md-datepicker-has-calendar-icon .md-input-message-animation { margin-left: auto; margin-right: 64px; } ._md-datepicker-has-triangle-icon { padding-right: 18px; margin-right: -18px; } [dir=rtl] ._md-datepicker-has-triangle-icon { padding-right: 0; padding-left: 18px; } [dir=rtl] ._md-datepicker-has-triangle-icon { margin-right: auto; margin-left: -18px; } .md-datepicker-input-container { position: relative; border-bottom-width: 1px; border-bottom-style: solid; display: inline-block; width: auto; } .md-icon-button + .md-datepicker-input-container { margin-left: 12px; } [dir=rtl] .md-icon-button + .md-datepicker-input-container { margin-left: auto; margin-right: 12px; } .md-datepicker-input-container.md-datepicker-focused { border-bottom-width: 2px; } .md-datepicker-is-showing .md-scroll-mask { z-index: 99; } .md-datepicker-calendar-pane { position: absolute; top: 0; left: -100%; z-index: 100; border-width: 1px; border-style: solid; background: transparent; -webkit-transform: scale(0); transform: scale(0); -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transition: -webkit-transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); transition: -webkit-transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); transition: transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); transition: transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1), -webkit-transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); } .md-datepicker-calendar-pane.md-pane-open { -webkit-transform: scale(1); transform: scale(1); } .md-datepicker-input-mask { height: 40px; width: 340px; position: relative; overflow: hidden; background: transparent; pointer-events: none; cursor: text; } .md-datepicker-calendar { opacity: 0; -webkit-transition: opacity 0.2s cubic-bezier(0.5, 0, 0.25, 1); transition: opacity 0.2s cubic-bezier(0.5, 0, 0.25, 1); } .md-pane-open .md-datepicker-calendar { opacity: 1; } .md-datepicker-calendar md-calendar:focus { outline: none; } .md-datepicker-expand-triangle { position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid; } .md-datepicker-triangle-button { position: absolute; right: 0; bottom: -2.5px; -webkit-transform: translateX(45%); transform: translateX(45%); } [dir=rtl] .md-datepicker-triangle-button { right: auto; left: 0; } [dir=rtl] .md-datepicker-triangle-button { -webkit-transform: translateX(-45%); transform: translateX(-45%); } .md-datepicker-triangle-button.md-button.md-icon-button { height: 36px; width: 36px; position: absolute; padding: 8px; } md-datepicker[disabled] .md-datepicker-input-container { border-bottom-color: transparent; } md-datepicker[disabled] .md-datepicker-triangle-button { display: none; } .md-datepicker-open { overflow: hidden; } .md-datepicker-open .md-datepicker-input-container, .md-datepicker-open input.md-input { border-bottom-color: transparent; } .md-datepicker-open .md-datepicker-triangle-button, .md-datepicker-open.md-input-has-value > label, .md-datepicker-open.md-input-has-placeholder > label { display: none; } .md-datepicker-pos-adjusted .md-datepicker-input-mask { display: none; } .md-datepicker-calendar-pane .md-calendar { -webkit-transform: translateY(-85px); transform: translateY(-85px); -webkit-transition: -webkit-transform 0.65s cubic-bezier(0.25, 0.8, 0.25, 1); transition: -webkit-transform 0.65s cubic-bezier(0.25, 0.8, 0.25, 1); transition: transform 0.65s cubic-bezier(0.25, 0.8, 0.25, 1); transition: transform 0.65s cubic-bezier(0.25, 0.8, 0.25, 1), -webkit-transform 0.65s cubic-bezier(0.25, 0.8, 0.25, 1); -webkit-transition-delay: 0.125s; transition-delay: 0.125s; } .md-datepicker-calendar-pane.md-pane-open .md-calendar { -webkit-transform: translateY(0); transform: translateY(0); } .md-dialog-is-showing { max-height: 100%; } .md-dialog-container { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center; -webkit-box-align: center; -webkit-align-items: center; align-items: center; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 80; overflow: hidden; } md-dialog { opacity: 0; min-width: 240px; max-width: 80%; max-height: 80%; position: relative; overflow: auto; box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2), 0px 13px 19px 2px rgba(0, 0, 0, 0.14), 0px 5px 24px 4px rgba(0, 0, 0, 0.12); display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; } md-dialog.md-transition-in { opacity: 1; -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); -webkit-transform: translate(0, 0) scale(1); transform: translate(0, 0) scale(1); } md-dialog.md-transition-out { opacity: 0; -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); -webkit-transform: translate(0, 100%) scale(0.2); transform: translate(0, 100%) scale(0.2); } md-dialog > form { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; overflow: auto; } md-dialog .md-dialog-content { padding: 24px; } md-dialog md-dialog-content { -webkit-box-ordinal-group: 2; -webkit-order: 1; order: 1; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; overflow: auto; -webkit-overflow-scrolling: touch; } md-dialog md-dialog-content:not([layout=row]) > *:first-child:not(.md-subheader) { margin-top: 0; } md-dialog md-dialog-content:focus { outline: none; } md-dialog md-dialog-content .md-subheader { margin: 0; } md-dialog md-dialog-content .md-dialog-content-body { width: 100%; } md-dialog md-dialog-content .md-prompt-input-container { width: 100%; box-sizing: border-box; } md-dialog .md-actions, md-dialog md-dialog-actions { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-ordinal-group: 3; -webkit-order: 2; order: 2; box-sizing: border-box; -webkit-box-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: end; -webkit-justify-content: flex-end; justify-content: flex-end; margin-bottom: 0; padding-right: 8px; padding-left: 16px; min-height: 52px; overflow: hidden; } [dir=rtl] md-dialog .md-actions, [dir=rtl] md-dialog md-dialog-actions { padding-right: 16px; } [dir=rtl] md-dialog .md-actions, [dir=rtl] md-dialog md-dialog-actions { padding-left: 8px; } md-dialog .md-actions .md-button, md-dialog md-dialog-actions .md-button { margin-bottom: 8px; margin-left: 8px; margin-right: 0; margin-top: 8px; } [dir=rtl] md-dialog .md-actions .md-button, [dir=rtl] md-dialog md-dialog-actions .md-button { margin-left: 0; } [dir=rtl] md-dialog .md-actions .md-button, [dir=rtl] md-dialog md-dialog-actions .md-button { margin-right: 8px; } md-dialog.md-content-overflow .md-actions, md-dialog.md-content-overflow md-dialog-actions { border-top-width: 1px; border-top-style: solid; } @media screen and (-ms-high-contrast: active) { md-dialog { border: 1px solid #fff; } } @media (max-width: 959px) { md-dialog.md-dialog-fullscreen { min-height: 100%; min-width: 100%; border-radius: 0; } } md-divider { display: block; border-top-width: 1px; border-top-style: solid; margin: 0; } md-divider[md-inset] { margin-left: 80px; } [dir=rtl] md-divider[md-inset] { margin-left: auto; margin-right: 80px; } .layout-row > md-divider, .layout-xs-row > md-divider, .layout-gt-xs-row > md-divider, .layout-sm-row > md-divider, .layout-gt-sm-row > md-divider, .layout-md-row > md-divider, .layout-gt-md-row > md-divider, .layout-lg-row > md-divider, .layout-gt-lg-row > md-divider, .layout-xl-row > md-divider { border-top-width: 0; border-right-width: 1px; border-right-style: solid; } md-fab-speed-dial { position: relative; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-align: center; -webkit-align-items: center; align-items: center; z-index: 20; /* * Hide some graphics glitches if switching animation types */ /* * Handle the animations */ } md-fab-speed-dial.md-fab-bottom-right { top: auto; right: 20px; bottom: 20px; left: auto; position: absolute; } md-fab-speed-dial.md-fab-bottom-left { top: auto; right: auto; bottom: 20px; left: 20px; position: absolute; } md-fab-speed-dial.md-fab-top-right { top: 20px; right: 20px; bottom: auto; left: auto; position: absolute; } md-fab-speed-dial.md-fab-top-left { top: 20px; right: auto; bottom: auto; left: 20px; position: absolute; } md-fab-speed-dial:not(.md-hover-full) { pointer-events: none; } md-fab-speed-dial:not(.md-hover-full) md-fab-trigger, md-fab-speed-dial:not(.md-hover-full) .md-fab-action-item { pointer-events: auto; } md-fab-speed-dial:not(.md-hover-full).md-is-open { pointer-events: auto; } md-fab-speed-dial ._md-css-variables { z-index: 20; } md-fab-speed-dial.md-is-open .md-fab-action-item { -webkit-box-align: center; -webkit-align-items: center; align-items: center; } md-fab-speed-dial md-fab-actions { display: -webkit-box; display: -webkit-flex; display: flex; height: auto; } md-fab-speed-dial md-fab-actions .md-fab-action-item { -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } md-fab-speed-dial.md-down { -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; } md-fab-speed-dial.md-down md-fab-trigger { -webkit-box-ordinal-group: 2; -webkit-order: 1; order: 1; } md-fab-speed-dial.md-down md-fab-actions { -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; -webkit-box-ordinal-group: 3; -webkit-order: 2; order: 2; } md-fab-speed-dial.md-up { -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; } md-fab-speed-dial.md-up md-fab-trigger { -webkit-box-ordinal-group: 3; -webkit-order: 2; order: 2; } md-fab-speed-dial.md-up md-fab-actions { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -webkit-flex-direction: column-reverse; flex-direction: column-reverse; -webkit-box-ordinal-group: 2; -webkit-order: 1; order: 1; } md-fab-speed-dial.md-left { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; } md-fab-speed-dial.md-left md-fab-trigger { -webkit-box-ordinal-group: 3; -webkit-order: 2; order: 2; } md-fab-speed-dial.md-left md-fab-actions { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -webkit-flex-direction: row-reverse; flex-direction: row-reverse; -webkit-box-ordinal-group: 2; -webkit-order: 1; order: 1; } md-fab-speed-dial.md-left md-fab-actions .md-fab-action-item { -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } md-fab-speed-dial.md-right { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; } md-fab-speed-dial.md-right md-fab-trigger { -webkit-box-ordinal-group: 2; -webkit-order: 1; order: 1; } md-fab-speed-dial.md-right md-fab-actions { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; -webkit-box-ordinal-group: 3; -webkit-order: 2; order: 2; } md-fab-speed-dial.md-right md-fab-actions .md-fab-action-item { -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } md-fab-speed-dial.md-fling-remove .md-fab-action-item > *, md-fab-speed-dial.md-scale-remove .md-fab-action-item > * { visibility: hidden; } md-fab-speed-dial.md-fling .md-fab-action-item { opacity: 1; } md-fab-speed-dial.md-fling.md-animations-waiting .md-fab-action-item { opacity: 0; -webkit-transition-duration: 0s; transition-duration: 0s; } md-fab-speed-dial.md-scale .md-fab-action-item { -webkit-transform: scale(0); transform: scale(0); -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); -webkit-transition-duration: 0.14286s; transition-duration: 0.14286s; } md-fab-toolbar { display: block; /* * Closed styling */ /* * Hover styling */ } md-fab-toolbar.md-fab-bottom-right { top: auto; right: 20px; bottom: 20px; left: auto; position: absolute; } md-fab-toolbar.md-fab-bottom-left { top: auto; right: auto; bottom: 20px; left: 20px; position: absolute; } md-fab-toolbar.md-fab-top-right { top: 20px; right: 20px; bottom: auto; left: auto; position: absolute; } md-fab-toolbar.md-fab-top-left { top: 20px; right: auto; bottom: auto; left: 20px; position: absolute; } md-fab-toolbar .md-fab-toolbar-wrapper { display: block; position: relative; overflow: hidden; height: 68px; } md-fab-toolbar md-fab-trigger { position: absolute; z-index: 20; } md-fab-toolbar md-fab-trigger button { overflow: visible !important; } md-fab-toolbar md-fab-trigger .md-fab-toolbar-background { display: block; position: absolute; z-index: 21; opacity: 1; -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } md-fab-toolbar md-fab-trigger md-icon { position: relative; z-index: 22; opacity: 1; -webkit-transition: all 200ms ease-in; transition: all 200ms ease-in; } md-fab-toolbar.md-left md-fab-trigger { right: 0; } [dir=rtl] md-fab-toolbar.md-left md-fab-trigger { right: auto; left: 0; } md-fab-toolbar.md-left .md-toolbar-tools { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -webkit-flex-direction: row-reverse; flex-direction: row-reverse; } md-fab-toolbar.md-left .md-toolbar-tools > .md-button:first-child { margin-right: 0.6rem; } [dir=rtl] md-fab-toolbar.md-left .md-toolbar-tools > .md-button:first-child { margin-right: auto; margin-left: 0.6rem; } md-fab-toolbar.md-left .md-toolbar-tools > .md-button:first-child { margin-left: -0.8rem; } [dir=rtl] md-fab-toolbar.md-left .md-toolbar-tools > .md-button:first-child { margin-left: auto; margin-right: -0.8rem; } md-fab-toolbar.md-left .md-toolbar-tools > .md-button:last-child { margin-right: 8px; } [dir=rtl] md-fab-toolbar.md-left .md-toolbar-tools > .md-button:last-child { margin-right: auto; margin-left: 8px; } md-fab-toolbar.md-right md-fab-trigger { left: 0; } [dir=rtl] md-fab-toolbar.md-right md-fab-trigger { left: auto; right: 0; } md-fab-toolbar.md-right .md-toolbar-tools { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; } md-fab-toolbar md-toolbar { background-color: transparent !important; pointer-events: none; z-index: 23; } md-fab-toolbar md-toolbar .md-toolbar-tools { padding: 0 20px; margin-top: 3px; } md-fab-toolbar md-toolbar .md-fab-action-item { opacity: 0; -webkit-transform: scale(0); transform: scale(0); -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); -webkit-transition-duration: 0.15s; transition-duration: 0.15s; } md-fab-toolbar.md-is-open md-fab-trigger > button { box-shadow: none; } md-fab-toolbar.md-is-open md-fab-trigger > button md-icon { opacity: 0; } md-fab-toolbar.md-is-open .md-fab-action-item { opacity: 1; -webkit-transform: scale(1); transform: scale(1); } md-icon { margin: auto; background-repeat: no-repeat no-repeat; display: inline-block; vertical-align: middle; fill: currentColor; height: 24px; width: 24px; min-height: 24px; min-width: 24px; } md-icon svg { pointer-events: none; display: block; } md-icon[md-font-icon] { line-height: 24px; width: auto; } md-grid-list { box-sizing: border-box; display: block; position: relative; } md-grid-list md-grid-tile, md-grid-list md-grid-tile > figure, md-grid-list md-grid-tile-header, md-grid-list md-grid-tile-footer { box-sizing: border-box; } md-grid-list md-grid-tile { display: block; position: absolute; } md-grid-list md-grid-tile figure { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center; height: 100%; position: absolute; top: 0; right: 0; bottom: 0; left: 0; padding: 0; margin: 0; } md-grid-list md-grid-tile md-grid-tile-header, md-grid-list md-grid-tile md-grid-tile-footer { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; -webkit-box-align: center; -webkit-align-items: center; align-items: center; height: 48px; color: #fff; background: rgba(0, 0, 0, 0.18); overflow: hidden; position: absolute; left: 0; right: 0; } md-grid-list md-grid-tile md-grid-tile-header h3, md-grid-list md-grid-tile md-grid-tile-header h4, md-grid-list md-grid-tile md-grid-tile-footer h3, md-grid-list md-grid-tile md-grid-tile-footer h4 { font-weight: 400; margin: 0 0 0 16px; } md-grid-list md-grid-tile md-grid-tile-header h3, md-grid-list md-grid-tile md-grid-tile-footer h3 { font-size: 14px; } md-grid-list md-grid-tile md-grid-tile-header h4, md-grid-list md-grid-tile md-grid-tile-footer h4 { font-size: 12px; } md-grid-list md-grid-tile md-grid-tile-header { top: 0; } md-grid-list md-grid-tile md-grid-tile-footer { bottom: 0; } @media screen and (-ms-high-contrast: active) { md-grid-tile { border: 1px solid #fff; } md-grid-tile-footer { border-top: 1px solid #fff; } } md-input-container { display: inline-block; position: relative; padding: 2px; margin: 18px 0; vertical-align: middle; /* * The .md-input class is added to the input/textarea */ } md-input-container:after { content: ''; display: table; clear: both; } md-input-container.md-block { display: block; } md-input-container .md-errors-spacer { float: right; min-height: 24px; min-width: 1px; } [dir=rtl] md-input-container .md-errors-spacer { float: left; } md-input-container > md-icon { position: absolute; top: 8px; left: 2px; right: auto; } [dir=rtl] md-input-container > md-icon { left: auto; } [dir=rtl] md-input-container > md-icon { right: 2px; } md-input-container textarea, md-input-container input[type="text"], md-input-container input[type="password"], md-input-container input[type="datetime"], md-input-container input[type="datetime-local"], md-input-container input[type="date"], md-input-container input[type="month"], md-input-container input[type="time"], md-input-container input[type="week"], md-input-container input[type="number"], md-input-container input[type="email"], md-input-container input[type="url"], md-input-container input[type="search"], md-input-container input[type="tel"], md-input-container input[type="color"] { /* remove default appearance from all input/textarea */ -moz-appearance: none; -webkit-appearance: none; } md-input-container input[type="date"], md-input-container input[type="datetime-local"], md-input-container input[type="month"], md-input-container input[type="time"], md-input-container input[type="week"] { min-height: 26px; } md-input-container textarea { resize: none; overflow: hidden; } md-input-container textarea.md-input { min-height: 26px; -ms-flex-preferred-size: auto; } md-input-container textarea[md-no-autogrow] { height: auto; overflow: auto; } md-input-container label:not(.md-container-ignore) { position: absolute; bottom: 100%; left: 0; right: auto; } [dir=rtl] md-input-container label:not(.md-container-ignore) { left: auto; } [dir=rtl] md-input-container label:not(.md-container-ignore) { right: 0; } md-input-container label:not(.md-container-ignore).md-required:after { content: ' *'; font-size: 13px; vertical-align: top; } md-input-container label:not(.md-no-float):not(.md-container-ignore), md-input-container .md-placeholder { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%; -webkit-box-ordinal-group: 2; -webkit-order: 1; order: 1; pointer-events: none; -webkit-font-smoothing: antialiased; padding-left: 3px; padding-right: 0; z-index: 1; -webkit-transform: translate3d(0, 28px, 0) scale(1); transform: translate3d(0, 28px, 0) scale(1); -webkit-transition: -webkit-transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: -webkit-transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1), -webkit-transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); max-width: 100%; -webkit-transform-origin: left top; transform-origin: left top; } [dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), [dir=rtl] md-input-container .md-placeholder { padding-left: 0; } [dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), [dir=rtl] md-input-container .md-placeholder { padding-right: 3px; } [dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), [dir=rtl] md-input-container .md-placeholder { -webkit-transform-origin: right top; transform-origin: right top; } md-input-container .md-placeholder { position: absolute; top: 0; opacity: 0; -webkit-transition-property: opacity, -webkit-transform; transition-property: opacity, -webkit-transform; transition-property: opacity, transform; transition-property: opacity, transform, -webkit-transform; -webkit-transform: translate3d(0, 30px, 0); transform: translate3d(0, 30px, 0); } md-input-container.md-input-focused .md-placeholder { opacity: 1; -webkit-transform: translate3d(0, 24px, 0); transform: translate3d(0, 24px, 0); } md-input-container.md-input-has-value .md-placeholder { -webkit-transition: none; transition: none; opacity: 0; } md-input-container:not(.md-input-has-value) input:not(:focus), md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-ampm-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-day-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-hour-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-millisecond-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-minute-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-month-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-second-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-week-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-year-field, md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-text { color: transparent; } md-input-container .md-input { -webkit-box-ordinal-group: 3; -webkit-order: 2; order: 2; display: block; margin-top: 0; background: none; padding-top: 2px; padding-bottom: 1px; padding-left: 2px; padding-right: 2px; border-width: 0 0 1px 0; line-height: 26px; height: 30px; -ms-flex-preferred-size: 26px; border-radius: 0; border-style: solid; width: 100%; box-sizing: border-box; float: left; } [dir=rtl] md-input-container .md-input { float: right; } md-input-container .md-input:focus { outline: none; } md-input-container .md-input:invalid { outline: none; box-shadow: none; } md-input-container .md-input.md-no-flex { -webkit-box-flex: 0 !important; -webkit-flex: none !important; flex: none !important; } md-input-container .md-char-counter { text-align: right; padding-right: 2px; padding-left: 0; } [dir=rtl] md-input-container .md-char-counter { text-align: left; } [dir=rtl] md-input-container .md-char-counter { padding-right: 0; } [dir=rtl] md-input-container .md-char-counter { padding-left: 2px; } md-input-container .md-input-messages-animation { position: relative; -webkit-box-ordinal-group: 5; -webkit-order: 4; order: 4; overflow: hidden; clear: left; } [dir=rtl] md-input-container .md-input-messages-animation { clear: right; } md-input-container .md-input-message-animation, md-input-container .md-char-counter { font-size: 12px; line-height: 14px; overflow: hidden; -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); opacity: 1; margin-top: 0; padding-top: 5px; } md-input-container .md-input-message-animation:not(.md-char-counter), md-input-container .md-char-counter:not(.md-char-counter) { padding-right: 5px; padding-left: 0; } [dir=rtl] md-input-container .md-input-message-animation:not(.md-char-counter), [dir=rtl] md-input-container .md-char-counter:not(.md-char-counter) { padding-right: 0; } [dir=rtl] md-input-container .md-input-message-animation:not(.md-char-counter), [dir=rtl] md-input-container .md-char-counter:not(.md-char-counter) { padding-left: 5px; } md-input-container:not(.md-input-invalid) .md-auto-hide .md-input-message-animation { opacity: 0; margin-top: -100px; } md-input-container .md-input-message-animation.ng-enter-prepare { opacity: 0; margin-top: -100px; } md-input-container .md-input-message-animation.ng-enter:not(.ng-enter-active) { opacity: 0; margin-top: -100px; } md-input-container.md-input-focused label:not(.md-no-float), md-input-container.md-input-has-placeholder label:not(.md-no-float), md-input-container.md-input-has-value label:not(.md-no-float) { -webkit-transform: translate3d(0, 6px, 0) scale(0.75); transform: translate3d(0, 6px, 0) scale(0.75); -webkit-transition: width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s; transition: width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s; transition: transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s; transition: transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s; } md-input-container.md-input-has-value label { -webkit-transition: none; transition: none; } md-input-container.md-input-focused .md-input, md-input-container .md-input.ng-invalid.ng-dirty, md-input-container.md-input-resized .md-input { padding-bottom: 0; border-width: 0 0 2px 0; } md-input-container .md-input[disabled], [disabled] md-input-container .md-input { background-position: bottom -1px left 0; background-size: 4px 1px; background-repeat: repeat-x; } md-input-container.md-icon-float { -webkit-transition: margin-top 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: margin-top 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } md-input-container.md-icon-float > label { pointer-events: none; position: absolute; } md-input-container.md-icon-float > md-icon { top: 8px; left: 2px; right: auto; } [dir=rtl] md-input-container.md-icon-float > md-icon { left: auto; } [dir=rtl] md-input-container.md-icon-float > md-icon { right: 2px; } md-input-container.md-icon-left > label:not(.md-no-float):not(.md-container-ignore), md-input-container.md-icon-left > label .md-placeholder, md-input-container.md-icon-right > label:not(.md-no-float):not(.md-container-ignore), md-input-container.md-icon-right > label .md-placeholder { width: calc(100% - 36px - 18px); } md-input-container.md-icon-left { padding-left: 36px; padding-right: 0; } [dir=rtl] md-input-container.md-icon-left { padding-left: 0; } [dir=rtl] md-input-container.md-icon-left { padding-right: 36px; } md-input-container.md-icon-left > label { left: 36px; right: auto; } [dir=rtl] md-input-container.md-icon-left > label { left: auto; } [dir=rtl] md-input-container.md-icon-left > label { right: 36px; } md-input-container.md-icon-right { padding-left: 0; padding-right: 36px; } [dir=rtl] md-input-container.md-icon-right { padding-left: 36px; } [dir=rtl] md-input-container.md-icon-right { padding-right: 0; } md-input-container.md-icon-right > md-icon:last-of-type { margin: 0; right: 2px; left: auto; } [dir=rtl] md-input-container.md-icon-right > md-icon:last-of-type { right: auto; } [dir=rtl] md-input-container.md-icon-right > md-icon:last-of-type { left: 2px; } md-input-container.md-icon-left.md-icon-right { padding-left: 36px; padding-right: 36px; } md-input-container.md-icon-left.md-icon-right > label:not(.md-no-float):not(.md-container-ignore), md-input-container.md-icon-left.md-icon-right > label .md-placeholder { width: calc(100% - (36px * 2)); } .md-resize-wrapper { position: relative; } .md-resize-wrapper:after { content: ''; display: table; clear: both; } .md-resize-handle { position: absolute; bottom: -5px; left: 0; height: 10px; background: transparent; width: 100%; cursor: ns-resize; } @media screen and (-ms-high-contrast: active) { md-input-container.md-default-theme > md-icon { fill: #fff; } } md-list { display: block; padding: 8px 0px 8px 0px; } md-list .md-subheader { font-size: 14px; font-weight: 500; letter-spacing: 0.010em; line-height: 1.2em; } md-list.md-dense md-list-item, md-list.md-dense md-list-item .md-list-item-inner { min-height: 48px; } md-list.md-dense md-list-item::before, md-list.md-dense md-list-item .md-list-item-inner::before { content: ''; min-height: 48px; visibility: hidden; display: inline-block; } md-list.md-dense md-list-item md-icon:first-child, md-list.md-dense md-list-item .md-list-item-inner md-icon:first-child { width: 20px; height: 20px; } md-list.md-dense md-list-item > md-icon:first-child:not(.md-avatar-icon), md-list.md-dense md-list-item .md-list-item-inner > md-icon:first-child:not(.md-avatar-icon) { margin-right: 36px; } [dir=rtl] md-list.md-dense md-list-item > md-icon:first-child:not(.md-avatar-icon), [dir=rtl] md-list.md-dense md-list-item .md-list-item-inner > md-icon:first-child:not(.md-avatar-icon) { margin-right: auto; margin-left: 36px; } md-list.md-dense md-list-item .md-avatar, md-list.md-dense md-list-item .md-avatar-icon, md-list.md-dense md-list-item .md-list-item-inner .md-avatar, md-list.md-dense md-list-item .md-list-item-inner .md-avatar-icon { margin-right: 20px; } [dir=rtl] md-list.md-dense md-list-item .md-avatar, [dir=rtl] md-list.md-dense md-list-item .md-avatar-icon, [dir=rtl] md-list.md-dense md-list-item .md-list-item-inner .md-avatar, [dir=rtl] md-list.md-dense md-list-item .md-list-item-inner .md-avatar-icon { margin-right: auto; margin-left: 20px; } md-list.md-dense md-list-item .md-avatar, md-list.md-dense md-list-item .md-list-item-inner .md-avatar { -webkit-box-flex: 0; -webkit-flex: none; flex: none; width: 36px; height: 36px; } md-list.md-dense md-list-item.md-2-line .md-list-item-text.md-offset, md-list.md-dense md-list-item.md-2-line > .md-no-style .md-list-item-text.md-offset, md-list.md-dense md-list-item.md-3-line .md-list-item-text.md-offset, md-list.md-dense md-list-item.md-3-line > .md-no-style .md-list-item-text.md-offset { margin-left: 56px; } [dir=rtl] md-list.md-dense md-list-item.md-2-line .md-list-item-text.md-offset, [dir=rtl] md-list.md-dense md-list-item.md-2-line > .md-no-style .md-list-item-text.md-offset, [dir=rtl] md-list.md-dense md-list-item.md-3-line .md-list-item-text.md-offset, [dir=rtl] md-list.md-dense md-list-item.md-3-line > .md-no-style .md-list-item-text.md-offset { margin-left: auto; margin-right: 56px; } md-list.md-dense md-list-item.md-2-line .md-list-item-text h3, md-list.md-dense md-list-item.md-2-line .md-list-item-text h4, md-list.md-dense md-list-item.md-2-line .md-list-item-text p, md-list.md-dense md-list-item.md-2-line > .md-no-style .md-list-item-text h3, md-list.md-dense md-list-item.md-2-line > .md-no-style .md-list-item-text h4, md-list.md-dense md-list-item.md-2-line > .md-no-style .md-list-item-text p, md-list.md-dense md-list-item.md-3-line .md-list-item-text h3, md-list.md-dense md-list-item.md-3-line .md-list-item-text h4, md-list.md-dense md-list-item.md-3-line .md-list-item-text p, md-list.md-dense md-list-item.md-3-line > .md-no-style .md-list-item-text h3, md-list.md-dense md-list-item.md-3-line > .md-no-style .md-list-item-text h4, md-list.md-dense md-list-item.md-3-line > .md-no-style .md-list-item-text p { line-height: 1.05; font-size: 12px; } md-list.md-dense md-list-item.md-2-line .md-list-item-text h3, md-list.md-dense md-list-item.md-2-line > .md-no-style .md-list-item-text h3, md-list.md-dense md-list-item.md-3-line .md-list-item-text h3, md-list.md-dense md-list-item.md-3-line > .md-no-style .md-list-item-text h3 { font-size: 13px; } md-list.md-dense md-list-item.md-2-line, md-list.md-dense md-list-item.md-2-line > .md-no-style { min-height: 60px; } md-list.md-dense md-list-item.md-2-line::before, md-list.md-dense md-list-item.md-2-line > .md-no-style::before { content: ''; min-height: 60px; visibility: hidden; display: inline-block; } md-list.md-dense md-list-item.md-2-line > .md-avatar, md-list.md-dense md-list-item.md-2-line .md-avatar-icon, md-list.md-dense md-list-item.md-2-line > .md-no-style > .md-avatar, md-list.md-dense md-list-item.md-2-line > .md-no-style .md-avatar-icon { margin-top: 12px; } md-list.md-dense md-list-item.md-3-line, md-list.md-dense md-list-item.md-3-line > .md-no-style { min-height: 76px; } md-list.md-dense md-list-item.md-3-line::before, md-list.md-dense md-list-item.md-3-line > .md-no-style::before { content: ''; min-height: 76px; visibility: hidden; display: inline-block; } md-list.md-dense md-list-item.md-3-line > md-icon:first-child, md-list.md-dense md-list-item.md-3-line > .md-avatar, md-list.md-dense md-list-item.md-3-line > .md-no-style > md-icon:first-child, md-list.md-dense md-list-item.md-3-line > .md-no-style > .md-avatar { margin-top: 16px; } md-list-item { position: relative; } md-list-item.md-proxy-focus.md-focused .md-no-style { -webkit-transition: background-color 0.15s linear; transition: background-color 0.15s linear; } md-list-item._md-button-wrap { position: relative; } md-list-item._md-button-wrap > div.md-button:first-child { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: start; -webkit-justify-content: flex-start; justify-content: flex-start; padding: 0 16px; margin: 0; font-weight: 400; text-align: left; border: medium none; } [dir=rtl] md-list-item._md-button-wrap > div.md-button:first-child { text-align: right; } md-list-item._md-button-wrap > div.md-button:first-child > .md-button:first-child { position: absolute; top: 0; left: 0; height: 100%; margin: 0; padding: 0; } md-list-item._md-button-wrap > div.md-button:first-child .md-list-item-inner { width: 100%; min-height: inherit; } md-list-item.md-no-proxy, md-list-item .md-no-style { position: relative; padding: 0px 16px; -webkit-box-flex: 1; -webkit-flex: 1 1 auto; flex: 1 1 auto; } md-list-item.md-no-proxy.md-button, md-list-item .md-no-style.md-button { font-size: inherit; height: inherit; text-align: left; text-transform: none; width: 100%; white-space: normal; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: inherit; flex-direction: inherit; -webkit-box-align: inherit; -webkit-align-items: inherit; align-items: inherit; border-radius: 0; margin: 0; } [dir=rtl] md-list-item.md-no-proxy.md-button, [dir=rtl] md-list-item .md-no-style.md-button { text-align: right; } md-list-item.md-no-proxy.md-button > .md-ripple-container, md-list-item .md-no-style.md-button > .md-ripple-container { border-radius: 0; } md-list-item.md-no-proxy:focus, md-list-item .md-no-style:focus { outline: none; } md-list-item.md-clickable:hover { cursor: pointer; } md-list-item md-divider { position: absolute; bottom: 0; left: 0; width: 100%; } [dir=rtl] md-list-item md-divider { left: auto; right: 0; } md-list-item md-divider[md-inset] { left: 72px; width: calc(100% - 72px); margin: 0 !important; } [dir=rtl] md-list-item md-divider[md-inset] { left: auto; right: 72px; } md-list-item, md-list-item .md-list-item-inner { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-pack: start; -webkit-justify-content: flex-start; justify-content: flex-start; -webkit-box-align: center; -webkit-align-items: center; align-items: center; min-height: 48px; height: auto; } md-list-item::before, md-list-item .md-list-item-inner::before { content: ''; min-height: 48px; visibility: hidden; display: inline-block; } md-list-item > div.md-primary > md-icon:not(.md-avatar-icon), md-list-item > div.md-secondary > md-icon:not(.md-avatar-icon), md-list-item > md-icon:first-child:not(.md-avatar-icon), md-list-item > md-icon.md-secondary:not(.md-avatar-icon), md-list-item .md-list-item-inner > div.md-primary > md-icon:not(.md-avatar-icon), md-list-item .md-list-item-inner > div.md-secondary > md-icon:not(.md-avatar-icon), md-list-item .md-list-item-inner > md-icon:first-child:not(.md-avatar-icon), md-list-item .md-list-item-inner > md-icon.md-secondary:not(.md-avatar-icon) { width: 24px; margin-top: 16px; margin-bottom: 12px; box-sizing: content-box; } md-list-item > div.md-primary > md-checkbox, md-list-item > div.md-secondary > md-checkbox, md-list-item > md-checkbox, md-list-item md-checkbox.md-secondary, md-list-item .md-list-item-inner > div.md-primary > md-checkbox, md-list-item .md-list-item-inner > div.md-secondary > md-checkbox, md-list-item .md-list-item-inner > md-checkbox, md-list-item .md-list-item-inner md-checkbox.md-secondary { -webkit-align-self: center; -ms-grid-row-align: center; align-self: center; } md-list-item > div.md-primary > md-checkbox .md-label, md-list-item > div.md-secondary > md-checkbox .md-label, md-list-item > md-checkbox .md-label, md-list-item md-checkbox.md-secondary .md-label, md-list-item .md-list-item-inner > div.md-primary > md-checkbox .md-label, md-list-item .md-list-item-inner > div.md-secondary > md-checkbox .md-label, md-list-item .md-list-item-inner > md-checkbox .md-label, md-list-item .md-list-item-inner md-checkbox.md-secondary .md-label { display: none; } md-list-item > md-icon:first-child:not(.md-avatar-icon), md-list-item .md-list-item-inner > md-icon:first-child:not(.md-avatar-icon) { margin-right: 32px; } [dir=rtl] md-list-item > md-icon:first-child:not(.md-avatar-icon), [dir=rtl] md-list-item .md-list-item-inner > md-icon:first-child:not(.md-avatar-icon) { margin-right: auto; margin-left: 32px; } md-list-item .md-avatar, md-list-item .md-avatar-icon, md-list-item .md-list-item-inner .md-avatar, md-list-item .md-list-item-inner .md-avatar-icon { margin-top: 8px; margin-bottom: 8px; margin-right: 16px; border-radius: 50%; box-sizing: content-box; } [dir=rtl] md-list-item .md-avatar, [dir=rtl] md-list-item .md-avatar-icon, [dir=rtl] md-list-item .md-list-item-inner .md-avatar, [dir=rtl] md-list-item .md-list-item-inner .md-avatar-icon { margin-right: auto; margin-left: 16px; } md-list-item .md-avatar, md-list-item .md-list-item-inner .md-avatar { -webkit-box-flex: 0; -webkit-flex: none; flex: none; width: 40px; height: 40px; } md-list-item .md-avatar-icon, md-list-item .md-list-item-inner .md-avatar-icon { padding: 8px; } md-list-item .md-avatar-icon svg, md-list-item .md-list-item-inner .md-avatar-icon svg { width: 24px; height: 24px; } md-list-item > md-checkbox, md-list-item .md-list-item-inner > md-checkbox { width: 24px; margin-left: 3px; margin-right: 29px; margin-top: 16px; } [dir=rtl] md-list-item > md-checkbox, [dir=rtl] md-list-item .md-list-item-inner > md-checkbox { margin-left: 29px; } [dir=rtl] md-list-item > md-checkbox, [dir=rtl] md-list-item .md-list-item-inner > md-checkbox { margin-right: 3px; } md-list-item .md-secondary-container, md-list-item .md-list-item-inner .md-secondary-container { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-align: center; -webkit-align-items: center; align-items: center; -webkit-flex-shrink: 0; flex-shrink: 0; margin: auto; margin-right: 0; margin-left: auto; } [dir=rtl] md-list-item .md-secondary-container, [dir=rtl] md-list-item .md-list-item-inner .md-secondary-container { margin-right: auto; } [dir=rtl] md-list-item .md-secondary-container, [dir=rtl] md-list-item .md-list-item-inner .md-secondary-container { margin-left: 0; } md-list-item .md-secondary-container .md-button:last-of-type, md-list-item .md-secondary-container .md-icon-button:last-of-type, md-list-item .md-list-item-inner .md-secondary-container .md-button:last-of-type, md-list-item .md-list-item-inner .md-secondary-container .md-icon-button:last-of-type { margin-right: 0; } [dir=rtl] md-list-item .md-secondary-container .md-button:last-of-type, [dir=rtl] md-list-item .md-secondary-container .md-icon-button:last-of-type, [dir=rtl] md-list-item .md-list-item-inner .md-secondary-container .md-button:last-of-type, [dir=rtl] md-list-item .md-list-item-inner .md-secondary-container .md-icon-button:last-of-type { margin-right: auto; margin-left: 0; } md-list-item .md-secondary-container md-checkbox, md-list-item .md-list-item-inner .md-secondary-container md-checkbox { margin-top: 0; margin-bottom: 0; } md-list-item .md-secondary-container md-checkbox:last-child, md-list-item .md-list-item-inner .md-secondary-container md-checkbox:last-child { width: 24px; margin-right: 0; } [dir=rtl] md-list-item .md-secondary-container md-checkbox:last-child, [dir=rtl] md-list-item .md-list-item-inner .md-secondary-container md-checkbox:last-child { margin-right: auto; margin-left: 0; } md-list-item .md-secondary-container md-switch, md-list-item .md-list-item-inner .md-secondary-container md-switch { margin-top: 0; margin-bottom: 0; margin-right: -6px; } [dir=rtl] md-list-item .md-secondary-container md-switch, [dir=rtl] md-list-item .md-list-item-inner .md-secondary-container md-switch { margin-right: auto; margin-left: -6px; } md-list-item > p, md-list-item > .md-list-item-inner > p, md-list-item .md-list-item-inner > p, md-list-item .md-list-item-inner > .md-list-item-inner > p { -webkit-box-flex: 1; -webkit-flex: 1 1 auto; flex: 1 1 auto; margin: 0; } md-list-item.md-2-line, md-list-item.md-2-line > .md-no-style, md-list-item.md-3-line, md-list-item.md-3-line > .md-no-style { -webkit-box-align: start; -webkit-align-items: flex-start; align-items: flex-start; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center; } md-list-item.md-2-line.md-long-text, md-list-item.md-2-line > .md-no-style.md-long-text, md-list-item.md-3-line.md-long-text, md-list-item.md-3-line > .md-no-style.md-long-text { margin-top: 8px; margin-bottom: 8px; } md-list-item.md-2-line .md-list-item-text, md-list-item.md-2-line > .md-no-style .md-list-item-text, md-list-item.md-3-line .md-list-item-text, md-list-item.md-3-line > .md-no-style .md-list-item-text { -webkit-box-flex: 1; -webkit-flex: 1 1 auto; flex: 1 1 auto; margin: auto; text-overflow: ellipsis; overflow: hidden; } md-list-item.md-2-line .md-list-item-text.md-offset, md-list-item.md-2-line > .md-no-style .md-list-item-text.md-offset, md-list-item.md-3-line .md-list-item-text.md-offset, md-list-item.md-3-line > .md-no-style .md-list-item-text.md-offset { margin-left: 56px; } [dir=rtl] md-list-item.md-2-line .md-list-item-text.md-offset, [dir=rtl] md-list-item.md-2-line > .md-no-style .md-list-item-text.md-offset, [dir=rtl] md-list-item.md-3-line .md-list-item-text.md-offset, [dir=rtl] md-list-item.md-3-line > .md-no-style .md-list-item-text.md-offset { margin-left: auto; margin-right: 56px; } md-list-item.md-2-line .md-list-item-text h3, md-list-item.md-2-line > .md-no-style .md-list-item-text h3, md-list-item.md-3-line .md-list-item-text h3, md-list-item.md-3-line > .md-no-style .md-list-item-text h3 { font-size: 16px; font-weight: 400; letter-spacing: 0.010em; margin: 0 0 0px 0; line-height: 1.2em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } md-list-item.md-2-line .md-list-item-text h4, md-list-item.md-2-line > .md-no-style .md-list-item-text h4, md-list-item.md-3-line .md-list-item-text h4, md-list-item.md-3-line > .md-no-style .md-list-item-text h4 { font-size: 14px; letter-spacing: 0.010em; margin: 3px 0 1px 0; font-weight: 400; line-height: 1.2em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } md-list-item.md-2-line .md-list-item-text p, md-list-item.md-2-line > .md-no-style .md-list-item-text p, md-list-item.md-3-line .md-list-item-text p, md-list-item.md-3-line > .md-no-style .md-list-item-text p { font-size: 14px; font-weight: 500; letter-spacing: 0.010em; margin: 0 0 0 0; line-height: 1.6em; } md-list-item.md-2-line, md-list-item.md-2-line > .md-no-style { height: auto; min-height: 72px; } md-list-item.md-2-line::before, md-list-item.md-2-line > .md-no-style::before { content: ''; min-height: 72px; visibility: hidden; display: inline-block; } md-list-item.md-2-line > .md-avatar, md-list-item.md-2-line .md-avatar-icon, md-list-item.md-2-line > .md-no-style > .md-avatar, md-list-item.md-2-line > .md-no-style .md-avatar-icon { margin-top: 12px; } md-list-item.md-2-line > md-icon:first-child, md-list-item.md-2-line > .md-no-style > md-icon:first-child { -webkit-align-self: flex-start; align-self: flex-start; } md-list-item.md-2-line .md-list-item-text, md-list-item.md-2-line > .md-no-style .md-list-item-text { -webkit-box-flex: 1; -webkit-flex: 1 1 auto; flex: 1 1 auto; } md-list-item.md-3-line, md-list-item.md-3-line > .md-no-style { height: auto; min-height: 88px; } md-list-item.md-3-line::before, md-list-item.md-3-line > .md-no-style::before { content: ''; min-height: 88px; visibility: hidden; display: inline-block; } md-list-item.md-3-line > md-icon:first-child, md-list-item.md-3-line > .md-avatar, md-list-item.md-3-line > .md-no-style > md-icon:first-child, md-list-item.md-3-line > .md-no-style > .md-avatar { margin-top: 16px; } .md-open-menu-container { position: fixed; left: 0; top: 0; z-index: 100; opacity: 0; border-radius: 2px; max-height: calc(100vh - 10px); overflow: auto; } .md-open-menu-container md-menu-divider { margin-top: 4px; margin-bottom: 4px; height: 1px; min-height: 1px; max-height: 1px; width: 100%; } .md-open-menu-container md-menu-content > * { opacity: 0; } .md-open-menu-container:not(.md-clickable) { pointer-events: none; } .md-open-menu-container.md-active { opacity: 1; -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); -webkit-transition-duration: 200ms; transition-duration: 200ms; } .md-open-menu-container.md-active > md-menu-content > * { opacity: 1; -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); -webkit-transition-duration: 200ms; transition-duration: 200ms; -webkit-transition-delay: 100ms; transition-delay: 100ms; } .md-open-menu-container.md-leave { opacity: 0; -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); -webkit-transition-duration: 250ms; transition-duration: 250ms; } md-menu-content { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; flex-direction: column; padding: 8px 0; max-height: 304px; overflow-y: auto; } md-menu-content.md-dense { max-height: 208px; } md-menu-content.md-dense md-menu-item { height: 32px; min-height: 0px; } md-menu-item { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; flex-direction: row; min-height: 48px; height: 48px; -webkit-align-content: center; align-content: center; -webkit-box-pack: start; -webkit-justify-content: flex-start; justify-content: flex-start; /* * We cannot use flex on