diff --git a/client/ayon_core/tools/common_models/hierarchy.py b/client/ayon_core/tools/common_models/hierarchy.py index 78b8a7f492..a90e06a63b 100644 --- a/client/ayon_core/tools/common_models/hierarchy.py +++ b/client/ayon_core/tools/common_models/hierarchy.py @@ -5,7 +5,6 @@ import ayon_api import six -from ayon_core.style import get_default_entity_icon_color from ayon_core.lib import NestedCacheItem HIERARCHY_MODEL_SENDER = "hierarchy.model" @@ -31,11 +30,10 @@ class FolderItem: path (str): Folder path. folder_type (str): Type of folder. label (Union[str, None]): Folder label. - icon (Union[dict[str, Any], None]): Icon definition. """ def __init__( - self, entity_id, parent_id, name, path, folder_type, label, icon + self, entity_id, parent_id, name, path, folder_type, label ): self.entity_id = entity_id self.parent_id = parent_id @@ -43,13 +41,6 @@ def __init__( self.path = path self.folder_type = folder_type self.label = label or name - if not icon: - icon = { - "type": "awesome-font", - "name": "fa.folder", - "color": get_default_entity_icon_color() - } - self.icon = icon def to_data(self): """Converts folder item to data. @@ -65,7 +56,6 @@ def to_data(self): "path": self.path, "folder_type": self.folder_type, "label": self.label, - "icon": self.icon, } @classmethod @@ -95,23 +85,15 @@ class TaskItem: name (str): Name of task. task_type (str): Type of task. parent_id (str): Parent folder id. - icon (Union[dict[str, Any], None]): Icon definitions. """ def __init__( - self, task_id, name, task_type, parent_id, icon + self, task_id, name, task_type, parent_id ): self.task_id = task_id self.name = name self.task_type = task_type self.parent_id = parent_id - if icon is None: - icon = { - "type": "awesome-font", - "name": "fa.male", - "color": get_default_entity_icon_color() - } - self.icon = icon self._label = None @@ -149,7 +131,6 @@ def to_data(self): "name": self.name, "parent_id": self.parent_id, "task_type": self.task_type, - "icon": self.icon, } @classmethod @@ -180,8 +161,7 @@ def _get_task_items_from_tasks(tasks): task["id"], task["name"], task["type"], - folder_id, - None + folder_id )) return output @@ -197,8 +177,7 @@ def _get_folder_item_from_hierarchy_item(item): name, path, item["folderType"], - item["label"], - None, + item["label"] ) @@ -210,8 +189,7 @@ def _get_folder_item_from_entity(entity): name, entity["path"], entity["folderType"], - entity["label"] or name, - None, + entity["label"] or name ) diff --git a/client/ayon_core/tools/common_models/projects.py b/client/ayon_core/tools/common_models/projects.py index 89dd881a10..90b75e15c1 100644 --- a/client/ayon_core/tools/common_models/projects.py +++ b/client/ayon_core/tools/common_models/projects.py @@ -60,6 +60,74 @@ def from_project_item(cls, status_data): ) +class FolderTypeItem: + """Item representing folder type of project. + + Args: + name (str): Folder type name ("Shot"). + short (str): Short folder type name ("sh"). + icon (str): Icon name in MaterialIcons ("fiber_new"). + + """ + def __init__(self, name, short, icon): + self.name = name + self.short = short + self.icon = icon + + def to_data(self): + return { + "name": self.name, + "short": self.short, + "icon": self.icon, + } + + @classmethod + def from_data(cls, data): + return cls(**data) + + @classmethod + def from_project_item(cls, folder_type_data): + return cls( + name=folder_type_data["name"], + short=folder_type_data["shortName"], + icon=folder_type_data["icon"], + ) + + +class TaskTypeItem: + """Item representing task type of project. + + Args: + name (str): Task type name ("Shot"). + short (str): Short task type name ("sh"). + icon (str): Icon name in MaterialIcons ("fiber_new"). + + """ + def __init__(self, name, short, icon): + self.name = name + self.short = short + self.icon = icon + + def to_data(self): + return { + "name": self.name, + "short": self.short, + "icon": self.icon, + } + + @classmethod + def from_data(cls, data): + return cls(**data) + + @classmethod + def from_project_item(cls, task_type_data): + return cls( + name=task_type_data["name"], + short=task_type_data["shortName"], + icon=task_type_data["icon"], + ) + + class ProjectItem: """Item representing folder entity on a server. @@ -147,19 +215,21 @@ def _get_project_items_from_entitiy(projects): class ProjectsModel(object): def __init__(self, controller): self._projects_cache = CacheItem(default_factory=list) - self._project_statuses_cache = NestedCacheItem( - levels=1, default_factory=list - ) self._projects_by_name = NestedCacheItem( levels=1, default_factory=list ) + self._project_statuses_cache = {} + self._folder_types_cache = {} + self._task_types_cache = {} self._is_refreshing = False self._controller = controller def reset(self): + self._project_statuses_cache = {} + self._folder_types_cache = {} + self._task_types_cache = {} self._projects_cache.reset() - self._project_statuses_cache.reset() self._projects_by_name.reset() def refresh(self): @@ -217,22 +287,87 @@ def get_project_status_items(self, project_name, sender): list[StatusItem]: Status items for project. """ - statuses_cache = self._project_statuses_cache[project_name] - if not statuses_cache.is_valid: - with self._project_statuses_refresh_event_manager( - sender, project_name + if project_name is None: + return [] + + statuses_cache = self._project_statuses_cache.get(project_name) + if ( + statuses_cache is not None + and not self._projects_cache.is_valid + ): + statuses_cache = None + + if statuses_cache is None: + with self._project_items_refresh_event_manager( + sender, project_name, "statuses" ): - project_entity = None - if project_name: - project_entity = self.get_project_entity(project_name) + project_entity = self.get_project_entity(project_name) statuses = [] if project_entity: statuses = [ StatusItem.from_project_item(status) for status in project_entity["statuses"] ] - statuses_cache.update_data(statuses) - return statuses_cache.get_data() + statuses_cache = statuses + self._project_statuses_cache[project_name] = statuses_cache + return list(statuses_cache) + + def get_folder_type_items(self, project_name, sender): + """Get project status items. + + Args: + project_name (str): Project name. + sender (Union[str, None]): Name of sender who asked for items. + + Returns: + list[FolderType]: Folder type items for project. + + """ + return self._get_project_items( + project_name, + sender, + "folder_types", + self._folder_types_cache, + self._folder_type_items_getter, + ) + + def get_task_type_items(self, project_name, sender): + """Get project task type items. + + Args: + project_name (str): Project name. + sender (Union[str, None]): Name of sender who asked for items. + + Returns: + list[TaskTypeItem]: Task type items for project. + + """ + return self._get_project_items( + project_name, + sender, + "task_types", + self._task_types_cache, + self._task_type_items_getter, + ) + + def _get_project_items( + self, project_name, sender, item_type, cache_obj, getter + ): + if ( + project_name in cache_obj + and ( + project_name is None + or self._projects_by_name[project_name].is_valid + ) + ): + return cache_obj[project_name] + + with self._project_items_refresh_event_manager( + sender, project_name, item_type + ): + cache_value = getter(self.get_project_entity(project_name)) + cache_obj[project_name] = cache_value + return cache_value @contextlib.contextmanager def _project_refresh_event_manager(self, sender): @@ -254,9 +389,11 @@ def _project_refresh_event_manager(self, sender): self._is_refreshing = False @contextlib.contextmanager - def _project_statuses_refresh_event_manager(self, sender, project_name): + def _project_items_refresh_event_manager( + self, sender, project_name, item_type + ): self._controller.emit_event( - "projects.statuses.refresh.started", + f"projects.{item_type}.refresh.started", {"sender": sender, "project_name": project_name}, PROJECTS_MODEL_SENDER ) @@ -265,7 +402,7 @@ def _project_statuses_refresh_event_manager(self, sender, project_name): finally: self._controller.emit_event( - "projects.statuses.refresh.finished", + f"projects.{item_type}.refresh.finished", {"sender": sender, "project_name": project_name}, PROJECTS_MODEL_SENDER ) @@ -282,3 +419,27 @@ def _refresh_projects_cache(self, sender=None): def _query_projects(self): projects = ayon_api.get_projects(fields=["name", "active", "library"]) return _get_project_items_from_entitiy(projects) + + def _status_items_getter(self, project_entity): + if not project_entity: + return [] + return [ + StatusItem.from_project_item(status) + for status in project_entity["statuses"] + ] + + def _folder_type_items_getter(self, project_entity): + if not project_entity: + return [] + return [ + FolderTypeItem.from_project_item(folder_type) + for folder_type in project_entity["folderTypes"] + ] + + def _task_type_items_getter(self, project_entity): + if not project_entity: + return [] + return [ + TaskTypeItem.from_project_item(task_type) + for task_type in project_entity["taskTypes"] + ] diff --git a/client/ayon_core/tools/context_dialog/window.py b/client/ayon_core/tools/context_dialog/window.py index ea5fdfbaec..a1921ec237 100644 --- a/client/ayon_core/tools/context_dialog/window.py +++ b/client/ayon_core/tools/context_dialog/window.py @@ -227,6 +227,16 @@ def set_strict(self, enabled): def get_project_items(self, sender=None): return self._projects_model.get_project_items(sender) + def get_folder_type_items(self, project_name, sender=None): + return self._projects_model.get_folder_type_items( + project_name, sender + ) + + def get_task_type_items(self, project_name, sender=None): + return self._projects_model.get_task_type_items( + project_name, sender + ) + def get_folder_items(self, project_name, sender=None): return self._hierarchy_model.get_folder_items(project_name, sender) diff --git a/client/ayon_core/tools/launcher/abstract.py b/client/ayon_core/tools/launcher/abstract.py index 95fe2b2c8d..921fe7bc5b 100644 --- a/client/ayon_core/tools/launcher/abstract.py +++ b/client/ayon_core/tools/launcher/abstract.py @@ -104,8 +104,48 @@ def get_project_items(self, sender=None): Returns: list[ProjectItem]: Minimum possible information needed for visualisation of folder hierarchy. + + """ + pass + + @abstractmethod + def get_folder_type_items(self, project_name, sender=None): + """Folder type items for a project. + + This function may trigger events with topics + 'projects.folder_types.refresh.started' and + 'projects.folder_types.refresh.finished' which will contain 'sender' + value in data. + That may help to avoid re-refresh of items in UI elements. + + Args: + project_name (str): Project name. + sender (str): Who requested folder type items. + + Returns: + list[FolderTypeItem]: Folder type information. + """ + pass + + @abstractmethod + def get_task_type_items(self, project_name, sender=None): + """Task type items for a project. + + This function may trigger events with topics + 'projects.task_types.refresh.started' and + 'projects.task_types.refresh.finished' which will contain 'sender' + value in data. + That may help to avoid re-refresh of items in UI elements. + Args: + project_name (str): Project name. + sender (str): Who requested task type items. + + Returns: + list[TaskTypeItem]: Task type information. + + """ pass @abstractmethod diff --git a/client/ayon_core/tools/launcher/control.py b/client/ayon_core/tools/launcher/control.py index abd0cd78d8..d60e4747e3 100644 --- a/client/ayon_core/tools/launcher/control.py +++ b/client/ayon_core/tools/launcher/control.py @@ -59,12 +59,23 @@ def register_event_callback(self, topic, callback): def get_project_items(self, sender=None): return self._projects_model.get_project_items(sender) + def get_folder_type_items(self, project_name, sender=None): + return self._projects_model.get_folder_type_items( + project_name, sender + ) + + def get_task_type_items(self, project_name, sender=None): + return self._projects_model.get_task_type_items( + project_name, sender + ) + def get_folder_items(self, project_name, sender=None): return self._hierarchy_model.get_folder_items(project_name, sender) def get_task_items(self, project_name, folder_id, sender=None): return self._hierarchy_model.get_task_items( - project_name, folder_id, sender) + project_name, folder_id, sender + ) # Project settings for applications actions def get_project_settings(self, project_name): diff --git a/client/ayon_core/tools/loader/abstract.py b/client/ayon_core/tools/loader/abstract.py index ba1dcb73b6..3a1a23edd7 100644 --- a/client/ayon_core/tools/loader/abstract.py +++ b/client/ayon_core/tools/loader/abstract.py @@ -510,6 +510,26 @@ def get_project_items(self, sender=None): pass + @abstractmethod + def get_folder_type_items(self, project_name, sender=None): + """Folder type items for a project. + + This function may trigger events with topics + 'projects.folder_types.refresh.started' and + 'projects.folder_types.refresh.finished' which will contain 'sender' + value in data. + That may help to avoid re-refresh of items in UI elements. + + Args: + project_name (str): Project name. + sender (str): Who requested folder type items. + + Returns: + list[FolderTypeItem]: Folder type information. + + """ + pass + @abstractmethod def get_project_status_items(self, project_name, sender=None): """Items for all projects available on server. diff --git a/client/ayon_core/tools/loader/control.py b/client/ayon_core/tools/loader/control.py index 9fead226f0..ee0b2f4b9d 100644 --- a/client/ayon_core/tools/loader/control.py +++ b/client/ayon_core/tools/loader/control.py @@ -180,6 +180,11 @@ def expected_folder_selected(self, folder_id): def get_project_items(self, sender=None): return self._projects_model.get_project_items(sender) + def get_folder_type_items(self, project_name, sender=None): + return self._projects_model.get_folder_type_items( + project_name, sender + ) + def get_project_status_items(self, project_name, sender=None): return self._projects_model.get_project_status_items( project_name, sender diff --git a/client/ayon_core/tools/loader/ui/folders_widget.py b/client/ayon_core/tools/loader/ui/folders_widget.py index efd041937d..f238eabcef 100644 --- a/client/ayon_core/tools/loader/ui/folders_widget.py +++ b/client/ayon_core/tools/loader/ui/folders_widget.py @@ -188,16 +188,6 @@ def __init__(self, *args, **kwargs): self._colored_items = set() - def _fill_item_data(self, item, folder_item): - """ - - Args: - item (QtGui.QStandardItem): Item to fill data. - folder_item (FolderItem): Folder item. - """ - - super(LoaderFoldersModel, self)._fill_item_data(item, folder_item) - def set_merged_products_selection(self, items): changes = { folder_id: None diff --git a/client/ayon_core/tools/loader/ui/products_model.py b/client/ayon_core/tools/loader/ui/products_model.py index 7b9124608b..6e36317da2 100644 --- a/client/ayon_core/tools/loader/ui/products_model.py +++ b/client/ayon_core/tools/loader/ui/products_model.py @@ -126,6 +126,7 @@ def __init__(self, controller): self._last_project_name = None self._last_folder_ids = [] self._last_project_statuses = {} + self._last_status_icons_by_name = {} def get_product_item_indexes(self): return [ @@ -181,6 +182,13 @@ def data(self, index, role=None): return status_item.color col = index.column() + if col == self.status_col and role == QtCore.Qt.DecorationRole: + role = VERSION_STATUS_ICON_ROLE + + if role == VERSION_STATUS_ICON_ROLE: + status_name = self.data(index, VERSION_STATUS_NAME_ROLE) + return self._get_status_icon(status_name) + if col == 0: return super(ProductsModel, self).data(index, role) @@ -260,6 +268,25 @@ def _color_iter(self): break yield color + def _get_status_icon(self, status_name): + icon = self._last_status_icons_by_name.get(status_name) + if icon is not None: + return icon + + status_item = self._last_project_statuses.get(status_name) + if status_item is not None: + icon = get_qt_icon({ + "type": "material-symbols", + "name": status_item.icon, + "color": status_item.color, + }) + + if icon is None: + icon = QtGui.QIcon() + + self._last_status_icons_by_name[status_name] = icon + return icon + def _clear(self): root_item = self.invisibleRootItem() root_item.removeRows(0, root_item.rowCount()) @@ -419,6 +446,7 @@ def refresh(self, project_name, folder_ids): status_item.name: status_item for status_item in status_items } + self._last_status_icons_by_name = {} active_site_icon_def = self._controller.get_active_site_icon_def( project_name diff --git a/client/ayon_core/tools/publisher/control.py b/client/ayon_core/tools/publisher/control.py index 4e2cfd8783..4a8ec72e4f 100644 --- a/client/ayon_core/tools/publisher/control.py +++ b/client/ayon_core/tools/publisher/control.py @@ -39,7 +39,7 @@ ConvertorsOperationFailed, ) from ayon_core.pipeline.publish import get_publish_instance_label -from ayon_core.tools.common_models import HierarchyModel +from ayon_core.tools.common_models import ProjectsModel, HierarchyModel from ayon_core.lib.profiles_filtering import filter_profiles # Define constant for plugin orders offset @@ -1632,6 +1632,7 @@ def __init__(self, headless=False): self._resetting_instances = False # Cacher of avalon documents + self._projects_model = ProjectsModel(self) self._hierarchy_model = HierarchyModel(self) @property @@ -1697,6 +1698,16 @@ def _get_current_project_settings(self): return self._create_context.get_current_project_settings() + def get_folder_type_items(self, project_name, sender=None): + return self._projects_model.get_folder_type_items( + project_name, sender + ) + + def get_task_type_items(self, project_name, sender=None): + return self._projects_model.get_task_type_items( + project_name, sender + ) + # Hierarchy model def get_folder_items(self, project_name, sender=None): return self._hierarchy_model.get_folder_items(project_name, sender) @@ -1725,14 +1736,14 @@ def get_folder_id_from_path(self, folder_path): return folder_item.entity_id return None - def get_task_names_by_folder_paths(self, folder_paths): + def get_task_items_by_folder_paths(self, folder_paths): if not folder_paths: return {} folder_items = self._hierarchy_model.get_folder_items_by_paths( self.project_name, folder_paths ) output = { - folder_path: set() + folder_path: [] for folder_path in folder_paths } project_name = self.project_name @@ -1740,10 +1751,7 @@ def get_task_names_by_folder_paths(self, folder_paths): task_items = self._hierarchy_model.get_task_items( project_name, folder_item.entity_id, None ) - output[folder_item.path] = { - task_item.name - for task_item in task_items - } + output[folder_item.path] = task_items return output diff --git a/client/ayon_core/tools/publisher/widgets/create_context_widgets.py b/client/ayon_core/tools/publisher/widgets/create_context_widgets.py index 235a778d0f..18df798bf0 100644 --- a/client/ayon_core/tools/publisher/widgets/create_context_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/create_context_widgets.py @@ -128,6 +128,16 @@ def get_task_items(self, project_name, folder_id, sender=None): project_name, folder_id, sender ) + def get_folder_type_items(self, project_name, sender=None): + return self._controller.get_folder_type_items( + project_name, sender + ) + + def get_task_type_items(self, project_name, sender=None): + return self._controller.get_task_type_items( + project_name, sender + ) + # Selection model def set_selected_project(self, project_name): self._selection_model.set_selected_project(project_name) diff --git a/client/ayon_core/tools/publisher/widgets/folders_dialog.py b/client/ayon_core/tools/publisher/widgets/folders_dialog.py index 8dce7aba3a..28bdce37b1 100644 --- a/client/ayon_core/tools/publisher/widgets/folders_dialog.py +++ b/client/ayon_core/tools/publisher/widgets/folders_dialog.py @@ -26,6 +26,11 @@ def register_event_callback(self, topic, callback): def get_folder_items(self, project_name, sender=None): return self._controller.get_folder_items(project_name, sender) + def get_folder_type_items(self, project_name, sender=None): + return self._controller.get_folder_type_items( + project_name, sender + ) + def set_selected_folder(self, folder_id): pass diff --git a/client/ayon_core/tools/publisher/widgets/tasks_model.py b/client/ayon_core/tools/publisher/widgets/tasks_model.py index 78b1f23b17..03fb95a310 100644 --- a/client/ayon_core/tools/publisher/widgets/tasks_model.py +++ b/client/ayon_core/tools/publisher/widgets/tasks_model.py @@ -99,12 +99,16 @@ def reset(self): root_item.removeRows(0, self.rowCount()) return - task_names_by_folder_path = ( - self._controller.get_task_names_by_folder_paths( + task_items_by_folder_path = ( + self._controller.get_task_items_by_folder_paths( self._folder_paths ) ) + task_names_by_folder_path = { + folder_path: {item.name for item in task_items} + for folder_path, task_items in task_items_by_folder_path.items() + } self._task_names_by_folder_path = task_names_by_folder_path new_task_names = self.get_intersection_of_tasks( @@ -122,22 +126,54 @@ def reset(self): item = self._items_by_name.pop(task_name) root_item.removeRow(item.row()) - icon = get_qt_icon({ + default_icon = get_qt_icon({ "type": "awesome-font", "name": "fa.male", "color": get_default_entity_icon_color(), }) new_items = [] + task_type_items = { + task_type_item.name: task_type_item + for task_type_item in self._controller.get_task_type_items( + self._controller.project_name + ) + } + icon_name_by_task_name = {} + for task_items in task_items_by_folder_path.values(): + for task_item in task_items: + task_name = task_item.name + if ( + task_name not in new_task_names + or task_name in icon_name_by_task_name + ): + continue + task_type_name = task_item.task_type + task_type_item = task_type_items.get(task_type_name) + if task_type_item: + icon_name_by_task_name[task_name] = task_type_item.icon + for task_name in new_task_names: - if task_name in self._items_by_name: + item = self._items_by_name.get(task_name) + if item is None: + item = QtGui.QStandardItem(task_name) + item.setData(task_name, TASK_NAME_ROLE) + self._items_by_name[task_name] = item + new_items.append(item) + + if not task_name: continue - item = QtGui.QStandardItem(task_name) - item.setData(task_name, TASK_NAME_ROLE) - if task_name: - item.setData(icon, QtCore.Qt.DecorationRole) - self._items_by_name[task_name] = item - new_items.append(item) + icon_name = icon_name_by_task_name.get(task_name) + icon = None + if icon_name: + icon = get_qt_icon({ + "type": "material-symbols", + "name": icon_name, + "color": get_default_entity_icon_color(), + }) + if icon is None: + icon = default_icon + item.setData(icon, QtCore.Qt.DecorationRole) if new_items: root_item.appendRows(new_items) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 1c51b7a98b..3e0c361535 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -116,6 +116,9 @@ def __init__(self, controller, parent=None): self._default_icon_color = get_default_entity_icon_color() + self._last_project_statuses = {} + self._last_status_icons_by_name = {} + def outdated(self, item): return item.get("isOutdated", True) @@ -159,10 +162,11 @@ def refresh(self, selected=None): self._controller.get_site_provider_icons().items() ) } - status_items_by_name = { + self._last_project_statuses = { status_item.name: status_item for status_item in self._controller.get_project_status_items() } + self._last_status_icons_by_name = {} group_item_icon = qtawesome.icon( "fa.folder", color=self._default_icon_color @@ -186,7 +190,6 @@ def refresh(self, selected=None): remote_site_icon = site_icons.get(sites_info["remote_site_provider"]) root_item = self.invisibleRootItem() - group_items = [] for repre_id, container_items in items_by_repre_id.items(): repre_info = repre_info_by_id[repre_id] @@ -195,8 +198,6 @@ def refresh(self, selected=None): is_latest = False is_hero = False status_name = None - status_color = None - status_short = None if not repre_info.is_valid: group_name = "< Entity N/A >" item_icon = invalid_item_icon @@ -219,10 +220,10 @@ def refresh(self, selected=None): if not is_latest: version_color = self.OUTDATED_COLOR status_name = version_item.status - status_item = status_items_by_name.get(status_name) - if status_item: - status_short = status_item.short - status_color = status_item.color + + status_color, status_short, status_icon = self._get_status_data( + status_name + ) container_model_items = [] for container_item in container_items: @@ -273,6 +274,7 @@ def refresh(self, selected=None): group_item.setData(status_name, STATUS_NAME_ROLE) group_item.setData(status_short, STATUS_SHORT_ROLE) group_item.setData(status_color, STATUS_COLOR_ROLE) + group_item.setData(status_icon, STATUS_ICON_ROLE) group_item.setData( active_site_progress, ACTIVE_SITE_PROGRESS_ROLE @@ -355,6 +357,32 @@ def _clear_items(self): root_item = self.invisibleRootItem() root_item.removeRows(0, root_item.rowCount()) + def _get_status_data(self, status_name): + status_item = self._last_project_statuses.get(status_name) + status_icon = self._get_status_icon(status_name, status_item) + status_color = status_short = None + if status_item is not None: + status_color = status_item.color + status_short = status_item.short + return status_color, status_short, status_icon + + def _get_status_icon(self, status_name, status_item): + icon = self._last_status_icons_by_name.get(status_name) + if icon is not None: + return icon + + icon = None + if status_item is not None: + icon = get_qt_icon({ + "type": "material-symbols", + "name": status_item.icon, + "color": status_item.color, + }) + if icon is None: + icon = QtGui.QIcon() + self._last_status_icons_by_name[status_name] = icon + return icon + class FilterProxyModel(QtCore.QSortFilterProxyModel): """Filter model to where key column's value is in the filtered tags""" diff --git a/client/ayon_core/tools/sceneinventory/select_version_dialog.py b/client/ayon_core/tools/sceneinventory/select_version_dialog.py index 098bc724e2..68284ad1fe 100644 --- a/client/ayon_core/tools/sceneinventory/select_version_dialog.py +++ b/client/ayon_core/tools/sceneinventory/select_version_dialog.py @@ -2,6 +2,7 @@ from qtpy import QtWidgets, QtCore, QtGui +from ayon_core.tools.utils import get_qt_icon from ayon_core.tools.utils.delegates import StatusDelegate from .model import ( @@ -20,13 +21,15 @@ def __init__( label, status_name, status_short, - status_color + status_color, + status_icon, ): self.version = version self.label = label self.status_name = status_name self.status_short = status_short self.status_color = status_color + self.status_icon = status_icon class SelectVersionModel(QtGui.QStandardItemModel): @@ -84,27 +87,52 @@ def paintEvent(self, event): return painter.save() - text_field_rect = self.style().subControlRect( + + status_icon = self.itemData(idx, STATUS_ICON_ROLE) + content_field_rect = self.style().subControlRect( QtWidgets.QStyle.CC_ComboBox, option, QtWidgets.QStyle.SC_ComboBoxEditField - ) - adj_rect = text_field_rect.adjusted(1, 0, -1, 0) + ).adjusted(1, 0, -1, 0) + + metrics = option.fontMetrics + version_text_width = metrics.width(option.currentText) + 2 + version_text_rect = QtCore.QRect(content_field_rect) + version_text_rect.setWidth(version_text_width) + painter.drawText( - adj_rect, + version_text_rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, option.currentText ) - metrics = QtGui.QFontMetrics(self.font()) - text_width = metrics.width(option.currentText) - x_offset = text_width + 2 - diff_width = adj_rect.width() - x_offset - if diff_width <= 0: + + status_text_rect = QtCore.QRect(content_field_rect) + status_text_rect.setLeft(version_text_rect.right() + 2) + if status_icon is not None and not status_icon.isNull(): + icon_rect = QtCore.QRect(status_text_rect) + diff = icon_rect.height() - metrics.height() + if diff < 0: + diff = 0 + top_offset = diff // 2 + bottom_offset = diff - top_offset + icon_rect.adjust(0, top_offset, 0, -bottom_offset) + icon_rect.setWidth(metrics.height()) + status_icon.paint( + painter, + icon_rect, + QtCore.Qt.AlignCenter, + QtGui.QIcon.Normal, + QtGui.QIcon.On + ) + status_text_rect.setLeft(icon_rect.right() + 2) + + if status_text_rect.width() <= 0: return - status_rect = adj_rect.adjusted(x_offset + 2, 0, 0, 0) - if diff_width < metrics.width(status_name): + if status_text_rect.width() < metrics.width(status_name): status_name = self.itemData(idx, STATUS_SHORT_ROLE) + if status_text_rect.width() < metrics.width(status_name): + status_name = "" color = QtGui.QColor(self.itemData(idx, STATUS_COLOR_ROLE)) @@ -112,7 +140,7 @@ def paintEvent(self, event): pen.setColor(color) painter.setPen(pen) painter.drawText( - status_rect, + status_text_rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, status_name ) @@ -140,7 +168,17 @@ def set_versions(self, version_options): root_item.removeRows(0, root_item.rowCount()) new_items = [] + icons_by_name = {} for version_option in version_options: + icon = icons_by_name.get(version_option.status_icon) + if icon is None: + icon = get_qt_icon({ + "type": "material-symbols", + "name": version_option.status_icon, + "color": version_option.status_color + }) + icons_by_name[version_option.status_icon] = icon + item_id = uuid.uuid4().hex item = QtGui.QStandardItem(version_option.label) item.setColumnCount(root_item.columnCount()) @@ -153,6 +191,7 @@ def set_versions(self, version_options): item.setData( version_option.status_color, STATUS_COLOR_ROLE ) + item.setData(icon, STATUS_ICON_ROLE) item.setData(item_id, ITEM_ID_ROLE) new_items.append(item) diff --git a/client/ayon_core/tools/sceneinventory/view.py b/client/ayon_core/tools/sceneinventory/view.py index 33fe3b516f..c8cc3299a2 100644 --- a/client/ayon_core/tools/sceneinventory/view.py +++ b/client/ayon_core/tools/sceneinventory/view.py @@ -740,10 +740,12 @@ def version_sorter(item): status_name = version_item.status status_short = None status_color = None + status_icon = None status_item = status_items_by_name.get(status_name) if status_item: status_short = status_item.short status_color = status_item.color + status_icon = status_item.icon version_options.append( VersionOption( version, @@ -751,6 +753,7 @@ def version_sorter(item): status_name, status_short, status_color, + status_icon, ) ) diff --git a/client/ayon_core/tools/utils/delegates.py b/client/ayon_core/tools/utils/delegates.py index b296f952e0..1cc18b5722 100644 --- a/client/ayon_core/tools/utils/delegates.py +++ b/client/ayon_core/tools/utils/delegates.py @@ -2,7 +2,7 @@ from datetime import datetime import logging -from qtpy import QtWidgets, QtGui +from qtpy import QtWidgets, QtGui, QtCore log = logging.getLogger(__name__) @@ -130,32 +130,65 @@ def paint(self, painter, option, index): else: style = QtWidgets.QApplication.style() - style.drawControl( - QtWidgets.QCommonStyle.CE_ItemViewItem, - option, - painter, - option.widget + self.initStyleOption(option, index) + + mode = QtGui.QIcon.Normal + if not (option.state & QtWidgets.QStyle.State_Enabled): + mode = QtGui.QIcon.Disabled + elif option.state & QtWidgets.QStyle.State_Selected: + mode = QtGui.QIcon.Selected + state = QtGui.QIcon.Off + if option.state & QtWidgets.QStyle.State_Open: + state = QtGui.QIcon.On + icon = self._get_status_icon(index) + option.features |= QtWidgets.QStyleOptionViewItem.HasDecoration + option.icon = icon + act_size = icon.actualSize(option.decorationSize, mode, state) + option.decorationSize = QtCore.QSize( + min(option.decorationSize.width(), act_size.width()), + min(option.decorationSize.height(), act_size.height()) ) + text = self._get_status_name(index) + if text: + option.features |= QtWidgets.QStyleOptionViewItem.HasDisplay + option.text = text + painter.save() + painter.setClipRect(option.rect) + icon_rect = style.subElementRect( + QtWidgets.QCommonStyle.SE_ItemViewItemDecoration, + option, + option.widget + ) text_rect = style.subElementRect( QtWidgets.QCommonStyle.SE_ItemViewItemText, - option + option, + option.widget ) - text_margin = style.proxy().pixelMetric( - QtWidgets.QCommonStyle.PM_FocusFrameHMargin, + + # Draw background + style.drawPrimitive( + QtWidgets.QCommonStyle.PE_PanelItemViewItem, option, + painter, option.widget - ) + 1 - padded_text_rect = text_rect.adjusted( - text_margin, 0, - text_margin, 0 ) + # Draw icon + option.icon.paint( + painter, + icon_rect, + option.decorationAlignment, + mode, + state + ) fm = QtGui.QFontMetrics(option.font) - text = self._get_status_name(index) - if padded_text_rect.width() < fm.width(text): + if text_rect.width() < fm.width(text): text = self._get_status_short_name(index) + if text_rect.width() < fm.width(text): + text = "" fg_color = self._get_status_color(index) pen = painter.pen() @@ -163,11 +196,47 @@ def paint(self, painter, option, index): painter.setPen(pen) painter.drawText( - padded_text_rect, + text_rect, option.displayAlignment, text ) + if option.state & QtWidgets.QStyle.State_HasFocus: + focus_opt = QtWidgets.QStyleOptionFocusRect() + focus_opt.state = option.state + focus_opt.direction = option.direction + focus_opt.rect = option.rect + focus_opt.fontMetrics = option.fontMetrics + focus_opt.palette = option.palette + + focus_opt.rect = style.subElementRect( + QtWidgets.QCommonStyle.SE_ItemViewItemFocusRect, + option, + option.widget + ) + focus_opt.state |= ( + QtWidgets.QStyle.State_KeyboardFocusChange + | QtWidgets.QStyle.State_Item + ) + focus_opt.backgroundColor = option.palette.color( + ( + QtGui.QPalette.Normal + if option.state & QtWidgets.QStyle.State_Enabled + else QtGui.QPalette.Disabled + ), + ( + QtGui.QPalette.Highlight + if option.state & QtWidgets.QStyle.State_Selected + else QtGui.QPalette.Window + ) + ) + style.drawPrimitive( + QtWidgets.QCommonStyle.PE_FrameFocusRect, + focus_opt, + painter, + option.widget + ) + painter.restore() def _get_status_name(self, index): @@ -180,6 +249,9 @@ def _get_status_color(self, index): return QtGui.QColor(index.data(self.status_color_role)) def _get_status_icon(self, index): + icon = None if self.status_icon_role is not None: - return index.data(self.status_icon_role) - return None + icon = index.data(self.status_icon_role) + if icon is None: + return QtGui.QIcon() + return icon diff --git a/client/ayon_core/tools/utils/folders_widget.py b/client/ayon_core/tools/utils/folders_widget.py index 6aae68bf8a..3b53266c9f 100644 --- a/client/ayon_core/tools/utils/folders_widget.py +++ b/client/ayon_core/tools/utils/folders_widget.py @@ -3,7 +3,9 @@ from qtpy import QtWidgets, QtGui, QtCore from ayon_core.lib.events import QueuedEventSystem +from ayon_core.style import get_default_entity_icon_color from ayon_core.tools.common_models import ( + ProjectsModel, HierarchyModel, HierarchyExpectedSelection, ) @@ -25,8 +27,9 @@ class FoldersQtModel(QtGui.QStandardItemModel): Args: controller (AbstractWorkfilesFrontend): The control object. - """ + """ + _default_folder_icon = None refreshed = QtCore.Signal() def __init__(self, controller): @@ -71,13 +74,6 @@ def refresh(self): self.set_project_name(self._last_project_name) - def _clear_items(self): - self._items_by_id = {} - self._parent_id_by_id = {} - self._has_content = False - root_item = self.invisibleRootItem() - root_item.removeRows(0, root_item.rowCount()) - def get_index_by_id(self, item_id): """Get index by folder id. @@ -123,7 +119,7 @@ def set_project_name(self, project_name): if not project_name: self._last_project_name = project_name - self._fill_items({}) + self._fill_items({}, {}) self._current_refresh_thread = None return @@ -140,15 +136,42 @@ def set_project_name(self, project_name): thread = RefreshThread( project_name, - self._controller.get_folder_items, - project_name, - FOLDERS_MODEL_SENDER_NAME + self._thread_getter, + project_name ) self._current_refresh_thread = thread self._refresh_threads[thread.id] = thread thread.refresh_finished.connect(self._on_refresh_thread) thread.start() + @classmethod + def _get_default_folder_icon(cls): + if cls._default_folder_icon is None: + cls._default_folder_icon = get_qt_icon({ + "type": "awesome-font", + "name": "fa.folder", + "color": get_default_entity_icon_color() + }) + return cls._default_folder_icon + + def _clear_items(self): + self._items_by_id = {} + self._parent_id_by_id = {} + self._has_content = False + root_item = self.invisibleRootItem() + root_item.removeRows(0, root_item.rowCount()) + + def _thread_getter(self, project_name): + folder_items = self._controller.get_folder_items( + project_name, FOLDERS_MODEL_SENDER_NAME + ) + folder_type_items = {} + if hasattr(self._controller, "get_folder_type_items"): + folder_type_items = self._controller.get_folder_type_items( + project_name, FOLDERS_MODEL_SENDER_NAME + ) + return folder_items, folder_type_items + def _on_refresh_thread(self, thread_id): """Callback when refresh thread is finished. @@ -169,19 +192,55 @@ def _on_refresh_thread(self, thread_id): or thread_id != self._current_refresh_thread.id ): return - - self._fill_items(thread.get_result()) + folder_items, folder_type_items = thread.get_result() + self._fill_items(folder_items, folder_type_items) self._current_refresh_thread = None - def _fill_item_data(self, item, folder_item): + def _get_folder_item_icon( + self, + folder_item, + folder_type_item_by_name, + folder_type_icon_cache + ): + icon = folder_type_icon_cache.get(folder_item.folder_type) + if icon is not None: + return icon + + folder_type_item = folder_type_item_by_name.get( + folder_item.folder_type + ) + icon = None + if folder_type_item is not None: + icon = get_qt_icon({ + "type": "material-symbols", + "name": folder_type_item.icon, + "color": get_default_entity_icon_color() + }) + + if icon is None: + icon = self._get_default_folder_icon() + folder_type_icon_cache[folder_item.folder_type] = icon + return icon + + def _fill_item_data( + self, + item, + folder_item, + folder_type_item_by_name, + folder_type_icon_cache + ): """ Args: item (QtGui.QStandardItem): Item to fill data. folder_item (FolderItem): Folder item. - """ - icon = get_qt_icon(folder_item.icon) + """ + icon = self._get_folder_item_icon( + folder_item, + folder_type_item_by_name, + folder_type_icon_cache + ) item.setData(folder_item.entity_id, FOLDER_ID_ROLE) item.setData(folder_item.name, FOLDER_NAME_ROLE) item.setData(folder_item.path, FOLDER_PATH_ROLE) @@ -189,7 +248,7 @@ def _fill_item_data(self, item, folder_item): item.setData(folder_item.label, QtCore.Qt.DisplayRole) item.setData(icon, QtCore.Qt.DecorationRole) - def _fill_items(self, folder_items_by_id): + def _fill_items(self, folder_items_by_id, folder_type_items): if not folder_items_by_id: if folder_items_by_id is not None: self._clear_items() @@ -197,6 +256,11 @@ def _fill_items(self, folder_items_by_id): self.refreshed.emit() return + folder_type_item_by_name = { + folder_type.name: folder_type + for folder_type in folder_type_items + } + folder_type_icon_cache = {} self._has_content = True folder_ids = set(folder_items_by_id) @@ -242,7 +306,12 @@ def _fill_items(self, folder_items_by_id): else: is_new = self._parent_id_by_id[item_id] != parent_id - self._fill_item_data(item, folder_item) + self._fill_item_data( + item, + folder_item, + folder_type_item_by_name, + folder_type_icon_cache + ) if is_new: new_items.append(item) self._items_by_id[item_id] = item @@ -619,6 +688,7 @@ def set_selected_folder(self, folder_id): class SimpleFoldersController(object): def __init__(self): self._event_system = self._create_event_system() + self._projects_model = ProjectsModel(self) self._hierarchy_model = HierarchyModel(self) self._selection_model = SimpleSelectionModel(self) self._expected_selection = HierarchyExpectedSelection( @@ -639,6 +709,11 @@ def register_event_callback(self, topic, callback): def get_folder_items(self, project_name, sender=None): return self._hierarchy_model.get_folder_items(project_name, sender) + def get_folder_type_items(self, project_name, sender=None): + return self._projects_model.get_folder_type_items( + project_name, sender + ) + def set_selected_project(self, project_name): self._selection_model.set_selected_project(project_name) diff --git a/client/ayon_core/tools/utils/lib.py b/client/ayon_core/tools/utils/lib.py index 323b5c07e1..e0626ec1db 100644 --- a/client/ayon_core/tools/utils/lib.py +++ b/client/ayon_core/tools/utils/lib.py @@ -6,6 +6,7 @@ from qtpy import QtWidgets, QtCore, QtGui import qtawesome +import qtmaterialsymbols from ayon_core.style import ( get_objected_colors, @@ -468,7 +469,7 @@ def _get_cache_key(cls, icon_def): if icon_type == "path": parts = [icon_type, icon_def["path"]] - elif icon_type == "awesome-font": + elif icon_type in {"awesome-font", "material-symbols"}: parts = [icon_type, icon_def["name"], icon_def["color"]] return "|".join(parts) @@ -495,6 +496,13 @@ def get_icon(cls, icon_def): if icon is None: icon = cls.get_qta_icon_by_name_and_color( "fa.{}".format(icon_name), icon_color) + + elif icon_type == "material-symbols": + icon_name = icon_def["name"] + icon_color = icon_def["color"] + if qtmaterialsymbols.get_icon_name_char(icon_name) is not None: + icon = qtmaterialsymbols.get_icon(icon_name, icon_color) + if icon is None: icon = cls.get_default() cls._cache[cache_key] = icon diff --git a/client/ayon_core/tools/utils/tasks_widget.py b/client/ayon_core/tools/utils/tasks_widget.py index 0ff8e8a5c1..314521b6b0 100644 --- a/client/ayon_core/tools/utils/tasks_widget.py +++ b/client/ayon_core/tools/utils/tasks_widget.py @@ -1,6 +1,9 @@ from qtpy import QtWidgets, QtGui, QtCore -from ayon_core.style import get_disabled_entity_icon_color +from ayon_core.style import ( + get_disabled_entity_icon_color, + get_default_entity_icon_color, +) from .views import DeselectableTreeView from .lib import RefreshThread, get_qt_icon @@ -17,8 +20,9 @@ class TasksQtModel(QtGui.QStandardItemModel): Args: controller (AbstractWorkfilesFrontend): The control object. - """ + """ + _default_task_icon = None refreshed = QtCore.Signal() def __init__(self, controller): @@ -176,7 +180,7 @@ def _refresh(self, project_name, folder_id): return thread = RefreshThread( folder_id, - self._controller.get_task_items, + self._thread_getter, project_name, folder_id ) @@ -185,8 +189,55 @@ def _refresh(self, project_name, folder_id): thread.refresh_finished.connect(self._on_refresh_thread) thread.start() + def _thread_getter(self, project_name, folder_id): + task_items = self._controller.get_task_items( + project_name, folder_id + ) + task_type_items = {} + if hasattr(self._controller, "get_task_type_items"): + task_type_items = self._controller.get_task_type_items( + project_name + ) + return task_items, task_type_items + + @classmethod + def _get_default_task_icon(cls): + if cls._default_task_icon is None: + cls._default_task_icon = get_qt_icon({ + "type": "awesome-font", + "name": "fa.male", + "color": get_default_entity_icon_color() + }) + return cls._default_task_icon + + def _get_task_item_icon( + self, + task_item, + task_type_item_by_name, + task_type_icon_cache + ): + icon = task_type_icon_cache.get(task_item.task_type) + if icon is not None: + return icon + + task_type_item = task_type_item_by_name.get( + task_item.task_type + ) + icon = None + if task_type_item is not None: + icon = get_qt_icon({ + "type": "material-symbols", + "name": task_type_item.icon, + "color": get_default_entity_icon_color() + }) + + if icon is None: + icon = self._get_default_task_icon() + task_type_icon_cache[task_item.task_type] = icon + return icon + def _fill_data_from_thread(self, thread): - task_items = thread.get_result() + task_items, task_type_items = thread.get_result() # Task items are refreshed if task_items is None: return @@ -197,6 +248,11 @@ def _fill_data_from_thread(self, thread): return self._remove_invalid_items() + task_type_item_by_name = { + task_type_item.name: task_type_item + for task_type_item in task_type_items + } + task_type_icon_cache = {} new_items = [] new_names = set() for task_item in task_items: @@ -209,8 +265,11 @@ def _fill_data_from_thread(self, thread): new_items.append(item) self._items_by_name[name] = item - # TODO cache locally - icon = get_qt_icon(task_item.icon) + icon = self._get_task_item_icon( + task_item, + task_type_item_by_name, + task_type_icon_cache + ) item.setData(task_item.label, QtCore.Qt.DisplayRole) item.setData(name, ITEM_NAME_ROLE) item.setData(task_item.id, ITEM_ID_ROLE) diff --git a/client/ayon_core/tools/workfiles/abstract.py b/client/ayon_core/tools/workfiles/abstract.py index 330b413300..e949915ab2 100644 --- a/client/ayon_core/tools/workfiles/abstract.py +++ b/client/ayon_core/tools/workfiles/abstract.py @@ -546,6 +546,46 @@ def get_user_items_by_name(self): """ pass + @abstractmethod + def get_folder_type_items(self, project_name, sender=None): + """Folder type items for a project. + + This function may trigger events with topics + 'projects.folder_types.refresh.started' and + 'projects.folder_types.refresh.finished' which will contain 'sender' + value in data. + That may help to avoid re-refresh of items in UI elements. + + Args: + project_name (str): Project name. + sender (str): Who requested folder type items. + + Returns: + list[FolderTypeItem]: Folder type information. + + """ + pass + + @abstractmethod + def get_task_type_items(self, project_name, sender=None): + """Task type items for a project. + + This function may trigger events with topics + 'projects.task_types.refresh.started' and + 'projects.task_types.refresh.finished' which will contain 'sender' + value in data. + That may help to avoid re-refresh of items in UI elements. + + Args: + project_name (str): Project name. + sender (str): Who requested task type items. + + Returns: + list[TaskTypeItem]: Task type information. + + """ + pass + # Host information @abstractmethod def get_workfile_extensions(self): diff --git a/client/ayon_core/tools/workfiles/control.py b/client/ayon_core/tools/workfiles/control.py index 31bdb2bab6..ca97015eea 100644 --- a/client/ayon_core/tools/workfiles/control.py +++ b/client/ayon_core/tools/workfiles/control.py @@ -231,6 +231,16 @@ def get_project_entity(self, project_name): return self._projects_model.get_project_entity( project_name) + def get_folder_type_items(self, project_name, sender=None): + return self._projects_model.get_folder_type_items( + project_name, sender + ) + + def get_task_type_items(self, project_name, sender=None): + return self._projects_model.get_task_type_items( + project_name, sender + ) + def get_folder_entity(self, project_name, folder_id): return self._hierarchy_model.get_folder_entity( project_name, folder_id) diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/__init__.py b/client/ayon_core/vendor/python/qtmaterialsymbols/__init__.py new file mode 100644 index 0000000000..4b3eeb41e9 --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/__init__.py @@ -0,0 +1,18 @@ +from .version import __version__ +from .utils import get_icon_name_char +from .iconic_font import ( + IconicFont, + get_instance, + get_icon, +) + + +__all__ = ( + "__version__", + + "get_icon_name_char", + + "IconicFont", + "get_instance", + "get_icon", +) diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/browser.py b/client/ayon_core/vendor/python/qtmaterialsymbols/browser.py new file mode 100644 index 0000000000..b8e07dd1a7 --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/browser.py @@ -0,0 +1,209 @@ +import sys + +from qtpy import QtCore, QtGui, QtWidgets + +from .iconic_font import get_instance + + +# TODO: Set icon colour and copy code with color kwarg + +VIEW_COLUMNS = 5 +AUTO_SEARCH_TIMEOUT = 500 +ALL_COLLECTIONS = 'All' + + +class IconBrowser(QtWidgets.QMainWindow): + """ + A small browser window that allows the user to search through all icons from + the available version of QtAwesome. You can also copy the name and python + code for the currently selected icon. + """ + + def __init__(self): + super(IconBrowser, self).__init__() + self.setMinimumSize(400, 300) + self.setWindowTitle("Material Icon Browser") + + instance = get_instance() + fontMaps = instance.get_charmap() + + iconNames = list(fontMaps) + + self._filterTimer = QtCore.QTimer(self) + self._filterTimer.setSingleShot(True) + self._filterTimer.setInterval(AUTO_SEARCH_TIMEOUT) + self._filterTimer.timeout.connect(self._updateFilter) + + model = IconModel(self.palette().color(QtGui.QPalette.Text)) + model.setStringList(sorted(iconNames)) + + self._proxyModel = QtCore.QSortFilterProxyModel() + self._proxyModel.setSourceModel(model) + self._proxyModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) + + self._listView = IconListView(self) + self._listView.setUniformItemSizes(True) + self._listView.setViewMode(QtWidgets.QListView.IconMode) + self._listView.setModel(self._proxyModel) + self._listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self._listView.doubleClicked.connect(self._copyIconText) + + self._lineEdit = QtWidgets.QLineEdit(self) + self._lineEdit.setAlignment(QtCore.Qt.AlignCenter) + self._lineEdit.textChanged.connect(self._triggerDelayedUpdate) + self._lineEdit.returnPressed.connect(self._triggerImmediateUpdate) + + self._comboBox = QtWidgets.QComboBox(self) + self._comboBox.setMinimumWidth(75) + self._comboBox.currentIndexChanged.connect(self._triggerImmediateUpdate) + self._comboBox.addItems([ALL_COLLECTIONS] + sorted(fontMaps.keys())) + + lyt = QtWidgets.QHBoxLayout() + lyt.setContentsMargins(0, 0, 0, 0) + lyt.addWidget(self._comboBox) + lyt.addWidget(self._lineEdit) + + searchBarFrame = QtWidgets.QFrame(self) + searchBarFrame.setLayout(lyt) + + self._copyButton = QtWidgets.QPushButton('Copy Name', self) + self._copyButton.clicked.connect(self._copyIconText) + + lyt = QtWidgets.QVBoxLayout() + lyt.addWidget(searchBarFrame) + lyt.addWidget(self._listView) + lyt.addWidget(self._copyButton) + + frame = QtWidgets.QFrame(self) + frame.setLayout(lyt) + + self.setCentralWidget(frame) + + QtWidgets.QShortcut( + QtGui.QKeySequence(QtCore.Qt.Key_Return), + self, + self._copyIconText, + ) + + self._lineEdit.setFocus() + + # geo = self.geometry() + # desktop = QtWidgets.QApplication.desktop() + # screen = desktop.screenNumber(desktop.cursor().pos()) + # centerPoint = desktop.screenGeometry(screen).center() + # geo.moveCenter(centerPoint) + # self.setGeometry(geo) + + def _updateFilter(self): + """ + Update the string used for filtering in the proxy model with the + current text from the line edit. + """ + reString = "" + + group = self._comboBox.currentText() + if group != ALL_COLLECTIONS: + reString += r"^%s\." % group + + searchTerm = self._lineEdit.text() + if searchTerm: + reString += ".*%s.*$" % searchTerm + + self._proxyModel.setFilterRegularExpression(reString) + + def _triggerDelayedUpdate(self): + """ + Reset the timer used for committing the search term to the proxy model. + """ + self._filterTimer.stop() + self._filterTimer.start() + + def _triggerImmediateUpdate(self): + """ + Stop the timer used for committing the search term and update the + proxy model immediately. + """ + self._filterTimer.stop() + self._updateFilter() + + def _copyIconText(self): + """ + Copy the name of the currently selected icon to the clipboard. + """ + indexes = self._listView.selectedIndexes() + if not indexes: + return + + clipboard = QtWidgets.QApplication.instance().clipboard() + clipboard.setText(indexes[0].data()) + + +class IconListView(QtWidgets.QListView): + """ + A QListView that scales it's grid size to ensure the same number of + columns are always drawn. + """ + + def __init__(self, parent=None): + super(IconListView, self).__init__(parent) + self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) + + def resizeEvent(self, event): + """ + Re-implemented to re-calculate the grid size to provide scaling icons + + Parameters + ---------- + event : QtCore.QEvent + """ + width = self.viewport().width() - 30 + # The minus 30 above ensures we don't end up with an item width that + # can't be drawn the expected number of times across the view without + # being wrapped. Without this, the view can flicker during resize + tileWidth = width / VIEW_COLUMNS + iconWidth = int(tileWidth * 0.8) + + self.setGridSize(QtCore.QSize(tileWidth, tileWidth)) + self.setIconSize(QtCore.QSize(iconWidth, iconWidth)) + + return super(IconListView, self).resizeEvent(event) + + +class IconModel(QtCore.QStringListModel): + def __init__(self, iconColor): + super(IconModel, self).__init__() + self._iconColor = iconColor + + def flags(self, index): + return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable + + def data(self, index, role): + """ + Re-implemented to return the icon for the current index. + + Parameters + ---------- + index : QtCore.QModelIndex + role : int + + Returns + ------- + Any + """ + if role == QtCore.Qt.DecorationRole: + iconString = self.data(index, role=QtCore.Qt.DisplayRole) + instance = get_instance() + return instance.get_icon(iconString, color=self._iconColor) + return super(IconModel, self).data(index, role) + + +def run(): + """ + Start the IconBrowser and block until the process exits. + """ + app = QtWidgets.QApplication([]) + + browser = IconBrowser() + browser.show() + + sys.exit(app.exec_()) diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/exceptions.py b/client/ayon_core/vendor/python/qtmaterialsymbols/exceptions.py new file mode 100644 index 0000000000..cd59837b0a --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/exceptions.py @@ -0,0 +1,8 @@ +class ApplicationNotRunning(Exception): + """Raised when the QApplication is not running.""" + pass + + +class FontError(Exception): + """Raised when there is an issue with font.""" + pass diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/iconic_font.py b/client/ayon_core/vendor/python/qtmaterialsymbols/iconic_font.py new file mode 100644 index 0000000000..00d166f3bc --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/iconic_font.py @@ -0,0 +1,254 @@ +r""" + +Iconic Font +=========== + +A lightweight module handling iconic fonts. + +It is designed to provide a simple way for creating QIcons from glyphs. + +From a user's viewpoint, the main entry point is the ``IconicFont`` class which +contains methods for loading new iconic fonts with their character map and +methods returning instances of ``QIcon``. + +""" +import warnings + +from typing import Dict, Optional, Union + +from qtpy import QtCore, QtGui, QtWidgets + +from .structures import IconOptions, Position +from .utils import get_char_mapping, get_icon_name_char, _get_font_name + + +class _Cache: + instance = None + + +def get_instance(): + if _Cache.instance is None: + _Cache.instance = IconicFont() + return _Cache.instance + + +def get_icon(*args, **kwargs): + return get_instance().get_icon(*args, **kwargs) + + +class CharIconPainter: + """Char icon painter.""" + def paint(self, iconic, painter, rect, mode, state, options): + """Main paint method.""" + self._paint_icon(iconic, painter, rect, mode, state, options) + + def _paint_icon(self, iconic, painter, rect, mode, state, options): + """Paint a single icon.""" + painter.save() + + color = options.get_color_for_state(state, mode) + char = options.get_char_for_state(state, mode) + + painter.setPen(QtGui.QColor(color)) + + # A 16 pixel-high icon yields a font size of 14, which is pixel perfect + # for font-awesome. 16 * 0.875 = 14 + # The reason why the glyph size is smaller than the icon size is to + # account for font bearing. + # draw_size = round(0.875 * rect.height() * options.scale_factor) + + draw_size = round(rect.height() * options.scale_factor) + + painter.setFont(iconic.get_font(draw_size)) + if options.offset is not None: + rect = QtCore.QRect(rect) + rect.translate( + round(options.offset.x * rect.width()), + round(options.offset.y * rect.height()) + ) + + scale_x = -1 if options.hflip else 1 + scale_y = -1 if options.vflip else 1 + + if options.vflip or options.hflip or options.rotate: + x_center = rect.width() * 0.5 + y_center = rect.height() * 0.5 + painter.translate(x_center, y_center) + + transfrom = QtGui.QTransform() + transfrom.scale(scale_x, scale_y) + painter.setTransform(transfrom, True) + + if options.rotate: + painter.rotate(options.rotate) + painter.translate(-x_center, -y_center) + + painter.setOpacity(options.opacity) + + painter.drawText(rect, QtCore.Qt.AlignCenter, char) + painter.restore() + + +class CharIconEngine(QtGui.QIconEngine): + """Specialization of QIconEngine used to draw font-based icons.""" + + def __init__( + self, + iconic: "IconicFont", + painter: QtGui.QPainter, + options: IconOptions + ): + super(CharIconEngine, self).__init__() + self._iconic = iconic + self._painter = painter + self._options = options + + def paint(self, painter, rect, mode, state): + self._painter.paint( + self._iconic, + painter, + rect, + mode, + state, + self._options + ) + + def pixmap(self, size, mode, state): + pm = QtGui.QPixmap(size) + pm.fill(QtCore.Qt.transparent) + painter = QtGui.QPainter(pm) + self.paint( + painter, + QtCore.QRect(QtCore.QPoint(0, 0), size), + mode, + state + ) + return pm + + +class IconicFont(QtCore.QObject): + """Main class for managing icons.""" + + def __init__(self): + super().__init__() + self._painter = CharIconPainter() + self._icon_cache = {} + + def get_charmap(self) -> Dict[str, int]: + return get_char_mapping() + + def get_font(self, size: int) -> QtGui.QFont: + """Return a QFont corresponding to the given size.""" + font = QtGui.QFont(_get_font_name()) + font.setPixelSize(round(size)) + return font + + def get_icon_with_options(self, options: IconOptions) -> QtGui.QIcon: + """Return a QIcon object corresponding to the provided icon name.""" + if QtWidgets.QApplication.instance() is None: + warnings.warn( + "You need to have a running QApplication!" + ) + return QtGui.QIcon() + + cache_key = options.identifier + if cache_key in self._icon_cache: + return self._icon_cache[cache_key] + + output = self._icon_by_painter(self._painter, options) + self._icon_cache[cache_key] = output + return output + + def get_icon( + self, + icon_name: Optional[str] = None, + color: Optional[Union[QtGui.QColor, str]] = None, + opacity: Optional[float] = None, + scale_factor: Optional[float] = None, + offset: Optional[Position] = None, + hflip: Optional[bool] = False, + vflip: Optional[bool] = False, + rotate: Optional[int] = 0, + icon_name_normal: Optional[str] = None, + icon_name_active: Optional[str] = None, + icon_name_selected: Optional[str] = None, + icon_name_disabled: Optional[str] = None, + icon_name_on: Optional[str] = None, + icon_name_off: Optional[str] = None, + icon_name_on_normal: Optional[str] = None, + icon_name_off_normal: Optional[str] = None, + icon_name_on_active: Optional[str] = None, + icon_name_off_active: Optional[str] = None, + icon_name_on_selected: Optional[str] = None, + icon_name_off_selected: Optional[str] = None, + icon_name_on_disabled: Optional[str] = None, + icon_name_off_disabled: Optional[str] = None, + color_normal: Optional[Union[QtGui.QColor, str]] = None, + color_active: Optional[Union[QtGui.QColor, str]] = None, + color_selected: Optional[Union[QtGui.QColor, str]] = None, + color_disabled: Optional[Union[QtGui.QColor, str]] = None, + color_on: Optional[Union[QtGui.QColor, str]] = None, + color_off: Optional[Union[QtGui.QColor, str]] = None, + color_on_normal: Optional[Union[QtGui.QColor, str]] = None, + color_off_normal: Optional[Union[QtGui.QColor, str]] = None, + color_on_active: Optional[Union[QtGui.QColor, str]] = None, + color_off_active: Optional[Union[QtGui.QColor, str]] = None, + color_on_selected: Optional[Union[QtGui.QColor, str]] = None, + color_off_selected: Optional[Union[QtGui.QColor, str]] = None, + color_on_disabled: Optional[Union[QtGui.QColor, str]] = None, + color_off_disabled: Optional[Union[QtGui.QColor, str]] = None, + ) -> QtGui.QIcon: + """Return a QIcon object corresponding to the provided icon name.""" + if QtWidgets.QApplication.instance() is None: + warnings.warn( + "You need to have a running QApplication!" + ) + return QtGui.QIcon() + + options = IconOptions.from_data( + icon_name=icon_name, + color=color, + opacity=opacity, + scale_factor=scale_factor, + offset=offset, + hflip=hflip, + vflip=vflip, + rotate=rotate, + icon_name_normal=icon_name_normal, + icon_name_active=icon_name_active, + icon_name_selected=icon_name_selected, + icon_name_disabled=icon_name_disabled, + icon_name_on=icon_name_on, + icon_name_off=icon_name_off, + icon_name_on_normal=icon_name_on_normal, + icon_name_off_normal=icon_name_off_normal, + icon_name_on_active=icon_name_on_active, + icon_name_off_active=icon_name_off_active, + icon_name_on_selected=icon_name_on_selected, + icon_name_off_selected=icon_name_off_selected, + icon_name_on_disabled=icon_name_on_disabled, + icon_name_off_disabled=icon_name_off_disabled, + color_normal=color_normal, + color_active=color_active, + color_selected=color_selected, + color_disabled=color_disabled, + color_on=color_on, + color_off=color_off, + color_on_normal=color_on_normal, + color_off_normal=color_off_normal, + color_on_active=color_on_active, + color_off_active=color_off_active, + color_on_selected=color_on_selected, + color_off_selected=color_off_selected, + color_on_disabled=color_on_disabled, + color_off_disabled=color_off_disabled, + ) + cache_key = options.identifier + if cache_key in self._icon_cache: + return self._icon_cache[cache_key] + return self.get_icon_with_options(options) + + def _icon_by_painter(self, painter, options): + """Return the icon corresponding to the given painter.""" + engine = CharIconEngine(self, painter, options) + return QtGui.QIcon(engine) diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.codepoints b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.codepoints new file mode 100644 index 0000000000..a4451c793a --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.codepoints @@ -0,0 +1,3599 @@ +10k e951 +10mp e952 +11mp e953 +123 eb8d +12mp e954 +13mp e955 +14mp e956 +15mp e957 +16mp e958 +17mp e959 +18_up_rating f8fd +18mp e95a +19mp e95b +1k e95c +1k_plus e95d +1x_mobiledata efcd +1x_mobiledata_badge f7f1 +20mp e95e +21mp e95f +22mp e960 +23mp e961 +24mp e962 +2d ef37 +2k e963 +2k_plus e964 +2mp e965 +30fps efce +30fps_select efcf +360 e577 +3d_rotation e84d +3g_mobiledata efd0 +3g_mobiledata_badge f7f0 +3k e966 +3k_plus e967 +3mp e968 +3p efd1 +4g_mobiledata efd2 +4g_mobiledata_badge f7ef +4g_plus_mobiledata efd3 +4k e072 +4k_plus e969 +4mp e96a +50mp f6f3 +5g ef38 +5g_mobiledata_badge f7ee +5k e96b +5k_plus e96c +5mp e96d +60fps efd4 +60fps_select efd5 +6_ft_apart f21e +6k e96e +6k_plus e96f +6mp e970 +7k e971 +7k_plus e972 +7mp e973 +8k e974 +8k_plus e975 +8mp e976 +9k e977 +9k_plus e978 +9mp e979 +abc eb94 +ac_unit eb3b +access_alarm e855 +access_alarms e855 +access_time efd6 +access_time_filled efd6 +accessibility e84e +accessibility_new e92c +accessible e914 +accessible_forward e934 +account_balance e84f +account_balance_wallet e850 +account_box e851 +account_child e852 +account_child_invert e659 +account_circle f20b +account_circle_filled f20b +account_circle_off f7b3 +account_tree e97a +action_key f502 +activity_zone e1e6 +acute e4cb +ad e65a +ad_group e65b +ad_group_off eae5 +ad_off f7b2 +ad_units ef39 +adaptive_audio_mic f4cc +adaptive_audio_mic_off f4cb +adb e60e +add e145 +add_a_photo e439 +add_ad e72a +add_alarm e856 +add_alert e003 +add_box e146 +add_business e729 +add_call f0b7 +add_card eb86 +add_chart ef3c +add_circle e3ba +add_circle_outline e3ba +add_comment e266 +add_diamond f49c +add_home f8eb +add_home_work f8ed +add_ic_call f0b7 +add_link e178 +add_location e567 +add_location_alt ef3a +add_moderator e97d +add_notes e091 +add_photo_alternate e43e +add_reaction e1d3 +add_road ef3b +add_shopping_cart e854 +add_task f23a +add_to_drive e65c +add_to_home_screen e1fe +add_to_photos e39d +add_to_queue e05c +add_triangle f48e +addchart ef3c +adf_scanner eada +adjust e39e +admin_meds e48d +admin_panel_settings ef3d +ads_click e762 +agender f888 +agriculture ea79 +air efd8 +air_freshener e2ca +air_purifier e97e +air_purifier_gen e829 +airline_seat_flat e630 +airline_seat_flat_angled e631 +airline_seat_individual_suite e632 +airline_seat_legroom_extra e633 +airline_seat_legroom_normal e634 +airline_seat_legroom_reduced e635 +airline_seat_recline_extra e636 +airline_seat_recline_normal e637 +airline_stops e7d0 +airlines e7ca +airplane_ticket efd9 +airplanemode_active e53d +airplanemode_inactive e194 +airplay e055 +airport_shuttle eb3c +airware f154 +airwave f154 +alarm e855 +alarm_add e856 +alarm_off e857 +alarm_on e858 +alarm_smart_wake f6b0 +album e019 +align_center e356 +align_end f797 +align_flex_center f796 +align_flex_end f795 +align_flex_start f794 +align_horizontal_center e00f +align_horizontal_left e00d +align_horizontal_right e010 +align_items_stretch f793 +align_justify_center f792 +align_justify_flex_end f791 +align_justify_flex_start f790 +align_justify_space_around f78f +align_justify_space_between f78e +align_justify_space_even f78d +align_justify_stretch f78c +align_self_stretch f78b +align_space_around f78a +align_space_between f789 +align_space_even f788 +align_start f787 +align_stretch f786 +align_vertical_bottom e015 +align_vertical_center e011 +align_vertical_top e00c +all_inbox e97f +all_inclusive eb3d +all_match e093 +all_out e90b +allergies e094 +allergy e64e +alt_route f184 +alternate_email e0e6 +altitude f873 +ambient_screen f6c4 +ambulance f803 +amend f802 +amp_stories ea13 +analytics ef3e +anchor f1cd +android e859 +animated_images f49a +animation e71c +announcement e87f +aod efda +aod_tablet f89f +aod_watch f6ac +apartment ea40 +api f1b7 +apk_document f88e +apk_install f88f +app_badging f72f +app_blocking ef3f +app_promo e981 +app_registration ef40 +app_settings_alt ef41 +app_shortcut eae4 +apparel ef7b +approval e982 +approval_delegation f84a +apps e5c3 +apps_outage e7cc +aq f55a +aq_indoor f55b +ar_on_you ef7c +ar_stickers e983 +architecture ea3b +archive e149 +area_chart e770 +arming_countdown e78a +arrow_and_edge f5d7 +arrow_back e5c4 +arrow_back_ios e5e0 +arrow_back_ios_new e2ea +arrow_circle_down f181 +arrow_circle_left eaa7 +arrow_circle_right eaaa +arrow_circle_up f182 +arrow_cool_down f4b6 +arrow_downward e5db +arrow_downward_alt e984 +arrow_drop_down e5c5 +arrow_drop_down_circle e5c6 +arrow_drop_up e5c7 +arrow_forward e5c8 +arrow_forward_ios e5e1 +arrow_insert f837 +arrow_left e5de +arrow_left_alt ef7d +arrow_or_edge f5d6 +arrow_outward f8ce +arrow_range f69b +arrow_right e5df +arrow_right_alt e941 +arrow_selector_tool f82f +arrow_split ea04 +arrow_top_left f72e +arrow_top_right f72d +arrow_upward e5d8 +arrow_upward_alt e986 +arrow_warm_up f4b5 +arrows_more_down f8ab +arrows_more_up f8ac +arrows_outward f72c +art_track e060 +article ef42 +article_shortcut f587 +artist e01a +aspect_ratio e85b +assessment f0cc +assignment e85d +assignment_add f848 +assignment_ind e85e +assignment_late e85f +assignment_return e860 +assignment_returned e861 +assignment_turned_in e862 +assist_walker f8d5 +assistant e39f +assistant_device e987 +assistant_direction e988 +assistant_navigation e989 +assistant_on_hub f6c1 +assistant_photo f0c6 +assured_workload eb6f +asterisk f525 +astrophotography_auto f1d9 +astrophotography_off f1da +atm e573 +atr ebc7 +attach_email ea5e +attach_file e226 +attach_file_add f841 +attach_file_off f4d9 +attach_money e227 +attachment e2bc +attractions ea52 +attribution efdb +audio_description f58c +audio_file eb82 +audio_video_receiver f5d3 +audiotrack e405 +auto_activity_zone f8ad +auto_awesome e65f +auto_awesome_mosaic e660 +auto_awesome_motion e661 +auto_delete ea4c +auto_detect_voice f83e +auto_draw_solid e98a +auto_fix e663 +auto_fix_high e663 +auto_fix_normal e664 +auto_fix_off e665 +auto_graph e4fb +auto_label f6be +auto_meeting_room f6bf +auto_mode ec20 +auto_read_pause f219 +auto_read_play f216 +auto_schedule e214 +auto_stories e666 +auto_timer ef7f +auto_towing e71e +auto_transmission f53f +auto_videocam f6c0 +autofps_select efdc +autopause f6b6 +autopay f84b +autoplay f6b5 +autorenew e863 +autostop f682 +av1 f4b0 +av_timer e01b +avc f4af +avg_pace f6bb +avg_time f813 +award_star f612 +azm f6ec +baby_changing_station f19b +back_hand e764 +back_to_tab f72b +background_dot_large f79e +background_dot_small f514 +background_grid_small f79d +background_replace f20a +backlight_high f7ed +backlight_high_off f4ef +backlight_low f7ec +backpack f19c +backspace e14a +backup e864 +backup_table ef43 +badge ea67 +badge_critical_battery f156 +bakery_dining ea53 +balance eaf6 +balcony e58f +ballot e172 +bar_chart e26b +bar_chart_4_bars f681 +barcode e70b +barcode_reader f85c +barcode_scanner e70c +barefoot f871 +batch_prediction f0f5 +bath_outdoor f6fb +bath_private f6fa +bath_public_large f6f9 +bathroom efdd +bathtub ea41 +battery_0_bar ebdc +battery_1_bar f09c +battery_20 f09c +battery_2_bar f09d +battery_30 f09d +battery_3_bar f09e +battery_4_bar f09f +battery_50 f09e +battery_5_bar f0a0 +battery_60 f09f +battery_6_bar f0a1 +battery_80 f0a0 +battery_90 f0a1 +battery_alert e19c +battery_change f7eb +battery_charging_20 f0a2 +battery_charging_30 f0a3 +battery_charging_50 f0a4 +battery_charging_60 f0a5 +battery_charging_80 f0a6 +battery_charging_90 f0a7 +battery_charging_full e1a3 +battery_error f7ea +battery_full e1a5 +battery_full_alt f13b +battery_horiz_000 f8ae +battery_horiz_050 f8af +battery_horiz_075 f8b0 +battery_low f155 +battery_plus f7e9 +battery_profile e206 +battery_saver efde +battery_share f67e +battery_status_good f67d +battery_std e1a5 +battery_unknown e1a6 +battery_vert_005 f8b1 +battery_vert_020 f8b2 +battery_vert_050 f8b3 +battery_very_low f156 +beach_access eb3e +bed efdf +bedroom_baby efe0 +bedroom_child efe1 +bedroom_parent efe2 +bedtime ef44 +bedtime_off eb76 +beenhere e52d +bento f1f4 +bia f6eb +bid_landscape e678 +bid_landscape_disabled ef81 +bigtop_updates e669 +bike_dock f47b +bike_lane f47a +bike_scooter ef45 +biotech ea3a +blanket e828 +blender efe3 +blind f8d6 +blinds e286 +blinds_closed ec1f +block f08c +blood_pressure e097 +bloodtype efe4 +bluetooth e1a7 +bluetooth_audio e60f +bluetooth_connected e1a8 +bluetooth_disabled e1a9 +bluetooth_drive efe5 +bluetooth_searching e60f +blur_circular e3a2 +blur_linear e3a3 +blur_medium e84c +blur_off e3a4 +blur_on e3a5 +blur_short e8cf +body_fat e098 +body_system e099 +bolt ea0b +bomb f568 +book e86e +book_2 f53e +book_3 f53d +book_4 f53c +book_5 f53b +book_online f217 +bookmark e8e7 +bookmark_add e598 +bookmark_added e599 +bookmark_border e8e7 +bookmark_check f457 +bookmark_flag f456 +bookmark_heart f455 +bookmark_manager f7b1 +bookmark_remove e59a +bookmark_star f454 +bookmarks e98b +border_all e228 +border_bottom e229 +border_clear e22a +border_color e22b +border_horizontal e22c +border_inner e22d +border_left e22e +border_outer e22f +border_right e230 +border_style e231 +border_top e232 +border_vertical e233 +bottom_app_bar e730 +bottom_drawer e72d +bottom_navigation e98c +bottom_panel_close f72a +bottom_panel_open f729 +bottom_right_click f684 +bottom_sheets e98d +box f5a4 +box_add f5a5 +box_edit f5a6 +boy eb67 +brand_awareness e98e +brand_family f4f1 +branding_watermark e06b +breakfast_dining ea54 +breaking_news ea08 +breaking_news_alt_1 f0ba +breastfeeding f856 +brightness_1 e3fa +brightness_2 f036 +brightness_3 e3a8 +brightness_4 e3a9 +brightness_5 e3aa +brightness_6 e3ab +brightness_7 e3ac +brightness_alert f5cf +brightness_auto e1ab +brightness_empty f7e8 +brightness_high e1ac +brightness_low e1ad +brightness_medium e1ae +bring_your_own_ip e016 +broadcast_on_home f8f8 +broadcast_on_personal f8f9 +broken_image e3ad +browse eb13 +browse_activity f8a5 +browse_gallery ebd1 +browser_not_supported ef47 +browser_updated e7cf +brunch_dining ea73 +brush e3ae +bubble ef83 +bubble_chart e6dd +bubbles f64e +bug_report e868 +build f8cd +build_circle ef48 +bungalow e591 +burst_mode e43c +bus_alert e98f +business e7ee +business_center eb3f +business_chip f84c +business_messages ef84 +buttons_alt e72f +cabin e589 +cable efe6 +cable_car f479 +cached e86a +cadence f4b4 +cake e7e9 +cake_add f85b +calculate ea5f +calendar_add_on ef85 +calendar_apps_script f0bb +calendar_clock f540 +calendar_month ebcc +calendar_today e935 +calendar_view_day e936 +calendar_view_month efe7 +calendar_view_week efe8 +call f0d4 +call_end f0bc +call_end_alt f0bc +call_log e08e +call_made e0b2 +call_merge e0b3 +call_missed e0b4 +call_missed_outgoing e0e4 +call_quality f652 +call_received e0b5 +call_split e0b6 +call_to_action e06c +camera e3af +camera_alt e412 +camera_enhance e8fc +camera_front e3b1 +camera_indoor efe9 +camera_outdoor efea +camera_rear e3b2 +camera_roll e3b3 +camera_video f7a6 +cameraswitch efeb +campaign ef49 +camping f8a2 +cancel e888 +cancel_presentation e0e9 +cancel_schedule_send ea39 +candle f588 +candlestick_chart ead4 +captive_portal f728 +capture f727 +car_crash ebf2 +car_rental ea55 +car_repair ea56 +car_tag f4e3 +card_giftcard e8f6 +card_membership e8f7 +card_travel e8f8 +cardio_load f4b9 +cardiology e09c +cards e991 +carpenter f1f8 +carry_on_bag eb08 +carry_on_bag_checked eb0b +carry_on_bag_inactive eb0a +carry_on_bag_question eb09 +cases e992 +casino eb40 +cast e307 +cast_connected e308 +cast_for_education efec +cast_pause f5f0 +cast_warning f5ef +castle eab1 +category e574 +celebration ea65 +cell_merge f82e +cell_tower ebba +cell_wifi e0ec +center_focus_strong e3b4 +center_focus_weak e3b5 +chair efed +chair_alt efee +chalet e585 +change_circle e2e7 +change_history e86b +charger e2ae +charging_station f19d +chart_data e473 +chat e0c9 +chat_add_on f0f3 +chat_apps_script f0bd +chat_bubble e0cb +chat_bubble_outline e0cb +chat_error f7ac +chat_info f52b +chat_paste_go f6bd +check e5ca +check_box e834 +check_box_outline_blank e835 +check_circle f0be +check_circle_filled f0be +check_circle_outline f0be +check_in_out f6f6 +check_indeterminate_small f88a +check_small f88b +checkbook e70d +checked_bag eb0c +checked_bag_question eb0d +checklist e6b1 +checklist_rtl e6b3 +checkroom f19e +cheer f6a8 +chess f5e7 +chevron_backward f46b +chevron_forward f46a +chevron_left e5cb +chevron_right e5cc +child_care eb41 +child_friendly eb42 +chip_extraction f821 +chips e993 +chrome_reader_mode e86d +chromecast_2 f17b +chromecast_device e83c +chronic ebb2 +church eaae +cinematic_blur f853 +circle ef4a +circle_notifications e994 +circles e7ea +circles_ext e7ec +clarify f0bf +class e86e +clean_hands f21f +cleaning e995 +cleaning_bucket f8b4 +cleaning_services f0ff +clear e5cd +clear_all e0b8 +clear_day f157 +clear_night f159 +climate_mini_split f8b5 +clinical_notes e09e +clock_loader_10 f726 +clock_loader_20 f725 +clock_loader_40 f724 +clock_loader_60 f723 +clock_loader_80 f722 +clock_loader_90 f721 +close e5cd +close_fullscreen f1cf +close_small f508 +closed_caption e996 +closed_caption_add f4ae +closed_caption_disabled f1dc +closed_caption_off e996 +cloud f15c +cloud_circle e2be +cloud_done e2bf +cloud_download e2c0 +cloud_off e2c1 +cloud_queue f15c +cloud_sync eb5a +cloud_upload e2c3 +cloudy f15c +cloudy_filled f15c +cloudy_snowing e810 +co2 e7b0 +co_present eaf0 +code e86f +code_blocks f84d +code_off e4f3 +coffee efef +coffee_maker eff0 +cognition e09f +collapse_all e944 +collapse_content f507 +collections e3d3 +collections_bookmark e431 +color_lens e40a +colorize e3b8 +colors e997 +comedy_mask f4d6 +comic_bubble f5dd +comment e24c +comment_bank ea4e +comments_disabled e7a2 +commit eaf5 +communication e27c +communities eb16 +communities_filled eb16 +commute e940 +compare e3b9 +compare_arrows e915 +compass_calibration e57c +component_exchange f1e7 +compost e761 +compress e94d +computer e31e +concierge f561 +conditions e0a0 +confirmation_number e638 +congenital e0a1 +connect_without_contact f223 +connected_tv e998 +connecting_airports e7c9 +construction ea3c +contact_emergency f8d1 +contact_mail e0d0 +contact_page f22e +contact_phone f0c0 +contact_phone_filled f0c0 +contact_support e94c +contactless ea71 +contactless_off f858 +contacts e0ba +contacts_product e999 +content_copy e14d +content_cut e14e +content_paste e14f +content_paste_go ea8e +content_paste_off e4f8 +content_paste_search ea9b +contextual_token f486 +contextual_token_add f485 +contract f5a0 +contract_delete f5a2 +contract_edit f5a1 +contrast eb37 +contrast_circle f49f +contrast_rtl_off ec72 +contrast_square f4a0 +control_camera e074 +control_point e3ba +control_point_duplicate e3bb +controller_gen e83d +conversion_path f0c1 +conversion_path_off f7b4 +conveyor_belt f867 +cookie eaac +cookie_off f79a +cooking e2b6 +cool_to_dry e276 +copy_all e2ec +copyright e90c +coronavirus f221 +corporate_fare f1d0 +cottage e587 +counter_0 f785 +counter_1 f784 +counter_2 f783 +counter_3 f782 +counter_4 f781 +counter_5 f780 +counter_6 f77f +counter_7 f77e +counter_8 f77d +counter_9 f77c +countertops f1f7 +create f097 +create_new_folder e2cc +credit_card e8a1 +credit_card_gear f52d +credit_card_heart f52c +credit_card_off e4f4 +credit_score eff1 +crib e588 +crisis_alert ebe9 +crop e3be +crop_16_9 e3bc +crop_3_2 e3bd +crop_5_4 e3bf +crop_7_5 e3c0 +crop_9_16 f549 +crop_din e3c6 +crop_free e3c2 +crop_landscape e3c3 +crop_original e3f4 +crop_portrait e3c5 +crop_rotate e437 +crop_square e3c6 +crossword f5e5 +crowdsource eb18 +cruelty_free e799 +css eb93 +csv e6cf +currency_bitcoin ebc5 +currency_exchange eb70 +currency_franc eafa +currency_lira eaef +currency_pound eaf1 +currency_ruble eaec +currency_rupee eaf7 +currency_rupee_circle f460 +currency_yen eafb +currency_yuan eaf9 +curtains ec1e +curtains_closed ec1d +custom_typography e732 +cut f08b +cycle f854 +cyclone ebd5 +dangerous e99a +dark_mode e51c +dashboard e871 +dashboard_customize e99b +data_alert f7f6 +data_array ead1 +data_check f7f2 +data_exploration e76f +data_info_alert f7f5 +data_loss_prevention e2dc +data_object ead3 +data_saver_off eff2 +data_saver_on eff3 +data_table e99c +data_thresholding eb9f +data_usage eff2 +database f20e +dataset f8ee +dataset_linked f8ef +date_range e916 +deblur eb77 +deceased e0a5 +decimal_decrease f82d +decimal_increase f82c +deck ea42 +dehaze e3c7 +delete e92e +delete_forever e92b +delete_history f518 +delete_outline e92e +delete_sweep e16c +demography e489 +density_large eba9 +density_medium eb9e +density_small eba8 +dentistry e0a6 +departure_board e576 +deployed_code f720 +deployed_code_account f51b +deployed_code_alert f5f2 +deployed_code_history f5f3 +deployed_code_update f5f4 +dermatology e0a7 +description e873 +deselect ebb6 +design_services f10a +desk f8f4 +deskphone f7fa +desktop_access_disabled e99d +desktop_landscape f45e +desktop_mac e30b +desktop_portrait f45d +desktop_windows e30c +destruction f585 +details e3c8 +detection_and_zone e29f +detector e282 +detector_alarm e1f7 +detector_battery e204 +detector_co e2af +detector_offline e223 +detector_smoke e285 +detector_status e1e8 +developer_board e30d +developer_board_off e4ff +developer_guide e99e +developer_mode e1b0 +developer_mode_tv e874 +device_hub e335 +device_reset e8b3 +device_thermostat e1ff +device_unknown e339 +devices e326 +devices_fold ebde +devices_off f7a5 +devices_other e337 +devices_wearables f6ab +dew_point f879 +diagnosis e0a8 +dialer_sip e0bb +dialogs e99f +dialpad e0bc +diamond ead5 +dictionary f539 +difference eb7d +digital_out_of_home f1de +digital_wellbeing ef86 +dining eff4 +dinner_dining ea57 +directions e52e +directions_alt f880 +directions_alt_off f881 +directions_bike e52f +directions_boat eff5 +directions_boat_filled eff5 +directions_bus eff6 +directions_bus_filled eff6 +directions_car eff7 +directions_car_filled eff7 +directions_off f10f +directions_railway eff8 +directions_railway_2 f462 +directions_railway_filled eff8 +directions_run e566 +directions_subway effa +directions_subway_filled effa +directions_transit effa +directions_transit_filled effa +directions_walk e536 +directory_sync e394 +dirty_lens ef4b +disabled_by_default f230 +disabled_visible e76e +disc_full e610 +discover_tune e018 +dishwasher e9a0 +dishwasher_gen e832 +display_external_input f7e7 +display_settings eb97 +distance f6ea +diversity_1 f8d7 +diversity_2 f8d8 +diversity_3 f8d9 +diversity_4 f857 +dns e875 +do_disturb f08c +do_disturb_alt f08d +do_disturb_off f08e +do_disturb_on f08f +do_not_disturb f08d +do_not_disturb_alt f08c +do_not_disturb_off f08e +do_not_disturb_on f08f +do_not_disturb_on_total_silence effb +do_not_step f19f +do_not_touch f1b0 +dock e30e +dock_to_bottom f7e6 +dock_to_left f7e5 +dock_to_right f7e4 +docs_add_on f0c2 +docs_apps_script f0c3 +document_scanner e5fa +domain e7ee +domain_add eb62 +domain_disabled e0ef +domain_verification ef4c +domain_verification_off f7b0 +domino_mask f5e4 +done e876 +done_all e877 +done_outline e92f +donut_large e917 +donut_small e918 +door_back effc +door_front effd +door_open e77c +door_sensor e28a +door_sliding effe +doorbell efff +doorbell_3p e1e7 +doorbell_chime e1f3 +double_arrow ea50 +downhill_skiing e509 +download f090 +download_2 f523 +download_done f091 +download_for_offline f000 +downloading f001 +draft e66d +draft_orders e7b3 +drafts e151 +drag_click f71f +drag_handle e25d +drag_indicator e945 +drag_pan f71e +draw e746 +draw_abstract f7f8 +draw_collage f7f7 +drawing_recognition eb00 +dresser e210 +drive_eta eff7 +drive_file_move e9a1 +drive_file_move_outline e9a1 +drive_file_move_rtl e9a1 +drive_file_rename_outline e9a2 +drive_folder_upload e9a3 +drive_fusiontable e678 +dropdown e9a4 +dry f1b3 +dry_cleaning ea58 +dual_screen f6cf +duo e9a5 +dvr e1b2 +dynamic_feed ea14 +dynamic_form f1bf +e911_avatar f11a +e911_emergency f119 +e_mobiledata f002 +e_mobiledata_badge f7e3 +earbuds f003 +earbuds_battery f004 +early_on e2ba +earthquake f64f +east f1df +ecg f80f +ecg_heart f6e9 +eco ea35 +eda f6e8 +edgesensor_high f005 +edgesensor_low f006 +edit f097 +edit_attributes e578 +edit_calendar e742 +edit_document f88c +edit_location e568 +edit_location_alt e1c5 +edit_note e745 +edit_notifications e525 +edit_off e950 +edit_road ef4d +edit_square f88d +editor_choice f528 +egg eacc +egg_alt eac8 +eject e8fb +elderly f21a +elderly_woman eb69 +electric_bike eb1b +electric_bolt ec1c +electric_car eb1c +electric_meter ec1b +electric_moped eb1d +electric_rickshaw eb1e +electric_scooter eb1f +electrical_services f102 +elevation f6e7 +elevator f1a0 +email e159 +emergency e1eb +emergency_heat f15d +emergency_heat_2 f4e5 +emergency_home e82a +emergency_recording ebf4 +emergency_share ebf6 +emergency_share_off f59e +emoji_emotions ea22 +emoji_events ea23 +emoji_flags f0c6 +emoji_food_beverage ea1b +emoji_language f4cd +emoji_nature ea1c +emoji_objects ea24 +emoji_people ea1d +emoji_symbols ea1e +emoji_transportation ea1f +emoticon e5f3 +empty_dashboard f844 +enable f188 +encrypted e593 +endocrinology e0a9 +energy e9a6 +energy_program_saving f15f +energy_program_time_used f161 +energy_savings_leaf ec1a +engineering ea3d +enhanced_encryption e63f +ent e0aa +enterprise e70e +enterprise_off eb4d +equal f77b +equalizer e01d +error f8b6 +error_circle_rounded f8b6 +error_med e49b +error_outline f8b6 +escalator f1a1 +escalator_warning f1ac +euro ea15 +euro_symbol e926 +ev_charger e56d +ev_mobiledata_badge f7e2 +ev_shadow ef8f +ev_shadow_add f580 +ev_shadow_minus f57f +ev_station e56d +event e878 +event_available e614 +event_busy e615 +event_list f683 +event_note e616 +event_repeat eb7b +event_seat e903 +event_upcoming f238 +exclamation f22f +exercise f6e6 +exit_to_app e879 +expand e94f +expand_all e946 +expand_circle_down e7cd +expand_circle_right f591 +expand_circle_up f5d2 +expand_content f830 +expand_less e5ce +expand_more e5cf +experiment e686 +explicit e01e +explore e87a +explore_nearby e538 +explore_off e9a8 +explosion f685 +export_notes e0ac +exposure e3f6 +exposure_neg_1 e3cb +exposure_neg_2 e3cc +exposure_plus_1 e800 +exposure_plus_2 e3ce +exposure_zero e3cf +extension e87b +extension_off e4f5 +eye_tracking f4c9 +eyeglasses f6ee +face f008 +face_2 f8da +face_3 f8db +face_4 f8dc +face_5 f8dd +face_6 f8de +face_retouching_natural ef4e +face_retouching_off f007 +face_unlock f008 +fact_check f0c5 +factory ebbc +falling f60d +familiar_face_and_zone e21c +family_history e0ad +family_home eb26 +family_link eb19 +family_restroom f1a2 +family_star f527 +farsight_digital f559 +fast_forward e01f +fast_rewind e020 +fastfood e57a +faucet e278 +favorite e87e +favorite_border e87e +fax ead8 +feature_search e9a9 +featured_play_list e06d +featured_seasonal_and_gifts ef91 +featured_video e06e +feed f009 +feedback e87f +female e590 +femur f891 +femur_alt f892 +fence f1f6 +fertile f6e5 +festival ea68 +fiber_dvr e05d +fiber_manual_record e061 +fiber_new e05e +fiber_pin e06a +fiber_smart_record e062 +file_copy e173 +file_copy_off f4d8 +file_download f090 +file_download_done f091 +file_download_off e4fe +file_map e2c5 +file_open eaf3 +file_present ea0e +file_save f17f +file_save_off e505 +file_upload f09b +file_upload_off f886 +filter e3d3 +filter_1 e3d0 +filter_2 e3d1 +filter_3 e3d2 +filter_4 e3d4 +filter_5 e3d5 +filter_6 e3d6 +filter_7 e3d7 +filter_8 e3d8 +filter_9 e3d9 +filter_9_plus e3da +filter_alt ef4f +filter_alt_off eb32 +filter_b_and_w e3db +filter_center_focus e3dc +filter_drama e3dd +filter_frames e3de +filter_hdr e3df +filter_list e152 +filter_list_alt e94e +filter_list_off eb57 +filter_none e3e0 +filter_retrolux e3e1 +filter_tilt_shift e3e2 +filter_vintage e3e3 +finance e6bf +finance_chip f84e +finance_mode ef92 +find_in_page e880 +find_replace e881 +fingerprint e90d +fingerprint_off f49d +fire_extinguisher f1d8 +fire_hydrant f1a3 +fire_truck f8f2 +fireplace ea43 +first_page e5dc +fit_page f77a +fit_screen ea10 +fit_width f779 +fitness_center eb43 +fitness_tracker f463 +flag f0c6 +flag_circle eaf8 +flag_filled f0c6 +flaky ef50 +flare e3e4 +flash_auto e3e5 +flash_off e3e6 +flash_on e3e7 +flashlight_off f00a +flashlight_on f00b +flatware f00c +flex_direction f778 +flex_no_wrap f777 +flex_wrap f776 +flight e539 +flight_class e7cb +flight_land e904 +flight_takeoff e905 +flights_and_hotels e9ab +flightsmode ef93 +flip e3e8 +flip_camera_android ea37 +flip_camera_ios ea38 +flip_to_back e882 +flip_to_front e883 +float_landscape_2 f45c +float_portrait_2 f45b +flood ebe6 +floor f6e4 +floor_lamp e21e +flourescent f07d +flowsheet e0ae +fluid e483 +fluid_balance f80d +fluid_med f80c +fluorescent f07d +flutter f1dd +flutter_dash e00b +flyover f478 +fmd_bad f00e +fmd_good f1db +foggy e818 +folded_hands f5ed +folder e2c7 +folder_copy ebbd +folder_data f586 +folder_delete eb34 +folder_limited f4e4 +folder_managed f775 +folder_off eb83 +folder_open e2c8 +folder_shared e2c9 +folder_special e617 +folder_supervised f774 +folder_zip eb2c +follow_the_signs f222 +font_download e167 +font_download_off e4f9 +food_bank f1f2 +foot_bones f893 +footprint f87d +for_you e9ac +forest ea99 +fork_left eba0 +fork_right ebac +forklift f868 +format_align_center e234 +format_align_justify e235 +format_align_left e236 +format_align_right e237 +format_bold e238 +format_clear e239 +format_color_fill e23a +format_color_reset e23b +format_color_text e23c +format_h1 f85d +format_h2 f85e +format_h3 f85f +format_h4 f860 +format_h5 f861 +format_h6 f862 +format_image_left f863 +format_image_right f864 +format_indent_decrease e23d +format_indent_increase e23e +format_ink_highlighter f82b +format_italic e23f +format_letter_spacing f773 +format_letter_spacing_2 f618 +format_letter_spacing_standard f617 +format_letter_spacing_wide f616 +format_letter_spacing_wider f615 +format_line_spacing e240 +format_list_bulleted e241 +format_list_bulleted_add f849 +format_list_numbered e242 +format_list_numbered_rtl e267 +format_overline eb65 +format_paint e243 +format_paragraph f865 +format_quote e244 +format_shapes e25e +format_size e245 +format_strikethrough e246 +format_text_clip f82a +format_text_overflow f829 +format_text_wrap f828 +format_textdirection_l_to_r e247 +format_textdirection_r_to_l e248 +format_textdirection_vertical f4b8 +format_underlined e249 +format_underlined_squiggle f885 +forms_add_on f0c7 +forms_apps_script f0c8 +fort eaad +forum e8af +forward f57a +forward_10 e056 +forward_30 e057 +forward_5 e058 +forward_circle f6f5 +forward_media f6f4 +forward_to_inbox f187 +foundation f200 +frame_inspect f772 +frame_person f8a6 +frame_person_mic f4d5 +frame_person_off f7d1 +frame_reload f771 +frame_source f770 +free_breakfast eb44 +free_cancellation e748 +front_hand e769 +front_loader f869 +full_coverage eb12 +full_hd f58b +full_stacked_bar_chart f212 +fullscreen e5d0 +fullscreen_exit e5d1 +fullscreen_portrait f45a +function f866 +functions e24a +funicular f477 +g_mobiledata f010 +g_mobiledata_badge f7e1 +g_translate e927 +gallery_thumbnail f86f +gamepad e30f +games e30f +garage f011 +garage_door e714 +garage_home e82d +garden_cart f8a9 +gas_meter ec19 +gastroenterology e0f1 +gate e277 +gavel e90e +general_device e6de +generating_tokens e749 +genetics e0f3 +genres e6ee +gesture e155 +gesture_select f657 +get_app f090 +gif e908 +gif_box e7a3 +girl eb68 +gite e58b +glass_cup f6e3 +globe e64c +globe_asia f799 +globe_uk f798 +glucose e4a0 +glyphs f8a3 +go_to_line f71d +golf_course eb45 +gondola_lift f476 +google_home_devices e715 +google_plus_reshare f57a +google_tv_remote f5db +google_wifi f579 +gpp_bad f012 +gpp_good f013 +gpp_maybe f014 +gps_fixed e55c +gps_not_fixed e1b7 +gps_off e1b6 +grade e885 +gradient e3e9 +grading ea4f +grain e3ea +graphic_eq e1b8 +grass f205 +grid_3x3 f015 +grid_3x3_off f67c +grid_4x4 f016 +grid_goldenratio f017 +grid_guides f76f +grid_off e3eb +grid_on e3ec +grid_view e9b0 +grocery ef97 +group ea21 +group_add e7f0 +group_off e747 +group_remove e7ad +group_work e886 +grouped_bar_chart f211 +groups f233 +groups_2 f8df +groups_3 f8e0 +guardian f4c1 +gynecology e0f4 +h_mobiledata f018 +h_mobiledata_badge f7e0 +h_plus_mobiledata f019 +h_plus_mobiledata_badge f7df +hail e9b1 +hallway e6f8 +hand_bones f894 +hand_gesture ef9c +handheld_controller f4c6 +handshake ebcb +handwriting_recognition eb02 +handyman f10b +hangout_video e0c1 +hangout_video_off e0c2 +hard_drive f80e +hard_drive_2 f7a4 +hardware ea59 +hd e052 +hdr_auto f01a +hdr_auto_select f01b +hdr_enhanced_select ef51 +hdr_off e3ed +hdr_off_select f01c +hdr_on e3ee +hdr_on_select f01d +hdr_plus f01e +hdr_plus_off e3ef +hdr_strong e3f1 +hdr_weak e3f2 +head_mounted_device f4c5 +headphones f01f +headphones_battery f020 +headset f01f +headset_mic e311 +headset_off e33a +healing e3f3 +health_and_beauty ef9d +health_and_safety e1d5 +health_metrics f6e2 +heap_snapshot_large f76e +heap_snapshot_multiple f76d +heap_snapshot_thumbnail f76c +hearing e023 +hearing_aid f464 +hearing_disabled f104 +heart_broken eac2 +heart_check f60a +heart_minus f883 +heart_plus f884 +heat f537 +heat_pump ec18 +heat_pump_balance e27e +height ea16 +helicopter f60c +help e8fd +help_center f1c0 +help_clinic f810 +help_outline e8fd +hematology e0f6 +hevc f021 +hexagon eb39 +hide ef9e +hide_image f022 +hide_source f023 +high_density f79c +high_quality e024 +high_res f54b +highlight e25f +highlight_keyboard_focus f510 +highlight_mouse_cursor f511 +highlight_off e888 +highlight_text_cursor f512 +highlighter_size_1 f76b +highlighter_size_2 f76a +highlighter_size_3 f769 +highlighter_size_4 f768 +highlighter_size_5 f767 +hiking e50a +history e8b3 +history_edu ea3e +history_off f4da +history_toggle_off f17d +hive eaa6 +hls eb8a +hls_off eb8c +holiday_village e58a +home e9b2 +home_and_garden ef9f +home_app_logo e295 +home_filled e9b2 +home_health e4b9 +home_improvement_and_tools efa0 +home_iot_device e283 +home_max f024 +home_max_dots e849 +home_mini f025 +home_pin f14d +home_repair_service f100 +home_speaker f11c +home_storage f86c +home_work f030 +horizontal_distribute e014 +horizontal_rule f108 +horizontal_split e947 +hot_tub eb46 +hotel e549 +hotel_class e743 +hourglass ebff +hourglass_bottom ea5c +hourglass_disabled ef53 +hourglass_empty e88b +hourglass_full e88c +hourglass_top ea5b +house ea44 +house_siding f202 +house_with_shield e786 +houseboat e584 +household_supplies efa1 +hov f475 +how_to_reg e174 +how_to_vote e175 +hr_resting f6ba +html eb7e +http e902 +https e899 +hub e9f4 +humerus f895 +humerus_alt f896 +humidity_high f163 +humidity_indoor f558 +humidity_low f164 +humidity_mid f165 +humidity_percentage f87e +hvac f10e +ice_skating e50b +icecream ea69 +id_card f4ca +ifl e025 +iframe f71b +iframe_off f71c +image e3f4 +image_aspect_ratio e3f5 +image_not_supported f116 +image_search e43f +imagesearch_roller e9b4 +imagesmode efa2 +immunology e0fb +import_contacts e0e0 +import_export e8d5 +important_devices e912 +in_home_mode e833 +inactive_order e0fc +inbox e156 +inbox_customize f859 +incomplete_circle e79b +indeterminate_check_box e909 +indeterminate_question_box f56d +info e88e +info_i f59b +infrared f87c +ink_eraser e6d0 +ink_eraser_off e7e3 +ink_highlighter e6d1 +ink_highlighter_move f524 +ink_marker e6d2 +ink_pen e6d3 +inpatient e0fe +input e890 +input_circle f71a +insert_chart f0cc +insert_chart_filled f0cc +insert_chart_outlined f0cc +insert_comment e24c +insert_drive_file e66d +insert_emoticon ea22 +insert_invitation e878 +insert_link e250 +insert_page_break eaca +insert_photo e3f4 +insert_text f827 +insights f092 +install_desktop eb71 +install_mobile eb72 +instant_mix e026 +integration_instructions ef54 +interactive_space f7ff +interests e7c8 +interpreter_mode e83b +inventory e179 +inventory_2 e1a1 +invert_colors e891 +invert_colors_off e0c4 +ios e027 +ios_share e6b8 +iron e583 +iso e3f6 +jamboard_kiosk e9b5 +javascript eb7c +join f84f +join_full f84f +join_inner eaf4 +join_left eaf2 +join_right eaea +joystick f5ee +jump_to_element f719 +kayaking e50c +kebab_dining e842 +keep f026 +keep_off e6f9 +keep_pin f026 +keep_public f56f +kettle e2b9 +key e73c +key_off eb84 +key_vertical f51a +key_visualizer f199 +keyboard e312 +keyboard_alt f028 +keyboard_arrow_down e313 +keyboard_arrow_left e314 +keyboard_arrow_right e315 +keyboard_arrow_up e316 +keyboard_backspace e317 +keyboard_capslock e318 +keyboard_capslock_badge f7de +keyboard_command_key eae7 +keyboard_control_key eae6 +keyboard_double_arrow_down ead0 +keyboard_double_arrow_left eac3 +keyboard_double_arrow_right eac9 +keyboard_double_arrow_up eacf +keyboard_external_input f7dd +keyboard_full f7dc +keyboard_hide e31a +keyboard_keys f67b +keyboard_lock f492 +keyboard_lock_off f491 +keyboard_off f67a +keyboard_onscreen f7db +keyboard_option_key eae8 +keyboard_previous_language f7da +keyboard_return e31b +keyboard_tab e31c +keyboard_tab_rtl ec73 +keyboard_voice e31d +kid_star f526 +king_bed ea45 +kitchen eb47 +kitesurfing e50d +lab_panel e103 +lab_profile e104 +lab_research f80b +label e893 +label_important e948 +label_important_outline e948 +label_off e9b6 +label_outline e893 +labs e105 +lan eb2f +landscape e564 +landscape_2 f4c4 +landscape_2_off f4c3 +landslide ebd7 +language e894 +language_chinese_array f766 +language_chinese_cangjie f765 +language_chinese_dayi f764 +language_chinese_pinyin f763 +language_chinese_quick f762 +language_chinese_wubi f761 +language_french f760 +language_gb_english f75f +language_international f75e +language_japanese_kana f513 +language_korean_latin f75d +language_pinyin f75c +language_spanish f5e9 +language_us f759 +language_us_colemak f75b +language_us_dvorak f75a +laps f6b9 +laptop e31e +laptop_chromebook e31f +laptop_mac e320 +laptop_windows e321 +lasso_select eb03 +last_page e5dd +launch e89e +laundry e2a8 +layers e53b +layers_clear e53c +lda e106 +leaderboard f20c +leak_add e3f8 +leak_remove e3f9 +left_click f718 +left_panel_close f717 +left_panel_open f716 +legend_toggle f11b +lens e3fa +lens_blur f029 +letter_switch f758 +library_add e03c +library_add_check e9b7 +library_books e02f +library_music e030 +license eb04 +lift_to_talk efa3 +light f02a +light_group e28b +light_mode e518 +light_off e9b8 +lightbulb e90f +lightbulb_circle ebfe +lightbulb_outline e90f +lightning_stand efa4 +line_axis ea9a +line_curve f757 +line_end f826 +line_end_arrow f81d +line_end_arrow_notch f81c +line_end_circle f81b +line_end_diamond f81a +line_end_square f819 +line_start f825 +line_start_arrow f818 +line_start_arrow_notch f817 +line_start_circle f816 +line_start_diamond f815 +line_start_square f814 +line_style e919 +line_weight e91a +linear_scale e260 +link e250 +link_off e16f +linked_camera e438 +linked_services f535 +liquor ea60 +list e896 +list_alt e0ee +list_alt_add f756 +lists e9b9 +live_help e0c6 +live_tv e63a +living f02b +local_activity e553 +local_airport e53d +local_atm e53e +local_bar e540 +local_cafe eb44 +local_car_wash e542 +local_convenience_store e543 +local_dining e561 +local_drink e544 +local_fire_department ef55 +local_florist e545 +local_gas_station e546 +local_grocery_store e8cc +local_hospital e548 +local_hotel e549 +local_laundry_service e54a +local_library e54b +local_mall e54c +local_movies e8da +local_offer f05b +local_parking e54f +local_pharmacy e550 +local_phone f0d4 +local_pizza e552 +local_play e553 +local_police ef56 +local_post_office e554 +local_printshop e8ad +local_see e557 +local_shipping e558 +local_taxi e559 +location_automation f14f +location_away f150 +location_chip f850 +location_city e7f1 +location_disabled e1b6 +location_home f152 +location_off e0c7 +location_on f1db +location_pin f1db +location_searching e1b7 +locator_tag f8c1 +lock e899 +lock_clock ef57 +lock_open e898 +lock_open_right f656 +lock_outline e899 +lock_person f8f3 +lock_reset eade +login ea77 +logo_dev ead6 +logout e9ba +looks e3fc +looks_3 e3fb +looks_4 e3fd +looks_5 e3fe +looks_6 e3ff +looks_one e400 +looks_two e401 +loop e863 +loupe e402 +low_density f79b +low_priority e16d +lowercase f48a +loyalty e89a +lte_mobiledata f02c +lte_mobiledata_badge f7d9 +lte_plus_mobiledata f02d +lte_plus_mobiledata_badge f7d8 +luggage f235 +lunch_dining ea61 +lyrics ec0b +macro_auto f6f2 +macro_off f8d2 +magic_button f136 +magic_exchange f7f4 +magic_tether f7d7 +magnification_large f83d +magnification_small f83c +magnify_docked f7d6 +magnify_fullscreen f7d5 +mail e159 +mail_lock ec0a +mail_off f48b +mail_outline e159 +male e58e +man e4eb +man_2 f8e1 +man_3 f8e2 +man_4 f8e3 +manage_accounts f02e +manage_history ebe7 +manage_search f02f +manga f5e3 +manufacturing e726 +map e55b +maps_home_work f030 +maps_ugc ef58 +margin e9bb +mark_as_unread e9bc +mark_chat_read f18b +mark_chat_unread f189 +mark_email_read f18c +mark_email_unread f18a +mark_unread_chat_alt eb9d +markdown f552 +markdown_copy f553 +markdown_paste f554 +markunread e159 +markunread_mailbox e89b +masked_transitions e72e +masks f218 +match_case f6f1 +match_word f6f0 +matter e907 +maximize e930 +measuring_tape f6af +media_bluetooth_off f031 +media_bluetooth_on f032 +media_link f83f +media_output f4f2 +media_output_off f4f3 +mediation efa7 +medical_information ebed +medical_mask f80a +medical_services f109 +medication f033 +medication_liquid ea87 +meeting_room eb4f +memory e322 +memory_alt f7a3 +menstrual_health f6e1 +menu e5d2 +menu_book ea19 +menu_open e9bd +merge eb98 +merge_type e252 +message e0c9 +metabolism e10b +metro f474 +mfg_nest_yale_lock f11d +mic e31d +mic_double f5d1 +mic_external_off ef59 +mic_external_on ef5a +mic_none e31d +mic_off e02b +microbiology e10c +microwave f204 +microwave_gen e847 +military_tech ea3f +mimo e9be +mimo_disconnect e9bf +mindfulness f6e0 +minimize e931 +minor_crash ebf1 +mintmark efa9 +missed_video_call f0ce +missed_video_call_filled f0ce +missing_controller e701 +mist e188 +mitre f547 +mixture_med e4c8 +mms e618 +mobile_friendly e200 +mobile_off e201 +mobile_screen_share e0e7 +mobiledata_off f034 +mode f097 +mode_comment e253 +mode_cool f166 +mode_cool_off f167 +mode_dual f557 +mode_edit f097 +mode_edit_outline f097 +mode_fan f168 +mode_fan_off ec17 +mode_heat f16a +mode_heat_cool f16b +mode_heat_off f16d +mode_night f036 +mode_of_travel e7ce +mode_off_on f16f +mode_standby f037 +model_training f0cf +monetization_on e263 +money e57d +money_off f038 +money_off_csred f038 +monitor ef5b +monitor_heart eaa2 +monitor_weight f039 +monitor_weight_gain f6df +monitor_weight_loss f6de +monitoring f190 +monochrome_photos e403 +monorail f473 +mood ea22 +mood_bad e7f3 +mop e28d +more e619 +more_down f196 +more_horiz e5d3 +more_time ea5d +more_up f197 +more_vert e5d4 +mosque eab2 +motion_blur f0d0 +motion_mode f842 +motion_photos_auto f03a +motion_photos_off e9c0 +motion_photos_on e9c1 +motion_photos_pause f227 +motion_photos_paused f227 +motion_sensor_active e792 +motion_sensor_alert e784 +motion_sensor_idle e783 +motion_sensor_urgent e78e +motorcycle e91b +mountain_flag f5e2 +mouse e323 +mouse_lock f490 +mouse_lock_off f48f +move e740 +move_down eb61 +move_group f715 +move_item f1ff +move_location e741 +move_selection_down f714 +move_selection_left f713 +move_selection_right f712 +move_selection_up f711 +move_to_inbox e168 +move_up eb64 +moved_location e594 +movie e404 +movie_creation e404 +movie_edit f840 +movie_filter e43a +movie_info e02d +movie_off f499 +moving e501 +moving_beds e73d +moving_ministry e73e +mp e9c3 +multicooker e293 +multiline_chart e6df +multiple_stop f1b9 +museum ea36 +music_cast eb1a +music_note e405 +music_off e440 +music_video e063 +my_location e55c +mystery f5e1 +nat ef5c +nature e406 +nature_people e407 +navigate_before e5cb +navigate_next e5cc +navigation e55d +near_me e569 +near_me_disabled f1ef +nearby e6b7 +nearby_error f03b +nearby_off f03c +nephrology e10d +nest_audio ebbf +nest_cam_floodlight f8b7 +nest_cam_indoor f11e +nest_cam_iq f11f +nest_cam_iq_outdoor f120 +nest_cam_magnet_mount f8b8 +nest_cam_outdoor f121 +nest_cam_stand f8b9 +nest_cam_wall_mount f8ba +nest_cam_wired_stand ec16 +nest_clock_farsight_analog f8bb +nest_clock_farsight_digital f8bc +nest_connect f122 +nest_detect f123 +nest_display f124 +nest_display_max f125 +nest_doorbell_visitor f8bd +nest_eco_leaf f8be +nest_farsight_weather f8bf +nest_found_savings f8c0 +nest_gale_wifi f579 +nest_heat_link_e f126 +nest_heat_link_gen_3 f127 +nest_hello_doorbell e82c +nest_locator_tag f8c1 +nest_mini e789 +nest_multi_room f8c2 +nest_protect e68e +nest_remote f5db +nest_remote_comfort_sensor f12a +nest_secure_alarm f12b +nest_sunblock f8c3 +nest_tag f8c1 +nest_thermostat e68f +nest_thermostat_e_eu f12d +nest_thermostat_gen_3 f12e +nest_thermostat_sensor f12f +nest_thermostat_sensor_eu f130 +nest_thermostat_zirconium_eu f131 +nest_true_radiant f8c4 +nest_wake_on_approach f8c5 +nest_wake_on_press f8c6 +nest_wifi_gale f132 +nest_wifi_mistral f133 +nest_wifi_point f134 +nest_wifi_point_vento f134 +nest_wifi_pro f56b +nest_wifi_pro_2 f56a +nest_wifi_router f133 +network_cell e1b9 +network_check e640 +network_intelligence_history f5f6 +network_intelligence_update f5f5 +network_locked e61a +network_manage f7ab +network_node f56e +network_ping ebca +network_wifi e1ba +network_wifi_1_bar ebe4 +network_wifi_1_bar_locked f58f +network_wifi_2_bar ebd6 +network_wifi_2_bar_locked f58e +network_wifi_3_bar ebe1 +network_wifi_3_bar_locked f58d +network_wifi_locked f532 +neurology e10e +new_label e609 +new_releases ef76 +new_window f710 +news e032 +newsmode efad +newspaper eb81 +newsstand e9c4 +next_plan ef5d +next_week e16a +nfc e1bb +night_shelter f1f1 +night_sight_auto f1d7 +night_sight_auto_off f1f9 +night_sight_max f6c3 +nightlife ea62 +nightlight f03d +nightlight_round f03d +nights_stay ea46 +no_accounts f03e +no_adult_content f8fe +no_backpack f237 +no_crash ebf0 +no_drinks f1a5 +no_encryption f03f +no_encryption_gmailerrorred f03f +no_flash f1a6 +no_food f1a7 +no_luggage f23b +no_meals f1d6 +no_meeting_room eb4e +no_photography f1a8 +no_sim e1ce +no_sound e710 +no_stroller f1af +no_transfer f1d5 +noise_aware ebec +noise_control_off ebf3 +noise_control_on f8a8 +nordic_walking e50e +north f1e0 +north_east f1e1 +north_west f1e2 +not_accessible f0fe +not_accessible_forward f54a +not_interested f08c +not_listed_location e575 +not_started f0d1 +note e66d +note_add e89c +note_alt f040 +note_stack f562 +note_stack_add f563 +notes e26c +notification_add e399 +notification_important e004 +notification_multiple e6c2 +notifications e7f5 +notifications_active e7f7 +notifications_none e7f5 +notifications_off e7f6 +notifications_paused e7f8 +notifications_unread f4fe +numbers eac7 +nutrition e110 +ods e6e8 +odt e6e9 +offline_bolt e932 +offline_pin e90a +offline_pin_off f4d0 +offline_share e9c5 +oil_barrel ec15 +on_device_training ebfd +on_hub_device e6c3 +oncology e114 +ondemand_video e63a +online_prediction f0eb +onsen f6f8 +opacity e91c +open_in_browser e89d +open_in_full f1ce +open_in_new e89e +open_in_new_down f70f +open_in_new_off e4f6 +open_in_phone e702 +open_jam efae +open_run f4b7 +open_with e89f +ophthalmology e115 +oral_disease e116 +order_approve f812 +order_play f811 +orders eb14 +orthopedics f897 +other_admission e47b +other_houses e58c +outbound e1ca +outbox ef5f +outbox_alt eb17 +outdoor_garden e205 +outdoor_grill ea47 +outgoing_mail f0d2 +outlet f1d4 +outlined_flag f0c6 +outpatient e118 +outpatient_med e119 +output ebbe +output_circle f70e +oven e9c7 +oven_gen e843 +overview e4a7 +overview_key f7d4 +oxygen_saturation e4de +p2p f52a +pace f6b8 +pacemaker e656 +package e48f +package_2 f569 +padding e9c8 +page_control e731 +page_info f614 +pageless f509 +pages e7f9 +pageview e8a0 +paid f041 +palette e40a +pallet f86a +pan_tool e925 +pan_tool_alt ebb9 +pan_zoom f655 +panorama e40b +panorama_fish_eye e40c +panorama_horizontal e40d +panorama_photosphere e9c9 +panorama_vertical e40e +panorama_wide_angle e40f +paragliding e50f +park ea63 +partly_cloudy_day f172 +partly_cloudy_night f174 +partner_exchange f7f9 +partner_reports efaf +party_mode e7fa +passkey f87f +password f042 +password_2 f4a9 +password_2_off f4a8 +patient_list e653 +pattern f043 +pause e034 +pause_circle e1a2 +pause_circle_filled e1a2 +pause_circle_outline e1a2 +pause_presentation e0ea +payment e8a1 +payments ef63 +pedal_bike eb29 +pediatrics e11d +pen_size_1 f755 +pen_size_2 f754 +pen_size_3 f753 +pen_size_4 f752 +pen_size_5 f751 +pending ef64 +pending_actions f1bb +pentagon eb50 +people ea21 +people_alt ea21 +people_outline ea21 +percent eb58 +performance_max e51a +pergola e203 +perm_camera_mic e8a2 +perm_contact_calendar e8a3 +perm_data_setting e8a4 +perm_device_information e8a5 +perm_identity f0d3 +perm_media e8a7 +perm_phone_msg e8a8 +perm_scan_wifi e8a9 +person f0d3 +person_2 f8e4 +person_3 f8e5 +person_4 f8e6 +person_add ea4d +person_add_alt ea4d +person_add_disabled e9cb +person_alert f567 +person_apron f5a3 +person_book f5e8 +person_cancel f566 +person_celebrate f7fe +person_check f565 +person_edit f4fa +person_filled f0d3 +person_off e510 +person_outline f0d3 +person_pin e55a +person_pin_circle e56a +person_play f7fd +person_raised_hand f59a +person_remove ef66 +person_search f106 +personal_bag eb0e +personal_bag_off eb0f +personal_bag_question eb10 +personal_injury e6da +personal_places e703 +personal_video e63b +pest_control f0fa +pest_control_rodent f0fd +pet_supplies efb1 +pets e91d +phishing ead7 +phone f0d4 +phone_alt f0d4 +phone_android e324 +phone_bluetooth_speaker e61b +phone_callback e649 +phone_disabled e9cc +phone_enabled e9cd +phone_forwarded e61c +phone_in_talk e61d +phone_iphone e325 +phone_locked e61e +phone_missed e61f +phone_paused e620 +phonelink e326 +phonelink_erase e0db +phonelink_lock e0dc +phonelink_off e327 +phonelink_ring e0dd +phonelink_ring_off f7aa +phonelink_setup ef41 +photo e432 +photo_album e411 +photo_auto_merge f530 +photo_camera e412 +photo_camera_back ef68 +photo_camera_front ef69 +photo_filter e43b +photo_frame f0d9 +photo_library e413 +photo_prints efb2 +photo_size_select_actual e432 +photo_size_select_large e433 +photo_size_select_small e434 +php eb8f +physical_therapy e11e +piano e521 +piano_off e520 +picture_as_pdf e415 +picture_in_picture e8aa +picture_in_picture_alt e911 +picture_in_picture_center f550 +picture_in_picture_large f54f +picture_in_picture_medium f54e +picture_in_picture_mobile f517 +picture_in_picture_off f52f +picture_in_picture_small f54d +pie_chart f0da +pie_chart_filled f0da +pie_chart_outline f0da +pie_chart_outlined f0da +pill e11f +pill_off f809 +pin f045 +pin_drop e55e +pin_end e767 +pin_invoke e763 +pinch eb38 +pinch_zoom_in f1fa +pinch_zoom_out f1fb +pip f64d +pip_exit f70d +pivot_table_chart e9ce +place f1db +place_item f1f0 +plagiarism ea5a +planner_banner_ad_pt e692 +planner_review e694 +play_arrow e037 +play_circle e1c4 +play_disabled ef6a +play_for_work e906 +play_lesson f047 +play_music e6ee +play_pause f137 +play_shapes f7fc +playing_cards f5dc +playlist_add e03b +playlist_add_check e065 +playlist_add_check_circle e7e6 +playlist_add_circle e7e5 +playlist_play e05f +playlist_remove eb80 +plumbing f107 +plus_one e800 +podcasts f048 +podiatry e120 +podium f7fb +point_of_sale f17e +point_scan f70c +poker_chip f49b +policy ea17 +poll f0cc +polyline ebbb +polymer e8ab +pool eb48 +portable_wifi_off f087 +portrait e851 +position_bottom_left f70b +position_bottom_right f70a +position_top_right f709 +post e705 +post_add ea20 +potted_plant f8aa +power e63c +power_input e336 +power_off e646 +power_rounded f8c7 +power_settings_new f8c7 +prayer_times f838 +precision_manufacturing f049 +pregnancy f5f1 +pregnant_woman f5f1 +preliminary e7d8 +prescriptions e121 +present_to_all e0df +preview f1c5 +preview_off f7af +price_change f04a +price_check f04b +print e8ad +print_add f7a2 +print_connect f7a1 +print_disabled e9cf +print_error f7a0 +print_lock f651 +priority e19f +priority_high e645 +privacy f148 +privacy_tip f0dc +private_connectivity e744 +problem e122 +procedure e651 +process_chart f855 +production_quantity_limits e1d1 +productivity e296 +progress_activity e9d0 +prompt_suggestion f4f6 +propane ec14 +propane_tank ec13 +psychiatry e123 +psychology ea4a +psychology_alt f8ea +public e80b +public_off f1ca +publish e255 +published_with_changes f232 +pulmonology e124 +pulse_alert f501 +punch_clock eaa8 +push_pin f10d +qr_code ef6b +qr_code_2 e00a +qr_code_2_add f658 +qr_code_scanner f206 +query_builder efd6 +query_stats e4fc +question_answer e8af +question_exchange f7f3 +question_mark eb8b +queue e03c +queue_music e03d +queue_play_next e066 +quick_phrases e7d1 +quick_reference e46e +quick_reference_all f801 +quick_reorder eb15 +quickreply ef6c +quiet_time e1f9 +quiet_time_active e291 +quiz f04c +r_mobiledata f04d +radar f04e +radio e03e +radio_button_checked e837 +radio_button_partial f560 +radio_button_unchecked e836 +radiology e125 +railway_alert e9d1 +railway_alert_2 f461 +rainy f176 +rainy_heavy f61f +rainy_light f61e +rainy_snow f61d +ramen_dining ea64 +ramp_left eb9c +ramp_right eb96 +range_hood e1ea +rate_review e560 +raven f555 +raw_off f04f +raw_on f050 +read_more ef6d +readiness_score f6dd +real_estate_agent e73a +rear_camera f6c2 +rebase f845 +rebase_edit f846 +receipt e8b0 +receipt_long ef6e +recent_actors e03f +recent_patient f808 +recenter f4c0 +recommend e9d2 +record_voice_over e91f +rectangle eb54 +recycling e760 +redeem e8f6 +redo e15a +reduce_capacity f21c +refresh e5d5 +regular_expression f750 +relax f6dc +release_alert f654 +remember_me f051 +reminder e6c6 +reminders_alt e6c6 +remote_gen e83e +remove e15b +remove_circle f08f +remove_circle_outline f08f +remove_done e9d3 +remove_from_queue e067 +remove_moderator e9d4 +remove_red_eye e8f4 +remove_road ebfc +remove_selection e9d5 +remove_shopping_cart e928 +reopen_window f708 +reorder e8fe +repartition f8e8 +repeat e040 +repeat_on e9d6 +repeat_one e041 +repeat_one_on e9d7 +replay e042 +replay_10 e059 +replay_30 e05a +replay_5 e05b +replay_circle_filled e9d8 +reply e15e +reply_all e15f +report f052 +report_gmailerrorred f052 +report_off e170 +report_problem f083 +request_page f22c +request_quote f1b6 +reset_brightness f482 +reset_focus f481 +reset_image f824 +reset_iso f480 +reset_settings f47f +reset_shadow f47e +reset_shutter_speed f47d +reset_tv e9d9 +reset_white_balance f47c +reset_wrench f56c +resize f707 +respiratory_rate e127 +responsive_layout e9da +restart_alt f053 +restaurant e56c +restaurant_menu e561 +restore e8b3 +restore_from_trash e938 +restore_page e929 +resume f7d0 +reviews f07c +rewarded_ads efb6 +rheumatology e128 +rib_cage f898 +rice_bowl f1f5 +right_click f706 +right_panel_close f705 +right_panel_open f704 +ring_volume f0dd +ring_volume_filled f0dd +ripples e9db +road f472 +robot f882 +robot_2 f5d0 +rocket eba5 +rocket_launch eb9b +roller_shades ec12 +roller_shades_closed ec11 +roller_skating ebcd +roofing f201 +room f1db +room_preferences f1b8 +room_service eb49 +rotate_90_degrees_ccw e418 +rotate_90_degrees_cw eaab +rotate_left e419 +rotate_right e41a +roundabout_left eb99 +roundabout_right eba3 +rounded_corner e920 +route eacd +router e328 +routine e20c +rowing e921 +rss_feed e0e5 +rsvp f055 +rtt e9ad +rubric eb27 +rule f1c2 +rule_folder f1c9 +rule_settings f64c +run_circle ef6f +running_with_errors e51d +rv_hookup e642 +safety_check ebef +safety_check_off f59d +safety_divider e1cc +sailing e502 +salinity f876 +sanitizer f21d +satellite e562 +satellite_alt eb3a +sauna f6f7 +save e161 +save_alt f090 +save_as eb60 +saved_search ea11 +savings e2eb +scale eb5f +scan f74e +scan_delete f74f +scanner e329 +scatter_plot e268 +scene e2a7 +schedule efd6 +schedule_send ea0a +schema e4fd +school e80c +science ea4b +science_off f542 +scooter f471 +score e269 +scoreboard ebd0 +screen_lock_landscape e1be +screen_lock_portrait e1bf +screen_lock_rotation e1c0 +screen_record f679 +screen_rotation e1c1 +screen_rotation_alt ebee +screen_rotation_up f678 +screen_search_desktop ef70 +screen_share e0e2 +screenshot f056 +screenshot_frame f677 +screenshot_keyboard f7d3 +screenshot_monitor ec08 +screenshot_region f7d2 +screenshot_tablet f697 +script f45f +scrollable_header e9dc +scuba_diving ebce +sd e9dd +sd_card e623 +sd_card_alert f057 +sd_storage e623 +sdk e720 +search e8b6 +search_check f800 +search_check_2 f469 +search_hands_free e696 +search_insights f4bc +search_off ea76 +security e32a +security_key f503 +security_update f072 +security_update_good f073 +security_update_warning f074 +segment e94b +select f74d +select_all e162 +select_check_box f1fe +select_to_speak f7cf +select_window e6fa +select_window_2 f4c8 +select_window_off e506 +self_care f86d +self_improvement ea78 +sell f05b +send e163 +send_and_archive ea0c +send_money e8b7 +send_time_extension eadb +send_to_mobile f05c +sensor_door f1b5 +sensor_occupied ec10 +sensor_window f1b4 +sensors e51e +sensors_krx f556 +sensors_krx_off f515 +sensors_off e51f +sentiment_calm f6a7 +sentiment_content f6a6 +sentiment_dissatisfied e811 +sentiment_excited f6a5 +sentiment_extremely_dissatisfied f194 +sentiment_frustrated f6a4 +sentiment_neutral e812 +sentiment_sad f6a3 +sentiment_satisfied e813 +sentiment_satisfied_alt e813 +sentiment_stressed f6a2 +sentiment_very_dissatisfied e814 +sentiment_very_satisfied e815 +sentiment_worried f6a1 +serif f4ac +service_toolbox e717 +set_meal f1ea +settings e8b8 +settings_accessibility f05d +settings_account_box f835 +settings_alert f143 +settings_applications e8b9 +settings_b_roll f625 +settings_backup_restore e8ba +settings_bluetooth e8bb +settings_brightness e8bd +settings_cell e8bc +settings_cinematic_blur f624 +settings_ethernet e8be +settings_heart f522 +settings_input_antenna e8bf +settings_input_component e8c1 +settings_input_composite e8c1 +settings_input_hdmi e8c2 +settings_input_svideo e8c3 +settings_motion_mode f833 +settings_night_sight f832 +settings_overscan e8c4 +settings_panorama f831 +settings_phone e8c5 +settings_photo_camera f834 +settings_power e8c6 +settings_remote e8c7 +settings_slow_motion f623 +settings_suggest f05e +settings_system_daydream e1c3 +settings_timelapse f622 +settings_video_camera f621 +settings_voice e8c8 +settop_component e2ac +severe_cold ebd3 +shadow e9df +shadow_add f584 +shadow_minus f583 +shape_line f8d3 +shape_recognition eb01 +shapes e602 +share e80d +share_location f05f +share_off f6cb +share_reviews f8a4 +share_windows f613 +sheets_rtl f823 +shelf_auto_hide f703 +shelf_position f702 +shelves f86e +shield e9e0 +shield_lock f686 +shield_locked f592 +shield_moon eaa9 +shield_person f650 +shield_question f529 +shield_with_heart e78f +shield_with_house e78d +shift e5f2 +shift_lock f7ae +shift_lock_off f483 +shop e8c9 +shop_2 e8ca +shop_two e8ca +shopping_bag f1cc +shopping_basket e8cb +shopping_cart e8cc +shopping_cart_checkout eb88 +shopping_cart_off f4f7 +shoppingmode efb7 +short_stay e4d0 +short_text e261 +shortcut f57a +show_chart e6e1 +shower f061 +shuffle e043 +shuffle_on e9e1 +shutter_speed e43d +shutter_speed_add f57e +shutter_speed_minus f57d +sick f220 +side_navigation e9e2 +sign_language ebe5 +signal_cellular_0_bar f0a8 +signal_cellular_1_bar f0a9 +signal_cellular_2_bar f0aa +signal_cellular_3_bar f0ab +signal_cellular_4_bar e1c8 +signal_cellular_add f7a9 +signal_cellular_alt e202 +signal_cellular_alt_1_bar ebdf +signal_cellular_alt_2_bar ebe3 +signal_cellular_connected_no_internet_0_bar f0ac +signal_cellular_connected_no_internet_4_bar e1cd +signal_cellular_no_sim e1ce +signal_cellular_nodata f062 +signal_cellular_null e1cf +signal_cellular_off e1d0 +signal_cellular_pause f5a7 +signal_disconnected f239 +signal_wifi_0_bar f0b0 +signal_wifi_4_bar f065 +signal_wifi_4_bar_lock e1e1 +signal_wifi_bad f064 +signal_wifi_connected_no_internet_4 f064 +signal_wifi_off e1da +signal_wifi_statusbar_4_bar f065 +signal_wifi_statusbar_not_connected f0ef +signal_wifi_statusbar_null f067 +signature f74c +signpost eb91 +sim_card e32b +sim_card_alert f057 +sim_card_download f068 +single_bed ea48 +sip f069 +skateboarding e511 +skeleton f899 +skillet f543 +skillet_cooktop f544 +skip_next e044 +skip_previous e045 +skull f89a +slab_serif f4ab +sledding e512 +sleep e213 +sleep_score f6b7 +slide_library f822 +sliders e9e3 +slideshow e41b +slow_motion_video e068 +smart_button f1c1 +smart_card_reader f4a5 +smart_card_reader_off f4a6 +smart_display f06a +smart_outlet e844 +smart_screen f06b +smart_toy f06c +smartphone e32c +smb_share f74b +smoke_free eb4a +smoking_rooms eb4b +sms e625 +sms_failed e87f +snippet_folder f1c7 +snooze e046 +snowboarding e513 +snowing e80f +snowing_heavy f61c +snowmobile e503 +snowshoeing e514 +soap f1b2 +social_distance e1cb +social_leaderboard f6a0 +solar_power ec0f +sort e164 +sort_by_alpha e053 +sos ebf7 +sound_detection_dog_barking f149 +sound_detection_glass_break f14a +sound_detection_loud_sound f14b +sound_sampler f6b4 +soup_kitchen e7d3 +source f1c8 +source_environment e527 +source_notes e12d +south f1e3 +south_america e7e4 +south_east f1e4 +south_west f1e5 +spa eb4c +space_bar e256 +space_dashboard e66b +spatial_audio ebeb +spatial_audio_off ebe8 +spatial_speaker f4cf +spatial_tracking ebea +speaker e32d +speaker_group e32e +speaker_notes e8cd +speaker_notes_off e92a +speaker_phone e0d2 +special_character f74a +specific_gravity f872 +speech_to_text f8a7 +speed e9e4 +speed_0_25 f4d4 +speed_0_2x f498 +speed_0_5 f4e2 +speed_0_5x f497 +speed_0_75 f4d3 +speed_0_7x f496 +speed_1_2 f4e1 +speed_1_25 f4d2 +speed_1_2x f495 +speed_1_5 f4e0 +speed_1_5x f494 +speed_1_75 f4d1 +speed_1_7x f493 +speed_2x f4eb +speed_camera f470 +spellcheck e8ce +splitscreen f06d +splitscreen_add f4fd +splitscreen_bottom f676 +splitscreen_landscape f459 +splitscreen_left f675 +splitscreen_portrait f458 +splitscreen_right f674 +splitscreen_top f673 +splitscreen_vertical_add f4fc +spo2 f6db +spoke e9a7 +sports ea30 +sports_and_outdoors efb8 +sports_bar f1f3 +sports_baseball ea51 +sports_basketball ea26 +sports_cricket ea27 +sports_esports ea28 +sports_football ea29 +sports_golf ea2a +sports_gymnastics ebc4 +sports_handball ea33 +sports_hockey ea2b +sports_kabaddi ea34 +sports_martial_arts eae9 +sports_mma ea2c +sports_motorsports ea2d +sports_rugby ea2e +sports_score f06e +sports_soccer ea2f +sports_tennis ea32 +sports_volleyball ea31 +sprinkler e29a +sprint f81f +square eb36 +square_foot ea49 +ssid_chart eb66 +stack f609 +stack_off f608 +stack_star f607 +stacked_bar_chart e9e6 +stacked_email e6c7 +stacked_inbox e6c9 +stacked_line_chart f22b +stacks f500 +stadia_controller f135 +stadium eb90 +stairs f1a9 +stairs_2 f46c +star f09a +star_border f09a +star_border_purple500 f09a +star_half e839 +star_outline f09a +star_purple500 f09a +star_rate f0ec +star_rate_half ec45 +stars e8d0 +start e089 +stat_0 e697 +stat_1 e698 +stat_2 e699 +stat_3 e69a +stat_minus_1 e69b +stat_minus_2 e69c +stat_minus_3 e69d +stay_current_landscape e0d3 +stay_current_portrait e0d4 +stay_primary_landscape e0d5 +stay_primary_portrait e0d6 +step f6fe +step_into f701 +step_out f700 +step_over f6ff +steppers e9e7 +steps f6da +stethoscope f805 +stethoscope_arrow f807 +stethoscope_check f806 +sticky_note e9e8 +sticky_note_2 f1fc +stock_media f570 +stockpot f545 +stop e047 +stop_circle ef71 +stop_screen_share e0e3 +storage e1db +store e8d1 +store_mall_directory e8d1 +storefront ea12 +storm f070 +straight eb95 +straighten e41c +strategy f5df +stream e9e9 +stream_apps f79f +streetview e56e +stress_management f6d9 +strikethrough_s e257 +stroke_full f749 +stroke_partial f748 +stroller f1ae +style e41d +styler e273 +stylus f604 +stylus_laser_pointer f747 +stylus_note f603 +subdirectory_arrow_left e5d9 +subdirectory_arrow_right e5da +subheader e9ea +subject e8d2 +subscript f111 +subscriptions e064 +subtitles e048 +subtitles_off ef72 +subway e56f +summarize f071 +sunny e81a +sunny_snowing e819 +superscript f112 +supervised_user_circle e939 +supervised_user_circle_off f60e +supervisor_account e8d3 +support ef73 +support_agent f0e2 +surfing e515 +surgical e131 +surround_sound e049 +swap_calls e0d7 +swap_driving_apps e69e +swap_driving_apps_wheel e69f +swap_horiz e8d4 +swap_horizontal_circle e933 +swap_vert e8d5 +swap_vertical_circle e8d6 +sweep e6ac +swipe e9ec +swipe_down eb53 +swipe_down_alt eb30 +swipe_left eb59 +swipe_left_alt eb33 +swipe_right eb52 +swipe_right_alt eb56 +swipe_up eb2e +swipe_up_alt eb35 +swipe_vertical eb51 +switch e1f4 +switch_access f6fd +switch_access_2 f506 +switch_access_shortcut e7e1 +switch_access_shortcut_add e7e2 +switch_account e9ed +switch_camera e41e +switch_left f1d1 +switch_right f1d2 +switch_video e41f +switches e733 +sword_rose f5de +swords f889 +symptoms e132 +synagogue eab0 +sync e627 +sync_alt ea18 +sync_disabled e628 +sync_lock eaee +sync_problem e629 +sync_saved_locally f820 +syringe e133 +system_security_update f072 +system_security_update_good f073 +system_security_update_warning f074 +system_update f072 +system_update_alt e8d7 +tab e8d8 +tab_close f745 +tab_close_right f746 +tab_duplicate f744 +tab_group f743 +tab_move f742 +tab_new_right f741 +tab_recent f740 +tab_unselected e8d9 +table f191 +table_bar ead2 +table_chart e265 +table_chart_view f6ef +table_eye f466 +table_lamp e1f2 +table_restaurant eac6 +table_rows f101 +table_rows_narrow f73f +table_view f1be +tablet e32f +tablet_android e330 +tablet_mac e331 +tabs e9ee +tactic f564 +tag e9ef +tag_faces ea22 +takeout_dining ea74 +tamper_detection_off e82e +tamper_detection_on f8c8 +tap_and_play e62b +tapas f1e9 +target e719 +task f075 +task_alt e2e6 +taunt f69f +taxi_alert ef74 +team_dashboard e013 +temp_preferences_custom f8c9 +temp_preferences_eco f8ca +temple_buddhist eab3 +temple_hindu eaaf +tenancy f0e3 +terminal eb8e +terrain e564 +text_ad e728 +text_decrease eadd +text_fields e262 +text_fields_alt e9f1 +text_format e165 +text_increase eae2 +text_rotate_up e93a +text_rotate_vertical e93b +text_rotation_angledown e93c +text_rotation_angleup e93d +text_rotation_down e93e +text_rotation_none e93f +text_select_end f73e +text_select_jump_to_beginning f73d +text_select_jump_to_end f73c +text_select_move_back_character f73b +text_select_move_back_word f73a +text_select_move_down f739 +text_select_move_forward_character f738 +text_select_move_forward_word f737 +text_select_move_up f736 +text_select_start f735 +text_snippet f1c6 +text_to_speech f1bc +text_up f49e +textsms e625 +texture e421 +texture_add f57c +texture_minus f57b +theater_comedy ea66 +theaters e8da +thermometer e846 +thermometer_add f582 +thermometer_gain f6d8 +thermometer_loss f6d7 +thermometer_minus f581 +thermostat f076 +thermostat_auto f077 +thermostat_carbon f178 +things_to_do eb2a +thread_unread f4f9 +thumb_down f578 +thumb_down_alt f578 +thumb_down_filled f578 +thumb_down_off f578 +thumb_down_off_alt f578 +thumb_up f577 +thumb_up_alt f577 +thumb_up_filled f577 +thumb_up_off f577 +thumb_up_off_alt f577 +thumbnail_bar f734 +thumbs_up_down e8dd +thunderstorm ebdb +tibia f89b +tibia_alt f89c +time_auto f0e4 +time_to_leave eff7 +timelapse e422 +timeline e922 +timer e425 +timer_10 e423 +timer_10_alt_1 efbf +timer_10_select f07a +timer_3 e424 +timer_3_alt_1 efc0 +timer_3_select f07b +timer_5 f4b1 +timer_5_shutter f4b2 +timer_off e426 +timer_pause f4bb +timer_play f4ba +tips_and_updates e79a +tire_repair ebc8 +title e264 +titlecase f489 +toast efc1 +toc e8de +today e8df +toggle_off e9f5 +toggle_on e9f6 +token ea25 +toll e8e0 +tonality e427 +toolbar e9f7 +tools_flat_head f8cb +tools_installation_kit e2ab +tools_ladder e2cb +tools_level e77b +tools_phillips f8cc +tools_pliers_wire_stripper e2aa +tools_power_drill e1e9 +tools_wrench f8cd +tooltip e9f8 +top_panel_close f733 +top_panel_open f732 +topic f1c8 +tornado e199 +total_dissolved_solids f877 +touch_app e913 +touchpad_mouse f687 +touchpad_mouse_off f4e6 +tour ef75 +toys e332 +toys_and_games efc2 +toys_fan f887 +track_changes e8e1 +trackpad_input f4c7 +traffic e565 +traffic_jam f46f +trail_length eb5e +trail_length_medium eb63 +trail_length_short eb6d +train e570 +tram e571 +transcribe f8ec +transfer_within_a_station e572 +transform e428 +transgender e58d +transit_enterexit e579 +transition_chop f50e +transition_dissolve f50d +transition_fade f50c +transition_push f50b +transition_slide f50a +translate e8e2 +transportation e21d +travel ef93 +travel_explore e2db +travel_luggage_and_bags efc3 +trending_down e8e3 +trending_flat e8e4 +trending_up e8e5 +trip e6fb +trip_origin e57b +trolley f86b +trolley_cable_car f46e +trophy ea23 +troubleshoot e1d2 +try f07c +tsunami ebd8 +tsv e6d6 +tty f1aa +tune e429 +tungsten f07d +turn_left eba6 +turn_right ebab +turn_sharp_left eba7 +turn_sharp_right ebaa +turn_slight_left eba4 +turn_slight_right eb9a +turned_in e8e7 +turned_in_not e8e7 +tv e63b +tv_gen e830 +tv_guide e1dc +tv_off e647 +tv_options_edit_channels e1dd +tv_options_input_settings e1de +tv_remote f5d9 +tv_signin e71b +tv_with_assistant e785 +two_pager f51f +two_wheeler e9f9 +type_specimen f8f0 +u_turn_left eba1 +u_turn_right eba2 +ulna_radius f89d +ulna_radius_alt f89e +umbrella f1ad +unarchive e169 +undo e166 +unfold_less e5d6 +unfold_less_double f8cf +unfold_more e5d7 +unfold_more_double f8d0 +ungroup f731 +universal_currency e9fa +universal_currency_alt e734 +universal_local e9fb +unknown_2 f49f +unknown_5 e6a5 +unknown_7 f49e +unknown_document f804 +unknown_med eabd +unlicense eb05 +unpaved_road f46d +unpin e6f9 +unpublished f236 +unsubscribe e0eb +upcoming f07e +update e923 +update_disabled e075 +upgrade f0fb +upload f09b +upload_2 f521 +upload_file e9fc +uppercase f488 +urology e137 +usb e1e0 +usb_off e4fa +user_attributes e708 +vaccines e138 +vacuum efc5 +valve e224 +vape_free ebc6 +vaping_rooms ebcf +variable_add f51e +variable_insert f51d +variable_remove f51c +variables f851 +ventilator e139 +verified ef76 +verified_user f013 +vertical_align_bottom e258 +vertical_align_center e259 +vertical_align_top e25a +vertical_distribute e076 +vertical_shades ec0e +vertical_shades_closed ec0d +vertical_split e949 +vibration e62d +video_call e070 +video_camera_back f07f +video_camera_front f080 +video_camera_front_off f83b +video_chat f8a0 +video_file eb87 +video_label e071 +video_library e04a +video_search efc6 +video_settings ea75 +video_stable f081 +videocam e04b +videocam_off e04c +videogame_asset e338 +videogame_asset_off e500 +view_agenda e8e9 +view_array e8ea +view_carousel e8eb +view_column e8ec +view_column_2 f847 +view_comfy e42a +view_comfy_alt eb73 +view_compact e42b +view_compact_alt eb74 +view_cozy eb75 +view_day e8ed +view_headline e8ee +view_in_ar efc9 +view_in_ar_new efc9 +view_in_ar_off f61b +view_kanban eb7f +view_list e8ef +view_module e8f0 +view_quilt e8f1 +view_real_size f4c2 +view_sidebar f114 +view_stream e8f2 +view_timeline eb85 +view_week e8f3 +vignette e435 +villa e586 +visibility e8f4 +visibility_lock f653 +visibility_off e8f5 +vital_signs e650 +vitals e13b +vo2_max f4aa +voice_chat e62e +voice_over_off e94a +voice_selection f58a +voicemail e0d9 +volcano ebda +volume_down e04d +volume_down_alt e79c +volume_mute e04e +volume_off e04f +volume_up e050 +volunteer_activism ea70 +voting_chip f852 +vpn_key e0da +vpn_key_alert f6cc +vpn_key_off eb7a +vpn_lock e62f +vr180_create2d efca +vr180_create2d_off f571 +vrpano f082 +wall_art efcb +wall_lamp e2b4 +wallet f8ff +wallpaper e1bc +wallpaper_slideshow f672 +ward e13c +warehouse ebb8 +warning f083 +warning_amber f083 +warning_off f7ad +wash f1b1 +watch e334 +watch_button_press f6aa +watch_check f468 +watch_later efd6 +watch_off eae3 +watch_screentime f6ae +watch_vibration f467 +watch_wake f6a9 +water f084 +water_bottle f69d +water_bottle_large f69e +water_damage f203 +water_do f870 +water_drop e798 +water_ec f875 +water_full f6d6 +water_heater e284 +water_lock f6ad +water_loss f6d5 +water_lux f874 +water_medium f6d4 +water_orp f878 +water_ph f87a +water_pump f5d8 +water_voc f87b +waterfall_chart ea00 +waves e176 +waving_hand e766 +wb_auto e42c +wb_cloudy f15c +wb_incandescent e42e +wb_iridescent f07d +wb_shade ea01 +wb_sunny e430 +wb_twilight e1c6 +wc e63d +weather_hail f67f +weather_mix f60b +weather_snowy e2cd +web e051 +web_asset e069 +web_asset_off ef47 +web_stories e595 +web_traffic ea03 +webhook eb92 +weekend e16b +weight e13d +west f1e6 +whatshot e80e +wheelchair_pickup f1ab +where_to_vote e177 +widgets e1bd +width f730 +width_full f8f5 +width_normal f8f6 +width_wide f8f7 +wifi e63e +wifi_1_bar e4ca +wifi_2_bar e4d9 +wifi_add f7a8 +wifi_calling ef77 +wifi_calling_1 f0e7 +wifi_calling_2 f0f6 +wifi_calling_3 f0e7 +wifi_channel eb6a +wifi_find eb31 +wifi_home f671 +wifi_lock e1e1 +wifi_notification f670 +wifi_off e648 +wifi_password eb6b +wifi_protected_setup f0fc +wifi_proxy f7a7 +wifi_tethering e1e2 +wifi_tethering_error ead9 +wifi_tethering_off f087 +wind_power ec0c +window f088 +window_closed e77e +window_open e78c +window_sensor e2bb +wine_bar f1e8 +woman e13e +woman_2 f8e7 +work e943 +work_alert f5f7 +work_history ec09 +work_off e942 +work_outline e943 +work_update f5f8 +workflow ea04 +workspace_premium e7af +workspaces ea0f +workspaces_outline ea0f +wounds_injuries e13f +wrap_text e25b +wrist f69c +wrong_location ef78 +wysiwyg f1c3 +yard f089 +your_trips eb2b +youtube_activity f85a +youtube_searched_for e8fa +zone_person_alert e781 +zone_person_idle e77a +zone_person_urgent e788 +zoom_in e8ff +zoom_in_map eb2d +zoom_out e900 +zoom_out_map e56b diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.json b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.json new file mode 100644 index 0000000000..2be9d15d69 --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.json @@ -0,0 +1,3601 @@ +{ + "10k": 59729, + "10mp": 59730, + "11mp": 59731, + "123": 60301, + "12mp": 59732, + "13mp": 59733, + "14mp": 59734, + "15mp": 59735, + "16mp": 59736, + "17mp": 59737, + "18_up_rating": 63741, + "18mp": 59738, + "19mp": 59739, + "1k": 59740, + "1k_plus": 59741, + "1x_mobiledata": 61389, + "1x_mobiledata_badge": 63473, + "20mp": 59742, + "21mp": 59743, + "22mp": 59744, + "23mp": 59745, + "24mp": 59746, + "2d": 61239, + "2k": 59747, + "2k_plus": 59748, + "2mp": 59749, + "30fps": 61390, + "30fps_select": 61391, + "360": 58743, + "3d_rotation": 59469, + "3g_mobiledata": 61392, + "3g_mobiledata_badge": 63472, + "3k": 59750, + "3k_plus": 59751, + "3mp": 59752, + "3p": 61393, + "4g_mobiledata": 61394, + "4g_mobiledata_badge": 63471, + "4g_plus_mobiledata": 61395, + "4k": 57458, + "4k_plus": 59753, + "4mp": 59754, + "50mp": 63219, + "5g": 61240, + "5g_mobiledata_badge": 63470, + "5k": 59755, + "5k_plus": 59756, + "5mp": 59757, + "60fps": 61396, + "60fps_select": 61397, + "6_ft_apart": 61982, + "6k": 59758, + "6k_plus": 59759, + "6mp": 59760, + "7k": 59761, + "7k_plus": 59762, + "7mp": 59763, + "8k": 59764, + "8k_plus": 59765, + "8mp": 59766, + "9k": 59767, + "9k_plus": 59768, + "9mp": 59769, + "abc": 60308, + "ac_unit": 60219, + "access_alarm": 59477, + "access_alarms": 59477, + "access_time": 61398, + "access_time_filled": 61398, + "accessibility": 59470, + "accessibility_new": 59692, + "accessible": 59668, + "accessible_forward": 59700, + "account_balance": 59471, + "account_balance_wallet": 59472, + "account_box": 59473, + "account_child": 59474, + "account_child_invert": 58969, + "account_circle": 61963, + "account_circle_filled": 61963, + "account_circle_off": 63411, + "account_tree": 59770, + "action_key": 62722, + "activity_zone": 57830, + "acute": 58571, + "ad": 58970, + "ad_group": 58971, + "ad_group_off": 60133, + "ad_off": 63410, + "ad_units": 61241, + "adaptive_audio_mic": 62668, + "adaptive_audio_mic_off": 62667, + "adb": 58894, + "add": 57669, + "add_a_photo": 58425, + "add_ad": 59178, + "add_alarm": 59478, + "add_alert": 57347, + "add_box": 57670, + "add_business": 59177, + "add_call": 61623, + "add_card": 60294, + "add_chart": 61244, + "add_circle": 58298, + "add_circle_outline": 58298, + "add_comment": 57958, + "add_diamond": 62620, + "add_home": 63723, + "add_home_work": 63725, + "add_ic_call": 61623, + "add_link": 57720, + "add_location": 58727, + "add_location_alt": 61242, + "add_moderator": 59773, + "add_notes": 57489, + "add_photo_alternate": 58430, + "add_reaction": 57811, + "add_road": 61243, + "add_shopping_cart": 59476, + "add_task": 62010, + "add_to_drive": 58972, + "add_to_home_screen": 57854, + "add_to_photos": 58269, + "add_to_queue": 57436, + "add_triangle": 62606, + "addchart": 61244, + "adf_scanner": 60122, + "adjust": 58270, + "admin_meds": 58509, + "admin_panel_settings": 61245, + "ads_click": 59234, + "agender": 63624, + "agriculture": 60025, + "air": 61400, + "air_freshener": 58058, + "air_purifier": 59774, + "air_purifier_gen": 59433, + "airline_seat_flat": 58928, + "airline_seat_flat_angled": 58929, + "airline_seat_individual_suite": 58930, + "airline_seat_legroom_extra": 58931, + "airline_seat_legroom_normal": 58932, + "airline_seat_legroom_reduced": 58933, + "airline_seat_recline_extra": 58934, + "airline_seat_recline_normal": 58935, + "airline_stops": 59344, + "airlines": 59338, + "airplane_ticket": 61401, + "airplanemode_active": 58685, + "airplanemode_inactive": 57748, + "airplay": 57429, + "airport_shuttle": 60220, + "airware": 61780, + "airwave": 61780, + "alarm": 59477, + "alarm_add": 59478, + "alarm_off": 59479, + "alarm_on": 59480, + "alarm_smart_wake": 63152, + "album": 57369, + "align_center": 58198, + "align_end": 63383, + "align_flex_center": 63382, + "align_flex_end": 63381, + "align_flex_start": 63380, + "align_horizontal_center": 57359, + "align_horizontal_left": 57357, + "align_horizontal_right": 57360, + "align_items_stretch": 63379, + "align_justify_center": 63378, + "align_justify_flex_end": 63377, + "align_justify_flex_start": 63376, + "align_justify_space_around": 63375, + "align_justify_space_between": 63374, + "align_justify_space_even": 63373, + "align_justify_stretch": 63372, + "align_self_stretch": 63371, + "align_space_around": 63370, + "align_space_between": 63369, + "align_space_even": 63368, + "align_start": 63367, + "align_stretch": 63366, + "align_vertical_bottom": 57365, + "align_vertical_center": 57361, + "align_vertical_top": 57356, + "all_inbox": 59775, + "all_inclusive": 60221, + "all_match": 57491, + "all_out": 59659, + "allergies": 57492, + "allergy": 58958, + "alt_route": 61828, + "alternate_email": 57574, + "altitude": 63603, + "ambient_screen": 63172, + "ambulance": 63491, + "amend": 63490, + "amp_stories": 59923, + "analytics": 61246, + "anchor": 61901, + "android": 59481, + "animated_images": 62618, + "animation": 59164, + "announcement": 59519, + "aod": 61402, + "aod_tablet": 63647, + "aod_watch": 63148, + "apartment": 59968, + "api": 61879, + "apk_document": 63630, + "apk_install": 63631, + "app_badging": 63279, + "app_blocking": 61247, + "app_promo": 59777, + "app_registration": 61248, + "app_settings_alt": 61249, + "app_shortcut": 60132, + "apparel": 61307, + "approval": 59778, + "approval_delegation": 63562, + "apps": 58819, + "apps_outage": 59340, + "aq": 62810, + "aq_indoor": 62811, + "ar_on_you": 61308, + "ar_stickers": 59779, + "architecture": 59963, + "archive": 57673, + "area_chart": 59248, + "arming_countdown": 59274, + "arrow_and_edge": 62935, + "arrow_back": 58820, + "arrow_back_ios": 58848, + "arrow_back_ios_new": 58090, + "arrow_circle_down": 61825, + "arrow_circle_left": 60071, + "arrow_circle_right": 60074, + "arrow_circle_up": 61826, + "arrow_cool_down": 62646, + "arrow_downward": 58843, + "arrow_downward_alt": 59780, + "arrow_drop_down": 58821, + "arrow_drop_down_circle": 58822, + "arrow_drop_up": 58823, + "arrow_forward": 58824, + "arrow_forward_ios": 58849, + "arrow_insert": 63543, + "arrow_left": 58846, + "arrow_left_alt": 61309, + "arrow_or_edge": 62934, + "arrow_outward": 63694, + "arrow_range": 63131, + "arrow_right": 58847, + "arrow_right_alt": 59713, + "arrow_selector_tool": 63535, + "arrow_split": 59908, + "arrow_top_left": 63278, + "arrow_top_right": 63277, + "arrow_upward": 58840, + "arrow_upward_alt": 59782, + "arrow_warm_up": 62645, + "arrows_more_down": 63659, + "arrows_more_up": 63660, + "arrows_outward": 63276, + "art_track": 57440, + "article": 61250, + "article_shortcut": 62855, + "artist": 57370, + "aspect_ratio": 59483, + "assessment": 61644, + "assignment": 59485, + "assignment_add": 63560, + "assignment_ind": 59486, + "assignment_late": 59487, + "assignment_return": 59488, + "assignment_returned": 59489, + "assignment_turned_in": 59490, + "assist_walker": 63701, + "assistant": 58271, + "assistant_device": 59783, + "assistant_direction": 59784, + "assistant_navigation": 59785, + "assistant_on_hub": 63169, + "assistant_photo": 61638, + "assured_workload": 60271, + "asterisk": 62757, + "astrophotography_auto": 61913, + "astrophotography_off": 61914, + "atm": 58739, + "atr": 60359, + "attach_email": 59998, + "attach_file": 57894, + "attach_file_add": 63553, + "attach_file_off": 62681, + "attach_money": 57895, + "attachment": 58044, + "attractions": 59986, + "attribution": 61403, + "audio_description": 62860, + "audio_file": 60290, + "audio_video_receiver": 62931, + "audiotrack": 58373, + "auto_activity_zone": 63661, + "auto_awesome": 58975, + "auto_awesome_mosaic": 58976, + "auto_awesome_motion": 58977, + "auto_delete": 59980, + "auto_detect_voice": 63550, + "auto_draw_solid": 59786, + "auto_fix": 58979, + "auto_fix_high": 58979, + "auto_fix_normal": 58980, + "auto_fix_off": 58981, + "auto_graph": 58619, + "auto_label": 63166, + "auto_meeting_room": 63167, + "auto_mode": 60448, + "auto_read_pause": 61977, + "auto_read_play": 61974, + "auto_schedule": 57876, + "auto_stories": 58982, + "auto_timer": 61311, + "auto_towing": 59166, + "auto_transmission": 62783, + "auto_videocam": 63168, + "autofps_select": 61404, + "autopause": 63158, + "autopay": 63563, + "autoplay": 63157, + "autorenew": 59491, + "autostop": 63106, + "av1": 62640, + "av_timer": 57371, + "avc": 62639, + "avg_pace": 63163, + "avg_time": 63507, + "award_star": 62994, + "azm": 63212, + "baby_changing_station": 61851, + "back_hand": 59236, + "back_to_tab": 63275, + "background_dot_large": 63390, + "background_dot_small": 62740, + "background_grid_small": 63389, + "background_replace": 61962, + "backlight_high": 63469, + "backlight_high_off": 62703, + "backlight_low": 63468, + "backpack": 61852, + "backspace": 57674, + "backup": 59492, + "backup_table": 61251, + "badge": 60007, + "badge_critical_battery": 61782, + "bakery_dining": 59987, + "balance": 60150, + "balcony": 58767, + "ballot": 57714, + "bar_chart": 57963, + "bar_chart_4_bars": 63105, + "barcode": 59147, + "barcode_reader": 63580, + "barcode_scanner": 59148, + "barefoot": 63601, + "batch_prediction": 61685, + "bath_outdoor": 63227, + "bath_private": 63226, + "bath_public_large": 63225, + "bathroom": 61405, + "bathtub": 59969, + "battery_0_bar": 60380, + "battery_1_bar": 61596, + "battery_20": 61596, + "battery_2_bar": 61597, + "battery_30": 61597, + "battery_3_bar": 61598, + "battery_4_bar": 61599, + "battery_50": 61598, + "battery_5_bar": 61600, + "battery_60": 61599, + "battery_6_bar": 61601, + "battery_80": 61600, + "battery_90": 61601, + "battery_alert": 57756, + "battery_change": 63467, + "battery_charging_20": 61602, + "battery_charging_30": 61603, + "battery_charging_50": 61604, + "battery_charging_60": 61605, + "battery_charging_80": 61606, + "battery_charging_90": 61607, + "battery_charging_full": 57763, + "battery_error": 63466, + "battery_full": 57765, + "battery_full_alt": 61755, + "battery_horiz_000": 63662, + "battery_horiz_050": 63663, + "battery_horiz_075": 63664, + "battery_low": 61781, + "battery_plus": 63465, + "battery_profile": 57862, + "battery_saver": 61406, + "battery_share": 63102, + "battery_status_good": 63101, + "battery_std": 57765, + "battery_unknown": 57766, + "battery_vert_005": 63665, + "battery_vert_020": 63666, + "battery_vert_050": 63667, + "battery_very_low": 61782, + "beach_access": 60222, + "bed": 61407, + "bedroom_baby": 61408, + "bedroom_child": 61409, + "bedroom_parent": 61410, + "bedtime": 61252, + "bedtime_off": 60278, + "beenhere": 58669, + "bento": 61940, + "bia": 63211, + "bid_landscape": 59000, + "bid_landscape_disabled": 61313, + "bigtop_updates": 58985, + "bike_dock": 62587, + "bike_lane": 62586, + "bike_scooter": 61253, + "biotech": 59962, + "blanket": 59432, + "blender": 61411, + "blind": 63702, + "blinds": 57990, + "blinds_closed": 60447, + "block": 61580, + "blood_pressure": 57495, + "bloodtype": 61412, + "bluetooth": 57767, + "bluetooth_audio": 58895, + "bluetooth_connected": 57768, + "bluetooth_disabled": 57769, + "bluetooth_drive": 61413, + "bluetooth_searching": 58895, + "blur_circular": 58274, + "blur_linear": 58275, + "blur_medium": 59468, + "blur_off": 58276, + "blur_on": 58277, + "blur_short": 59599, + "body_fat": 57496, + "body_system": 57497, + "bolt": 59915, + "bomb": 62824, + "book": 59502, + "book_2": 62782, + "book_3": 62781, + "book_4": 62780, + "book_5": 62779, + "book_online": 61975, + "bookmark": 59623, + "bookmark_add": 58776, + "bookmark_added": 58777, + "bookmark_border": 59623, + "bookmark_check": 62551, + "bookmark_flag": 62550, + "bookmark_heart": 62549, + "bookmark_manager": 63409, + "bookmark_remove": 58778, + "bookmark_star": 62548, + "bookmarks": 59787, + "border_all": 57896, + "border_bottom": 57897, + "border_clear": 57898, + "border_color": 57899, + "border_horizontal": 57900, + "border_inner": 57901, + "border_left": 57902, + "border_outer": 57903, + "border_right": 57904, + "border_style": 57905, + "border_top": 57906, + "border_vertical": 57907, + "bottom_app_bar": 59184, + "bottom_drawer": 59181, + "bottom_navigation": 59788, + "bottom_panel_close": 63274, + "bottom_panel_open": 63273, + "bottom_right_click": 63108, + "bottom_sheets": 59789, + "box": 62884, + "box_add": 62885, + "box_edit": 62886, + "boy": 60263, + "brand_awareness": 59790, + "brand_family": 62705, + "branding_watermark": 57451, + "breakfast_dining": 59988, + "breaking_news": 59912, + "breaking_news_alt_1": 61626, + "breastfeeding": 63574, + "brightness_1": 58362, + "brightness_2": 61494, + "brightness_3": 58280, + "brightness_4": 58281, + "brightness_5": 58282, + "brightness_6": 58283, + "brightness_7": 58284, + "brightness_alert": 62927, + "brightness_auto": 57771, + "brightness_empty": 63464, + "brightness_high": 57772, + "brightness_low": 57773, + "brightness_medium": 57774, + "bring_your_own_ip": 57366, + "broadcast_on_home": 63736, + "broadcast_on_personal": 63737, + "broken_image": 58285, + "browse": 60179, + "browse_activity": 63653, + "browse_gallery": 60369, + "browser_not_supported": 61255, + "browser_updated": 59343, + "brunch_dining": 60019, + "brush": 58286, + "bubble": 61315, + "bubble_chart": 59101, + "bubbles": 63054, + "bug_report": 59496, + "build": 63693, + "build_circle": 61256, + "bungalow": 58769, + "burst_mode": 58428, + "bus_alert": 59791, + "business": 59374, + "business_center": 60223, + "business_chip": 63564, + "business_messages": 61316, + "buttons_alt": 59183, + "cabin": 58761, + "cable": 61414, + "cable_car": 62585, + "cached": 59498, + "cadence": 62644, + "cake": 59369, + "cake_add": 63579, + "calculate": 59999, + "calendar_add_on": 61317, + "calendar_apps_script": 61627, + "calendar_clock": 62784, + "calendar_month": 60364, + "calendar_today": 59701, + "calendar_view_day": 59702, + "calendar_view_month": 61415, + "calendar_view_week": 61416, + "call": 61652, + "call_end": 61628, + "call_end_alt": 61628, + "call_log": 57486, + "call_made": 57522, + "call_merge": 57523, + "call_missed": 57524, + "call_missed_outgoing": 57572, + "call_quality": 63058, + "call_received": 57525, + "call_split": 57526, + "call_to_action": 57452, + "camera": 58287, + "camera_alt": 58386, + "camera_enhance": 59644, + "camera_front": 58289, + "camera_indoor": 61417, + "camera_outdoor": 61418, + "camera_rear": 58290, + "camera_roll": 58291, + "camera_video": 63398, + "cameraswitch": 61419, + "campaign": 61257, + "camping": 63650, + "cancel": 59528, + "cancel_presentation": 57577, + "cancel_schedule_send": 59961, + "candle": 62856, + "candlestick_chart": 60116, + "captive_portal": 63272, + "capture": 63271, + "car_crash": 60402, + "car_rental": 59989, + "car_repair": 59990, + "car_tag": 62691, + "card_giftcard": 59638, + "card_membership": 59639, + "card_travel": 59640, + "cardio_load": 62649, + "cardiology": 57500, + "cards": 59793, + "carpenter": 61944, + "carry_on_bag": 60168, + "carry_on_bag_checked": 60171, + "carry_on_bag_inactive": 60170, + "carry_on_bag_question": 60169, + "cases": 59794, + "casino": 60224, + "cast": 58119, + "cast_connected": 58120, + "cast_for_education": 61420, + "cast_pause": 62960, + "cast_warning": 62959, + "castle": 60081, + "category": 58740, + "celebration": 60005, + "cell_merge": 63534, + "cell_tower": 60346, + "cell_wifi": 57580, + "center_focus_strong": 58292, + "center_focus_weak": 58293, + "chair": 61421, + "chair_alt": 61422, + "chalet": 58757, + "change_circle": 58087, + "change_history": 59499, + "charger": 58030, + "charging_station": 61853, + "chart_data": 58483, + "chat": 57545, + "chat_add_on": 61683, + "chat_apps_script": 61629, + "chat_bubble": 57547, + "chat_bubble_outline": 57547, + "chat_error": 63404, + "chat_info": 62763, + "chat_paste_go": 63165, + "check": 58826, + "check_box": 59444, + "check_box_outline_blank": 59445, + "check_circle": 61630, + "check_circle_filled": 61630, + "check_circle_outline": 61630, + "check_in_out": 63222, + "check_indeterminate_small": 63626, + "check_small": 63627, + "checkbook": 59149, + "checked_bag": 60172, + "checked_bag_question": 60173, + "checklist": 59057, + "checklist_rtl": 59059, + "checkroom": 61854, + "cheer": 63144, + "chess": 62951, + "chevron_backward": 62571, + "chevron_forward": 62570, + "chevron_left": 58827, + "chevron_right": 58828, + "child_care": 60225, + "child_friendly": 60226, + "chip_extraction": 63521, + "chips": 59795, + "chrome_reader_mode": 59501, + "chromecast_2": 61819, + "chromecast_device": 59452, + "chronic": 60338, + "church": 60078, + "cinematic_blur": 63571, + "circle": 61258, + "circle_notifications": 59796, + "circles": 59370, + "circles_ext": 59372, + "clarify": 61631, + "class": 59502, + "clean_hands": 61983, + "cleaning": 59797, + "cleaning_bucket": 63668, + "cleaning_services": 61695, + "clear": 58829, + "clear_all": 57528, + "clear_day": 61783, + "clear_night": 61785, + "climate_mini_split": 63669, + "clinical_notes": 57502, + "clock_loader_10": 63270, + "clock_loader_20": 63269, + "clock_loader_40": 63268, + "clock_loader_60": 63267, + "clock_loader_80": 63266, + "clock_loader_90": 63265, + "close": 58829, + "close_fullscreen": 61903, + "close_small": 62728, + "closed_caption": 59798, + "closed_caption_add": 62638, + "closed_caption_disabled": 61916, + "closed_caption_off": 59798, + "cloud": 61788, + "cloud_circle": 58046, + "cloud_done": 58047, + "cloud_download": 58048, + "cloud_off": 58049, + "cloud_queue": 61788, + "cloud_sync": 60250, + "cloud_upload": 58051, + "cloudy": 61788, + "cloudy_filled": 61788, + "cloudy_snowing": 59408, + "co2": 59312, + "co_present": 60144, + "code": 59503, + "code_blocks": 63565, + "code_off": 58611, + "coffee": 61423, + "coffee_maker": 61424, + "cognition": 57503, + "collapse_all": 59716, + "collapse_content": 62727, + "collections": 58323, + "collections_bookmark": 58417, + "color_lens": 58378, + "colorize": 58296, + "colors": 59799, + "comedy_mask": 62678, + "comic_bubble": 62941, + "comment": 57932, + "comment_bank": 59982, + "comments_disabled": 59298, + "commit": 60149, + "communication": 57980, + "communities": 60182, + "communities_filled": 60182, + "commute": 59712, + "compare": 58297, + "compare_arrows": 59669, + "compass_calibration": 58748, + "component_exchange": 61927, + "compost": 59233, + "compress": 59725, + "computer": 58142, + "concierge": 62817, + "conditions": 57504, + "confirmation_number": 58936, + "congenital": 57505, + "connect_without_contact": 61987, + "connected_tv": 59800, + "connecting_airports": 59337, + "construction": 59964, + "contact_emergency": 63697, + "contact_mail": 57552, + "contact_page": 61998, + "contact_phone": 61632, + "contact_phone_filled": 61632, + "contact_support": 59724, + "contactless": 60017, + "contactless_off": 63576, + "contacts": 57530, + "contacts_product": 59801, + "content_copy": 57677, + "content_cut": 57678, + "content_paste": 57679, + "content_paste_go": 60046, + "content_paste_off": 58616, + "content_paste_search": 60059, + "contextual_token": 62598, + "contextual_token_add": 62597, + "contract": 62880, + "contract_delete": 62882, + "contract_edit": 62881, + "contrast": 60215, + "contrast_circle": 62623, + "contrast_rtl_off": 60530, + "contrast_square": 62624, + "control_camera": 57460, + "control_point": 58298, + "control_point_duplicate": 58299, + "controller_gen": 59453, + "conversion_path": 61633, + "conversion_path_off": 63412, + "conveyor_belt": 63591, + "cookie": 60076, + "cookie_off": 63386, + "cooking": 58038, + "cool_to_dry": 57974, + "copy_all": 58092, + "copyright": 59660, + "coronavirus": 61985, + "corporate_fare": 61904, + "cottage": 58759, + "counter_0": 63365, + "counter_1": 63364, + "counter_2": 63363, + "counter_3": 63362, + "counter_4": 63361, + "counter_5": 63360, + "counter_6": 63359, + "counter_7": 63358, + "counter_8": 63357, + "counter_9": 63356, + "countertops": 61943, + "create": 61591, + "create_new_folder": 58060, + "credit_card": 59553, + "credit_card_gear": 62765, + "credit_card_heart": 62764, + "credit_card_off": 58612, + "credit_score": 61425, + "crib": 58760, + "crisis_alert": 60393, + "crop": 58302, + "crop_16_9": 58300, + "crop_3_2": 58301, + "crop_5_4": 58303, + "crop_7_5": 58304, + "crop_9_16": 62793, + "crop_din": 58310, + "crop_free": 58306, + "crop_landscape": 58307, + "crop_original": 58356, + "crop_portrait": 58309, + "crop_rotate": 58423, + "crop_square": 58310, + "crossword": 62949, + "crowdsource": 60184, + "cruelty_free": 59289, + "css": 60307, + "csv": 59087, + "currency_bitcoin": 60357, + "currency_exchange": 60272, + "currency_franc": 60154, + "currency_lira": 60143, + "currency_pound": 60145, + "currency_ruble": 60140, + "currency_rupee": 60151, + "currency_rupee_circle": 62560, + "currency_yen": 60155, + "currency_yuan": 60153, + "curtains": 60446, + "curtains_closed": 60445, + "custom_typography": 59186, + "cut": 61579, + "cycle": 63572, + "cyclone": 60373, + "dangerous": 59802, + "dark_mode": 58652, + "dashboard": 59505, + "dashboard_customize": 59803, + "data_alert": 63478, + "data_array": 60113, + "data_check": 63474, + "data_exploration": 59247, + "data_info_alert": 63477, + "data_loss_prevention": 58076, + "data_object": 60115, + "data_saver_off": 61426, + "data_saver_on": 61427, + "data_table": 59804, + "data_thresholding": 60319, + "data_usage": 61426, + "database": 61966, + "dataset": 63726, + "dataset_linked": 63727, + "date_range": 59670, + "deblur": 60279, + "deceased": 57509, + "decimal_decrease": 63533, + "decimal_increase": 63532, + "deck": 59970, + "dehaze": 58311, + "delete": 59694, + "delete_forever": 59691, + "delete_history": 62744, + "delete_outline": 59694, + "delete_sweep": 57708, + "demography": 58505, + "density_large": 60329, + "density_medium": 60318, + "density_small": 60328, + "dentistry": 57510, + "departure_board": 58742, + "deployed_code": 63264, + "deployed_code_account": 62747, + "deployed_code_alert": 62962, + "deployed_code_history": 62963, + "deployed_code_update": 62964, + "dermatology": 57511, + "description": 59507, + "deselect": 60342, + "design_services": 61706, + "desk": 63732, + "deskphone": 63482, + "desktop_access_disabled": 59805, + "desktop_landscape": 62558, + "desktop_mac": 58123, + "desktop_portrait": 62557, + "desktop_windows": 58124, + "destruction": 62853, + "details": 58312, + "detection_and_zone": 58015, + "detector": 57986, + "detector_alarm": 57847, + "detector_battery": 57860, + "detector_co": 58031, + "detector_offline": 57891, + "detector_smoke": 57989, + "detector_status": 57832, + "developer_board": 58125, + "developer_board_off": 58623, + "developer_guide": 59806, + "developer_mode": 57776, + "developer_mode_tv": 59508, + "device_hub": 58165, + "device_reset": 59571, + "device_thermostat": 57855, + "device_unknown": 58169, + "devices": 58150, + "devices_fold": 60382, + "devices_off": 63397, + "devices_other": 58167, + "devices_wearables": 63147, + "dew_point": 63609, + "diagnosis": 57512, + "dialer_sip": 57531, + "dialogs": 59807, + "dialpad": 57532, + "diamond": 60117, + "dictionary": 62777, + "difference": 60285, + "digital_out_of_home": 61918, + "digital_wellbeing": 61318, + "dining": 61428, + "dinner_dining": 59991, + "directions": 58670, + "directions_alt": 63616, + "directions_alt_off": 63617, + "directions_bike": 58671, + "directions_boat": 61429, + "directions_boat_filled": 61429, + "directions_bus": 61430, + "directions_bus_filled": 61430, + "directions_car": 61431, + "directions_car_filled": 61431, + "directions_off": 61711, + "directions_railway": 61432, + "directions_railway_2": 62562, + "directions_railway_filled": 61432, + "directions_run": 58726, + "directions_subway": 61434, + "directions_subway_filled": 61434, + "directions_transit": 61434, + "directions_transit_filled": 61434, + "directions_walk": 58678, + "directory_sync": 58260, + "dirty_lens": 61259, + "disabled_by_default": 62000, + "disabled_visible": 59246, + "disc_full": 58896, + "discover_tune": 57368, + "dishwasher": 59808, + "dishwasher_gen": 59442, + "display_external_input": 63463, + "display_settings": 60311, + "distance": 63210, + "diversity_1": 63703, + "diversity_2": 63704, + "diversity_3": 63705, + "diversity_4": 63575, + "dns": 59509, + "do_disturb": 61580, + "do_disturb_alt": 61581, + "do_disturb_off": 61582, + "do_disturb_on": 61583, + "do_not_disturb": 61581, + "do_not_disturb_alt": 61580, + "do_not_disturb_off": 61582, + "do_not_disturb_on": 61583, + "do_not_disturb_on_total_silence": 61435, + "do_not_step": 61855, + "do_not_touch": 61872, + "dock": 58126, + "dock_to_bottom": 63462, + "dock_to_left": 63461, + "dock_to_right": 63460, + "docs_add_on": 61634, + "docs_apps_script": 61635, + "document_scanner": 58874, + "domain": 59374, + "domain_add": 60258, + "domain_disabled": 57583, + "domain_verification": 61260, + "domain_verification_off": 63408, + "domino_mask": 62948, + "done": 59510, + "done_all": 59511, + "done_outline": 59695, + "donut_large": 59671, + "donut_small": 59672, + "door_back": 61436, + "door_front": 61437, + "door_open": 59260, + "door_sensor": 57994, + "door_sliding": 61438, + "doorbell": 61439, + "doorbell_3p": 57831, + "doorbell_chime": 57843, + "double_arrow": 59984, + "downhill_skiing": 58633, + "download": 61584, + "download_2": 62755, + "download_done": 61585, + "download_for_offline": 61440, + "downloading": 61441, + "draft": 58989, + "draft_orders": 59315, + "drafts": 57681, + "drag_click": 63263, + "drag_handle": 57949, + "drag_indicator": 59717, + "drag_pan": 63262, + "draw": 59206, + "draw_abstract": 63480, + "draw_collage": 63479, + "drawing_recognition": 60160, + "dresser": 57872, + "drive_eta": 61431, + "drive_file_move": 59809, + "drive_file_move_outline": 59809, + "drive_file_move_rtl": 59809, + "drive_file_rename_outline": 59810, + "drive_folder_upload": 59811, + "drive_fusiontable": 59000, + "dropdown": 59812, + "dry": 61875, + "dry_cleaning": 59992, + "dual_screen": 63183, + "duo": 59813, + "dvr": 57778, + "dynamic_feed": 59924, + "dynamic_form": 61887, + "e911_avatar": 61722, + "e911_emergency": 61721, + "e_mobiledata": 61442, + "e_mobiledata_badge": 63459, + "earbuds": 61443, + "earbuds_battery": 61444, + "early_on": 58042, + "earthquake": 63055, + "east": 61919, + "ecg": 63503, + "ecg_heart": 63209, + "eco": 59957, + "eda": 63208, + "edgesensor_high": 61445, + "edgesensor_low": 61446, + "edit": 61591, + "edit_attributes": 58744, + "edit_calendar": 59202, + "edit_document": 63628, + "edit_location": 58728, + "edit_location_alt": 57797, + "edit_note": 59205, + "edit_notifications": 58661, + "edit_off": 59728, + "edit_road": 61261, + "edit_square": 63629, + "editor_choice": 62760, + "egg": 60108, + "egg_alt": 60104, + "eject": 59643, + "elderly": 61978, + "elderly_woman": 60265, + "electric_bike": 60187, + "electric_bolt": 60444, + "electric_car": 60188, + "electric_meter": 60443, + "electric_moped": 60189, + "electric_rickshaw": 60190, + "electric_scooter": 60191, + "electrical_services": 61698, + "elevation": 63207, + "elevator": 61856, + "email": 57689, + "emergency": 57835, + "emergency_heat": 61789, + "emergency_heat_2": 62693, + "emergency_home": 59434, + "emergency_recording": 60404, + "emergency_share": 60406, + "emergency_share_off": 62878, + "emoji_emotions": 59938, + "emoji_events": 59939, + "emoji_flags": 61638, + "emoji_food_beverage": 59931, + "emoji_language": 62669, + "emoji_nature": 59932, + "emoji_objects": 59940, + "emoji_people": 59933, + "emoji_symbols": 59934, + "emoji_transportation": 59935, + "emoticon": 58867, + "empty_dashboard": 63556, + "enable": 61832, + "encrypted": 58771, + "endocrinology": 57513, + "energy": 59814, + "energy_program_saving": 61791, + "energy_program_time_used": 61793, + "energy_savings_leaf": 60442, + "engineering": 59965, + "enhanced_encryption": 58943, + "ent": 57514, + "enterprise": 59150, + "enterprise_off": 60237, + "equal": 63355, + "equalizer": 57373, + "error": 63670, + "error_circle_rounded": 63670, + "error_med": 58523, + "error_outline": 63670, + "escalator": 61857, + "escalator_warning": 61868, + "euro": 59925, + "euro_symbol": 59686, + "ev_charger": 58733, + "ev_mobiledata_badge": 63458, + "ev_shadow": 61327, + "ev_shadow_add": 62848, + "ev_shadow_minus": 62847, + "ev_station": 58733, + "event": 59512, + "event_available": 58900, + "event_busy": 58901, + "event_list": 63107, + "event_note": 58902, + "event_repeat": 60283, + "event_seat": 59651, + "event_upcoming": 62008, + "exclamation": 61999, + "exercise": 63206, + "exit_to_app": 59513, + "expand": 59727, + "expand_all": 59718, + "expand_circle_down": 59341, + "expand_circle_right": 62865, + "expand_circle_up": 62930, + "expand_content": 63536, + "expand_less": 58830, + "expand_more": 58831, + "experiment": 59014, + "explicit": 57374, + "explore": 59514, + "explore_nearby": 58680, + "explore_off": 59816, + "explosion": 63109, + "export_notes": 57516, + "exposure": 58358, + "exposure_neg_1": 58315, + "exposure_neg_2": 58316, + "exposure_plus_1": 59392, + "exposure_plus_2": 58318, + "exposure_zero": 58319, + "extension": 59515, + "extension_off": 58613, + "eye_tracking": 62665, + "eyeglasses": 63214, + "face": 61448, + "face_2": 63706, + "face_3": 63707, + "face_4": 63708, + "face_5": 63709, + "face_6": 63710, + "face_retouching_natural": 61262, + "face_retouching_off": 61447, + "face_unlock": 61448, + "fact_check": 61637, + "factory": 60348, + "falling": 62989, + "familiar_face_and_zone": 57884, + "family_history": 57517, + "family_home": 60198, + "family_link": 60185, + "family_restroom": 61858, + "family_star": 62759, + "farsight_digital": 62809, + "fast_forward": 57375, + "fast_rewind": 57376, + "fastfood": 58746, + "faucet": 57976, + "favorite": 59518, + "favorite_border": 59518, + "fax": 60120, + "feature_search": 59817, + "featured_play_list": 57453, + "featured_seasonal_and_gifts": 61329, + "featured_video": 57454, + "feed": 61449, + "feedback": 59519, + "female": 58768, + "femur": 63633, + "femur_alt": 63634, + "fence": 61942, + "fertile": 63205, + "festival": 60008, + "fiber_dvr": 57437, + "fiber_manual_record": 57441, + "fiber_new": 57438, + "fiber_pin": 57450, + "fiber_smart_record": 57442, + "file_copy": 57715, + "file_copy_off": 62680, + "file_download": 61584, + "file_download_done": 61585, + "file_download_off": 58622, + "file_map": 58053, + "file_open": 60147, + "file_present": 59918, + "file_save": 61823, + "file_save_off": 58629, + "file_upload": 61595, + "file_upload_off": 63622, + "filter": 58323, + "filter_1": 58320, + "filter_2": 58321, + "filter_3": 58322, + "filter_4": 58324, + "filter_5": 58325, + "filter_6": 58326, + "filter_7": 58327, + "filter_8": 58328, + "filter_9": 58329, + "filter_9_plus": 58330, + "filter_alt": 61263, + "filter_alt_off": 60210, + "filter_b_and_w": 58331, + "filter_center_focus": 58332, + "filter_drama": 58333, + "filter_frames": 58334, + "filter_hdr": 58335, + "filter_list": 57682, + "filter_list_alt": 59726, + "filter_list_off": 60247, + "filter_none": 58336, + "filter_retrolux": 58337, + "filter_tilt_shift": 58338, + "filter_vintage": 58339, + "finance": 59071, + "finance_chip": 63566, + "finance_mode": 61330, + "find_in_page": 59520, + "find_replace": 59521, + "fingerprint": 59661, + "fingerprint_off": 62621, + "fire_extinguisher": 61912, + "fire_hydrant": 61859, + "fire_truck": 63730, + "fireplace": 59971, + "first_page": 58844, + "fit_page": 63354, + "fit_screen": 59920, + "fit_width": 63353, + "fitness_center": 60227, + "fitness_tracker": 62563, + "flag": 61638, + "flag_circle": 60152, + "flag_filled": 61638, + "flaky": 61264, + "flare": 58340, + "flash_auto": 58341, + "flash_off": 58342, + "flash_on": 58343, + "flashlight_off": 61450, + "flashlight_on": 61451, + "flatware": 61452, + "flex_direction": 63352, + "flex_no_wrap": 63351, + "flex_wrap": 63350, + "flight": 58681, + "flight_class": 59339, + "flight_land": 59652, + "flight_takeoff": 59653, + "flights_and_hotels": 59819, + "flightsmode": 61331, + "flip": 58344, + "flip_camera_android": 59959, + "flip_camera_ios": 59960, + "flip_to_back": 59522, + "flip_to_front": 59523, + "float_landscape_2": 62556, + "float_portrait_2": 62555, + "flood": 60390, + "floor": 63204, + "floor_lamp": 57886, + "flourescent": 61565, + "flowsheet": 57518, + "fluid": 58499, + "fluid_balance": 63501, + "fluid_med": 63500, + "fluorescent": 61565, + "flutter": 61917, + "flutter_dash": 57355, + "flyover": 62584, + "fmd_bad": 61454, + "fmd_good": 61915, + "foggy": 59416, + "folded_hands": 62957, + "folder": 58055, + "folder_copy": 60349, + "folder_data": 62854, + "folder_delete": 60212, + "folder_limited": 62692, + "folder_managed": 63349, + "folder_off": 60291, + "folder_open": 58056, + "folder_shared": 58057, + "folder_special": 58903, + "folder_supervised": 63348, + "folder_zip": 60204, + "follow_the_signs": 61986, + "font_download": 57703, + "font_download_off": 58617, + "food_bank": 61938, + "foot_bones": 63635, + "footprint": 63613, + "for_you": 59820, + "forest": 60057, + "fork_left": 60320, + "fork_right": 60332, + "forklift": 63592, + "format_align_center": 57908, + "format_align_justify": 57909, + "format_align_left": 57910, + "format_align_right": 57911, + "format_bold": 57912, + "format_clear": 57913, + "format_color_fill": 57914, + "format_color_reset": 57915, + "format_color_text": 57916, + "format_h1": 63581, + "format_h2": 63582, + "format_h3": 63583, + "format_h4": 63584, + "format_h5": 63585, + "format_h6": 63586, + "format_image_left": 63587, + "format_image_right": 63588, + "format_indent_decrease": 57917, + "format_indent_increase": 57918, + "format_ink_highlighter": 63531, + "format_italic": 57919, + "format_letter_spacing": 63347, + "format_letter_spacing_2": 63000, + "format_letter_spacing_standard": 62999, + "format_letter_spacing_wide": 62998, + "format_letter_spacing_wider": 62997, + "format_line_spacing": 57920, + "format_list_bulleted": 57921, + "format_list_bulleted_add": 63561, + "format_list_numbered": 57922, + "format_list_numbered_rtl": 57959, + "format_overline": 60261, + "format_paint": 57923, + "format_paragraph": 63589, + "format_quote": 57924, + "format_shapes": 57950, + "format_size": 57925, + "format_strikethrough": 57926, + "format_text_clip": 63530, + "format_text_overflow": 63529, + "format_text_wrap": 63528, + "format_textdirection_l_to_r": 57927, + "format_textdirection_r_to_l": 57928, + "format_textdirection_vertical": 62648, + "format_underlined": 57929, + "format_underlined_squiggle": 63621, + "forms_add_on": 61639, + "forms_apps_script": 61640, + "fort": 60077, + "forum": 59567, + "forward": 62842, + "forward_10": 57430, + "forward_30": 57431, + "forward_5": 57432, + "forward_circle": 63221, + "forward_media": 63220, + "forward_to_inbox": 61831, + "foundation": 61952, + "frame_inspect": 63346, + "frame_person": 63654, + "frame_person_mic": 62677, + "frame_person_off": 63441, + "frame_reload": 63345, + "frame_source": 63344, + "free_breakfast": 60228, + "free_cancellation": 59208, + "front_hand": 59241, + "front_loader": 63593, + "full_coverage": 60178, + "full_hd": 62859, + "full_stacked_bar_chart": 61970, + "fullscreen": 58832, + "fullscreen_exit": 58833, + "fullscreen_portrait": 62554, + "function": 63590, + "functions": 57930, + "funicular": 62583, + "g_mobiledata": 61456, + "g_mobiledata_badge": 63457, + "g_translate": 59687, + "gallery_thumbnail": 63599, + "gamepad": 58127, + "games": 58127, + "garage": 61457, + "garage_door": 59156, + "garage_home": 59437, + "garden_cart": 63657, + "gas_meter": 60441, + "gastroenterology": 57585, + "gate": 57975, + "gavel": 59662, + "general_device": 59102, + "generating_tokens": 59209, + "genetics": 57587, + "genres": 59118, + "gesture": 57685, + "gesture_select": 63063, + "get_app": 61584, + "gif": 59656, + "gif_box": 59299, + "girl": 60264, + "gite": 58763, + "glass_cup": 63203, + "globe": 58956, + "globe_asia": 63385, + "globe_uk": 63384, + "glucose": 58528, + "glyphs": 63651, + "go_to_line": 63261, + "golf_course": 60229, + "gondola_lift": 62582, + "google_home_devices": 59157, + "google_plus_reshare": 62842, + "google_tv_remote": 62939, + "google_wifi": 62841, + "gpp_bad": 61458, + "gpp_good": 61459, + "gpp_maybe": 61460, + "gps_fixed": 58716, + "gps_not_fixed": 57783, + "gps_off": 57782, + "grade": 59525, + "gradient": 58345, + "grading": 59983, + "grain": 58346, + "graphic_eq": 57784, + "grass": 61957, + "grid_3x3": 61461, + "grid_3x3_off": 63100, + "grid_4x4": 61462, + "grid_goldenratio": 61463, + "grid_guides": 63343, + "grid_off": 58347, + "grid_on": 58348, + "grid_view": 59824, + "grocery": 61335, + "group": 59937, + "group_add": 59376, + "group_off": 59207, + "group_remove": 59309, + "group_work": 59526, + "grouped_bar_chart": 61969, + "groups": 62003, + "groups_2": 63711, + "groups_3": 63712, + "guardian": 62657, + "gynecology": 57588, + "h_mobiledata": 61464, + "h_mobiledata_badge": 63456, + "h_plus_mobiledata": 61465, + "h_plus_mobiledata_badge": 63455, + "hail": 59825, + "hallway": 59128, + "hand_bones": 63636, + "hand_gesture": 61340, + "handheld_controller": 62662, + "handshake": 60363, + "handwriting_recognition": 60162, + "handyman": 61707, + "hangout_video": 57537, + "hangout_video_off": 57538, + "hard_drive": 63502, + "hard_drive_2": 63396, + "hardware": 59993, + "hd": 57426, + "hdr_auto": 61466, + "hdr_auto_select": 61467, + "hdr_enhanced_select": 61265, + "hdr_off": 58349, + "hdr_off_select": 61468, + "hdr_on": 58350, + "hdr_on_select": 61469, + "hdr_plus": 61470, + "hdr_plus_off": 58351, + "hdr_strong": 58353, + "hdr_weak": 58354, + "head_mounted_device": 62661, + "headphones": 61471, + "headphones_battery": 61472, + "headset": 61471, + "headset_mic": 58129, + "headset_off": 58170, + "healing": 58355, + "health_and_beauty": 61341, + "health_and_safety": 57813, + "health_metrics": 63202, + "heap_snapshot_large": 63342, + "heap_snapshot_multiple": 63341, + "heap_snapshot_thumbnail": 63340, + "hearing": 57379, + "hearing_aid": 62564, + "hearing_disabled": 61700, + "heart_broken": 60098, + "heart_check": 62986, + "heart_minus": 63619, + "heart_plus": 63620, + "heat": 62775, + "heat_pump": 60440, + "heat_pump_balance": 57982, + "height": 59926, + "helicopter": 62988, + "help": 59645, + "help_center": 61888, + "help_clinic": 63504, + "help_outline": 59645, + "hematology": 57590, + "hevc": 61473, + "hexagon": 60217, + "hide": 61342, + "hide_image": 61474, + "hide_source": 61475, + "high_density": 63388, + "high_quality": 57380, + "high_res": 62795, + "highlight": 57951, + "highlight_keyboard_focus": 62736, + "highlight_mouse_cursor": 62737, + "highlight_off": 59528, + "highlight_text_cursor": 62738, + "highlighter_size_1": 63339, + "highlighter_size_2": 63338, + "highlighter_size_3": 63337, + "highlighter_size_4": 63336, + "highlighter_size_5": 63335, + "hiking": 58634, + "history": 59571, + "history_edu": 59966, + "history_off": 62682, + "history_toggle_off": 61821, + "hive": 60070, + "hls": 60298, + "hls_off": 60300, + "holiday_village": 58762, + "home": 59826, + "home_and_garden": 61343, + "home_app_logo": 58005, + "home_filled": 59826, + "home_health": 58553, + "home_improvement_and_tools": 61344, + "home_iot_device": 57987, + "home_max": 61476, + "home_max_dots": 59465, + "home_mini": 61477, + "home_pin": 61773, + "home_repair_service": 61696, + "home_speaker": 61724, + "home_storage": 63596, + "home_work": 61488, + "horizontal_distribute": 57364, + "horizontal_rule": 61704, + "horizontal_split": 59719, + "hot_tub": 60230, + "hotel": 58697, + "hotel_class": 59203, + "hourglass": 60415, + "hourglass_bottom": 59996, + "hourglass_disabled": 61267, + "hourglass_empty": 59531, + "hourglass_full": 59532, + "hourglass_top": 59995, + "house": 59972, + "house_siding": 61954, + "house_with_shield": 59270, + "houseboat": 58756, + "household_supplies": 61345, + "hov": 62581, + "how_to_reg": 57716, + "how_to_vote": 57717, + "hr_resting": 63162, + "html": 60286, + "http": 59650, + "https": 59545, + "hub": 59892, + "humerus": 63637, + "humerus_alt": 63638, + "humidity_high": 61795, + "humidity_indoor": 62808, + "humidity_low": 61796, + "humidity_mid": 61797, + "humidity_percentage": 63614, + "hvac": 61710, + "ice_skating": 58635, + "icecream": 60009, + "id_card": 62666, + "ifl": 57381, + "iframe": 63259, + "iframe_off": 63260, + "image": 58356, + "image_aspect_ratio": 58357, + "image_not_supported": 61718, + "image_search": 58431, + "imagesearch_roller": 59828, + "imagesmode": 61346, + "immunology": 57595, + "import_contacts": 57568, + "import_export": 59605, + "important_devices": 59666, + "in_home_mode": 59443, + "inactive_order": 57596, + "inbox": 57686, + "inbox_customize": 63577, + "incomplete_circle": 59291, + "indeterminate_check_box": 59657, + "indeterminate_question_box": 62829, + "info": 59534, + "info_i": 62875, + "infrared": 63612, + "ink_eraser": 59088, + "ink_eraser_off": 59363, + "ink_highlighter": 59089, + "ink_highlighter_move": 62756, + "ink_marker": 59090, + "ink_pen": 59091, + "inpatient": 57598, + "input": 59536, + "input_circle": 63258, + "insert_chart": 61644, + "insert_chart_filled": 61644, + "insert_chart_outlined": 61644, + "insert_comment": 57932, + "insert_drive_file": 58989, + "insert_emoticon": 59938, + "insert_invitation": 59512, + "insert_link": 57936, + "insert_page_break": 60106, + "insert_photo": 58356, + "insert_text": 63527, + "insights": 61586, + "install_desktop": 60273, + "install_mobile": 60274, + "instant_mix": 57382, + "integration_instructions": 61268, + "interactive_space": 63487, + "interests": 59336, + "interpreter_mode": 59451, + "inventory": 57721, + "inventory_2": 57761, + "invert_colors": 59537, + "invert_colors_off": 57540, + "ios": 57383, + "ios_share": 59064, + "iron": 58755, + "iso": 58358, + "jamboard_kiosk": 59829, + "javascript": 60284, + "join": 63567, + "join_full": 63567, + "join_inner": 60148, + "join_left": 60146, + "join_right": 60138, + "joystick": 62958, + "jump_to_element": 63257, + "kayaking": 58636, + "kebab_dining": 59458, + "keep": 61478, + "keep_off": 59129, + "keep_pin": 61478, + "keep_public": 62831, + "kettle": 58041, + "key": 59196, + "key_off": 60292, + "key_vertical": 62746, + "key_visualizer": 61849, + "keyboard": 58130, + "keyboard_alt": 61480, + "keyboard_arrow_down": 58131, + "keyboard_arrow_left": 58132, + "keyboard_arrow_right": 58133, + "keyboard_arrow_up": 58134, + "keyboard_backspace": 58135, + "keyboard_capslock": 58136, + "keyboard_capslock_badge": 63454, + "keyboard_command_key": 60135, + "keyboard_control_key": 60134, + "keyboard_double_arrow_down": 60112, + "keyboard_double_arrow_left": 60099, + "keyboard_double_arrow_right": 60105, + "keyboard_double_arrow_up": 60111, + "keyboard_external_input": 63453, + "keyboard_full": 63452, + "keyboard_hide": 58138, + "keyboard_keys": 63099, + "keyboard_lock": 62610, + "keyboard_lock_off": 62609, + "keyboard_off": 63098, + "keyboard_onscreen": 63451, + "keyboard_option_key": 60136, + "keyboard_previous_language": 63450, + "keyboard_return": 58139, + "keyboard_tab": 58140, + "keyboard_tab_rtl": 60531, + "keyboard_voice": 58141, + "kid_star": 62758, + "king_bed": 59973, + "kitchen": 60231, + "kitesurfing": 58637, + "lab_panel": 57603, + "lab_profile": 57604, + "lab_research": 63499, + "label": 59539, + "label_important": 59720, + "label_important_outline": 59720, + "label_off": 59830, + "label_outline": 59539, + "labs": 57605, + "lan": 60207, + "landscape": 58724, + "landscape_2": 62660, + "landscape_2_off": 62659, + "landslide": 60375, + "language": 59540, + "language_chinese_array": 63334, + "language_chinese_cangjie": 63333, + "language_chinese_dayi": 63332, + "language_chinese_pinyin": 63331, + "language_chinese_quick": 63330, + "language_chinese_wubi": 63329, + "language_french": 63328, + "language_gb_english": 63327, + "language_international": 63326, + "language_japanese_kana": 62739, + "language_korean_latin": 63325, + "language_pinyin": 63324, + "language_spanish": 62953, + "language_us": 63321, + "language_us_colemak": 63323, + "language_us_dvorak": 63322, + "laps": 63161, + "laptop": 58142, + "laptop_chromebook": 58143, + "laptop_mac": 58144, + "laptop_windows": 58145, + "lasso_select": 60163, + "last_page": 58845, + "launch": 59550, + "laundry": 58024, + "layers": 58683, + "layers_clear": 58684, + "lda": 57606, + "leaderboard": 61964, + "leak_add": 58360, + "leak_remove": 58361, + "left_click": 63256, + "left_panel_close": 63255, + "left_panel_open": 63254, + "legend_toggle": 61723, + "lens": 58362, + "lens_blur": 61481, + "letter_switch": 63320, + "library_add": 57404, + "library_add_check": 59831, + "library_books": 57391, + "library_music": 57392, + "license": 60164, + "lift_to_talk": 61347, + "light": 61482, + "light_group": 57995, + "light_mode": 58648, + "light_off": 59832, + "lightbulb": 59663, + "lightbulb_circle": 60414, + "lightbulb_outline": 59663, + "lightning_stand": 61348, + "line_axis": 60058, + "line_curve": 63319, + "line_end": 63526, + "line_end_arrow": 63517, + "line_end_arrow_notch": 63516, + "line_end_circle": 63515, + "line_end_diamond": 63514, + "line_end_square": 63513, + "line_start": 63525, + "line_start_arrow": 63512, + "line_start_arrow_notch": 63511, + "line_start_circle": 63510, + "line_start_diamond": 63509, + "line_start_square": 63508, + "line_style": 59673, + "line_weight": 59674, + "linear_scale": 57952, + "link": 57936, + "link_off": 57711, + "linked_camera": 58424, + "linked_services": 62773, + "liquor": 60000, + "list": 59542, + "list_alt": 57582, + "list_alt_add": 63318, + "lists": 59833, + "live_help": 57542, + "live_tv": 58938, + "living": 61483, + "local_activity": 58707, + "local_airport": 58685, + "local_atm": 58686, + "local_bar": 58688, + "local_cafe": 60228, + "local_car_wash": 58690, + "local_convenience_store": 58691, + "local_dining": 58721, + "local_drink": 58692, + "local_fire_department": 61269, + "local_florist": 58693, + "local_gas_station": 58694, + "local_grocery_store": 59596, + "local_hospital": 58696, + "local_hotel": 58697, + "local_laundry_service": 58698, + "local_library": 58699, + "local_mall": 58700, + "local_movies": 59610, + "local_offer": 61531, + "local_parking": 58703, + "local_pharmacy": 58704, + "local_phone": 61652, + "local_pizza": 58706, + "local_play": 58707, + "local_police": 61270, + "local_post_office": 58708, + "local_printshop": 59565, + "local_see": 58711, + "local_shipping": 58712, + "local_taxi": 58713, + "location_automation": 61775, + "location_away": 61776, + "location_chip": 63568, + "location_city": 59377, + "location_disabled": 57782, + "location_home": 61778, + "location_off": 57543, + "location_on": 61915, + "location_pin": 61915, + "location_searching": 57783, + "locator_tag": 63681, + "lock": 59545, + "lock_clock": 61271, + "lock_open": 59544, + "lock_open_right": 63062, + "lock_outline": 59545, + "lock_person": 63731, + "lock_reset": 60126, + "login": 60023, + "logo_dev": 60118, + "logout": 59834, + "looks": 58364, + "looks_3": 58363, + "looks_4": 58365, + "looks_5": 58366, + "looks_6": 58367, + "looks_one": 58368, + "looks_two": 58369, + "loop": 59491, + "loupe": 58370, + "low_density": 63387, + "low_priority": 57709, + "lowercase": 62602, + "loyalty": 59546, + "lte_mobiledata": 61484, + "lte_mobiledata_badge": 63449, + "lte_plus_mobiledata": 61485, + "lte_plus_mobiledata_badge": 63448, + "luggage": 62005, + "lunch_dining": 60001, + "lyrics": 60427, + "macro_auto": 63218, + "macro_off": 63698, + "magic_button": 61750, + "magic_exchange": 63476, + "magic_tether": 63447, + "magnification_large": 63549, + "magnification_small": 63548, + "magnify_docked": 63446, + "magnify_fullscreen": 63445, + "mail": 57689, + "mail_lock": 60426, + "mail_off": 62603, + "mail_outline": 57689, + "male": 58766, + "man": 58603, + "man_2": 63713, + "man_3": 63714, + "man_4": 63715, + "manage_accounts": 61486, + "manage_history": 60391, + "manage_search": 61487, + "manga": 62947, + "manufacturing": 59174, + "map": 58715, + "maps_home_work": 61488, + "maps_ugc": 61272, + "margin": 59835, + "mark_as_unread": 59836, + "mark_chat_read": 61835, + "mark_chat_unread": 61833, + "mark_email_read": 61836, + "mark_email_unread": 61834, + "mark_unread_chat_alt": 60317, + "markdown": 62802, + "markdown_copy": 62803, + "markdown_paste": 62804, + "markunread": 57689, + "markunread_mailbox": 59547, + "masked_transitions": 59182, + "masks": 61976, + "match_case": 63217, + "match_word": 63216, + "matter": 59655, + "maximize": 59696, + "measuring_tape": 63151, + "media_bluetooth_off": 61489, + "media_bluetooth_on": 61490, + "media_link": 63551, + "media_output": 62706, + "media_output_off": 62707, + "mediation": 61351, + "medical_information": 60397, + "medical_mask": 63498, + "medical_services": 61705, + "medication": 61491, + "medication_liquid": 60039, + "meeting_room": 60239, + "memory": 58146, + "memory_alt": 63395, + "menstrual_health": 63201, + "menu": 58834, + "menu_book": 59929, + "menu_open": 59837, + "merge": 60312, + "merge_type": 57938, + "message": 57545, + "metabolism": 57611, + "metro": 62580, + "mfg_nest_yale_lock": 61725, + "mic": 58141, + "mic_double": 62929, + "mic_external_off": 61273, + "mic_external_on": 61274, + "mic_none": 58141, + "mic_off": 57387, + "microbiology": 57612, + "microwave": 61956, + "microwave_gen": 59463, + "military_tech": 59967, + "mimo": 59838, + "mimo_disconnect": 59839, + "mindfulness": 63200, + "minimize": 59697, + "minor_crash": 60401, + "mintmark": 61353, + "missed_video_call": 61646, + "missed_video_call_filled": 61646, + "missing_controller": 59137, + "mist": 57736, + "mitre": 62791, + "mixture_med": 58568, + "mms": 58904, + "mobile_friendly": 57856, + "mobile_off": 57857, + "mobile_screen_share": 57575, + "mobiledata_off": 61492, + "mode": 61591, + "mode_comment": 57939, + "mode_cool": 61798, + "mode_cool_off": 61799, + "mode_dual": 62807, + "mode_edit": 61591, + "mode_edit_outline": 61591, + "mode_fan": 61800, + "mode_fan_off": 60439, + "mode_heat": 61802, + "mode_heat_cool": 61803, + "mode_heat_off": 61805, + "mode_night": 61494, + "mode_of_travel": 59342, + "mode_off_on": 61807, + "mode_standby": 61495, + "model_training": 61647, + "monetization_on": 57955, + "money": 58749, + "money_off": 61496, + "money_off_csred": 61496, + "monitor": 61275, + "monitor_heart": 60066, + "monitor_weight": 61497, + "monitor_weight_gain": 63199, + "monitor_weight_loss": 63198, + "monitoring": 61840, + "monochrome_photos": 58371, + "monorail": 62579, + "mood": 59938, + "mood_bad": 59379, + "mop": 57997, + "more": 58905, + "more_down": 61846, + "more_horiz": 58835, + "more_time": 59997, + "more_up": 61847, + "more_vert": 58836, + "mosque": 60082, + "motion_blur": 61648, + "motion_mode": 63554, + "motion_photos_auto": 61498, + "motion_photos_off": 59840, + "motion_photos_on": 59841, + "motion_photos_pause": 61991, + "motion_photos_paused": 61991, + "motion_sensor_active": 59282, + "motion_sensor_alert": 59268, + "motion_sensor_idle": 59267, + "motion_sensor_urgent": 59278, + "motorcycle": 59675, + "mountain_flag": 62946, + "mouse": 58147, + "mouse_lock": 62608, + "mouse_lock_off": 62607, + "move": 59200, + "move_down": 60257, + "move_group": 63253, + "move_item": 61951, + "move_location": 59201, + "move_selection_down": 63252, + "move_selection_left": 63251, + "move_selection_right": 63250, + "move_selection_up": 63249, + "move_to_inbox": 57704, + "move_up": 60260, + "moved_location": 58772, + "movie": 58372, + "movie_creation": 58372, + "movie_edit": 63552, + "movie_filter": 58426, + "movie_info": 57389, + "movie_off": 62617, + "moving": 58625, + "moving_beds": 59197, + "moving_ministry": 59198, + "mp": 59843, + "multicooker": 58003, + "multiline_chart": 59103, + "multiple_stop": 61881, + "museum": 59958, + "music_cast": 60186, + "music_note": 58373, + "music_off": 58432, + "music_video": 57443, + "my_location": 58716, + "mystery": 62945, + "nat": 61276, + "nature": 58374, + "nature_people": 58375, + "navigate_before": 58827, + "navigate_next": 58828, + "navigation": 58717, + "near_me": 58729, + "near_me_disabled": 61935, + "nearby": 59063, + "nearby_error": 61499, + "nearby_off": 61500, + "nephrology": 57613, + "nest_audio": 60351, + "nest_cam_floodlight": 63671, + "nest_cam_indoor": 61726, + "nest_cam_iq": 61727, + "nest_cam_iq_outdoor": 61728, + "nest_cam_magnet_mount": 63672, + "nest_cam_outdoor": 61729, + "nest_cam_stand": 63673, + "nest_cam_wall_mount": 63674, + "nest_cam_wired_stand": 60438, + "nest_clock_farsight_analog": 63675, + "nest_clock_farsight_digital": 63676, + "nest_connect": 61730, + "nest_detect": 61731, + "nest_display": 61732, + "nest_display_max": 61733, + "nest_doorbell_visitor": 63677, + "nest_eco_leaf": 63678, + "nest_farsight_weather": 63679, + "nest_found_savings": 63680, + "nest_gale_wifi": 62841, + "nest_heat_link_e": 61734, + "nest_heat_link_gen_3": 61735, + "nest_hello_doorbell": 59436, + "nest_locator_tag": 63681, + "nest_mini": 59273, + "nest_multi_room": 63682, + "nest_protect": 59022, + "nest_remote": 62939, + "nest_remote_comfort_sensor": 61738, + "nest_secure_alarm": 61739, + "nest_sunblock": 63683, + "nest_tag": 63681, + "nest_thermostat": 59023, + "nest_thermostat_e_eu": 61741, + "nest_thermostat_gen_3": 61742, + "nest_thermostat_sensor": 61743, + "nest_thermostat_sensor_eu": 61744, + "nest_thermostat_zirconium_eu": 61745, + "nest_true_radiant": 63684, + "nest_wake_on_approach": 63685, + "nest_wake_on_press": 63686, + "nest_wifi_gale": 61746, + "nest_wifi_mistral": 61747, + "nest_wifi_point": 61748, + "nest_wifi_point_vento": 61748, + "nest_wifi_pro": 62827, + "nest_wifi_pro_2": 62826, + "nest_wifi_router": 61747, + "network_cell": 57785, + "network_check": 58944, + "network_intelligence_history": 62966, + "network_intelligence_update": 62965, + "network_locked": 58906, + "network_manage": 63403, + "network_node": 62830, + "network_ping": 60362, + "network_wifi": 57786, + "network_wifi_1_bar": 60388, + "network_wifi_1_bar_locked": 62863, + "network_wifi_2_bar": 60374, + "network_wifi_2_bar_locked": 62862, + "network_wifi_3_bar": 60385, + "network_wifi_3_bar_locked": 62861, + "network_wifi_locked": 62770, + "neurology": 57614, + "new_label": 58889, + "new_releases": 61302, + "new_window": 63248, + "news": 57394, + "newsmode": 61357, + "newspaper": 60289, + "newsstand": 59844, + "next_plan": 61277, + "next_week": 57706, + "nfc": 57787, + "night_shelter": 61937, + "night_sight_auto": 61911, + "night_sight_auto_off": 61945, + "night_sight_max": 63171, + "nightlife": 60002, + "nightlight": 61501, + "nightlight_round": 61501, + "nights_stay": 59974, + "no_accounts": 61502, + "no_adult_content": 63742, + "no_backpack": 62007, + "no_crash": 60400, + "no_drinks": 61861, + "no_encryption": 61503, + "no_encryption_gmailerrorred": 61503, + "no_flash": 61862, + "no_food": 61863, + "no_luggage": 62011, + "no_meals": 61910, + "no_meeting_room": 60238, + "no_photography": 61864, + "no_sim": 57806, + "no_sound": 59152, + "no_stroller": 61871, + "no_transfer": 61909, + "noise_aware": 60396, + "noise_control_off": 60403, + "noise_control_on": 63656, + "nordic_walking": 58638, + "north": 61920, + "north_east": 61921, + "north_west": 61922, + "not_accessible": 61694, + "not_accessible_forward": 62794, + "not_interested": 61580, + "not_listed_location": 58741, + "not_started": 61649, + "note": 58989, + "note_add": 59548, + "note_alt": 61504, + "note_stack": 62818, + "note_stack_add": 62819, + "notes": 57964, + "notification_add": 58265, + "notification_important": 57348, + "notification_multiple": 59074, + "notifications": 59381, + "notifications_active": 59383, + "notifications_none": 59381, + "notifications_off": 59382, + "notifications_paused": 59384, + "notifications_unread": 62718, + "numbers": 60103, + "nutrition": 57616, + "ods": 59112, + "odt": 59113, + "offline_bolt": 59698, + "offline_pin": 59658, + "offline_pin_off": 62672, + "offline_share": 59845, + "oil_barrel": 60437, + "on_device_training": 60413, + "on_hub_device": 59075, + "oncology": 57620, + "ondemand_video": 58938, + "online_prediction": 61675, + "onsen": 63224, + "opacity": 59676, + "open_in_browser": 59549, + "open_in_full": 61902, + "open_in_new": 59550, + "open_in_new_down": 63247, + "open_in_new_off": 58614, + "open_in_phone": 59138, + "open_jam": 61358, + "open_run": 62647, + "open_with": 59551, + "ophthalmology": 57621, + "oral_disease": 57622, + "order_approve": 63506, + "order_play": 63505, + "orders": 60180, + "orthopedics": 63639, + "other_admission": 58491, + "other_houses": 58764, + "outbound": 57802, + "outbox": 61279, + "outbox_alt": 60183, + "outdoor_garden": 57861, + "outdoor_grill": 59975, + "outgoing_mail": 61650, + "outlet": 61908, + "outlined_flag": 61638, + "outpatient": 57624, + "outpatient_med": 57625, + "output": 60350, + "output_circle": 63246, + "oven": 59847, + "oven_gen": 59459, + "overview": 58535, + "overview_key": 63444, + "oxygen_saturation": 58590, + "p2p": 62762, + "pace": 63160, + "pacemaker": 58966, + "package": 58511, + "package_2": 62825, + "padding": 59848, + "page_control": 59185, + "page_info": 62996, + "pageless": 62729, + "pages": 59385, + "pageview": 59552, + "paid": 61505, + "palette": 58378, + "pallet": 63594, + "pan_tool": 59685, + "pan_tool_alt": 60345, + "pan_zoom": 63061, + "panorama": 58379, + "panorama_fish_eye": 58380, + "panorama_horizontal": 58381, + "panorama_photosphere": 59849, + "panorama_vertical": 58382, + "panorama_wide_angle": 58383, + "paragliding": 58639, + "park": 60003, + "partly_cloudy_day": 61810, + "partly_cloudy_night": 61812, + "partner_exchange": 63481, + "partner_reports": 61359, + "party_mode": 59386, + "passkey": 63615, + "password": 61506, + "password_2": 62633, + "password_2_off": 62632, + "patient_list": 58963, + "pattern": 61507, + "pause": 57396, + "pause_circle": 57762, + "pause_circle_filled": 57762, + "pause_circle_outline": 57762, + "pause_presentation": 57578, + "payment": 59553, + "payments": 61283, + "pedal_bike": 60201, + "pediatrics": 57629, + "pen_size_1": 63317, + "pen_size_2": 63316, + "pen_size_3": 63315, + "pen_size_4": 63314, + "pen_size_5": 63313, + "pending": 61284, + "pending_actions": 61883, + "pentagon": 60240, + "people": 59937, + "people_alt": 59937, + "people_outline": 59937, + "percent": 60248, + "performance_max": 58650, + "pergola": 57859, + "perm_camera_mic": 59554, + "perm_contact_calendar": 59555, + "perm_data_setting": 59556, + "perm_device_information": 59557, + "perm_identity": 61651, + "perm_media": 59559, + "perm_phone_msg": 59560, + "perm_scan_wifi": 59561, + "person": 61651, + "person_2": 63716, + "person_3": 63717, + "person_4": 63718, + "person_add": 59981, + "person_add_alt": 59981, + "person_add_disabled": 59851, + "person_alert": 62823, + "person_apron": 62883, + "person_book": 62952, + "person_cancel": 62822, + "person_celebrate": 63486, + "person_check": 62821, + "person_edit": 62714, + "person_filled": 61651, + "person_off": 58640, + "person_outline": 61651, + "person_pin": 58714, + "person_pin_circle": 58730, + "person_play": 63485, + "person_raised_hand": 62874, + "person_remove": 61286, + "person_search": 61702, + "personal_bag": 60174, + "personal_bag_off": 60175, + "personal_bag_question": 60176, + "personal_injury": 59098, + "personal_places": 59139, + "personal_video": 58939, + "pest_control": 61690, + "pest_control_rodent": 61693, + "pet_supplies": 61361, + "pets": 59677, + "phishing": 60119, + "phone": 61652, + "phone_alt": 61652, + "phone_android": 58148, + "phone_bluetooth_speaker": 58907, + "phone_callback": 58953, + "phone_disabled": 59852, + "phone_enabled": 59853, + "phone_forwarded": 58908, + "phone_in_talk": 58909, + "phone_iphone": 58149, + "phone_locked": 58910, + "phone_missed": 58911, + "phone_paused": 58912, + "phonelink": 58150, + "phonelink_erase": 57563, + "phonelink_lock": 57564, + "phonelink_off": 58151, + "phonelink_ring": 57565, + "phonelink_ring_off": 63402, + "phonelink_setup": 61249, + "photo": 58418, + "photo_album": 58385, + "photo_auto_merge": 62768, + "photo_camera": 58386, + "photo_camera_back": 61288, + "photo_camera_front": 61289, + "photo_filter": 58427, + "photo_frame": 61657, + "photo_library": 58387, + "photo_prints": 61362, + "photo_size_select_actual": 58418, + "photo_size_select_large": 58419, + "photo_size_select_small": 58420, + "php": 60303, + "physical_therapy": 57630, + "piano": 58657, + "piano_off": 58656, + "picture_as_pdf": 58389, + "picture_in_picture": 59562, + "picture_in_picture_alt": 59665, + "picture_in_picture_center": 62800, + "picture_in_picture_large": 62799, + "picture_in_picture_medium": 62798, + "picture_in_picture_mobile": 62743, + "picture_in_picture_off": 62767, + "picture_in_picture_small": 62797, + "pie_chart": 61658, + "pie_chart_filled": 61658, + "pie_chart_outline": 61658, + "pie_chart_outlined": 61658, + "pill": 57631, + "pill_off": 63497, + "pin": 61509, + "pin_drop": 58718, + "pin_end": 59239, + "pin_invoke": 59235, + "pinch": 60216, + "pinch_zoom_in": 61946, + "pinch_zoom_out": 61947, + "pip": 63053, + "pip_exit": 63245, + "pivot_table_chart": 59854, + "place": 61915, + "place_item": 61936, + "plagiarism": 59994, + "planner_banner_ad_pt": 59026, + "planner_review": 59028, + "play_arrow": 57399, + "play_circle": 57796, + "play_disabled": 61290, + "play_for_work": 59654, + "play_lesson": 61511, + "play_music": 59118, + "play_pause": 61751, + "play_shapes": 63484, + "playing_cards": 62940, + "playlist_add": 57403, + "playlist_add_check": 57445, + "playlist_add_check_circle": 59366, + "playlist_add_circle": 59365, + "playlist_play": 57439, + "playlist_remove": 60288, + "plumbing": 61703, + "plus_one": 59392, + "podcasts": 61512, + "podiatry": 57632, + "podium": 63483, + "point_of_sale": 61822, + "point_scan": 63244, + "poker_chip": 62619, + "policy": 59927, + "poll": 61644, + "polyline": 60347, + "polymer": 59563, + "pool": 60232, + "portable_wifi_off": 61575, + "portrait": 59473, + "position_bottom_left": 63243, + "position_bottom_right": 63242, + "position_top_right": 63241, + "post": 59141, + "post_add": 59936, + "potted_plant": 63658, + "power": 58940, + "power_input": 58166, + "power_off": 58950, + "power_rounded": 63687, + "power_settings_new": 63687, + "prayer_times": 63544, + "precision_manufacturing": 61513, + "pregnancy": 62961, + "pregnant_woman": 62961, + "preliminary": 59352, + "prescriptions": 57633, + "present_to_all": 57567, + "preview": 61893, + "preview_off": 63407, + "price_change": 61514, + "price_check": 61515, + "print": 59565, + "print_add": 63394, + "print_connect": 63393, + "print_disabled": 59855, + "print_error": 63392, + "print_lock": 63057, + "priority": 57759, + "priority_high": 58949, + "privacy": 61768, + "privacy_tip": 61660, + "private_connectivity": 59204, + "problem": 57634, + "procedure": 58961, + "process_chart": 63573, + "production_quantity_limits": 57809, + "productivity": 58006, + "progress_activity": 59856, + "prompt_suggestion": 62710, + "propane": 60436, + "propane_tank": 60435, + "psychiatry": 57635, + "psychology": 59978, + "psychology_alt": 63722, + "public": 59403, + "public_off": 61898, + "publish": 57941, + "published_with_changes": 62002, + "pulmonology": 57636, + "pulse_alert": 62721, + "punch_clock": 60072, + "push_pin": 61709, + "qr_code": 61291, + "qr_code_2": 57354, + "qr_code_2_add": 63064, + "qr_code_scanner": 61958, + "query_builder": 61398, + "query_stats": 58620, + "question_answer": 59567, + "question_exchange": 63475, + "question_mark": 60299, + "queue": 57404, + "queue_music": 57405, + "queue_play_next": 57446, + "quick_phrases": 59345, + "quick_reference": 58478, + "quick_reference_all": 63489, + "quick_reorder": 60181, + "quickreply": 61292, + "quiet_time": 57849, + "quiet_time_active": 58001, + "quiz": 61516, + "r_mobiledata": 61517, + "radar": 61518, + "radio": 57406, + "radio_button_checked": 59447, + "radio_button_partial": 62816, + "radio_button_unchecked": 59446, + "radiology": 57637, + "railway_alert": 59857, + "railway_alert_2": 62561, + "rainy": 61814, + "rainy_heavy": 63007, + "rainy_light": 63006, + "rainy_snow": 63005, + "ramen_dining": 60004, + "ramp_left": 60316, + "ramp_right": 60310, + "range_hood": 57834, + "rate_review": 58720, + "raven": 62805, + "raw_off": 61519, + "raw_on": 61520, + "read_more": 61293, + "readiness_score": 63197, + "real_estate_agent": 59194, + "rear_camera": 63170, + "rebase": 63557, + "rebase_edit": 63558, + "receipt": 59568, + "receipt_long": 61294, + "recent_actors": 57407, + "recent_patient": 63496, + "recenter": 62656, + "recommend": 59858, + "record_voice_over": 59679, + "rectangle": 60244, + "recycling": 59232, + "redeem": 59638, + "redo": 57690, + "reduce_capacity": 61980, + "refresh": 58837, + "regular_expression": 63312, + "relax": 63196, + "release_alert": 63060, + "remember_me": 61521, + "reminder": 59078, + "reminders_alt": 59078, + "remote_gen": 59454, + "remove": 57691, + "remove_circle": 61583, + "remove_circle_outline": 61583, + "remove_done": 59859, + "remove_from_queue": 57447, + "remove_moderator": 59860, + "remove_red_eye": 59636, + "remove_road": 60412, + "remove_selection": 59861, + "remove_shopping_cart": 59688, + "reopen_window": 63240, + "reorder": 59646, + "repartition": 63720, + "repeat": 57408, + "repeat_on": 59862, + "repeat_one": 57409, + "repeat_one_on": 59863, + "replay": 57410, + "replay_10": 57433, + "replay_30": 57434, + "replay_5": 57435, + "replay_circle_filled": 59864, + "reply": 57694, + "reply_all": 57695, + "report": 61522, + "report_gmailerrorred": 61522, + "report_off": 57712, + "report_problem": 61571, + "request_page": 61996, + "request_quote": 61878, + "reset_brightness": 62594, + "reset_focus": 62593, + "reset_image": 63524, + "reset_iso": 62592, + "reset_settings": 62591, + "reset_shadow": 62590, + "reset_shutter_speed": 62589, + "reset_tv": 59865, + "reset_white_balance": 62588, + "reset_wrench": 62828, + "resize": 63239, + "respiratory_rate": 57639, + "responsive_layout": 59866, + "restart_alt": 61523, + "restaurant": 58732, + "restaurant_menu": 58721, + "restore": 59571, + "restore_from_trash": 59704, + "restore_page": 59689, + "resume": 63440, + "reviews": 61564, + "rewarded_ads": 61366, + "rheumatology": 57640, + "rib_cage": 63640, + "rice_bowl": 61941, + "right_click": 63238, + "right_panel_close": 63237, + "right_panel_open": 63236, + "ring_volume": 61661, + "ring_volume_filled": 61661, + "ripples": 59867, + "road": 62578, + "robot": 63618, + "robot_2": 62928, + "rocket": 60325, + "rocket_launch": 60315, + "roller_shades": 60434, + "roller_shades_closed": 60433, + "roller_skating": 60365, + "roofing": 61953, + "room": 61915, + "room_preferences": 61880, + "room_service": 60233, + "rotate_90_degrees_ccw": 58392, + "rotate_90_degrees_cw": 60075, + "rotate_left": 58393, + "rotate_right": 58394, + "roundabout_left": 60313, + "roundabout_right": 60323, + "rounded_corner": 59680, + "route": 60109, + "router": 58152, + "routine": 57868, + "rowing": 59681, + "rss_feed": 57573, + "rsvp": 61525, + "rtt": 59821, + "rubric": 60199, + "rule": 61890, + "rule_folder": 61897, + "rule_settings": 63052, + "run_circle": 61295, + "running_with_errors": 58653, + "rv_hookup": 58946, + "safety_check": 60399, + "safety_check_off": 62877, + "safety_divider": 57804, + "sailing": 58626, + "salinity": 63606, + "sanitizer": 61981, + "satellite": 58722, + "satellite_alt": 60218, + "sauna": 63223, + "save": 57697, + "save_alt": 61584, + "save_as": 60256, + "saved_search": 59921, + "savings": 58091, + "scale": 60255, + "scan": 63310, + "scan_delete": 63311, + "scanner": 58153, + "scatter_plot": 57960, + "scene": 58023, + "schedule": 61398, + "schedule_send": 59914, + "schema": 58621, + "school": 59404, + "science": 59979, + "science_off": 62786, + "scooter": 62577, + "score": 57961, + "scoreboard": 60368, + "screen_lock_landscape": 57790, + "screen_lock_portrait": 57791, + "screen_lock_rotation": 57792, + "screen_record": 63097, + "screen_rotation": 57793, + "screen_rotation_alt": 60398, + "screen_rotation_up": 63096, + "screen_search_desktop": 61296, + "screen_share": 57570, + "screenshot": 61526, + "screenshot_frame": 63095, + "screenshot_keyboard": 63443, + "screenshot_monitor": 60424, + "screenshot_region": 63442, + "screenshot_tablet": 63127, + "script": 62559, + "scrollable_header": 59868, + "scuba_diving": 60366, + "sd": 59869, + "sd_card": 58915, + "sd_card_alert": 61527, + "sd_storage": 58915, + "sdk": 59168, + "search": 59574, + "search_check": 63488, + "search_check_2": 62569, + "search_hands_free": 59030, + "search_insights": 62652, + "search_off": 60022, + "security": 58154, + "security_key": 62723, + "security_update": 61554, + "security_update_good": 61555, + "security_update_warning": 61556, + "segment": 59723, + "select": 63309, + "select_all": 57698, + "select_check_box": 61950, + "select_to_speak": 63439, + "select_window": 59130, + "select_window_2": 62664, + "select_window_off": 58630, + "self_care": 63597, + "self_improvement": 60024, + "sell": 61531, + "send": 57699, + "send_and_archive": 59916, + "send_money": 59575, + "send_time_extension": 60123, + "send_to_mobile": 61532, + "sensor_door": 61877, + "sensor_occupied": 60432, + "sensor_window": 61876, + "sensors": 58654, + "sensors_krx": 62806, + "sensors_krx_off": 62741, + "sensors_off": 58655, + "sentiment_calm": 63143, + "sentiment_content": 63142, + "sentiment_dissatisfied": 59409, + "sentiment_excited": 63141, + "sentiment_extremely_dissatisfied": 61844, + "sentiment_frustrated": 63140, + "sentiment_neutral": 59410, + "sentiment_sad": 63139, + "sentiment_satisfied": 59411, + "sentiment_satisfied_alt": 59411, + "sentiment_stressed": 63138, + "sentiment_very_dissatisfied": 59412, + "sentiment_very_satisfied": 59413, + "sentiment_worried": 63137, + "serif": 62636, + "service_toolbox": 59159, + "set_meal": 61930, + "settings": 59576, + "settings_accessibility": 61533, + "settings_account_box": 63541, + "settings_alert": 61763, + "settings_applications": 59577, + "settings_b_roll": 63013, + "settings_backup_restore": 59578, + "settings_bluetooth": 59579, + "settings_brightness": 59581, + "settings_cell": 59580, + "settings_cinematic_blur": 63012, + "settings_ethernet": 59582, + "settings_heart": 62754, + "settings_input_antenna": 59583, + "settings_input_component": 59585, + "settings_input_composite": 59585, + "settings_input_hdmi": 59586, + "settings_input_svideo": 59587, + "settings_motion_mode": 63539, + "settings_night_sight": 63538, + "settings_overscan": 59588, + "settings_panorama": 63537, + "settings_phone": 59589, + "settings_photo_camera": 63540, + "settings_power": 59590, + "settings_remote": 59591, + "settings_slow_motion": 63011, + "settings_suggest": 61534, + "settings_system_daydream": 57795, + "settings_timelapse": 63010, + "settings_video_camera": 63009, + "settings_voice": 59592, + "settop_component": 58028, + "severe_cold": 60371, + "shadow": 59871, + "shadow_add": 62852, + "shadow_minus": 62851, + "shape_line": 63699, + "shape_recognition": 60161, + "shapes": 58882, + "share": 59405, + "share_location": 61535, + "share_off": 63179, + "share_reviews": 63652, + "share_windows": 62995, + "sheets_rtl": 63523, + "shelf_auto_hide": 63235, + "shelf_position": 63234, + "shelves": 63598, + "shield": 59872, + "shield_lock": 63110, + "shield_locked": 62866, + "shield_moon": 60073, + "shield_person": 63056, + "shield_question": 62761, + "shield_with_heart": 59279, + "shield_with_house": 59277, + "shift": 58866, + "shift_lock": 63406, + "shift_lock_off": 62595, + "shop": 59593, + "shop_2": 59594, + "shop_two": 59594, + "shopping_bag": 61900, + "shopping_basket": 59595, + "shopping_cart": 59596, + "shopping_cart_checkout": 60296, + "shopping_cart_off": 62711, + "shoppingmode": 61367, + "short_stay": 58576, + "short_text": 57953, + "shortcut": 62842, + "show_chart": 59105, + "shower": 61537, + "shuffle": 57411, + "shuffle_on": 59873, + "shutter_speed": 58429, + "shutter_speed_add": 62846, + "shutter_speed_minus": 62845, + "sick": 61984, + "side_navigation": 59874, + "sign_language": 60389, + "signal_cellular_0_bar": 61608, + "signal_cellular_1_bar": 61609, + "signal_cellular_2_bar": 61610, + "signal_cellular_3_bar": 61611, + "signal_cellular_4_bar": 57800, + "signal_cellular_add": 63401, + "signal_cellular_alt": 57858, + "signal_cellular_alt_1_bar": 60383, + "signal_cellular_alt_2_bar": 60387, + "signal_cellular_connected_no_internet_0_bar": 61612, + "signal_cellular_connected_no_internet_4_bar": 57805, + "signal_cellular_no_sim": 57806, + "signal_cellular_nodata": 61538, + "signal_cellular_null": 57807, + "signal_cellular_off": 57808, + "signal_cellular_pause": 62887, + "signal_disconnected": 62009, + "signal_wifi_0_bar": 61616, + "signal_wifi_4_bar": 61541, + "signal_wifi_4_bar_lock": 57825, + "signal_wifi_bad": 61540, + "signal_wifi_connected_no_internet_4": 61540, + "signal_wifi_off": 57818, + "signal_wifi_statusbar_4_bar": 61541, + "signal_wifi_statusbar_not_connected": 61679, + "signal_wifi_statusbar_null": 61543, + "signature": 63308, + "signpost": 60305, + "sim_card": 58155, + "sim_card_alert": 61527, + "sim_card_download": 61544, + "single_bed": 59976, + "sip": 61545, + "skateboarding": 58641, + "skeleton": 63641, + "skillet": 62787, + "skillet_cooktop": 62788, + "skip_next": 57412, + "skip_previous": 57413, + "skull": 63642, + "slab_serif": 62635, + "sledding": 58642, + "sleep": 57875, + "sleep_score": 63159, + "slide_library": 63522, + "sliders": 59875, + "slideshow": 58395, + "slow_motion_video": 57448, + "smart_button": 61889, + "smart_card_reader": 62629, + "smart_card_reader_off": 62630, + "smart_display": 61546, + "smart_outlet": 59460, + "smart_screen": 61547, + "smart_toy": 61548, + "smartphone": 58156, + "smb_share": 63307, + "smoke_free": 60234, + "smoking_rooms": 60235, + "sms": 58917, + "sms_failed": 59519, + "snippet_folder": 61895, + "snooze": 57414, + "snowboarding": 58643, + "snowing": 59407, + "snowing_heavy": 63004, + "snowmobile": 58627, + "snowshoeing": 58644, + "soap": 61874, + "social_distance": 57803, + "social_leaderboard": 63136, + "solar_power": 60431, + "sort": 57700, + "sort_by_alpha": 57427, + "sos": 60407, + "sound_detection_dog_barking": 61769, + "sound_detection_glass_break": 61770, + "sound_detection_loud_sound": 61771, + "sound_sampler": 63156, + "soup_kitchen": 59347, + "source": 61896, + "source_environment": 58663, + "source_notes": 57645, + "south": 61923, + "south_america": 59364, + "south_east": 61924, + "south_west": 61925, + "spa": 60236, + "space_bar": 57942, + "space_dashboard": 58987, + "spatial_audio": 60395, + "spatial_audio_off": 60392, + "spatial_speaker": 62671, + "spatial_tracking": 60394, + "speaker": 58157, + "speaker_group": 58158, + "speaker_notes": 59597, + "speaker_notes_off": 59690, + "speaker_phone": 57554, + "special_character": 63306, + "specific_gravity": 63602, + "speech_to_text": 63655, + "speed": 59876, + "speed_0_25": 62676, + "speed_0_2x": 62616, + "speed_0_5": 62690, + "speed_0_5x": 62615, + "speed_0_75": 62675, + "speed_0_7x": 62614, + "speed_1_2": 62689, + "speed_1_25": 62674, + "speed_1_2x": 62613, + "speed_1_5": 62688, + "speed_1_5x": 62612, + "speed_1_75": 62673, + "speed_1_7x": 62611, + "speed_2x": 62699, + "speed_camera": 62576, + "spellcheck": 59598, + "splitscreen": 61549, + "splitscreen_add": 62717, + "splitscreen_bottom": 63094, + "splitscreen_landscape": 62553, + "splitscreen_left": 63093, + "splitscreen_portrait": 62552, + "splitscreen_right": 63092, + "splitscreen_top": 63091, + "splitscreen_vertical_add": 62716, + "spo2": 63195, + "spoke": 59815, + "sports": 59952, + "sports_and_outdoors": 61368, + "sports_bar": 61939, + "sports_baseball": 59985, + "sports_basketball": 59942, + "sports_cricket": 59943, + "sports_esports": 59944, + "sports_football": 59945, + "sports_golf": 59946, + "sports_gymnastics": 60356, + "sports_handball": 59955, + "sports_hockey": 59947, + "sports_kabaddi": 59956, + "sports_martial_arts": 60137, + "sports_mma": 59948, + "sports_motorsports": 59949, + "sports_rugby": 59950, + "sports_score": 61550, + "sports_soccer": 59951, + "sports_tennis": 59954, + "sports_volleyball": 59953, + "sprinkler": 58010, + "sprint": 63519, + "square": 60214, + "square_foot": 59977, + "ssid_chart": 60262, + "stack": 62985, + "stack_off": 62984, + "stack_star": 62983, + "stacked_bar_chart": 59878, + "stacked_email": 59079, + "stacked_inbox": 59081, + "stacked_line_chart": 61995, + "stacks": 62720, + "stadia_controller": 61749, + "stadium": 60304, + "stairs": 61865, + "stairs_2": 62572, + "star": 61594, + "star_border": 61594, + "star_border_purple500": 61594, + "star_half": 59449, + "star_outline": 61594, + "star_purple500": 61594, + "star_rate": 61676, + "star_rate_half": 60485, + "stars": 59600, + "start": 57481, + "stat_0": 59031, + "stat_1": 59032, + "stat_2": 59033, + "stat_3": 59034, + "stat_minus_1": 59035, + "stat_minus_2": 59036, + "stat_minus_3": 59037, + "stay_current_landscape": 57555, + "stay_current_portrait": 57556, + "stay_primary_landscape": 57557, + "stay_primary_portrait": 57558, + "step": 63230, + "step_into": 63233, + "step_out": 63232, + "step_over": 63231, + "steppers": 59879, + "steps": 63194, + "stethoscope": 63493, + "stethoscope_arrow": 63495, + "stethoscope_check": 63494, + "sticky_note": 59880, + "sticky_note_2": 61948, + "stock_media": 62832, + "stockpot": 62789, + "stop": 57415, + "stop_circle": 61297, + "stop_screen_share": 57571, + "storage": 57819, + "store": 59601, + "store_mall_directory": 59601, + "storefront": 59922, + "storm": 61552, + "straight": 60309, + "straighten": 58396, + "strategy": 62943, + "stream": 59881, + "stream_apps": 63391, + "streetview": 58734, + "stress_management": 63193, + "strikethrough_s": 57943, + "stroke_full": 63305, + "stroke_partial": 63304, + "stroller": 61870, + "style": 58397, + "styler": 57971, + "stylus": 62980, + "stylus_laser_pointer": 63303, + "stylus_note": 62979, + "subdirectory_arrow_left": 58841, + "subdirectory_arrow_right": 58842, + "subheader": 59882, + "subject": 59602, + "subscript": 61713, + "subscriptions": 57444, + "subtitles": 57416, + "subtitles_off": 61298, + "subway": 58735, + "summarize": 61553, + "sunny": 59418, + "sunny_snowing": 59417, + "superscript": 61714, + "supervised_user_circle": 59705, + "supervised_user_circle_off": 62990, + "supervisor_account": 59603, + "support": 61299, + "support_agent": 61666, + "surfing": 58645, + "surgical": 57649, + "surround_sound": 57417, + "swap_calls": 57559, + "swap_driving_apps": 59038, + "swap_driving_apps_wheel": 59039, + "swap_horiz": 59604, + "swap_horizontal_circle": 59699, + "swap_vert": 59605, + "swap_vertical_circle": 59606, + "sweep": 59052, + "swipe": 59884, + "swipe_down": 60243, + "swipe_down_alt": 60208, + "swipe_left": 60249, + "swipe_left_alt": 60211, + "swipe_right": 60242, + "swipe_right_alt": 60246, + "swipe_up": 60206, + "swipe_up_alt": 60213, + "swipe_vertical": 60241, + "switch": 57844, + "switch_access": 63229, + "switch_access_2": 62726, + "switch_access_shortcut": 59361, + "switch_access_shortcut_add": 59362, + "switch_account": 59885, + "switch_camera": 58398, + "switch_left": 61905, + "switch_right": 61906, + "switch_video": 58399, + "switches": 59187, + "sword_rose": 62942, + "swords": 63625, + "symptoms": 57650, + "synagogue": 60080, + "sync": 58919, + "sync_alt": 59928, + "sync_disabled": 58920, + "sync_lock": 60142, + "sync_problem": 58921, + "sync_saved_locally": 63520, + "syringe": 57651, + "system_security_update": 61554, + "system_security_update_good": 61555, + "system_security_update_warning": 61556, + "system_update": 61554, + "system_update_alt": 59607, + "tab": 59608, + "tab_close": 63301, + "tab_close_right": 63302, + "tab_duplicate": 63300, + "tab_group": 63299, + "tab_move": 63298, + "tab_new_right": 63297, + "tab_recent": 63296, + "tab_unselected": 59609, + "table": 61841, + "table_bar": 60114, + "table_chart": 57957, + "table_chart_view": 63215, + "table_eye": 62566, + "table_lamp": 57842, + "table_restaurant": 60102, + "table_rows": 61697, + "table_rows_narrow": 63295, + "table_view": 61886, + "tablet": 58159, + "tablet_android": 58160, + "tablet_mac": 58161, + "tabs": 59886, + "tactic": 62820, + "tag": 59887, + "tag_faces": 59938, + "takeout_dining": 60020, + "tamper_detection_off": 59438, + "tamper_detection_on": 63688, + "tap_and_play": 58923, + "tapas": 61929, + "target": 59161, + "task": 61557, + "task_alt": 58086, + "taunt": 63135, + "taxi_alert": 61300, + "team_dashboard": 57363, + "temp_preferences_custom": 63689, + "temp_preferences_eco": 63690, + "temple_buddhist": 60083, + "temple_hindu": 60079, + "tenancy": 61667, + "terminal": 60302, + "terrain": 58724, + "text_ad": 59176, + "text_decrease": 60125, + "text_fields": 57954, + "text_fields_alt": 59889, + "text_format": 57701, + "text_increase": 60130, + "text_rotate_up": 59706, + "text_rotate_vertical": 59707, + "text_rotation_angledown": 59708, + "text_rotation_angleup": 59709, + "text_rotation_down": 59710, + "text_rotation_none": 59711, + "text_select_end": 63294, + "text_select_jump_to_beginning": 63293, + "text_select_jump_to_end": 63292, + "text_select_move_back_character": 63291, + "text_select_move_back_word": 63290, + "text_select_move_down": 63289, + "text_select_move_forward_character": 63288, + "text_select_move_forward_word": 63287, + "text_select_move_up": 63286, + "text_select_start": 63285, + "text_snippet": 61894, + "text_to_speech": 61884, + "text_up": 62622, + "textsms": 58917, + "texture": 58401, + "texture_add": 62844, + "texture_minus": 62843, + "theater_comedy": 60006, + "theaters": 59610, + "thermometer": 59462, + "thermometer_add": 62850, + "thermometer_gain": 63192, + "thermometer_loss": 63191, + "thermometer_minus": 62849, + "thermostat": 61558, + "thermostat_auto": 61559, + "thermostat_carbon": 61816, + "things_to_do": 60202, + "thread_unread": 62713, + "thumb_down": 62840, + "thumb_down_alt": 62840, + "thumb_down_filled": 62840, + "thumb_down_off": 62840, + "thumb_down_off_alt": 62840, + "thumb_up": 62839, + "thumb_up_alt": 62839, + "thumb_up_filled": 62839, + "thumb_up_off": 62839, + "thumb_up_off_alt": 62839, + "thumbnail_bar": 63284, + "thumbs_up_down": 59613, + "thunderstorm": 60379, + "tibia": 63643, + "tibia_alt": 63644, + "time_auto": 61668, + "time_to_leave": 61431, + "timelapse": 58402, + "timeline": 59682, + "timer": 58405, + "timer_10": 58403, + "timer_10_alt_1": 61375, + "timer_10_select": 61562, + "timer_3": 58404, + "timer_3_alt_1": 61376, + "timer_3_select": 61563, + "timer_5": 62641, + "timer_5_shutter": 62642, + "timer_off": 58406, + "timer_pause": 62651, + "timer_play": 62650, + "tips_and_updates": 59290, + "tire_repair": 60360, + "title": 57956, + "titlecase": 62601, + "toast": 61377, + "toc": 59614, + "today": 59615, + "toggle_off": 59893, + "toggle_on": 59894, + "token": 59941, + "toll": 59616, + "tonality": 58407, + "toolbar": 59895, + "tools_flat_head": 63691, + "tools_installation_kit": 58027, + "tools_ladder": 58059, + "tools_level": 59259, + "tools_phillips": 63692, + "tools_pliers_wire_stripper": 58026, + "tools_power_drill": 57833, + "tools_wrench": 63693, + "tooltip": 59896, + "top_panel_close": 63283, + "top_panel_open": 63282, + "topic": 61896, + "tornado": 57753, + "total_dissolved_solids": 63607, + "touch_app": 59667, + "touchpad_mouse": 63111, + "touchpad_mouse_off": 62694, + "tour": 61301, + "toys": 58162, + "toys_and_games": 61378, + "toys_fan": 63623, + "track_changes": 59617, + "trackpad_input": 62663, + "traffic": 58725, + "traffic_jam": 62575, + "trail_length": 60254, + "trail_length_medium": 60259, + "trail_length_short": 60269, + "train": 58736, + "tram": 58737, + "transcribe": 63724, + "transfer_within_a_station": 58738, + "transform": 58408, + "transgender": 58765, + "transit_enterexit": 58745, + "transition_chop": 62734, + "transition_dissolve": 62733, + "transition_fade": 62732, + "transition_push": 62731, + "transition_slide": 62730, + "translate": 59618, + "transportation": 57885, + "travel": 61331, + "travel_explore": 58075, + "travel_luggage_and_bags": 61379, + "trending_down": 59619, + "trending_flat": 59620, + "trending_up": 59621, + "trip": 59131, + "trip_origin": 58747, + "trolley": 63595, + "trolley_cable_car": 62574, + "trophy": 59939, + "troubleshoot": 57810, + "try": 61564, + "tsunami": 60376, + "tsv": 59094, + "tty": 61866, + "tune": 58409, + "tungsten": 61565, + "turn_left": 60326, + "turn_right": 60331, + "turn_sharp_left": 60327, + "turn_sharp_right": 60330, + "turn_slight_left": 60324, + "turn_slight_right": 60314, + "turned_in": 59623, + "turned_in_not": 59623, + "tv": 58939, + "tv_gen": 59440, + "tv_guide": 57820, + "tv_off": 58951, + "tv_options_edit_channels": 57821, + "tv_options_input_settings": 57822, + "tv_remote": 62937, + "tv_signin": 59163, + "tv_with_assistant": 59269, + "two_pager": 62751, + "two_wheeler": 59897, + "type_specimen": 63728, + "u_turn_left": 60321, + "u_turn_right": 60322, + "ulna_radius": 63645, + "ulna_radius_alt": 63646, + "umbrella": 61869, + "unarchive": 57705, + "undo": 57702, + "unfold_less": 58838, + "unfold_less_double": 63695, + "unfold_more": 58839, + "unfold_more_double": 63696, + "ungroup": 63281, + "universal_currency": 59898, + "universal_currency_alt": 59188, + "universal_local": 59899, + "unknown_2": 62623, + "unknown_5": 59045, + "unknown_7": 62622, + "unknown_document": 63492, + "unknown_med": 60093, + "unlicense": 60165, + "unpaved_road": 62573, + "unpin": 59129, + "unpublished": 62006, + "unsubscribe": 57579, + "upcoming": 61566, + "update": 59683, + "update_disabled": 57461, + "upgrade": 61691, + "upload": 61595, + "upload_2": 62753, + "upload_file": 59900, + "uppercase": 62600, + "urology": 57655, + "usb": 57824, + "usb_off": 58618, + "user_attributes": 59144, + "vaccines": 57656, + "vacuum": 61381, + "valve": 57892, + "vape_free": 60358, + "vaping_rooms": 60367, + "variable_add": 62750, + "variable_insert": 62749, + "variable_remove": 62748, + "variables": 63569, + "ventilator": 57657, + "verified": 61302, + "verified_user": 61459, + "vertical_align_bottom": 57944, + "vertical_align_center": 57945, + "vertical_align_top": 57946, + "vertical_distribute": 57462, + "vertical_shades": 60430, + "vertical_shades_closed": 60429, + "vertical_split": 59721, + "vibration": 58925, + "video_call": 57456, + "video_camera_back": 61567, + "video_camera_front": 61568, + "video_camera_front_off": 63547, + "video_chat": 63648, + "video_file": 60295, + "video_label": 57457, + "video_library": 57418, + "video_search": 61382, + "video_settings": 60021, + "video_stable": 61569, + "videocam": 57419, + "videocam_off": 57420, + "videogame_asset": 58168, + "videogame_asset_off": 58624, + "view_agenda": 59625, + "view_array": 59626, + "view_carousel": 59627, + "view_column": 59628, + "view_column_2": 63559, + "view_comfy": 58410, + "view_comfy_alt": 60275, + "view_compact": 58411, + "view_compact_alt": 60276, + "view_cozy": 60277, + "view_day": 59629, + "view_headline": 59630, + "view_in_ar": 61385, + "view_in_ar_new": 61385, + "view_in_ar_off": 63003, + "view_kanban": 60287, + "view_list": 59631, + "view_module": 59632, + "view_quilt": 59633, + "view_real_size": 62658, + "view_sidebar": 61716, + "view_stream": 59634, + "view_timeline": 60293, + "view_week": 59635, + "vignette": 58421, + "villa": 58758, + "visibility": 59636, + "visibility_lock": 63059, + "visibility_off": 59637, + "vital_signs": 58960, + "vitals": 57659, + "vo2_max": 62634, + "voice_chat": 58926, + "voice_over_off": 59722, + "voice_selection": 62858, + "voicemail": 57561, + "volcano": 60378, + "volume_down": 57421, + "volume_down_alt": 59292, + "volume_mute": 57422, + "volume_off": 57423, + "volume_up": 57424, + "volunteer_activism": 60016, + "voting_chip": 63570, + "vpn_key": 57562, + "vpn_key_alert": 63180, + "vpn_key_off": 60282, + "vpn_lock": 58927, + "vr180_create2d": 61386, + "vr180_create2d_off": 62833, + "vrpano": 61570, + "wall_art": 61387, + "wall_lamp": 58036, + "wallet": 63743, + "wallpaper": 57788, + "wallpaper_slideshow": 63090, + "ward": 57660, + "warehouse": 60344, + "warning": 61571, + "warning_amber": 61571, + "warning_off": 63405, + "wash": 61873, + "watch": 58164, + "watch_button_press": 63146, + "watch_check": 62568, + "watch_later": 61398, + "watch_off": 60131, + "watch_screentime": 63150, + "watch_vibration": 62567, + "watch_wake": 63145, + "water": 61572, + "water_bottle": 63133, + "water_bottle_large": 63134, + "water_damage": 61955, + "water_do": 63600, + "water_drop": 59288, + "water_ec": 63605, + "water_full": 63190, + "water_heater": 57988, + "water_lock": 63149, + "water_loss": 63189, + "water_lux": 63604, + "water_medium": 63188, + "water_orp": 63608, + "water_ph": 63610, + "water_pump": 62936, + "water_voc": 63611, + "waterfall_chart": 59904, + "waves": 57718, + "waving_hand": 59238, + "wb_auto": 58412, + "wb_cloudy": 61788, + "wb_incandescent": 58414, + "wb_iridescent": 61565, + "wb_shade": 59905, + "wb_sunny": 58416, + "wb_twilight": 57798, + "wc": 58941, + "weather_hail": 63103, + "weather_mix": 62987, + "weather_snowy": 58061, + "web": 57425, + "web_asset": 57449, + "web_asset_off": 61255, + "web_stories": 58773, + "web_traffic": 59907, + "webhook": 60306, + "weekend": 57707, + "weight": 57661, + "west": 61926, + "whatshot": 59406, + "wheelchair_pickup": 61867, + "where_to_vote": 57719, + "widgets": 57789, + "width": 63280, + "width_full": 63733, + "width_normal": 63734, + "width_wide": 63735, + "wifi": 58942, + "wifi_1_bar": 58570, + "wifi_2_bar": 58585, + "wifi_add": 63400, + "wifi_calling": 61303, + "wifi_calling_1": 61671, + "wifi_calling_2": 61686, + "wifi_calling_3": 61671, + "wifi_channel": 60266, + "wifi_find": 60209, + "wifi_home": 63089, + "wifi_lock": 57825, + "wifi_notification": 63088, + "wifi_off": 58952, + "wifi_password": 60267, + "wifi_protected_setup": 61692, + "wifi_proxy": 63399, + "wifi_tethering": 57826, + "wifi_tethering_error": 60121, + "wifi_tethering_off": 61575, + "wind_power": 60428, + "window": 61576, + "window_closed": 59262, + "window_open": 59276, + "window_sensor": 58043, + "wine_bar": 61928, + "woman": 57662, + "woman_2": 63719, + "work": 59715, + "work_alert": 62967, + "work_history": 60425, + "work_off": 59714, + "work_outline": 59715, + "work_update": 62968, + "workflow": 59908, + "workspace_premium": 59311, + "workspaces": 59919, + "workspaces_outline": 59919, + "wounds_injuries": 57663, + "wrap_text": 57947, + "wrist": 63132, + "wrong_location": 61304, + "wysiwyg": 61891, + "yard": 61577, + "your_trips": 60203, + "youtube_activity": 63578, + "youtube_searched_for": 59642, + "zone_person_alert": 59265, + "zone_person_idle": 59258, + "zone_person_urgent": 59272, + "zoom_in": 59647, + "zoom_in_map": 60205, + "zoom_out": 59648, + "zoom_out_map": 58731 +} \ No newline at end of file diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.ttf b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.ttf new file mode 100644 index 0000000000..255db6f479 Binary files /dev/null and b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined.ttf differ diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/resources/__init__.py b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/__init__.py new file mode 100644 index 0000000000..6da4c6986b --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/resources/__init__.py @@ -0,0 +1,16 @@ +import os +from typing import Optional + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) + + +def get_font_filepath( + font_name: Optional[str] = "MaterialSymbolsOutlined" +) -> str: + return os.path.join(CURRENT_DIR, f"{font_name}.ttf") + + +def get_mapping_filepath( + font_name: Optional[str] = "MaterialSymbolsOutlined" +) -> str: + return os.path.join(CURRENT_DIR, f"{font_name}.json") diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/structures.py b/client/ayon_core/vendor/python/qtmaterialsymbols/structures.py new file mode 100644 index 0000000000..e2b9d9c1d6 --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/structures.py @@ -0,0 +1,221 @@ +import collections +import json +from typing import Optional, Union + +from qtpy import QtGui + +from .utils import get_icon_name_char + +Position = collections.namedtuple("Offset", ["x", "y"]) + + +class IconSubOption: + def __init__( + self, + on_normal, + on_disabled=None, + on_active=None, + on_selected=None, + off_normal=None, + off_disabled=None, + off_active=None, + off_selected=None, + ): + if off_normal is None: + off_normal = on_normal + + if on_disabled is None: + on_disabled = on_normal + if off_disabled is None: + off_disabled = on_disabled + + if on_active is None: + on_active = on_normal + if off_active is None: + off_active = on_active + + if on_selected is None: + on_selected = on_normal + if off_selected is None: + off_selected = on_selected + + self._identifier = None + self.on_normal = on_normal + self.on_disabled = on_disabled + self.on_active = on_active + self.on_selected = on_selected + self.off_normal = off_normal + self.off_disabled = off_disabled + self.off_active = off_active + self.off_selected = off_selected + + @property + def identifier(self): + if self._identifier is None: + self._identifier = self._generate_identifier() + return self._identifier + + def get_value_for_state(self, state, mode): + if state == QtGui.QIcon.On: + if mode == QtGui.QIcon.Disabled: + return self.on_disabled + if mode == QtGui.QIcon.Active: + return self.on_active + if mode == QtGui.QIcon.Selected: + return self.on_selected + return self.on_normal + + if mode == QtGui.QIcon.Disabled: + return self.off_disabled + if mode == QtGui.QIcon.Active: + return self.off_active + if mode == QtGui.QIcon.Selected: + return self.off_selected + return self.off_normal + + def _generate_identifier(self): + prev_value = None + values = [] + for value in ( + self.on_normal, + self.off_normal, + self.on_active, + self.off_active, + self.on_selected, + self.off_selected, + self.on_disabled, + self.off_disabled, + ): + id_value = "" + if value != prev_value: + id_value = self._get_value_id(value) + values.append(id_value) + prev_value = value + + return "|".join(values) + + def _get_value_id(self, value): + if isinstance(value, QtGui.QColor): + return value.name() + return str(value) + + +def _prepare_mapping(option_name): + mapping = [] + for store_key, alternative_keys in ( + ("on_normal", ["normal", "on", ""]), + ("off_normal", ["off"]), + ("on_active", ["active"]), + ("off_active", []), + ("on_selected", ["selected"]), + ("off_selected", []), + ("on_disabled", ["disabled"]), + ("off_disabled", []), + ): + mapping_keys = [f"{option_name}_{store_key}"] + for alt_key in alternative_keys: + key = option_name + if alt_key: + key = f"{option_name}_{alt_key}" + mapping_keys.append(key) + mapping.append((store_key, mapping_keys)) + return mapping + + +class IconOptions: + mapping_color_keys = _prepare_mapping("color") + mapping_name_keys = _prepare_mapping("icon_name") + data_keys = { + "opacity", + "offset", + "scale_factor", + "hflip", + "vflip", + "rotate", + } + + def __init__( + self, + char_option: IconSubOption, + color_option: IconSubOption, + opacity: Optional[float] = None, + scale_factor: Optional[float] = None, + offset: Optional[Position] = None, + hflip: Optional[bool] = False, + vflip: Optional[bool] = False, + rotate: Optional[int] = 0, + ): + if opacity is None: + opacity = 1.0 + if scale_factor is None: + scale_factor = 1.0 + + self._identifier = None + self.char_option = char_option + self.color_option = color_option + self.opacity = opacity + self.scale_factor = scale_factor + self.offset = offset + self.hflip = hflip + self.vflip = vflip + self.rotate = rotate + + @property + def identifier(self): + if self._identifier is None: + self._identifier = self._generate_identifier() + return self._identifier + + def get_color_for_state(self, state, mode) -> QtGui.QColor: + return self.color_option.get_value_for_state(state, mode) + + def get_char_for_state(self, state, mode) -> str: + return self.char_option.get_value_for_state(state, mode) + + @classmethod + def from_data(cls, **kwargs): + new_kwargs = { + key: value + for key, value in kwargs.items() + if key in cls.data_keys and value is not None + } + color_kwargs = cls._prepare_mapping_values( + cls.mapping_color_keys, kwargs + ) + name_kwargs = cls._prepare_mapping_values( + cls.mapping_name_keys, kwargs + ) + char_kwargs = { + key: get_icon_name_char(value) + for key, value in name_kwargs.items() + } + + new_kwargs["color_option"] = IconSubOption(**color_kwargs) + new_kwargs["char_option"] = IconSubOption(**char_kwargs) + return cls(**new_kwargs) + + @classmethod + def _prepare_mapping_values(cls, mapping, kwargs): + mapping_values = {} + for store_key, mapping_keys in mapping: + for key in mapping_keys: + value = kwargs.pop(key, None) + if value is not None: + mapping_values[store_key] = value + break + return mapping_values + + def _generate_identifier(self): + return ( + str(value) + for value in ( + self.char_option.identifier, + self.color_option.identifier, + self.opacity, + self.scale_factor, + self.offset, + self.hflip, + self.vflip, + self.rotate, + ) + ) diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/utils.py b/client/ayon_core/vendor/python/qtmaterialsymbols/utils.py new file mode 100644 index 0000000000..06fbd46573 --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/utils.py @@ -0,0 +1,69 @@ +import json +import copy +from typing import Dict, Union + +from qtpy import QtWidgets, QtGui, QtCore + +from .exceptions import ApplicationNotRunning, FontError +from .resources import get_mapping_filepath, get_font_filepath + + +class _Cache: + mapping = None + font_id = None + font_name = None + + +def _load_font(): + if QtWidgets.QApplication.instance() is None: + raise ApplicationNotRunning("No QApplication instance found.") + + if _Cache.font_id is not None: + loaded_font_families = QtGui.QFontDatabase.applicationFontFamilies( + _Cache.font_id + ) + if loaded_font_families: + return + + filepath = get_font_filepath() + with open(filepath, "rb") as font_data: + font_id = QtGui.QFontDatabase.addApplicationFontFromData( + QtCore.QByteArray(font_data.read()) + ) + + loaded_font_families = QtGui.QFontDatabase.applicationFontFamilies( + font_id + ) + if not loaded_font_families: + raise FontError("Failed to load font.") + + _Cache.font_id = font_id + _Cache.font_name = loaded_font_families[0] + + +def _load_mapping(): + if _Cache.mapping is not None: + return + + filepath = get_mapping_filepath() + with open(filepath, "r") as stream: + mapping = json.load(stream) + _Cache.mapping = { + key: chr(value) + for key, value in mapping.items() + } + + +def _get_font_name(): + _load_font() + return _Cache.font_name + + +def get_icon_name_char(icon_name: str) -> Union[int, None]: + _load_mapping() + return _Cache.mapping.get(icon_name, None) + + +def get_char_mapping() -> Dict[str, int]: + _load_mapping() + return copy.deepcopy(_Cache.mapping) diff --git a/client/ayon_core/vendor/python/qtmaterialsymbols/version.py b/client/ayon_core/vendor/python/qtmaterialsymbols/version.py new file mode 100644 index 0000000000..5becc17c04 --- /dev/null +++ b/client/ayon_core/vendor/python/qtmaterialsymbols/version.py @@ -0,0 +1 @@ +__version__ = "1.0.0"