mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 21:05:36 +00:00
merge mozilla-central to mozilla-inbound. r=merge a=merge
This commit is contained in:
commit
943e69c7fa
@ -33,11 +33,11 @@ jobs:
|
||||
mozilla-central: [{hour: 10, minute: 0}]
|
||||
# No default
|
||||
|
||||
- name: nightly-desktop-win64
|
||||
- name: nightly-desktop-win
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: Nd-Win64
|
||||
target-tasks-method: nightly_win64
|
||||
treeherder-symbol: Nd-Win
|
||||
target-tasks-method: nightly_win
|
||||
run-on-projects:
|
||||
- date
|
||||
when: [] # never (hook only)
|
||||
|
@ -4988,16 +4988,6 @@ var CombinedStopReload = {
|
||||
});
|
||||
},
|
||||
|
||||
/* This function is necessary to correctly vertically center the animation
|
||||
within the toolbar, which uses -moz-pack-align:stretch; and thus a height
|
||||
which is dependant on the font-size. */
|
||||
setAnimationImageHeightRelativeToToolbarButtonHeight() {
|
||||
let dwu = window.getInterface(Ci.nsIDOMWindowUtils);
|
||||
let toolbarItem = this.stopReloadContainer.closest(".customization-target > toolbaritem");
|
||||
let bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
||||
toolbarItem.style.setProperty("--toolbarbutton-height", bounds.height + "px");
|
||||
},
|
||||
|
||||
switchToStop(aRequest, aWebProgress) {
|
||||
if (!this._initialized || !this._shouldSwitch(aRequest))
|
||||
return;
|
||||
@ -5010,7 +5000,7 @@ var CombinedStopReload = {
|
||||
|
||||
this._cancelTransition();
|
||||
if (shouldAnimate) {
|
||||
this.setAnimationImageHeightRelativeToToolbarButtonHeight();
|
||||
BrowserUtils.setToolbarButtonHeightProperty(this.stopReloadContainer);
|
||||
this.stopReloadContainer.setAttribute("animate", "true");
|
||||
} else {
|
||||
this.stopReloadContainer.removeAttribute("animate");
|
||||
@ -5030,7 +5020,7 @@ var CombinedStopReload = {
|
||||
this.animate;
|
||||
|
||||
if (shouldAnimate) {
|
||||
this.setAnimationImageHeightRelativeToToolbarButtonHeight();
|
||||
BrowserUtils.setToolbarButtonHeightProperty(this.stopReloadContainer);
|
||||
this.stopReloadContainer.setAttribute("animate", "true");
|
||||
} else {
|
||||
this.stopReloadContainer.removeAttribute("animate");
|
||||
|
@ -1220,7 +1220,11 @@
|
||||
<toolbarbutton id="library-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
oncommand="PanelUI.showSubView('appMenu-libraryView', this, null, event);"
|
||||
closemenu="none"
|
||||
label="&places.library.title;"/>
|
||||
label="&places.library.title;">
|
||||
<box class="toolbarbutton-animatable-box">
|
||||
<image class="toolbarbutton-animatable-image"/>
|
||||
</box>
|
||||
</toolbarbutton>
|
||||
#endif
|
||||
</toolbarpalette>
|
||||
</toolbox>
|
||||
|
@ -12,6 +12,7 @@ support-files =
|
||||
|
||||
[browser_aboutCertError.js]
|
||||
[browser_aboutStopReload.js]
|
||||
run-if = nightly_build # Photon only
|
||||
[browser_aboutNetError.js]
|
||||
[browser_aboutSupport.js]
|
||||
[browser_aboutSupport_newtab_security_state.js]
|
||||
|
@ -2,6 +2,7 @@
|
||||
support-files =
|
||||
head.js
|
||||
[browser_appmenu_reflows.js]
|
||||
skip-if = (os == 'mac' || os == 'win') && debug # Bug 1382809
|
||||
[browser_startup.js]
|
||||
[browser_startup_content.js]
|
||||
skip-if = !e10s
|
||||
@ -15,3 +16,4 @@ skip-if = !debug
|
||||
[browser_toolbariconcolor_restyles.js]
|
||||
[browser_windowclose_reflows.js]
|
||||
[browser_windowopen_reflows.js]
|
||||
skip-if = os == 'linux' # Disabled due to frequent failures. Bug 1380465.
|
||||
|
@ -118,7 +118,7 @@ add_task(async function() {
|
||||
BrowserTestUtils.waitForEvent(PanelUI.panel, "popuppositioned");
|
||||
await PanelUI.show();
|
||||
await popupPositioned;
|
||||
}, EXPECTED_APPMENU_OPEN_REFLOWS, window, PanelUI.panel);
|
||||
}, EXPECTED_APPMENU_OPEN_REFLOWS);
|
||||
|
||||
// Now open a series of subviews, and then close the appmenu. We
|
||||
// should not reflow during any of this.
|
||||
@ -160,5 +160,5 @@ add_task(async function() {
|
||||
let hidden = BrowserTestUtils.waitForEvent(PanelUI.panel, "popuphidden");
|
||||
PanelUI.hide();
|
||||
await hidden;
|
||||
}, EXPECTED_APPMENU_SUBVIEW_REFLOWS, window, PanelUI.panel);
|
||||
}, EXPECTED_APPMENU_SUBVIEW_REFLOWS);
|
||||
});
|
||||
|
@ -36,12 +36,6 @@ add_task(async function() {
|
||||
const TAB_COUNT_FOR_GROWTH = computeMaxTabCount();
|
||||
await createTabs(TAB_COUNT_FOR_GROWTH);
|
||||
|
||||
// Because the tab strip is a scrollable frame, we can't use the
|
||||
// default dirtying function from withReflowObserver and reliably
|
||||
// get reflows for the strip. Instead, we provide a node that's
|
||||
// already in the scrollable frame to dirty - in this case, the
|
||||
// original tab.
|
||||
let origTab = gBrowser.selectedTab;
|
||||
let lastTab = gBrowser.tabs[gBrowser.tabs.length - 1];
|
||||
await BrowserTestUtils.switchTab(gBrowser, lastTab);
|
||||
|
||||
@ -52,7 +46,7 @@ add_task(async function() {
|
||||
await BrowserTestUtils.waitForEvent(tab, "transitionend",
|
||||
false, e => e.propertyName === "max-width");
|
||||
await switchDone;
|
||||
}, EXPECTED_REFLOWS, window, origTab);
|
||||
}, EXPECTED_REFLOWS);
|
||||
|
||||
await removeAllButFirstTab();
|
||||
});
|
||||
|
@ -22,13 +22,6 @@ const EXPECTED_REFLOWS = [
|
||||
add_task(async function() {
|
||||
await ensureNoPreloadedBrowser();
|
||||
|
||||
// Because the tab strip is a scrollable frame, we can't use the
|
||||
// default dirtying function from withReflowObserver and reliably
|
||||
// get reflows for the strip. Instead, we provide a node that's
|
||||
// already in the scrollable frame to dirty - in this case, the
|
||||
// original tab.
|
||||
let origTab = gBrowser.selectedTab;
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
||||
await BrowserTestUtils.waitForCondition(() => tab._fullyOpen);
|
||||
|
||||
@ -39,6 +32,6 @@ add_task(async function() {
|
||||
await BrowserTestUtils.waitForEvent(tab, "transitionend",
|
||||
false, e => e.propertyName === "max-width");
|
||||
await switchDone;
|
||||
}, EXPECTED_REFLOWS, window, origTab);
|
||||
}, EXPECTED_REFLOWS);
|
||||
is(EXPECTED_REFLOWS.length, 0, "No reflows are expected when closing a tab");
|
||||
});
|
||||
|
@ -27,13 +27,6 @@ const EXPECTED_REFLOWS = [
|
||||
add_task(async function() {
|
||||
await ensureNoPreloadedBrowser();
|
||||
|
||||
// Because the tab strip is a scrollable frame, we can't use the
|
||||
// default dirtying function from withReflowObserver and reliably
|
||||
// get reflows for the strip. Instead, we provide a node that's
|
||||
// already in the scrollable frame to dirty - in this case, the
|
||||
// original tab.
|
||||
let origTab = gBrowser.selectedTab;
|
||||
|
||||
// Add a reflow observer and open a new tab.
|
||||
await withReflowObserver(async function() {
|
||||
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
|
||||
@ -41,7 +34,7 @@ add_task(async function() {
|
||||
await BrowserTestUtils.waitForEvent(gBrowser.selectedTab, "transitionend",
|
||||
false, e => e.propertyName === "max-width");
|
||||
await switchDone;
|
||||
}, EXPECTED_REFLOWS, window, origTab);
|
||||
}, EXPECTED_REFLOWS);
|
||||
|
||||
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
|
@ -33,20 +33,13 @@ add_task(async function() {
|
||||
|
||||
await createTabs(TAB_COUNT_FOR_SQUEEZE);
|
||||
|
||||
// Because the tab strip is a scrollable frame, we can't use the
|
||||
// default dirtying function from withReflowObserver and reliably
|
||||
// get reflows for the strip. Instead, we provide a node that's
|
||||
// already in the scrollable frame to dirty - in this case, the
|
||||
// original tab.
|
||||
let origTab = gBrowser.selectedTab;
|
||||
|
||||
await withReflowObserver(async function() {
|
||||
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
|
||||
BrowserOpenTab();
|
||||
await BrowserTestUtils.waitForEvent(gBrowser.selectedTab, "transitionend",
|
||||
false, e => e.propertyName === "max-width");
|
||||
await switchDone;
|
||||
}, EXPECTED_REFLOWS, window, origTab);
|
||||
}, EXPECTED_REFLOWS);
|
||||
|
||||
await removeAllButFirstTab();
|
||||
});
|
||||
|
@ -32,13 +32,7 @@ add_task(async function() {
|
||||
Assert.equal(EXPECTED_REFLOWS.length, 0,
|
||||
"We shouldn't have added any new expected reflows.");
|
||||
|
||||
// Because the tab strip is a scrollable frame, we can't use the
|
||||
// default dirtying function from withReflowObserver and reliably
|
||||
// get reflows for the strip. Instead, we provide a node that's
|
||||
// already in the scrollable frame to dirty - in this case, the
|
||||
// original tab.
|
||||
let origTab = gBrowser.selectedTab;
|
||||
|
||||
let firstSwitchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
|
||||
let otherTab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
||||
await firstSwitchDone;
|
||||
@ -47,7 +41,7 @@ add_task(async function() {
|
||||
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
|
||||
gBrowser.selectedTab = origTab;
|
||||
await switchDone;
|
||||
}, EXPECTED_REFLOWS, window, origTab);
|
||||
}, EXPECTED_REFLOWS);
|
||||
|
||||
await BrowserTestUtils.removeTab(otherTab);
|
||||
});
|
||||
|
@ -20,21 +20,26 @@ const EXPECTED_REFLOWS = [
|
||||
],
|
||||
];
|
||||
|
||||
if (Services.appinfo.OS == "Darwin") {
|
||||
// TabsInTitlebar._update causes a reflow on OS X trying to do calculations
|
||||
// since layout info is already dirty. This doesn't seem to happen before
|
||||
// MozAfterPaint on Linux.
|
||||
if (Services.appinfo.OS == "Linux") {
|
||||
if (gMultiProcessBrowser) {
|
||||
EXPECTED_REFLOWS.push(
|
||||
[
|
||||
"rect@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
"EventListener.handleEvent*tabbrowser-tabs_XBL_Constructor@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
);
|
||||
} else {
|
||||
EXPECTED_REFLOWS.push(
|
||||
[
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
"inferFromText@chrome://browser/content/browser.js",
|
||||
"handleEvent@chrome://browser/content/browser.js",
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
|
||||
if (Services.appinfo.OS == "Darwin") {
|
||||
EXPECTED_REFLOWS.push(
|
||||
[
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
@ -44,11 +49,99 @@ if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
|
||||
);
|
||||
}
|
||||
|
||||
if (Services.appinfo.OS == "WINNT") {
|
||||
EXPECTED_REFLOWS.push(
|
||||
[
|
||||
"verticalMargins@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
|
||||
[
|
||||
"verticalMargins@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
|
||||
[
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
"inferFromText@chrome://browser/content/browser.js",
|
||||
"handleEvent@chrome://browser/content/browser.js",
|
||||
],
|
||||
|
||||
[
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
"EventListener.handleEvent*tabbrowser-tabs_XBL_Constructor@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
|
||||
EXPECTED_REFLOWS.push(
|
||||
[
|
||||
"rect@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
|
||||
[
|
||||
"rect@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
|
||||
[
|
||||
"rect@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
|
||||
[
|
||||
"rect@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
|
||||
[
|
||||
"verticalMargins@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
|
||||
[
|
||||
"verticalMargins@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* This test ensures that there are no unexpected
|
||||
* uninterruptible reflows when opening new windows.
|
||||
*/
|
||||
add_task(async function() {
|
||||
const IS_WIN8 = (navigator.userAgent.indexOf("Windows NT 6.2") != -1);
|
||||
if (IS_WIN8) {
|
||||
ok(true, "Skipping this test because of perma-failures on Windows 8 x64 (bug 1381521)");
|
||||
return;
|
||||
}
|
||||
|
||||
// Flushing all caches helps to ensure that we get consistent
|
||||
// behaviour when opening a new window, even if windows have been
|
||||
// opened in previous tests.
|
||||
Services.obs.notifyObservers(null, "startupcache-invalidate");
|
||||
Services.obs.notifyObservers(null, "chrome-flush-skin-caches");
|
||||
Services.obs.notifyObservers(null, "chrome-flush-caches");
|
||||
|
||||
let win = OpenBrowserWindow();
|
||||
|
||||
await withReflowObserver(async function() {
|
||||
|
@ -65,20 +65,17 @@
|
||||
* it defaults to the empty Array, meaning no reflows are expected.
|
||||
* @param window (browser window, optional)
|
||||
* The browser window to monitor. Defaults to the current window.
|
||||
* @param elemToDirty (DOM node, optional)
|
||||
* Callers can provide a custom DOM node to change some layout style
|
||||
* on in the event that the action being tested is occurring within
|
||||
* a scrollable frame. Otherwise, withReflowObserver defaults to dirtying
|
||||
* the first element child of the window.
|
||||
*/
|
||||
async function withReflowObserver(testFn, expectedStacks = [], win = window, elemToDirty) {
|
||||
if (!elemToDirty) {
|
||||
elemToDirty = win.document.firstElementChild;
|
||||
async function withReflowObserver(testFn, expectedStacks = [], win = window) {
|
||||
let dwu = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
let dirtyFrameFn = () => {
|
||||
try {
|
||||
dwu.ensureDirtyRootFrame();
|
||||
} catch (e) {
|
||||
// If this fails, we should probably make note of it, but it's not fatal.
|
||||
info("Note: ensureDirtyRootFrame threw an exception.");
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
let dirtyFrameFn = (e) => {
|
||||
elemToDirty.style.margin = (++i % 4) + "px";
|
||||
};
|
||||
|
||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
@ -120,7 +117,9 @@ async function withReflowObserver(testFn, expectedStacks = [], win = window, ele
|
||||
},
|
||||
|
||||
reflowInterruptible(start, end) {
|
||||
// We're not interested in interruptible reflows.
|
||||
// We're not interested in interruptible reflows, but might as well take the
|
||||
// opportuntiy to dirty the root frame.
|
||||
dirtyFrameFn();
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
|
||||
@ -148,8 +147,6 @@ async function withReflowObserver(testFn, expectedStacks = [], win = window, ele
|
||||
|
||||
els.removeListenerForAllEvents(win, dirtyFrameFn, true);
|
||||
docShell.removeWeakReflowObserver(observer);
|
||||
|
||||
elemToDirty.style.margin = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1449,29 +1449,29 @@ CustomizeMode.prototype = {
|
||||
let gUIDensity = win.gUIDensity;
|
||||
let currentDensity = gUIDensity.getCurrentDensity();
|
||||
|
||||
let normalButton = doc.getElementById("customization-uidensity-menu-button-normal");
|
||||
normalButton.mode = gUIDensity.MODE_NORMAL;
|
||||
let normalItem = doc.getElementById("customization-uidensity-menuitem-normal");
|
||||
normalItem.mode = gUIDensity.MODE_NORMAL;
|
||||
|
||||
let compactButton = doc.getElementById("customization-uidensity-menu-button-compact");
|
||||
compactButton.mode = gUIDensity.MODE_COMPACT;
|
||||
let compactItem = doc.getElementById("customization-uidensity-menuitem-compact");
|
||||
compactItem.mode = gUIDensity.MODE_COMPACT;
|
||||
|
||||
let buttons = [normalButton, compactButton];
|
||||
let items = [normalItem, compactItem];
|
||||
|
||||
let touchButton = doc.getElementById("customization-uidensity-menu-button-touch");
|
||||
let touchItem = doc.getElementById("customization-uidensity-menuitem-touch");
|
||||
// Touch mode can not be enabled in OSX right now.
|
||||
if (touchButton) {
|
||||
touchButton.mode = gUIDensity.MODE_TOUCH;
|
||||
buttons.push(touchButton);
|
||||
if (touchItem) {
|
||||
touchItem.mode = gUIDensity.MODE_TOUCH;
|
||||
items.push(touchItem);
|
||||
}
|
||||
|
||||
// Mark the active mode button.
|
||||
for (let button of buttons) {
|
||||
if (button.mode == currentDensity.mode) {
|
||||
button.setAttribute("aria-checked", "true");
|
||||
button.setAttribute("active", "true");
|
||||
// Mark the active mode menuitem.
|
||||
for (let item of items) {
|
||||
if (item.mode == currentDensity.mode) {
|
||||
item.setAttribute("aria-checked", "true");
|
||||
item.setAttribute("active", "true");
|
||||
} else {
|
||||
button.removeAttribute("aria-checked");
|
||||
button.removeAttribute("active");
|
||||
item.removeAttribute("aria-checked");
|
||||
item.removeAttribute("active");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1486,10 +1486,10 @@ CustomizeMode.prototype = {
|
||||
// Show a hint that the UI density was overridden automatically.
|
||||
if (currentDensity.overridden) {
|
||||
let sb = Services.strings.createBundle("chrome://browser/locale/uiDensity.properties");
|
||||
touchButton.setAttribute("acceltext",
|
||||
sb.GetStringFromName("uiDensity.menu-button-touch.acceltext"));
|
||||
touchItem.setAttribute("acceltext",
|
||||
sb.GetStringFromName("uiDensity.menuitem-touch.acceltext"));
|
||||
} else {
|
||||
touchButton.removeAttribute("acceltext");
|
||||
touchItem.removeAttribute("acceltext");
|
||||
}
|
||||
|
||||
let autoTouchMode = Services.prefs.getBoolPref(win.gUIDensity.autoTouchModePref);
|
||||
|
@ -61,8 +61,8 @@
|
||||
position="topcenter bottomleft"
|
||||
flip="none"
|
||||
role="menu">
|
||||
<menuitem id="customization-uidensity-menu-button-compact"
|
||||
class="menuitem-iconic customization-uidensity-menu-button"
|
||||
<menuitem id="customization-uidensity-menuitem-compact"
|
||||
class="menuitem-iconic customization-uidensity-menuitem"
|
||||
role="menuitemradio"
|
||||
label="&customizeMode.uidensity.menuCompact.label;"
|
||||
accesskey="&customizeMode.uidensity.menuCompact.accessKey;"
|
||||
@ -73,8 +73,8 @@
|
||||
onblur="gCustomizeMode.resetUIDensity();"
|
||||
onmouseout="gCustomizeMode.resetUIDensity();"
|
||||
oncommand="gCustomizeMode.setUIDensity(this.mode);" />
|
||||
<menuitem id="customization-uidensity-menu-button-normal"
|
||||
class="menuitem-iconic customization-uidensity-menu-button"
|
||||
<menuitem id="customization-uidensity-menuitem-normal"
|
||||
class="menuitem-iconic customization-uidensity-menuitem"
|
||||
role="menuitemradio"
|
||||
label="&customizeMode.uidensity.menuNormal.label;"
|
||||
accesskey="&customizeMode.uidensity.menuNormal.accessKey;"
|
||||
@ -86,8 +86,8 @@
|
||||
onmouseout="gCustomizeMode.resetUIDensity();"
|
||||
oncommand="gCustomizeMode.setUIDensity(this.mode);" />
|
||||
#ifndef XP_MACOSX
|
||||
<menuitem id="customization-uidensity-menu-button-touch"
|
||||
class="menuitem-iconic customization-uidensity-menu-button"
|
||||
<menuitem id="customization-uidensity-menuitem-touch"
|
||||
class="menuitem-iconic customization-uidensity-menuitem"
|
||||
role="menuitemradio"
|
||||
label="&customizeMode.uidensity.menuTouch.label;"
|
||||
accesskey="&customizeMode.uidensity.menuTouch.accessKey;"
|
||||
|
@ -7,7 +7,7 @@
|
||||
const PREF_UI_DENSITY = "browser.uidensity";
|
||||
const PREF_AUTO_TOUCH_MODE = "browser.touchmode.auto";
|
||||
|
||||
async function testModeButton(mode, modePref) {
|
||||
async function testModeMenuitem(mode, modePref) {
|
||||
await startCustomizing();
|
||||
|
||||
let win = document.getElementById("main-window");
|
||||
@ -19,54 +19,54 @@ async function testModeButton(mode, modePref) {
|
||||
EventUtils.synthesizeMouseAtCenter(popupButton, {});
|
||||
await popupShownPromise;
|
||||
|
||||
let button = document.getElementById("customization-uidensity-menu-button-" + mode);
|
||||
let normalButton = document.getElementById("customization-uidensity-menu-button-normal");
|
||||
let item = document.getElementById("customization-uidensity-menuitem-" + mode);
|
||||
let normalItem = document.getElementById("customization-uidensity-menuitem-normal");
|
||||
|
||||
is(normalButton.getAttribute("active"), "true",
|
||||
"Normal mode button should be active by default.");
|
||||
is(normalItem.getAttribute("active"), "true",
|
||||
"Normal mode menuitem should be active by default");
|
||||
|
||||
// Hover over the mode button and wait until the UI density is updated.
|
||||
EventUtils.synthesizeMouseAtCenter(button, { type: "mouseover" });
|
||||
// Hover over the mode menuitem and wait until the UI density is updated.
|
||||
EventUtils.synthesizeMouseAtCenter(item, { type: "mouseover" });
|
||||
await BrowserTestUtils.waitForAttribute("uidensity", win, mode);
|
||||
|
||||
is(win.getAttribute("uidensity"), mode,
|
||||
`UI Density should be set to ${mode} on ${mode} button hover.`);
|
||||
`UI Density should be set to ${mode} on ${mode} menuitem hover`);
|
||||
|
||||
is(Services.prefs.getIntPref(PREF_UI_DENSITY), window.gUIDensity.MODE_NORMAL,
|
||||
`UI Density pref should still be set to normal on ${mode} button hover.`);
|
||||
`UI Density pref should still be set to normal on ${mode} menuitem hover`);
|
||||
|
||||
// Hover the normal button again and check that the UI density reset to normal.
|
||||
EventUtils.synthesizeMouseAtCenter(normalButton, { type: "mouseover" });
|
||||
// Hover the normal menuitem again and check that the UI density reset to normal.
|
||||
EventUtils.synthesizeMouseAtCenter(normalItem, { type: "mouseover" });
|
||||
await BrowserTestUtils.waitForCondition(() => !win.hasAttribute("uidensity"));
|
||||
|
||||
ok(!win.hasAttribute("uidensity"),
|
||||
`UI Density should be reset when no longer hovering the ${mode} button.`);
|
||||
`UI Density should be reset when no longer hovering the ${mode} menuitem`);
|
||||
|
||||
// Select the custom UI density and wait for the popup to be hidden.
|
||||
let popupHiddenPromise = popupHidden(popup);
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
EventUtils.synthesizeMouseAtCenter(item, {});
|
||||
await popupHiddenPromise;
|
||||
|
||||
// Check that the click permanently changed the UI density.
|
||||
is(win.getAttribute("uidensity"), mode,
|
||||
`UI Density should be set to ${mode} on ${mode} button click.`);
|
||||
`UI Density should be set to ${mode} on ${mode} menuitem click`);
|
||||
is(Services.prefs.getIntPref(PREF_UI_DENSITY), modePref,
|
||||
`UI Density pref should be set to ${mode} when clicking the ${mode} button.`);
|
||||
`UI Density pref should be set to ${mode} when clicking the ${mode} menuitem`);
|
||||
|
||||
// Open the popup again.
|
||||
popupShownPromise = popupShown(popup);
|
||||
EventUtils.synthesizeMouseAtCenter(popupButton, {});
|
||||
await popupShownPromise;
|
||||
|
||||
// Check that the button is still active after opening and closing the popup.
|
||||
is(button.getAttribute("active"), "true", `${mode} mode button should be active.`);
|
||||
// Check that the menuitem is still active after opening and closing the popup.
|
||||
is(item.getAttribute("active"), "true", `${mode} mode menuitem should be active`);
|
||||
|
||||
// Hide the popup again.
|
||||
popupHiddenPromise = popupHidden(popup);
|
||||
EventUtils.synthesizeMouseAtCenter(popupButton, {});
|
||||
await popupHiddenPromise;
|
||||
|
||||
// Check that the button is still active after re-opening customize mode.
|
||||
// Check that the menuitem is still active after re-opening customize mode.
|
||||
await endCustomizing();
|
||||
await startCustomizing();
|
||||
|
||||
@ -74,40 +74,40 @@ async function testModeButton(mode, modePref) {
|
||||
EventUtils.synthesizeMouseAtCenter(popupButton, {});
|
||||
await popupShownPromise;
|
||||
|
||||
is(button.getAttribute("active"), "true",
|
||||
`${mode} mode button should be active after entering and exiting customize mode.`);
|
||||
is(item.getAttribute("active"), "true",
|
||||
`${mode} mode menuitem should be active after entering and exiting customize mode`);
|
||||
|
||||
// Click the normal button and check that the density is reset.
|
||||
// Click the normal menuitem and check that the density is reset.
|
||||
popupHiddenPromise = popupHidden(popup);
|
||||
EventUtils.synthesizeMouseAtCenter(normalButton, {});
|
||||
EventUtils.synthesizeMouseAtCenter(normalItem, {});
|
||||
await popupHiddenPromise;
|
||||
|
||||
ok(!win.hasAttribute("uidensity"),
|
||||
"UI Density should be reset when clicking the normal button.");
|
||||
"UI Density should be reset when clicking the normal menuitem");
|
||||
|
||||
is(Services.prefs.getIntPref(PREF_UI_DENSITY), window.gUIDensity.MODE_NORMAL,
|
||||
"UI Density pref should be set to normal.");
|
||||
|
||||
// Show the popup and click on the mode button again to test the
|
||||
// Show the popup and click on the mode menuitem again to test the
|
||||
// reset default feature.
|
||||
popupShownPromise = popupShown(popup);
|
||||
EventUtils.synthesizeMouseAtCenter(popupButton, {});
|
||||
await popupShownPromise;
|
||||
|
||||
popupHiddenPromise = popupHidden(popup);
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
EventUtils.synthesizeMouseAtCenter(item, {});
|
||||
await popupHiddenPromise;
|
||||
|
||||
is(win.getAttribute("uidensity"), mode,
|
||||
`UI Density should be set to ${mode} on ${mode} button click.`);
|
||||
`UI Density should be set to ${mode} on ${mode} menuitem click`);
|
||||
|
||||
is(Services.prefs.getIntPref(PREF_UI_DENSITY), modePref,
|
||||
`UI Density pref should be set to ${mode} when clicking the ${mode} button.`);
|
||||
`UI Density pref should be set to ${mode} when clicking the ${mode} menuitem`);
|
||||
|
||||
await gCustomizeMode.reset();
|
||||
|
||||
ok(!win.hasAttribute("uidensity"),
|
||||
"UI Density should be reset when clicking the normal button.");
|
||||
"UI Density should be reset when clicking the normal menuitem");
|
||||
|
||||
is(Services.prefs.getIntPref(PREF_UI_DENSITY), window.gUIDensity.MODE_NORMAL,
|
||||
"UI Density pref should be set to normal.");
|
||||
@ -115,16 +115,16 @@ async function testModeButton(mode, modePref) {
|
||||
await endCustomizing();
|
||||
}
|
||||
|
||||
add_task(async function test_compact_mode_button() {
|
||||
add_task(async function test_compact_mode_menuitem() {
|
||||
if (!AppConstants.MOZ_PHOTON_THEME) {
|
||||
ok(true, "Skipping test because Photon is not enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
await testModeButton("compact", window.gUIDensity.MODE_COMPACT);
|
||||
await testModeMenuitem("compact", window.gUIDensity.MODE_COMPACT);
|
||||
});
|
||||
|
||||
add_task(async function test_touch_mode_button() {
|
||||
add_task(async function test_touch_mode_menuitem() {
|
||||
if (!AppConstants.MOZ_PHOTON_THEME) {
|
||||
ok(true, "Skipping test because Photon is not enabled.");
|
||||
return;
|
||||
@ -132,12 +132,12 @@ add_task(async function test_touch_mode_button() {
|
||||
|
||||
// OSX doesn't get touch mode for now.
|
||||
if (AppConstants.platform == "macosx") {
|
||||
is(document.getElementById("customization-uidensity-menu-button-touch"), null,
|
||||
is(document.getElementById("customization-uidensity-menuitem-touch"), null,
|
||||
"There's no touch option on Mac OSX");
|
||||
return;
|
||||
}
|
||||
|
||||
await testModeButton("touch", window.gUIDensity.MODE_TOUCH);
|
||||
await testModeMenuitem("touch", window.gUIDensity.MODE_TOUCH);
|
||||
|
||||
// Test the checkbox for automatic Touch Mode transition
|
||||
// in Windows 10 Tablet Mode.
|
||||
|
21
browser/extensions/pocket/bootstrap.js
vendored
21
browser/extensions/pocket/bootstrap.js
vendored
@ -9,6 +9,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, manager: Cm} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
@ -92,6 +93,13 @@ function CreatePocketWidget(reason) {
|
||||
label: gPocketBundle.GetStringFromName("pocket-button.label"),
|
||||
tooltiptext: gPocketBundle.GetStringFromName("pocket-button.tooltiptext"),
|
||||
// Use forwarding functions here to avoid loading Pocket.jsm on startup:
|
||||
onBeforeCommand() {
|
||||
// We need to use onBeforeCommand to calculate the height
|
||||
// of the pocket-button before it is opened since we need
|
||||
// the height of the button to perform the animation that is
|
||||
// triggered off of [open="true"].
|
||||
return Pocket.onBeforeCommand.apply(this, arguments);
|
||||
},
|
||||
onViewShowing() {
|
||||
return Pocket.onPanelViewShowing.apply(this, arguments);
|
||||
},
|
||||
@ -108,7 +116,20 @@ function CreatePocketWidget(reason) {
|
||||
panel.setAttribute("class", "panel-subview-body");
|
||||
view.appendChild(panel);
|
||||
doc.getElementById("PanelUI-multiView").appendChild(view);
|
||||
},
|
||||
onCreated(node) {
|
||||
if (Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") &&
|
||||
AppConstants.MOZ_PHOTON_ANIMATIONS) {
|
||||
let doc = node.ownerDocument;
|
||||
let box = doc.createElement("box");
|
||||
box.classList.add("toolbarbutton-animatable-box");
|
||||
let image = doc.createElement("image");
|
||||
image.classList.add("toolbarbutton-animatable-image");
|
||||
box.appendChild(image);
|
||||
node.appendChild(box);
|
||||
node.setAttribute("animationsenabled", "true");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
CustomizableUI.createWidget(pocketButton);
|
||||
|
@ -10,6 +10,8 @@ this.EXPORTED_SYMBOLS = ["Pocket"];
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
|
||||
"resource:///modules/CustomizableUI.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
|
||||
@ -22,11 +24,18 @@ var Pocket = {
|
||||
/**
|
||||
* Functions related to the Pocket panel UI.
|
||||
*/
|
||||
onBeforeCommand(event) {
|
||||
BrowserUtils.setToolbarButtonHeightProperty(event.target);
|
||||
},
|
||||
|
||||
onPanelViewShowing(event) {
|
||||
let document = event.target.ownerDocument;
|
||||
let window = document.defaultView;
|
||||
let iframe = window.pktUI.getPanelFrame();
|
||||
|
||||
let libraryButton = document.getElementById("library-button");
|
||||
BrowserUtils.setToolbarButtonHeightProperty(libraryButton);
|
||||
|
||||
let urlToSave = Pocket._urlToSave;
|
||||
let titleToSave = Pocket._titleToSave;
|
||||
Pocket._urlToSave = null;
|
||||
|
@ -68,6 +68,8 @@ var pktUI = (function() {
|
||||
var savePanelWidth = 350;
|
||||
var savePanelHeights = {collapsed: 153, expanded: 272};
|
||||
|
||||
var _lastAddSucceeded = false;
|
||||
|
||||
// -- Event Handling -- //
|
||||
|
||||
/**
|
||||
@ -88,8 +90,34 @@ var pktUI = (function() {
|
||||
|
||||
// clear the panel
|
||||
getPanelFrame().setAttribute("src", "about:blank");
|
||||
|
||||
if (_lastAddSucceeded) {
|
||||
var libraryButton = document.getElementById("library-button");
|
||||
if (!Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") ||
|
||||
!libraryButton ||
|
||||
libraryButton.getAttribute("cui-areatype") == "menu-panel" ||
|
||||
libraryButton.getAttribute("overflowedItem") == "true" ||
|
||||
!libraryButton.closest("toolbar") ||
|
||||
libraryButton.closest("toolbar").id != "nav-bar") {
|
||||
return;
|
||||
}
|
||||
libraryButton.removeAttribute("fade");
|
||||
libraryButton.setAttribute("animate", "pocket");
|
||||
libraryButton.addEventListener("animationend", onLibraryButtonAnimationEnd);
|
||||
}
|
||||
}
|
||||
|
||||
function onLibraryButtonAnimationEnd(event) {
|
||||
let doc = event.target.ownerDocument;
|
||||
let libraryButton = doc.getElementById("library-button");
|
||||
if (event.animationName.startsWith("library-pocket-animation")) {
|
||||
libraryButton.setAttribute("fade", "true");
|
||||
} else if (event.animationName == "library-pocket-fade") {
|
||||
libraryButton.removeEventListener("animationend", onLibraryButtonAnimationEnd);
|
||||
libraryButton.removeAttribute("animate");
|
||||
libraryButton.removeAttribute("fade");
|
||||
}
|
||||
}
|
||||
|
||||
// -- Communication to API -- //
|
||||
|
||||
@ -197,6 +225,7 @@ var pktUI = (function() {
|
||||
var panelId = showPanel("about:pocket-saved?pockethost=" + Services.prefs.getCharPref("extensions.pocket.site") + "&premiumStatus=" + (pktApi.isPremiumUser() ? "1" : "0") + "&inoverflowmenu=" + inOverflowMenu + "&locale=" + getUILocale(), {
|
||||
onShow() {
|
||||
var saveLinkMessageId = "saveLink";
|
||||
_lastAddSucceeded = false;
|
||||
|
||||
// Send error message for invalid url
|
||||
if (!isValidURL) {
|
||||
@ -228,6 +257,7 @@ var pktUI = (function() {
|
||||
item
|
||||
};
|
||||
pktUIMessaging.sendMessageToPanel(panelId, saveLinkMessageId, successResponse);
|
||||
_lastAddSucceeded = true;
|
||||
},
|
||||
error(error, request) {
|
||||
// If user is not authorized show singup page
|
||||
|
@ -0,0 +1,986 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1078" height="54">
|
||||
<svg x="0">
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
</svg>
|
||||
<svg x="22">
|
||||
<defs>
|
||||
<mask id="a" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="b" mask-type="alpha">
|
||||
<g opacity=".055">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#b)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M8.913 13.992c-3.55 -1.232 -5.428 -5.108 -4.197 -8.657l1.116 -3.214a1.7 1.7 0 0 1 2.164 -1.05l9.64 3.347a1.7 1.7 0 0 1 1.05 2.164l-1.116 3.214c-1.231 3.549 -5.108 5.428 -8.657 4.196z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#a)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.831 7.252a0.84 0.84 0 0 0 -0.671 0.054l-3.552 1.723 -1.688 -3.497a0.838 0.838 0 0 0 -0.504 -0.506 0.85 0.85 0 0 0 -1.047 1.166l-0.016 0.005 1.723 3.574 0.371 0.765a0.851 0.851 0 0 0 1.136 0.394l0.765 -0.37 3.58 -1.734a0.851 0.851 0 0 0 0.483 -0.82 0.851 0.851 0 0 0 -0.58 -0.754z" opacity=".043"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="44">
|
||||
<defs>
|
||||
<mask id="d" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="c" mask-type="alpha">
|
||||
<g opacity=".198">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#c)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M9.209 14.005c-3.574 -1.084 -5.593 -4.86 -4.509 -8.434l0.982 -3.235a1.69 1.69 0 0 1 2.108 -1.128l9.707 2.945a1.69 1.69 0 0 1 1.127 2.108l-0.981 3.236c-1.084 3.573 -4.86 5.592 -8.434 4.508z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#d)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.822 7.078a0.836 0.836 0 0 0 -0.665 0.08l-3.46 1.85 -1.814 -3.406a0.833 0.833 0 0 0 -0.52 -0.483 0.846 0.846 0 0 0 -0.995 1.2l-0.015 0.005 1.852 3.482 0.399 0.745a0.846 0.846 0 0 0 1.143 0.347l0.746 -0.398 3.487 -1.862a0.846 0.846 0 0 0 0.448 -0.834 0.846 0.846 0 0 0 -0.606 -0.726z" opacity=".156"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="66">
|
||||
<defs>
|
||||
<mask id="f" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="e" mask-type="alpha">
|
||||
<g opacity=".394">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#e)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M9.627 14.025c-3.598 -0.875 -5.805 -4.501 -4.93 -8.1l0.792 -3.257a1.676 1.676 0 0 1 2.025 -1.232l9.773 2.377a1.676 1.676 0 0 1 1.232 2.024l-0.792 3.258c-0.875 3.598 -4.502 5.805 -8.1 4.93z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#f)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.8 6.857a0.829 0.829 0 0 0 -0.653 0.116l-3.323 2.023 -1.984 -3.272a0.826 0.826 0 0 0 -0.542 -0.449 0.838 0.838 0 0 0 -0.919 1.243l-0.015 0.006 2.027 3.345 0.436 0.715a0.839 0.839 0 0 0 1.151 0.28l0.716 -0.435 3.35 -2.037a0.839 0.839 0 0 0 0.396 -0.85 0.839 0.839 0 0 0 -0.64 -0.685z" opacity=".316"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="88">
|
||||
<defs>
|
||||
<mask id="h" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="g" mask-type="alpha">
|
||||
<g opacity=".606">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#g)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M10.107 14.027c-3.611 -0.637 -6.022 -4.08 -5.386 -7.691l0.577 -3.27a1.66 1.66 0 0 1 1.922 -1.346l9.808 1.73a1.66 1.66 0 0 1 1.346 1.922l-0.576 3.27c-0.637 3.61 -4.08 6.021 -7.691 5.385z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#h)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.764 6.615a0.82 0.82 0 0 0 -0.639 0.157l-3.155 2.21 -2.168 -3.108a0.818 0.818 0 0 0 -0.564 -0.41 0.83 0.83 0 0 0 -0.829 1.287l-0.014 0.007 2.215 3.176 0.476 0.68a0.83 0.83 0 0 0 1.155 0.204l0.68 -0.476 3.18 -2.225a0.83 0.83 0 0 0 0.339 -0.865 0.83 0.83 0 0 0 -0.676 -0.637z" opacity=".5"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="110">
|
||||
<defs>
|
||||
<mask id="j" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="i" mask-type="alpha">
|
||||
<g opacity=".802">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#i)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M10.583 13.998c-3.608 -0.4 -6.208 -3.65 -5.808 -7.258l0.362 -3.266a1.643 1.643 0 0 1 1.815 -1.452l9.8 1.087a1.643 1.643 0 0 1 1.451 1.814l-0.362 3.267c-0.4 3.608 -3.65 6.208 -7.258 5.808z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#j)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.715 6.38a0.812 0.812 0 0 0 -0.62 0.195l-2.978 2.384 -2.34 -2.933a0.81 0.81 0 0 0 -0.583 -0.37 0.822 0.822 0 0 0 -0.737 1.324l-0.014 0.008 2.39 2.998 0.513 0.641a0.822 0.822 0 0 0 1.155 0.129l0.641 -0.514 3.002 -2.4a0.822 0.822 0 0 0 0.28 -0.876 0.822 0.822 0 0 0 -0.709 -0.586z" opacity=".684"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="132">
|
||||
<defs>
|
||||
<mask id="l" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="k" mask-type="alpha">
|
||||
<g opacity=".945">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#k)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M10.996 13.943c-3.593 -0.196 -6.347 -3.268 -6.15 -6.861l0.177 -3.253a1.628 1.628 0 0 1 1.715 -1.538l9.76 0.533a1.628 1.628 0 0 1 1.537 1.716l-0.178 3.253c-0.196 3.592 -3.268 6.346 -6.861 6.15z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#l)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.663 6.175a0.805 0.805 0 0 0 -0.603 0.227l-2.815 2.524 -2.478 -2.773a0.803 0.803 0 0 0 -0.597 -0.333 0.815 0.815 0 0 0 -0.657 1.35l-0.013 0.009 2.531 2.835 0.544 0.606a0.815 0.815 0 0 0 1.15 0.063l0.606 -0.543 2.838 -2.542a0.815 0.815 0 0 0 0.228 -0.882 0.815 0.815 0 0 0 -0.734 -0.541z" opacity=".844"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="154">
|
||||
<defs>
|
||||
<mask id="n" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="m" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#m)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.285 13.878c-3.575 -0.054 -6.43 -2.996 -6.377 -6.571l0.049 -3.237a1.618 1.618 0 0 1 1.643 -1.595l9.711 0.146a1.618 1.618 0 0 1 1.594 1.643l-0.048 3.237c-0.054 3.576 -2.996 6.43 -6.572 6.377z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#n)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.622 6.02a0.8 0.8 0 0 0 -0.591 0.25l-2.696 2.617 -2.569 -2.657a0.798 0.798 0 0 0 -0.607 -0.307 0.81 0.81 0 0 0 -0.598 1.367l-0.013 0.009 2.625 2.715 0.563 0.581a0.81 0.81 0 0 0 1.145 0.017l0.58 -0.563 2.719 -2.635a0.81 0.81 0 0 0 0.19 -0.886 0.81 0.81 0 0 0 -0.748 -0.508z" opacity=".957"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="176">
|
||||
<defs>
|
||||
<mask id="p" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="o" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#o)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.395 13.825c-3.568 0 -6.46 -2.893 -6.46 -6.46v-3.23a1.614 1.614 0 0 1 1.615 -1.615h9.69a1.614 1.614 0 0 1 1.614 1.615v3.23c0 3.567 -2.892 6.46 -6.46 6.46z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#p)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.605 5.936a0.798 0.798 0 0 0 -0.585 0.258l-2.65 2.65 -2.603 -2.61a0.796 0.796 0 0 0 -0.61 -0.298 0.808 0.808 0 0 0 -0.576 1.373l-0.013 0.009 2.659 2.67 0.57 0.57a0.808 0.808 0 0 0 1.143 0l0.57 -0.57 2.672 -2.67a0.808 0.808 0 0 0 0.178 -0.886 0.808 0.808 0 0 0 -0.755 -0.496z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="198">
|
||||
<defs>
|
||||
<mask id="r" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="q" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#q)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.453 13.875c-3.567 0.03 -6.483 -2.839 -6.512 -6.406l-0.027 -3.23a1.614 1.614 0 0 1 1.602 -1.628l9.69 -0.08a1.614 1.614 0 0 1 1.627 1.602l0.027 3.23c0.029 3.567 -2.84 6.483 -6.407 6.512z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#r)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.599 5.96a0.798 0.798 0 0 0 -0.583 0.263l-2.629 2.673 -2.623 -2.59a0.796 0.796 0 0 0 -0.612 -0.292 0.808 0.808 0 0 0 -0.566 1.377l-0.012 0.009 2.68 2.648 0.576 0.566a0.808 0.808 0 0 0 1.142 -0.01l0.566 -0.575 2.65 -2.691a0.808 0.808 0 0 0 0.17 -0.888 0.808 0.808 0 0 0 -0.759 -0.49z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="220">
|
||||
<defs>
|
||||
<mask id="t" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="s" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#s)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.535 13.94c-3.567 0.07 -6.515 -2.766 -6.585 -6.332l-0.063 -3.23a1.614 1.614 0 0 1 1.582 -1.646l9.688 -0.19a1.614 1.614 0 0 1 1.646 1.583l0.064 3.23c0.07 3.566 -2.765 6.514 -6.332 6.584z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#t)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.59 5.99a0.798 0.798 0 0 0 -0.58 0.269l-2.598 2.702 -2.653 -2.56a0.796 0.796 0 0 0 -0.615 -0.285 0.808 0.808 0 0 0 -0.55 1.384l-0.012 0.009 2.71 2.617 0.582 0.56a0.808 0.808 0 0 0 1.142 -0.023l0.56 -0.582 2.618 -2.721a0.808 0.808 0 0 0 0.16 -0.89 0.808 0.808 0 0 0 -0.764 -0.48z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="242">
|
||||
<defs>
|
||||
<mask id="v" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="u" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#u)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.63 14.017c-3.566 0.117 -6.551 -2.678 -6.669 -6.244l-0.106 -3.228a1.614 1.614 0 0 1 1.561 -1.667l9.684 -0.319a1.614 1.614 0 0 1 1.667 1.561l0.107 3.228c0.117 3.566 -2.679 6.552 -6.244 6.669z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#v)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.58 6.027a0.798 0.798 0 0 0 -0.577 0.277l-2.562 2.737 -2.687 -2.525a0.796 0.796 0 0 0 -0.619 -0.277 0.808 0.808 0 0 0 -0.53 1.391l-0.013 0.01 2.745 2.58 0.59 0.552a0.808 0.808 0 0 0 1.14 -0.038l0.552 -0.59 2.583 -2.755a0.808 0.808 0 0 0 0.148 -0.891 0.808 0.808 0 0 0 -0.77 -0.47z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="264">
|
||||
<defs>
|
||||
<mask id="x" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="w" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#w)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.733 14.108c-3.563 0.17 -6.589 -2.583 -6.758 -6.146l-0.153 -3.226a1.614 1.614 0 0 1 1.537 -1.69l9.678 -0.459a1.614 1.614 0 0 1 1.69 1.537l0.153 3.226c0.169 3.563 -2.583 6.59 -6.147 6.758z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#x)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.567 6.077a0.798 0.798 0 0 0 -0.573 0.285l-2.521 2.773 -2.724 -2.485a0.796 0.796 0 0 0 -0.623 -0.268 0.808 0.808 0 0 0 -0.51 1.399l-0.013 0.01 2.782 2.54 0.598 0.543a0.808 0.808 0 0 0 1.14 -0.054l0.543 -0.598 2.543 -2.792a0.808 0.808 0 0 0 0.135 -0.894 0.808 0.808 0 0 0 -0.777 -0.46z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="286">
|
||||
<defs>
|
||||
<mask id="z" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="y" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#y)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.843 14.215c-3.56 0.223 -6.628 -2.482 -6.852 -6.042l-0.203 -3.224a1.614 1.614 0 0 1 1.51 -1.713l9.671 -0.607a1.614 1.614 0 0 1 1.713 1.51l0.203 3.224c0.223 3.56 -2.482 6.628 -6.042 6.852z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#z)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.552 6.14a0.798 0.798 0 0 0 -0.568 0.294l-2.478 2.812 -2.761 -2.443a0.796 0.796 0 0 0 -0.627 -0.258 0.808 0.808 0 0 0 -0.49 1.406l-0.012 0.01 2.821 2.497 0.606 0.534a0.808 0.808 0 0 0 1.14 -0.072l0.533 -0.605 2.5 -2.832a0.808 0.808 0 0 0 0.121 -0.895 0.808 0.808 0 0 0 -0.785 -0.448z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="308">
|
||||
<defs>
|
||||
<mask id="B" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="A" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#A)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M11.957 14.336c-3.556 0.281 -6.667 -2.375 -6.948 -5.93l-0.254 -3.22a1.614 1.614 0 0 1 1.483 -1.738l9.66 -0.762a1.614 1.614 0 0 1 1.736 1.483l0.254 3.22c0.281 3.556 -2.375 6.667 -5.931 6.947z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#B)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.537 6.22a0.798 0.798 0 0 0 -0.563 0.303l-2.434 2.85 -2.8 -2.398a0.796 0.796 0 0 0 -0.63 -0.248 0.808 0.808 0 0 0 -0.467 1.414l-0.013 0.01 2.861 2.452 0.614 0.524a0.808 0.808 0 0 0 1.138 -0.09l0.525 -0.614 2.453 -2.871a0.808 0.808 0 0 0 0.107 -0.897 0.808 0.808 0 0 0 -0.791 -0.435z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="330">
|
||||
<defs>
|
||||
<mask id="D" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="C" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#C)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.074 14.475c-3.55 0.34 -6.705 -2.265 -7.044 -5.816l-0.308 -3.215a1.614 1.614 0 0 1 1.454 -1.761l9.646 -0.922a1.614 1.614 0 0 1 1.76 1.454l0.308 3.215c0.34 3.551 -2.264 6.706 -5.816 7.045z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#D)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.52 6.317a0.798 0.798 0 0 0 -0.558 0.312l-2.386 2.891 -2.84 -2.352a0.796 0.796 0 0 0 -0.634 -0.238 0.808 0.808 0 0 0 -0.444 1.422l-0.012 0.01 2.901 2.404 0.623 0.514a0.808 0.808 0 0 0 1.136 -0.109l0.514 -0.622 2.406 -2.912a0.808 0.808 0 0 0 0.093 -0.898 0.808 0.808 0 0 0 -0.8 -0.422z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="352">
|
||||
<defs>
|
||||
<mask id="F" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="E" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#E)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.194 14.632c-3.545 0.4 -6.742 -2.15 -7.142 -5.696l-0.361 -3.21a1.614 1.614 0 0 1 1.424 -1.785l9.628 -1.085a1.614 1.614 0 0 1 1.786 1.424l0.361 3.21c0.4 3.545 -2.15 6.743 -5.696 7.142z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#F)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.502 6.434a0.798 0.798 0 0 0 -0.553 0.321l-2.337 2.931 -2.878 -2.303a0.796 0.796 0 0 0 -0.64 -0.227 0.808 0.808 0 0 0 -0.419 1.428l-0.011 0.01 2.94 2.355 0.632 0.504a0.808 0.808 0 0 0 1.134 -0.128l0.504 -0.631 2.356 -2.952a0.808 0.808 0 0 0 0.077 -0.9 0.808 0.808 0 0 0 -0.805 -0.408z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="374">
|
||||
<defs>
|
||||
<mask id="H" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="G" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#G)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.316 14.809c-3.537 0.46 -6.779 -2.035 -7.239 -5.572l-0.417 -3.203a1.614 1.614 0 0 1 1.393 -1.81l9.609 -1.25a1.614 1.614 0 0 1 1.81 1.393l0.416 3.203c0.46 3.537 -2.034 6.779 -5.572 7.239z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#H)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.482 6.572a0.798 0.798 0 0 0 -0.547 0.331l-2.286 2.97 -2.918 -2.253a0.796 0.796 0 0 0 -0.643 -0.216 0.808 0.808 0 0 0 -0.394 1.436l-0.012 0.01 2.981 2.304 0.64 0.493a0.808 0.808 0 0 0 1.132 -0.148l0.493 -0.64 2.305 -2.991a0.808 0.808 0 0 0 0.061 -0.902 0.808 0.808 0 0 0 -0.812 -0.394z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="396">
|
||||
<defs>
|
||||
<mask id="J" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="I" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#I)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.44 15.008c-3.53 0.522 -6.814 -1.916 -7.336 -5.445l-0.473 -3.195a1.614 1.614 0 0 1 1.361 -1.834l9.585 -1.418a1.614 1.614 0 0 1 1.834 1.361l0.473 3.195c0.522 3.53 -1.916 6.814 -5.445 7.336z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#J)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.46 6.734a0.798 0.798 0 0 0 -0.54 0.341l-2.234 3.01 -2.957 -2.202a0.796 0.796 0 0 0 -0.646 -0.205 0.808 0.808 0 0 0 -0.37 1.442l-0.011 0.011 3.02 2.252 0.649 0.48a0.808 0.808 0 0 0 1.13 -0.166l0.48 -0.649 2.253 -3.031a0.808 0.808 0 0 0 0.046 -0.903 0.808 0.808 0 0 0 -0.82 -0.38z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="418">
|
||||
<defs>
|
||||
<mask id="L" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="K" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#K)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.563 15.231c-3.519 0.584 -6.846 -1.795 -7.43 -5.314l-0.53 -3.187a1.614 1.614 0 0 1 1.33 -1.857l9.558 -1.587a1.614 1.614 0 0 1 1.858 1.328l0.529 3.187c0.584 3.519 -1.796 6.846 -5.315 7.43z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#L)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.438 6.923a0.798 0.798 0 0 0 -0.535 0.35l-2.18 3.05 -2.995 -2.15a0.796 0.796 0 0 0 -0.65 -0.194 0.808 0.808 0 0 0 -0.344 1.449l-0.011 0.01 3.06 2.199 0.657 0.47a0.808 0.808 0 0 0 1.126 -0.188l0.47 -0.656 2.198 -3.071a0.808 0.808 0 0 0 0.03 -0.903 0.808 0.808 0 0 0 -0.826 -0.366z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="440">
|
||||
<defs>
|
||||
<mask id="N" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="M" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#M)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.688 15.481c-3.509 0.647 -6.877 -1.673 -7.524 -5.181l-0.586 -3.176a1.614 1.614 0 0 1 1.296 -1.881l9.528 -1.757a1.614 1.614 0 0 1 1.881 1.295l0.586 3.177c0.647 3.508 -1.673 6.877 -5.181 7.523z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#N)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.415 7.142a0.798 0.798 0 0 0 -0.53 0.359l-2.125 3.087 -3.033 -2.096a0.796 0.796 0 0 0 -0.653 -0.181 0.808 0.808 0 0 0 -0.318 1.454l-0.011 0.011 3.099 2.143 0.665 0.458a0.808 0.808 0 0 0 1.122 -0.207l0.458 -0.665 2.144 -3.11a0.808 0.808 0 0 0 0.014 -0.903 0.808 0.808 0 0 0 -0.832 -0.35z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="462">
|
||||
<defs>
|
||||
<mask id="P" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="O" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#O)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.812 15.762c-3.496 0.71 -6.906 -1.55 -7.615 -5.046l-0.642 -3.165a1.614 1.614 0 0 1 1.261 -1.904l9.496 -1.927a1.614 1.614 0 0 1 1.904 1.261l0.642 3.166c0.71 3.496 -1.55 6.905 -5.046 7.615z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#P)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.39 7.393a0.798 0.798 0 0 0 -0.523 0.369l-2.07 3.124 -3.07 -2.041a0.796 0.796 0 0 0 -0.656 -0.17 0.808 0.808 0 0 0 -0.292 1.46l-0.01 0.011 3.136 2.087 0.673 0.446a0.808 0.808 0 0 0 1.119 -0.227l0.446 -0.673 2.087 -3.147a0.808 0.808 0 0 0 -0.002 -0.904 0.808 0.808 0 0 0 -0.838 -0.335z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="484">
|
||||
<defs>
|
||||
<mask id="R" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="Q" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#Q)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M12.937 16.077c-3.483 0.772 -6.933 -1.425 -7.705 -4.908l-0.7 -3.153a1.614 1.614 0 0 1 1.228 -1.927l9.46 -2.097a1.614 1.614 0 0 1 1.925 1.227l0.7 3.153c0.772 3.483 -1.426 6.933 -4.908 7.705z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#R)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.363 7.68a0.798 0.798 0 0 0 -0.515 0.379l-2.014 3.162 -3.106 -1.986a0.796 0.796 0 0 0 -0.66 -0.159 0.808 0.808 0 0 0 -0.265 1.465l-0.01 0.012 3.173 2.03 0.68 0.434a0.808 0.808 0 0 0 1.116 -0.247l0.433 -0.681 2.031 -3.185a0.808 0.808 0 0 0 -0.018 -0.903 0.808 0.808 0 0 0 -0.845 -0.32z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="506">
|
||||
<defs>
|
||||
<mask id="T" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="S" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#S)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.06 16.431c-3.468 0.835 -6.957 -1.3 -7.792 -4.768l-0.755 -3.14a1.614 1.614 0 0 1 1.192 -1.948l9.42 -2.268a1.614 1.614 0 0 1 1.948 1.192l0.756 3.14c0.835 3.468 -1.3 6.957 -4.769 7.792z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#T)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.336 8.01a0.798 0.798 0 0 0 -0.51 0.388l-1.955 3.197 -3.142 -1.93a0.796 0.796 0 0 0 -0.662 -0.146 0.808 0.808 0 0 0 -0.24 1.47l-0.01 0.011 3.21 1.974 0.689 0.42a0.808 0.808 0 0 0 1.11 -0.266l0.421 -0.689 1.973 -3.22a0.808 0.808 0 0 0 -0.034 -0.903 0.808 0.808 0 0 0 -0.85 -0.306z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="528">
|
||||
<defs>
|
||||
<mask id="V" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="U" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#U)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.183 16.83c-3.452 0.897 -6.979 -1.174 -7.876 -4.627l-0.813 -3.126a1.614 1.614 0 0 1 1.157 -1.97l9.378 -2.436a1.614 1.614 0 0 1 1.97 1.157l0.812 3.126c0.897 3.452 -1.175 6.979 -4.628 7.876z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#V)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.307 8.388a0.798 0.798 0 0 0 -0.502 0.396l-1.898 3.233 -3.176 -1.873a0.796 0.796 0 0 0 -0.665 -0.134 0.808 0.808 0 0 0 -0.212 1.473l-0.01 0.012 3.244 1.915 0.696 0.409a0.808 0.808 0 0 0 1.105 -0.287l0.41 -0.696 1.914 -3.256a0.808 0.808 0 0 0 -0.051 -0.902 0.808 0.808 0 0 0 -0.855 -0.29z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="550">
|
||||
<defs>
|
||||
<mask id="X" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="W" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#W)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.305 17.282c-3.436 0.959 -7 -1.049 -7.959 -4.485l-0.868 -3.11a1.614 1.614 0 0 1 1.121 -1.99l9.333 -2.606a1.614 1.614 0 0 1 1.99 1.121l0.868 3.11c0.96 3.437 -1.049 7 -4.485 7.96z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#X)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.276 8.82a0.798 0.798 0 0 0 -0.494 0.406l-1.84 3.266 -3.209 -1.815a0.796 0.796 0 0 0 -0.667 -0.123 0.808 0.808 0 0 0 -0.186 1.477l-0.01 0.013 3.279 1.856 0.703 0.396a0.808 0.808 0 0 0 1.1 -0.307l0.396 -0.703 1.856 -3.29a0.808 0.808 0 0 0 -0.067 -0.901 0.808 0.808 0 0 0 -0.86 -0.274z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="572">
|
||||
<defs>
|
||||
<mask id="Z" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="Y" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#Y)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.426 17.795c-3.419 1.02 -7.018 -0.923 -8.038 -4.341l-0.925 -3.095a1.614 1.614 0 0 1 1.085 -2.01l9.285 -2.772a1.614 1.614 0 0 1 2.009 1.085l0.924 3.095c1.021 3.418 -0.922 7.017 -4.34 8.038z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#Z)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.244 9.318a0.798 0.798 0 0 0 -0.487 0.414l-1.78 3.298 -3.241 -1.757a0.796 0.796 0 0 0 -0.67 -0.11 0.808 0.808 0 0 0 -0.16 1.48l-0.009 0.012 3.312 1.797 0.71 0.384a0.808 0.808 0 0 0 1.094 -0.327l0.384 -0.71 1.796 -3.323a0.808 0.808 0 0 0 -0.083 -0.9 0.808 0.808 0 0 0 -0.866 -0.258z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="594">
|
||||
<defs>
|
||||
<mask id="ab" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aa" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#aa)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.544 18.382c-3.4 1.081 -7.032 -0.797 -8.114 -4.197l-0.98 -3.077a1.614 1.614 0 0 1 1.05 -2.029l9.232 -2.939a1.614 1.614 0 0 1 2.029 1.05l0.98 3.077c1.081 3.4 -0.798 7.033 -4.197 8.115z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#ab)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.21 9.891a0.798 0.798 0 0 0 -0.479 0.423l-1.721 3.33 -3.272 -1.7a0.796 0.796 0 0 0 -0.67 -0.097 0.808 0.808 0 0 0 -0.134 1.482l-0.01 0.013 3.344 1.737 0.717 0.37a0.808 0.808 0 0 0 1.088 -0.345l0.37 -0.718 1.737 -3.354a0.808 0.808 0 0 0 -0.1 -0.898 0.808 0.808 0 0 0 -0.87 -0.243z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="616">
|
||||
<defs>
|
||||
<mask id="ad" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="ac" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#ac)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.66 19.058c-3.38 1.143 -7.045 -0.671 -8.187 -4.05l-1.035 -3.06a1.614 1.614 0 0 1 1.013 -2.047l9.18 -3.103a1.614 1.614 0 0 1 2.046 1.013l1.034 3.06c1.143 3.379 -0.671 7.045 -4.05 8.187z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#ad)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.176 10.557a0.798 0.798 0 0 0 -0.472 0.432l-1.662 3.36 -3.301 -1.64a0.796 0.796 0 0 0 -0.673 -0.087 0.808 0.808 0 0 0 -0.107 1.485l-0.01 0.012 3.375 1.678 0.723 0.358a0.808 0.808 0 0 0 1.082 -0.366l0.358 -0.723 1.676 -3.385a0.808 0.808 0 0 0 -0.115 -0.896 0.808 0.808 0 0 0 -0.874 -0.228z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="638">
|
||||
<defs>
|
||||
<mask id="af" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="ae" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5166 0 0 .5 13.667 28.016)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5166 0 0 .5 13.667 28.016)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M7.985 22.141c-0.57 0 -1.033 0.448 -1.033 1v10c0 0.552 0.463 1 1.033 1 0.57 0 1.033 -0.448 1.033 -1v-10c0 -0.552 -0.462 -1 -1.033 -1zm3.1 -1c-0.57 0 -1.033 0.448 -1.033 1v11c0 0.552 0.462 1 1.033 1 0.57 0 1.033 -0.448 1.033 -1v-11c0 -0.552 -0.463 -1 -1.033 -1zm8.202 11.658l-4.132 -11c-0.185 -0.523 -0.772 -0.8 -1.313 -0.622 -0.539 0.178 -0.827 0.747 -0.642 1.27a0.509 0.509 0 0 0 0.013 0.036l4.133 11c0.185 0.523 0.772 0.801 1.312 0.622 0.54 -0.178 0.828 -0.747 0.643 -1.27 -0.004 -0.012 -0.008 -0.024 -0.014 -0.036zm-14.401 -12.658c-0.57 0 -1.034 0.448 -1.034 1v12c0 0.552 0.463 1 1.034 1 0.57 0 1.033 -0.448 1.033 -1v-12c0 -0.552 -0.463 -1 -1.033 -1z" opacity="1"/>
|
||||
<g mask="url(#ae)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.774 19.847c-3.359 1.202 -7.056 -0.547 -8.258 -3.905l-1.088 -3.041a1.614 1.614 0 0 1 0.976 -2.065l9.123 -3.264a1.614 1.614 0 0 1 2.065 0.976l1.088 3.041c1.202 3.36 -0.547 7.057 -3.906 8.258z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#af)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.14 11.339a0.798 0.798 0 0 0 -0.465 0.44l-1.602 3.388 -3.33 -1.582a0.796 0.796 0 0 0 -0.674 -0.074 0.808 0.808 0 0 0 -0.08 1.486l-0.01 0.013 3.403 1.618 0.73 0.345a0.808 0.808 0 0 0 1.075 -0.385l0.345 -0.73 1.616 -3.413a0.808 0.808 0 0 0 -0.13 -0.894 0.808 0.808 0 0 0 -0.879 -0.212z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="660">
|
||||
<defs>
|
||||
<mask id="ah" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="ag" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5332 0 0 .5 13.9 28.407)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5332 0 0 .5 13.9 28.407)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.035 22.532c-0.589 0 -1.066 0.448 -1.066 1v10c0 0.552 0.477 1 1.066 1 0.589 0 1.066 -0.448 1.066 -1v-10c0 -0.552 -0.477 -1 -1.066 -1zm3.2 -1c-0.59 0 -1.067 0.448 -1.067 1v11c0 0.552 0.478 1 1.066 1 0.589 0 1.067 -0.448 1.067 -1v-11c0 -0.552 -0.478 -1 -1.067 -1zm8.465 11.658l-4.265 -11c-0.191 -0.523 -0.797 -0.8 -1.355 -0.622 -0.556 0.178 -0.854 0.747 -0.663 1.27l0.014 0.036 4.266 11c0.19 0.523 0.796 0.801 1.354 0.622 0.557 -0.178 0.854 -0.747 0.663 -1.27 -0.004 -0.012 -0.008 -0.024 -0.014 -0.036zm-14.864 -12.658c-0.589 0 -1.067 0.448 -1.067 1v12c0 0.552 0.478 1 1.067 1 0.588 0 1.066 -0.448 1.066 -1v-12c0 -0.552 -0.478 -1 -1.066 -1z" opacity="1"/>
|
||||
<g mask="url(#ag)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.884 20.78c-3.337 1.261 -7.065 -0.423 -8.325 -3.76l-1.141 -3.021a1.614 1.614 0 0 1 0.94 -2.082l9.064 -3.423a1.614 1.614 0 0 1 2.082 0.94l1.14 3.022c1.261 3.337 -0.423 7.065 -3.76 8.325z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#ah)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.1 12.267a0.798 0.798 0 0 0 -0.456 0.448l-1.543 3.416 -3.357 -1.523a0.796 0.796 0 0 0 -0.675 -0.063 0.808 0.808 0 0 0 -0.054 1.488l-0.01 0.013 3.431 1.557 0.736 0.333a0.808 0.808 0 0 0 1.068 -0.404l0.332 -0.735 1.557 -3.442a0.808 0.808 0 0 0 -0.147 -0.89 0.808 0.808 0 0 0 -0.881 -0.198z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="682">
|
||||
<defs>
|
||||
<mask id="aj" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="ai" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54974 0 0 .5 14.157 28.922)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54974 0 0 .5 14.157 28.922)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.11 23.047c-0.606 0 -1.099 0.448 -1.099 1v10c0 0.552 0.493 1 1.1 1 0.607 0 1.1 -0.448 1.1 -1v-10c0 -0.552 -0.493 -1 -1.1 -1zm3.3 -1c-0.608 0 -1.1 0.448 -1.1 1v11c0 0.552 0.492 1 1.1 1 0.606 0 1.099 -0.448 1.099 -1v-11c0 -0.552 -0.493 -1 -1.1 -1zm8.728 11.658l-4.398 -11c-0.197 -0.523 -0.821 -0.8 -1.396 -0.622 -0.574 0.178 -0.881 0.747 -0.684 1.27l0.014 0.036 4.398 11c0.197 0.523 0.821 0.801 1.396 0.622 0.574 -0.178 0.881 -0.747 0.684 -1.27l-0.014 -0.036zm-15.326 -12.658c-0.607 0 -1.1 0.448 -1.1 1v12c0 0.552 0.493 1 1.1 1 0.607 0 1.1 -0.448 1.1 -1v-12c0 -0.552 -0.493 -1 -1.1 -1z" opacity="1"/>
|
||||
<g mask="url(#ai)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M13.99 21.907c-3.315 1.318 -7.07 -0.301 -8.389 -3.616l-1.193 -3.001a1.614 1.614 0 0 1 0.904 -2.098l9.004 -3.58a1.614 1.614 0 0 1 2.097 0.905l1.193 3.001c1.318 3.315 -0.3 7.071 -3.616 8.39z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aj)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.06 13.39a0.798 0.798 0 0 0 -0.45 0.456l-1.483 3.443 -3.383 -1.465a0.796 0.796 0 0 0 -0.676 -0.051 0.808 0.808 0 0 0 -0.029 1.488l-0.008 0.013 3.457 1.499 0.741 0.32a0.808 0.808 0 0 0 1.061 -0.423l0.32 -0.741 1.496 -3.468a0.808 0.808 0 0 0 -0.162 -0.888 0.808 0.808 0 0 0 -0.885 -0.182z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="704">
|
||||
<defs>
|
||||
<mask id="al" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="ak" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56608 0 0 .5 14.405 29.44)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56608 0 0 .5 14.405 29.44)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.18 23.565c-0.626 0 -1.133 0.448 -1.133 1v10c0 0.552 0.507 1 1.132 1 0.625 0 1.133 -0.448 1.133 -1v-10c0 -0.552 -0.508 -1 -1.133 -1zm3.396 -1c-0.625 0 -1.132 0.448 -1.132 1v11c0 0.552 0.507 1 1.132 1 0.625 0 1.132 -0.448 1.132 -1v-11c0 -0.552 -0.507 -1 -1.132 -1zm8.988 11.658l-4.529 -11c-0.202 -0.523 -0.845 -0.8 -1.437 -0.622 -0.591 0.178 -0.907 0.747 -0.705 1.27a0.481 0.481 0 0 0 0.015 0.036l4.529 11c0.202 0.523 0.846 0.801 1.438 0.622 0.59 -0.178 0.907 -0.747 0.704 -1.27a0.481 0.481 0 0 0 -0.015 -0.036zm-15.781 -12.658c-0.625 0 -1.132 0.448 -1.132 1v12c0 0.552 0.507 1 1.132 1 0.625 0 1.132 -0.448 1.132 -1v-12c0 -0.552 -0.507 -1 -1.132 -1z" opacity="1"/>
|
||||
<g mask="url(#ak)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.091 23.304c-3.292 1.374 -7.075 -0.181 -8.45 -3.473l-1.243 -2.98a1.614 1.614 0 0 1 0.868 -2.113l8.941 -3.732a1.614 1.614 0 0 1 2.113 0.868l1.244 2.98c1.374 3.292 -0.18 7.076 -3.473 8.45z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#al)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M14.015 14.788a0.798 0.798 0 0 0 -0.44 0.463l-1.425 3.467 -3.408 -1.407a0.796 0.796 0 0 0 -0.677 -0.04 0.808 0.808 0 0 0 -0.003 1.489l-0.009 0.013 3.483 1.44 0.746 0.306a0.808 0.808 0 0 0 1.054 -0.44l0.307 -0.746 1.437 -3.493a0.808 0.808 0 0 0 -0.177 -0.886 0.808 0.808 0 0 0 -0.888 -0.166z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="726">
|
||||
<defs>
|
||||
<mask id="an" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="am" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58198 0 0 .5 14.61 29.84)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58198 0 0 .5 14.61 29.84)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.209 23.965c-0.643 0 -1.164 0.448 -1.164 1v10c0 0.552 0.521 1 1.164 1 0.642 0 1.164 -0.448 1.164 -1v-10c0 -0.552 -0.522 -1 -1.164 -1zm3.492 -1c-0.643 0 -1.164 0.448 -1.164 1v11c0 0.552 0.521 1 1.164 1 0.642 0 1.164 -0.448 1.164 -1v-11c0 -0.552 -0.522 -1 -1.164 -1zm9.24 11.658l-4.655 -11c-0.209 -0.523 -0.87 -0.801 -1.479 -0.622 -0.607 0.178 -0.932 0.747 -0.724 1.27a0.474 0.474 0 0 0 0.016 0.036l4.655 11c0.209 0.523 0.87 0.8 1.479 0.622 0.607 -0.178 0.932 -0.747 0.724 -1.27l-0.016 -0.036zm-16.224 -12.658c-0.642 0 -1.164 0.448 -1.164 1v12c0 0.552 0.522 1 1.164 1 0.643 0 1.164 -0.448 1.164 -1v-12c0 -0.552 -0.521 -1 -1.164 -1z" opacity="1"/>
|
||||
<g mask="url(#am)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.185 25.102c-3.269 1.429 -7.077 -0.063 -8.506 -3.331l-1.294 -2.96a1.614 1.614 0 0 1 0.833 -2.126l8.878 -3.882a1.614 1.614 0 0 1 2.126 0.833l1.294 2.96c1.429 3.268 -0.062 7.077 -3.331 8.506z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#an)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.967 16.588a0.798 0.798 0 0 0 -0.434 0.47l-1.366 3.49 -3.43 -1.35a0.796 0.796 0 0 0 -0.678 -0.028 0.808 0.808 0 0 0 0.022 1.49l-0.009 0.012 3.506 1.381 0.752 0.295a0.808 0.808 0 0 0 1.046 -0.458l0.294 -0.752 1.379 -3.516a0.808 0.808 0 0 0 -0.192 -0.882 0.808 0.808 0 0 0 -0.89 -0.152z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="748">
|
||||
<defs>
|
||||
<mask id="ap" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="ao" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5969 0 0 .5 14.733 30)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5969 0 0 .5 14.733 30)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.169 24.125c-0.66 0 -1.194 0.448 -1.194 1v10c0 0.552 0.535 1 1.194 1 0.659 0 1.193 -0.448 1.193 -1v-10c0 -0.552 -0.534 -1 -1.193 -1zm3.581 -1c-0.659 0 -1.194 0.448 -1.194 1v11c0 0.552 0.535 1 1.194 1 0.659 0 1.194 -0.448 1.194 -1v-11c0 -0.552 -0.535 -1 -1.194 -1zm9.478 11.658l-4.776 -11c-0.213 -0.523 -0.891 -0.801 -1.516 -0.622 -0.623 0.178 -0.956 0.747 -0.742 1.27a0.467 0.467 0 0 0 0.015 0.036l4.775 11c0.214 0.523 0.892 0.801 1.517 0.622 0.623 -0.178 0.956 -0.747 0.742 -1.27l-0.015 -0.036zm-16.64 -12.658c-0.66 0 -1.195 0.448 -1.195 1v12c0 0.552 0.535 1 1.194 1 0.66 0 1.194 -0.448 1.194 -1v-12c0 -0.552 -0.535 -1 -1.194 -1z" opacity="1"/>
|
||||
<g mask="url(#ao)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.27 27.514c-3.246 1.482 -7.078 0.053 -8.56 -3.191l-1.342 -2.938a1.614 1.614 0 0 1 0.797 -2.14l8.814 -4.026a1.614 1.614 0 0 1 2.14 0.798l1.342 2.938c1.482 3.244 0.053 7.077 -3.192 8.56z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#ap)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.912 19.005a0.798 0.798 0 0 0 -0.426 0.478l-1.309 3.512 -3.452 -1.294a0.796 0.796 0 0 0 -0.678 -0.017 0.808 0.808 0 0 0 0.046 1.488l-0.008 0.014 3.528 1.323 0.756 0.282a0.808 0.808 0 0 0 1.039 -0.475l0.282 -0.756 1.32 -3.538a0.808 0.808 0 0 0 -0.206 -0.88 0.808 0.808 0 0 0 -0.892 -0.137z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="770">
|
||||
<defs>
|
||||
<mask id="ar" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aq" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.60979 0 0 .5 14.812 29.779)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.60979 0 0 .5 14.812 29.779)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.105 23.904c-0.673 0 -1.22 0.448 -1.22 1v10c0 0.552 0.547 1 1.22 1 0.674 0 1.22 -0.448 1.22 -1v-10c0 -0.552 -0.546 -1 -1.22 -1zm3.659 -1c-0.673 0 -1.22 0.448 -1.22 1v11c0 0.552 0.547 1 1.22 1 0.673 0 1.22 -0.448 1.22 -1v-11c0 -0.552 -0.547 -1 -1.22 -1zm9.682 11.658l-4.878 -11c-0.218 -0.523 -0.911 -0.801 -1.549 -0.622 -0.637 0.178 -0.977 0.747 -0.758 1.27a0.462 0.462 0 0 0 0.015 0.036l4.879 11c0.218 0.523 0.91 0.8 1.549 0.622 0.636 -0.178 0.976 -0.747 0.758 -1.27l-0.016 -0.036zm-17 -12.658c-0.673 0 -1.219 0.448 -1.219 1v12c0 0.552 0.546 1 1.22 1 0.673 0 1.22 -0.448 1.22 -1v-12c0 -0.552 -0.547 -1 -1.22 -1z" opacity="1"/>
|
||||
<g mask="url(#aq)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.342 30.655c-3.22 1.534 -7.075 0.166 -8.61 -3.055l-1.388 -2.916a1.614 1.614 0 0 1 0.764 -2.152l8.748 -4.166a1.614 1.614 0 0 1 2.153 0.764l1.388 2.916c1.534 3.22 0.166 7.075 -3.055 8.61z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#ar)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.85 22.153a0.798 0.798 0 0 0 -0.418 0.484l-1.253 3.533 -3.473 -1.24a0.796 0.796 0 0 0 -0.678 -0.005 0.808 0.808 0 0 0 0.07 1.487l-0.008 0.013 3.548 1.267 0.761 0.27a0.808 0.808 0 0 0 1.03 -0.49l0.27 -0.761 1.266 -3.56a0.808 0.808 0 0 0 -0.22 -0.875 0.808 0.808 0 0 0 -0.896 -0.123z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="792">
|
||||
<defs>
|
||||
<mask id="at" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="as" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61897 0 0 .5 14.884 29.251)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61897 0 0 .5 14.884 29.251)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.076 23.376c-0.683 0 -1.237 0.448 -1.237 1v10c0 0.552 0.554 1 1.237 1 0.684 0 1.238 -0.448 1.238 -1v-10c0 -0.552 -0.554 -1 -1.238 -1zm3.714 -1c-0.683 0 -1.238 0.448 -1.238 1v11c0 0.552 0.555 1 1.238 1 0.684 0 1.238 -0.448 1.238 -1v-11c0 -0.552 -0.554 -1 -1.238 -1zm9.828 11.658l-4.951 -11c-0.222 -0.523 -0.925 -0.801 -1.573 -0.622 -0.646 0.178 -0.991 0.747 -0.77 1.27a0.459 0.459 0 0 0 0.016 0.036l4.952 11c0.222 0.523 0.925 0.801 1.572 0.622 0.647 -0.178 0.992 -0.747 0.77 -1.27a0.459 0.459 0 0 0 -0.016 -0.036zm-17.255 -12.658c-0.684 0 -1.238 0.448 -1.238 1v12c0 0.552 0.554 1 1.238 1 0.683 0 1.238 -0.448 1.238 -1v-12c0 -0.552 -0.555 -1 -1.238 -1z" opacity="1"/>
|
||||
<g mask="url(#as)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.412 33.611c-3.196 1.583 -7.072 0.274 -8.655 -2.923l-1.433 -2.894a1.614 1.614 0 0 1 0.73 -2.164l8.684 -4.3a1.614 1.614 0 0 1 2.164 0.731l1.433 2.895c1.583 3.197 0.274 7.072 -2.923 8.655z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#at)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.79 25.117a0.798 0.798 0 0 0 -0.411 0.49l-1.199 3.552 -3.49 -1.185a0.796 0.796 0 0 0 -0.679 0.004 0.808 0.808 0 0 0 0.093 1.486l-0.008 0.014 3.567 1.212 0.765 0.258a0.808 0.808 0 0 0 1.023 -0.506l0.259 -0.765 1.21 -3.578a0.808 0.808 0 0 0 -0.234 -0.873 0.808 0.808 0 0 0 -0.897 -0.109z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="814">
|
||||
<defs>
|
||||
<mask id="av" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="au" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62351 0 0 .5 14.922 28.62)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62351 0 0 .5 14.922 28.62)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.064 22.746c-0.688 0 -1.247 0.448 -1.247 1v10c0 0.552 0.56 1 1.247 1 0.689 0 1.247 -0.448 1.247 -1v-10c0 -0.552 -0.558 -1 -1.247 -1zm3.741 -1c-0.688 0 -1.247 0.448 -1.247 1v11c0 0.552 0.56 1 1.247 1 0.689 0 1.247 -0.448 1.247 -1v-11c0 -0.552 -0.558 -1 -1.247 -1zm9.9 11.658l-4.988 -11c-0.223 -0.523 -0.931 -0.801 -1.583 -0.622 -0.651 0.178 -1 0.747 -0.776 1.27l0.016 0.036 4.988 11c0.224 0.523 0.932 0.8 1.584 0.622 0.651 -0.178 0.999 -0.747 0.776 -1.27a0.457 0.457 0 0 0 -0.016 -0.036zm-17.382 -12.658c-0.688 0 -1.247 0.448 -1.247 1v12c0 0.552 0.559 1 1.247 1 0.689 0 1.247 -0.448 1.247 -1v-12c0 -0.552 -0.558 -1 -1.247 -1z" opacity="1"/>
|
||||
<g mask="url(#au)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.489 35.462c-3.174 1.63 -7.068 0.378 -8.697 -2.796l-1.475 -2.873a1.614 1.614 0 0 1 0.698 -2.174l8.62 -4.426a1.614 1.614 0 0 1 2.174 0.699l1.475 2.873c1.63 3.173 0.378 7.067 -2.795 8.697z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#av)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.741 26.978a0.798 0.798 0 0 0 -0.403 0.497l-1.146 3.568 -3.508 -1.134a0.796 0.796 0 0 0 -0.678 0.014 0.808 0.808 0 0 0 0.114 1.485l-0.007 0.013 3.584 1.16 0.769 0.248a0.808 0.808 0 0 0 1.016 -0.522l0.247 -0.769 1.157 -3.595a0.808 0.808 0 0 0 -0.247 -0.869 0.808 0.808 0 0 0 -0.898 -0.096z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="836">
|
||||
<defs>
|
||||
<mask id="ax" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aw" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62484 0 0 .5 14.911 28.093)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62484 0 0 .5 14.911 28.093)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.04 22.218c-0.69 0 -1.25 0.448 -1.25 1v10c0 0.552 0.56 1 1.25 1s1.249 -0.448 1.249 -1v-10c0 -0.552 -0.56 -1 -1.25 -1zm3.748 -1c-0.69 0 -1.25 0.448 -1.25 1v11c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-11c0 -0.552 -0.56 -1 -1.25 -1zm9.922 11.658l-5 -11c-0.223 -0.523 -0.933 -0.801 -1.586 -0.622 -0.653 0.178 -1.001 0.747 -0.778 1.27a0.457 0.457 0 0 0 0.017 0.036l4.998 11c0.224 0.523 0.934 0.801 1.588 0.622 0.652 -0.178 1 -0.747 0.777 -1.27a0.457 0.457 0 0 0 -0.016 -0.036zm-17.42 -12.658c-0.69 0 -1.25 0.448 -1.25 1v12c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-12c0 -0.552 -0.56 -1 -1.25 -1z" opacity="1"/>
|
||||
<g mask="url(#aw)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.567 36.513c-3.15 1.673 -7.061 0.475 -8.734 -2.676l-1.515 -2.852a1.614 1.614 0 0 1 0.669 -2.184l8.558 -4.544a1.614 1.614 0 0 1 2.183 0.669l1.515 2.852c1.673 3.151 0.475 7.062 -2.676 8.735z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#ax)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.703 28.04a0.798 0.798 0 0 0 -0.396 0.502l-1.097 3.584 -3.523 -1.085a0.796 0.796 0 0 0 -0.678 0.023 0.808 0.808 0 0 0 0.134 1.483l-0.007 0.014 3.6 1.11 0.772 0.237a0.808 0.808 0 0 0 1.009 -0.536l0.236 -0.772 1.108 -3.61a0.808 0.808 0 0 0 -0.258 -0.866 0.808 0.808 0 0 0 -0.9 -0.084z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="858">
|
||||
<defs>
|
||||
<mask id="az" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="ay" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.625 0 0 .5 14.874 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.625 0 0 .5 14.874 27.875)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22c-0.69 0 -1.25 0.448 -1.25 1v10c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-10c0 -0.552 -0.56 -1 -1.25 -1zm3.75 -1c-0.69 0 -1.25 0.448 -1.25 1v11c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-11c0 -0.552 -0.56 -1 -1.25 -1zm9.924 11.658l-5 -11c-0.224 -0.523 -0.934 -0.801 -1.588 -0.622 -0.652 0.178 -1.001 0.747 -0.777 1.27l0.016 0.036 5 11c0.224 0.523 0.934 0.801 1.587 0.622 0.653 -0.178 1.002 -0.747 0.778 -1.27a0.457 0.457 0 0 0 -0.016 -0.036zm-17.424 -12.658c-0.69 0 -1.25 0.448 -1.25 1v12c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-12c0 -0.552 -0.56 -1 -1.25 -1z" opacity="1"/>
|
||||
<g mask="url(#ay)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.642 37.113c-3.13 1.713 -7.055 0.564 -8.768 -2.566l-1.55 -2.833a1.614 1.614 0 0 1 0.642 -2.192l8.5 -4.651a1.614 1.614 0 0 1 2.192 0.641l1.55 2.834c1.712 3.13 0.563 7.055 -2.566 8.767z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#az)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.672 28.652a0.798 0.798 0 0 0 -0.39 0.507l-1.052 3.597 -3.537 -1.041a0.796 0.796 0 0 0 -0.677 0.032 0.808 0.808 0 0 0 0.153 1.48l-0.007 0.015 3.614 1.065 0.774 0.227a0.808 0.808 0 0 0 1.002 -0.548l0.227 -0.775 1.062 -3.624a0.808 0.808 0 0 0 -0.269 -0.863 0.808 0.808 0 0 0 -0.9 -0.072z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="880">
|
||||
<defs>
|
||||
<mask id="aB" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aA" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61111 0 0 .5 14.775 27.817)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61111 0 0 .5 14.775 27.817)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.054 21.942c-0.674 0 -1.222 0.448 -1.222 1v10c0 0.552 0.548 1 1.222 1 0.675 0 1.223 -0.448 1.223 -1v-10c0 -0.552 -0.548 -1 -1.223 -1zm3.667 -1c-0.675 0 -1.222 0.448 -1.222 1v11c0 0.552 0.547 1 1.222 1 0.675 0 1.222 -0.448 1.222 -1v-11c0 -0.552 -0.547 -1 -1.222 -1zm9.703 11.658l-4.889 -11c-0.218 -0.523 -0.913 -0.8 -1.552 -0.622 -0.638 0.178 -0.979 0.747 -0.76 1.27l0.016 0.036 4.889 11c0.219 0.523 0.913 0.801 1.552 0.622 0.638 -0.178 0.979 -0.747 0.76 -1.27l-0.016 -0.036zm-17.036 -12.658c-0.675 0 -1.222 0.448 -1.222 1v12c0 0.552 0.547 1 1.222 1 0.674 0 1.222 -0.448 1.222 -1v-12c0 -0.552 -0.548 -1 -1.222 -1z" opacity="1"/>
|
||||
<g mask="url(#aA)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.708 37.444c-3.11 1.746 -7.048 0.64 -8.795 -2.47l-1.58 -2.817a1.614 1.614 0 0 1 0.617 -2.199l8.449 -4.743a1.614 1.614 0 0 1 2.199 0.617l1.58 2.817c1.747 3.11 0.64 7.048 -2.47 8.795z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aB)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.646 28.993a0.798 0.798 0 0 0 -0.384 0.512l-1.013 3.608 -3.548 -1.003a0.796 0.796 0 0 0 -0.677 0.04 0.808 0.808 0 0 0 0.17 1.479l-0.008 0.014 3.626 1.026 0.777 0.218a0.808 0.808 0 0 0 0.995 -0.559l0.219 -0.777 1.023 -3.636a0.808 0.808 0 0 0 -0.279 -0.859 0.808 0.808 0 0 0 -0.9 -0.063z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="902">
|
||||
<defs>
|
||||
<mask id="aD" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aC" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.59722 0 0 .5 14.62 27.745)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.59722 0 0 .5 14.62 27.745)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.052 21.87c-0.659 0 -1.194 0.448 -1.194 1v10c0 0.552 0.535 1 1.194 1 0.66 0 1.195 -0.448 1.195 -1v-10c0 -0.552 -0.535 -1 -1.195 -1zm3.584 -1c-0.66 0 -1.195 0.448 -1.195 1v11c0 0.552 0.535 1 1.195 1 0.659 0 1.194 -0.448 1.194 -1v-11c0 -0.552 -0.535 -1 -1.194 -1zm9.482 11.658l-4.777 -11c-0.214 -0.523 -0.893 -0.801 -1.517 -0.622 -0.624 0.178 -0.957 0.747 -0.743 1.27a0.467 0.467 0 0 0 0.015 0.036l4.778 11c0.214 0.523 0.892 0.8 1.517 0.622 0.623 -0.178 0.957 -0.747 0.743 -1.27a0.467 0.467 0 0 0 -0.016 -0.036zm-16.649 -12.658c-0.66 0 -1.194 0.448 -1.194 1v12c0 0.552 0.535 1 1.194 1 0.66 0 1.194 -0.448 1.194 -1v-12c0 -0.552 -0.535 -1 -1.194 -1z" opacity="1"/>
|
||||
<g mask="url(#aC)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.76 37.601c-3.096 1.772 -7.043 0.7 -8.815 -2.397l-1.605 -2.803a1.614 1.614 0 0 1 0.6 -2.204l8.409 -4.813a1.614 1.614 0 0 1 2.204 0.6l1.604 2.802c1.772 3.096 0.699 7.043 -2.397 8.815z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aD)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.627 29.16a0.798 0.798 0 0 0 -0.38 0.515l-0.983 3.617 -3.556 -0.974a0.796 0.796 0 0 0 -0.676 0.045 0.808 0.808 0 0 0 0.181 1.478l-0.007 0.014 3.634 0.996 0.78 0.212a0.808 0.808 0 0 0 0.99 -0.567l0.212 -0.78 0.993 -3.643a0.808 0.808 0 0 0 -0.286 -0.857 0.808 0.808 0 0 0 -0.902 -0.056z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="924">
|
||||
<defs>
|
||||
<mask id="aF" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aE" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58333 0 0 .5 14.429 27.718)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58333 0 0 .5 14.429 27.718)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8.013 21.843c-0.644 0 -1.166 0.448 -1.166 1v10c0 0.552 0.522 1 1.166 1 0.644 0 1.167 -0.448 1.167 -1v-10c0 -0.552 -0.523 -1 -1.167 -1zm3.5 -1c-0.644 0 -1.166 0.448 -1.166 1v11c0 0.552 0.522 1 1.166 1 0.644 0 1.167 -0.448 1.167 -1v-11c0 -0.552 -0.523 -1 -1.167 -1zm9.262 11.658l-4.666 -11c-0.21 -0.523 -0.872 -0.801 -1.482 -0.622 -0.609 0.178 -0.934 0.747 -0.726 1.27a0.473 0.473 0 0 0 0.016 0.036l4.666 11c0.21 0.523 0.872 0.8 1.482 0.622 0.609 -0.178 0.934 -0.747 0.726 -1.27l-0.016 -0.036zm-16.262 -12.658c-0.644 0 -1.166 0.448 -1.166 1v12c0 0.552 0.522 1 1.166 1 0.644 0 1.167 -0.448 1.167 -1v-12c0 -0.552 -0.523 -1 -1.167 -1z" opacity="1"/>
|
||||
<g mask="url(#aE)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.783 37.647c-3.09 1.784 -7.04 0.725 -8.824 -2.364l-1.615 -2.797a1.614 1.614 0 0 1 0.591 -2.206l8.391 -4.845a1.614 1.614 0 0 1 2.206 0.591l1.615 2.797c1.784 3.09 0.725 7.04 -2.364 8.824z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aF)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.62 29.21a0.798 0.798 0 0 0 -0.379 0.516l-0.97 3.62 -3.559 -0.96a0.796 0.796 0 0 0 -0.677 0.048 0.808 0.808 0 0 0 0.188 1.477l-0.007 0.014 3.637 0.982 0.78 0.21a0.808 0.808 0 0 0 0.989 -0.571l0.209 -0.78 0.979 -3.648a0.808 0.808 0 0 0 -0.29 -0.856 0.808 0.808 0 0 0 -0.9 -0.052z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="946">
|
||||
<defs>
|
||||
<mask id="aH" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aG" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56944 0 0 .5 14.233 27.728)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56944 0 0 .5 14.233 27.728)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M7.97 21.853c-0.629 0 -1.139 0.448 -1.139 1v10c0 0.552 0.51 1 1.139 1s1.139 -0.448 1.139 -1v-10c0 -0.552 -0.51 -1 -1.139 -1zm3.417 -1c-0.629 0 -1.14 0.448 -1.14 1v11c0 0.552 0.511 1 1.14 1 0.628 0 1.139 -0.448 1.139 -1v-11c0 -0.552 -0.51 -1 -1.14 -1zm9.041 11.658l-4.555 -11c-0.204 -0.523 -0.851 -0.8 -1.447 -0.622 -0.594 0.178 -0.912 0.747 -0.708 1.27a0.48 0.48 0 0 0 0.015 0.036l4.555 11c0.204 0.523 0.851 0.801 1.447 0.622 0.594 -0.178 0.912 -0.747 0.708 -1.27a0.48 0.48 0 0 0 -0.015 -0.036zm-15.875 -12.658c-0.628 0 -1.139 0.448 -1.139 1v12c0 0.552 0.51 1 1.14 1 0.628 0 1.138 -0.448 1.138 -1v-12c0 -0.552 -0.51 -1 -1.139 -1z" opacity="1"/>
|
||||
<g mask="url(#aG)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.783 37.647c-3.09 1.784 -7.04 0.725 -8.824 -2.364l-1.615 -2.797a1.614 1.614 0 0 1 0.591 -2.206l8.391 -4.845a1.614 1.614 0 0 1 2.206 0.591l1.615 2.797c1.784 3.09 0.725 7.04 -2.364 8.824z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aH)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.62 29.21a0.798 0.798 0 0 0 -0.379 0.516l-0.97 3.621 -3.559 -0.96a0.796 0.796 0 0 0 -0.677 0.047 0.808 0.808 0 0 0 0.188 1.477l-0.007 0.014 3.637 0.983 0.78 0.209a0.808 0.808 0 0 0 0.989 -0.571l0.209 -0.78 0.979 -3.648a0.808 0.808 0 0 0 -0.29 -0.856 0.808 0.808 0 0 0 -0.9 -0.051z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="968">
|
||||
<defs>
|
||||
<mask id="aJ" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aI" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.55556 0 0 .5 14.046 27.757)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.55556 0 0 .5 14.046 27.757)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M7.936 21.882c-0.614 0 -1.112 0.448 -1.112 1v10c0 0.552 0.498 1 1.112 1 0.613 0 1.11 -0.448 1.11 -1v-10c0 -0.552 -0.497 -1 -1.11 -1zm3.333 -1c-0.613 0 -1.111 0.448 -1.111 1v11c0 0.552 0.498 1 1.11 1 0.614 0 1.112 -0.448 1.112 -1v-11c0 -0.552 -0.498 -1 -1.111 -1zm8.821 11.658l-4.444 -11c-0.2 -0.523 -0.83 -0.8 -1.412 -0.622 -0.58 0.178 -0.89 0.747 -0.69 1.27a0.487 0.487 0 0 0 0.014 0.036l4.444 11c0.2 0.523 0.83 0.801 1.411 0.622 0.58 -0.178 0.89 -0.747 0.691 -1.27a0.487 0.487 0 0 0 -0.014 -0.036zm-15.488 -12.658c-0.613 0 -1.11 0.448 -1.11 1v12c0 0.552 0.497 1 1.11 1 0.614 0 1.111 -0.448 1.111 -1v-12c0 -0.552 -0.497 -1 -1.11 -1z" opacity="1"/>
|
||||
<g mask="url(#aI)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.783 37.647c-3.09 1.784 -7.04 0.725 -8.824 -2.364l-1.615 -2.797a1.614 1.614 0 0 1 0.591 -2.206l8.391 -4.845a1.614 1.614 0 0 1 2.206 0.591l1.615 2.797c1.784 3.09 0.725 7.04 -2.364 8.824z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aJ)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.62 29.21a0.798 0.798 0 0 0 -0.379 0.516l-0.97 3.621 -3.559 -0.96a0.796 0.796 0 0 0 -0.677 0.047 0.808 0.808 0 0 0 0.188 1.477l-0.007 0.014 3.637 0.983 0.78 0.209a0.808 0.808 0 0 0 0.989 -0.571l0.209 -0.78 0.979 -3.648a0.808 0.808 0 0 0 -0.29 -0.856 0.808 0.808 0 0 0 -0.9 -0.051z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="990">
|
||||
<defs>
|
||||
<mask id="aL" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aK" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54167 0 0 .5 13.872 27.794)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54167 0 0 .5 13.872 27.794)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M7.915 21.919c-0.598 0 -1.083 0.448 -1.083 1v10c0 0.552 0.485 1 1.083 1s1.084 -0.448 1.084 -1v-10c0 -0.552 -0.486 -1 -1.084 -1zm3.25 -1c-0.598 0 -1.083 0.448 -1.083 1v11c0 0.552 0.485 1 1.083 1s1.084 -0.448 1.084 -1v-11c0 -0.552 -0.486 -1 -1.084 -1zm8.6 11.658l-4.333 -11c-0.193 -0.523 -0.809 -0.801 -1.375 -0.622 -0.566 0.178 -0.868 0.747 -0.674 1.27a0.494 0.494 0 0 0 0.014 0.036l4.333 11c0.194 0.523 0.81 0.8 1.376 0.622 0.566 -0.178 0.868 -0.747 0.674 -1.27a0.494 0.494 0 0 0 -0.014 -0.036zm-15.1 -12.658c-0.598 0 -1.083 0.448 -1.083 1v12c0 0.552 0.485 1 1.083 1s1.084 -0.448 1.084 -1v-12c0 -0.552 -0.486 -1 -1.084 -1z" opacity="1"/>
|
||||
<g mask="url(#aK)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.783 37.647c-3.09 1.784 -7.04 0.725 -8.824 -2.364l-1.615 -2.797a1.614 1.614 0 0 1 0.591 -2.206l8.391 -4.845a1.614 1.614 0 0 1 2.206 0.591l1.615 2.797c1.784 3.09 0.725 7.04 -2.364 8.824z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aL)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.62 29.21a0.798 0.798 0 0 0 -0.379 0.516l-0.97 3.621 -3.559 -0.96a0.796 0.796 0 0 0 -0.677 0.047 0.808 0.808 0 0 0 0.188 1.477l-0.007 0.014 3.637 0.983 0.78 0.209a0.808 0.808 0 0 0 0.989 -0.571l0.209 -0.78 0.979 -3.648a0.808 0.808 0 0 0 -0.29 -0.856 0.808 0.808 0 0 0 -0.9 -0.051z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="1012">
|
||||
<defs>
|
||||
<mask id="aN" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aM" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.52778 0 0 .5 13.719 27.83)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.52778 0 0 .5 13.719 27.83)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M7.914 21.956c-0.583 0 -1.056 0.448 -1.056 1v10c0 0.552 0.473 1 1.056 1 0.583 0 1.056 -0.448 1.056 -1v-10c0 -0.552 -0.473 -1 -1.056 -1zm3.167 -1c-0.583 0 -1.056 0.448 -1.056 1v11c0 0.552 0.473 1 1.056 1 0.582 0 1.055 -0.448 1.055 -1v-11c0 -0.552 -0.473 -1 -1.055 -1zm8.38 11.658l-4.222 -11c-0.19 -0.523 -0.789 -0.801 -1.341 -0.622 -0.551 0.178 -0.846 0.747 -0.657 1.27l0.014 0.036 4.222 11c0.19 0.523 0.789 0.8 1.34 0.622 0.552 -0.178 0.846 -0.747 0.657 -1.27l-0.013 -0.036zm-14.714 -12.658c-0.582 0 -1.055 0.448 -1.055 1v12c0 0.552 0.473 1 1.055 1 0.583 0 1.056 -0.448 1.056 -1v-12c0 -0.552 -0.473 -1 -1.056 -1z" opacity="1"/>
|
||||
<g mask="url(#aM)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.783 37.647c-3.09 1.784 -7.04 0.725 -8.824 -2.364l-1.615 -2.797a1.614 1.614 0 0 1 0.591 -2.206l8.391 -4.845a1.614 1.614 0 0 1 2.206 0.591l1.615 2.797c1.784 3.09 0.725 7.04 -2.364 8.824z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aN)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.62 29.21a0.798 0.798 0 0 0 -0.379 0.516l-0.97 3.621 -3.559 -0.96a0.796 0.796 0 0 0 -0.677 0.047 0.808 0.808 0 0 0 0.188 1.477l-0.007 0.014 3.637 0.983 0.78 0.209a0.808 0.808 0 0 0 0.989 -0.571l0.209 -0.78 0.979 -3.648a0.808 0.808 0 0 0 -0.29 -0.856 0.808 0.808 0 0 0 -0.9 -0.051z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="1034">
|
||||
<defs>
|
||||
<mask id="aP" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aO" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.51389 0 0 .5 13.59 27.86)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.51389 0 0 .5 13.59 27.86)"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M7.938 21.986c-0.567 0 -1.027 0.448 -1.027 1v10c0 0.552 0.46 1 1.027 1 0.568 0 1.028 -0.448 1.028 -1v-10c0 -0.552 -0.46 -1 -1.028 -1zm3.084 -1c-0.568 0 -1.028 0.448 -1.028 1v11c0 0.552 0.46 1 1.028 1 0.567 0 1.028 -0.448 1.028 -1v-11c0 -0.552 -0.46 -1 -1.028 -1zm8.16 11.658l-4.112 -11c-0.184 -0.523 -0.768 -0.801 -1.305 -0.622 -0.537 0.178 -0.823 0.747 -0.64 1.27a0.51 0.51 0 0 0 0.014 0.036l4.111 11c0.184 0.523 0.768 0.8 1.305 0.622 0.537 -0.178 0.824 -0.747 0.64 -1.27l-0.014 -0.036zm-14.327 -12.658c-0.567 0 -1.028 0.448 -1.028 1v12c0 0.552 0.46 1 1.028 1 0.567 0 1.028 -0.448 1.028 -1v-12c0 -0.552 -0.46 -1 -1.028 -1z" opacity="1"/>
|
||||
<g mask="url(#aO)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.783 37.647c-3.09 1.784 -7.04 0.725 -8.824 -2.364l-1.615 -2.797a1.614 1.614 0 0 1 0.591 -2.206l8.391 -4.845a1.614 1.614 0 0 1 2.206 0.591l1.615 2.797c1.784 3.09 0.725 7.04 -2.364 8.824z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aP)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.62 29.21a0.798 0.798 0 0 0 -0.379 0.516l-0.97 3.621 -3.559 -0.96a0.796 0.796 0 0 0 -0.677 0.047 0.808 0.808 0 0 0 0.188 1.477l-0.007 0.014 3.637 0.983 0.78 0.209a0.808 0.808 0 0 0 0.989 -0.571l0.209 -0.78 0.979 -3.648a0.808 0.808 0 0 0 -0.29 -0.856 0.808 0.808 0 0 0 -0.9 -0.051z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="1056">
|
||||
<defs>
|
||||
<mask id="aR" mask-type="alpha">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.658 0.5 2.375 5.876 8.467 -1.751 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" opacity="1" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
</mask>
|
||||
<mask id="aQ" mask-type="alpha">
|
||||
<g opacity="1">
|
||||
<path fill="#11DBEA" fill-opacity="1" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 3.75 5.5 1 0.75 -2.25 3.25 -0.125 6.229 0.505 4.259 11.371 7.012 -7.251 2.75 -18.125 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.499 27.875)"/>
|
||||
<path fill-opacity="0" stroke="#871111" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="0" d="M-1.063 -10.563l-7.75 24.313 10.687 6 2.75 -0.375 1.5 -0.125 1.125 1.875 2.75 0.5 0.375 -1.125 1.625 -0.063 3.115 0.253 2.129 5.685 3.506 -3.625 1.375 -9.062 3 -12.625 -0.375 -11.125 -25.812 -0.5z"/>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#aQ)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M14.783 37.647c-3.09 1.784 -7.04 0.725 -8.824 -2.364l-1.615 -2.797a1.614 1.614 0 0 1 0.591 -2.206l8.391 -4.845a1.614 1.614 0 0 1 2.206 0.591l1.615 2.797c1.784 3.09 0.725 7.04 -2.364 8.824z" opacity="1"/>
|
||||
</g>
|
||||
<g mask="url(#aR)">
|
||||
<path fill="#FFF" fill-opacity="1" d="M13.62 29.21a0.798 0.798 0 0 0 -0.379 0.516l-0.97 3.621 -3.559 -0.96a0.796 0.796 0 0 0 -0.677 0.047 0.808 0.808 0 0 0 0.188 1.477l-0.007 0.014 3.637 0.983 0.78 0.209a0.808 0.808 0 0 0 0.989 -0.571l0.209 -0.78 0.979 -3.648a0.808 0.808 0 0 0 -0.29 -0.856 0.808 0.808 0 0 0 -0.9 -0.051z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg x="1078">
|
||||
<path fill="context-fill" fill-opacity="1" d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z" opacity="1"/>
|
||||
<g mask="url(#bS)">
|
||||
<path fill="#EF3F56" fill-opacity="1" d="M8.8 14.017c-3.538 -1.288 -5.363 -5.201 -4.075 -8.74l1.166 -3.203a1.704 1.704 0 0 1 2.185 -1.02l9.611 3.499a1.704 1.704 0 0 1 1.019 2.185l-1.166 3.203c-1.288 3.539 -5.201 5.364 -8.74 4.076z" opacity="1"/>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
After Width: | Height: | Size: 109 KiB |
157
browser/extensions/pocket/skin/shared/pocket-animation.svg
Normal file
157
browser/extensions/pocket/skin/shared/pocket-animation.svg
Normal file
@ -0,0 +1,157 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="18" fill="context-fill">
|
||||
<svg width="20" height="18">
|
||||
<defs>
|
||||
<filter id="a" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g>
|
||||
<g fill-opacity=".25">
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
</g>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#a)" transform="translate(10.005 9.286) scale(1.02438)"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="20">
|
||||
<defs>
|
||||
<filter id="b" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g>
|
||||
<g fill-opacity=".25">
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
<path d="M10 16.41c-4.527 0 -8.179 -3.826 -8.179 -8.352v-4.097a2.05 2.05 0 0 1 2.05 -2.05h12.253a2.05 2.05 0 0 1 2.049 2.05v4.097c0 4.526 -3.648 8.352 -8.174 8.352z"/>
|
||||
</g>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#b)" transform="translate(10.005 9.286) scale(1.02438)"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="40">
|
||||
<defs>
|
||||
<filter id="c" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#c)" transform="translate(10.005 10.054) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="60">
|
||||
<defs>
|
||||
<filter id="d" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#d)" transform="translate(10.009 10.057) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="80">
|
||||
<defs>
|
||||
<filter id="e" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#e)" transform="translate(10.005 10.054) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="100">
|
||||
<defs>
|
||||
<filter id="f" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#f)" transform="translate(10.005 10.016) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="120">
|
||||
<defs>
|
||||
<filter id="g" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#g)" transform="translate(10.005 9.925) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="140">
|
||||
<defs>
|
||||
<filter id="h" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#h)" transform="translate(10.005 9.802) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="160">
|
||||
<defs>
|
||||
<filter id="i" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.955c-4.978 0 -8.995 -4.208 -8.995 -9.187v-4.507a2.253 2.253 0 0 1 2.254 -2.254h13.479a2.253 2.253 0 0 1 2.253 2.254v4.507c0 4.979 -4.012 9.187 -8.99 9.187z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#i)" transform="translate(10.005 9.66) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="180">
|
||||
<defs>
|
||||
<filter id="j" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.997 16.924c-4.958 0 -8.96 -4.192 -8.96 -9.151v-4.49a2.244 2.244 0 0 1 2.245 -2.245h13.426a2.244 2.244 0 0 1 2.245 2.245v4.49c0 4.959 -3.997 9.15 -8.956 9.15z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.924c-4.958 0 -8.96 -4.192 -8.96 -9.151v-4.49a2.244 2.244 0 0 1 2.245 -2.245h13.426a2.244 2.244 0 0 1 2.245 2.245v4.49c0 4.959 -3.997 9.15 -8.956 9.15z"/>
|
||||
<path fill-opacity=".25" d="M9.997 16.924c-4.958 0 -8.96 -4.192 -8.96 -9.151v-4.49a2.244 2.244 0 0 1 2.245 -2.245h13.426a2.244 2.244 0 0 1 2.245 2.245v4.49c0 4.959 -3.997 9.15 -8.956 9.15z"/>
|
||||
<path fill="#EE4055" d="M9.997 16.924c-4.958 0 -8.96 -4.192 -8.96 -9.151v-4.49a2.244 2.244 0 0 1 2.245 -2.245h13.426a2.244 2.244 0 0 1 2.245 2.245v4.49c0 4.959 -3.997 9.15 -8.956 9.15z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#j)" transform="translate(10.005 9.512) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="200">
|
||||
<defs>
|
||||
<filter id="k" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.998 16.84c-4.908 0 -8.868 -4.148 -8.868 -9.056v-4.443a2.222 2.222 0 0 1 2.222 -2.222h13.287a2.222 2.222 0 0 1 2.222 2.222v4.443c0 4.908 -3.956 9.057 -8.863 9.057z"/>
|
||||
<path fill-opacity=".25" d="M9.998 16.84c-4.908 0 -8.868 -4.148 -8.868 -9.056v-4.443a2.222 2.222 0 0 1 2.222 -2.222h13.287a2.222 2.222 0 0 1 2.222 2.222v4.443c0 4.908 -3.956 9.057 -8.863 9.057z"/>
|
||||
<path fill-opacity=".25" d="M9.998 16.84c-4.908 0 -8.868 -4.148 -8.868 -9.056v-4.443a2.222 2.222 0 0 1 2.222 -2.222h13.287a2.222 2.222 0 0 1 2.222 2.222v4.443c0 4.908 -3.956 9.057 -8.863 9.057z"/>
|
||||
<path fill="#EE4055" d="M9.998 16.84c-4.908 0 -8.868 -4.148 -8.868 -9.056v-4.443a2.222 2.222 0 0 1 2.222 -2.222h13.287a2.222 2.222 0 0 1 2.222 2.222v4.443c0 4.908 -3.956 9.057 -8.863 9.057z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#k)" transform="translate(10.005 9.372) scale(1.02438)"/>
|
||||
</svg>
|
||||
<svg width="20" height="18" x="220">
|
||||
<defs>
|
||||
<filter id="l" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
|
||||
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<path fill-opacity=".25" d="M9.998 16.723c-4.835 0 -8.737 -4.087 -8.737 -8.922v-4.378a2.189 2.189 0 0 1 2.19 -2.189h13.09a2.19 2.19 0 0 1 2.19 2.19v4.376c0 4.835 -3.898 8.922 -8.733 8.922z"/>
|
||||
<path fill-opacity=".25" d="M9.998 16.723c-4.835 0 -8.737 -4.087 -8.737 -8.922v-4.378a2.189 2.189 0 0 1 2.19 -2.189h13.09a2.19 2.19 0 0 1 2.19 2.19v4.376c0 4.835 -3.898 8.922 -8.733 8.922z"/>
|
||||
<path fill-opacity=".25" d="M9.998 16.723c-4.835 0 -8.737 -4.087 -8.737 -8.922v-4.378a2.189 2.189 0 0 1 2.19 -2.189h13.09a2.19 2.19 0 0 1 2.19 2.19v4.376c0 4.835 -3.898 8.922 -8.733 8.922z"/>
|
||||
<path fill="#EE4055" d="M9.998 16.723c-4.835 0 -8.737 -4.087 -8.737 -8.922v-4.378a2.189 2.189 0 0 1 2.19 -2.189h13.09a2.19 2.19 0 0 1 2.19 2.19v4.376c0 4.835 -3.898 8.922 -8.733 8.922z"/>
|
||||
<path d="M3.986 -3.055a0.991 0.991 0 0 0 -0.726 0.319l-3.281 3.284 -3.224 -3.235a0.984 0.984 0 0 0 -0.754 -0.368 1.001 1.001 0 0 0 -0.715 1.7l-0.016 0.011 3.294 3.306 0.706 0.707a1 1 0 0 0 1.414 0l0.707 -0.707 3.31 -3.306a1.001 1.001 0 0 0 -0.715 -1.711z" filter="url(#l)" transform="translate(10.005 9.286) scale(1.02438)"/>
|
||||
</svg>
|
||||
</svg>
|
After Width: | Height: | Size: 17 KiB |
@ -23,6 +23,182 @@ toolbar[brighttext] #pocket-button {
|
||||
fill: var(--toolbarbutton-icon-fill-inverted);
|
||||
}
|
||||
|
||||
#pocket-button[open="true"][animationsenabled] > .toolbarbutton-icon {
|
||||
fill: transparent;
|
||||
}
|
||||
|
||||
@keyframes pocket-animation {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
}
|
||||
to {
|
||||
transform: translateX(-220px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pocket-animation-rtl {
|
||||
from {
|
||||
transform: scaleX(-1) translateX(0);
|
||||
}
|
||||
to {
|
||||
transform: scaleX(-1) translateX(-220px);
|
||||
}
|
||||
}
|
||||
|
||||
#pocket-button > .toolbarbutton-animatable-box {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: calc(50% - 9px); /* 9px is half the height of the sprite */
|
||||
/* Since .toolbarbutton-icon uses a different width than the animatable box,
|
||||
we need to set a padding relative to the difference in widths. */
|
||||
margin-inline-start: calc((16px + 2 * var(--toolbarbutton-inner-padding) - 20px) / 2);
|
||||
/* Set the min- and max- width and height of the box equal to that
|
||||
of each frame of the SVG sprite. Setting the width and height via
|
||||
the `width` and `height` CSS properties causes an assertion for
|
||||
`inline-size less than zero: 'aContainingBlockISize >= 0'` (bug 1379332). */
|
||||
min-width: 20px;
|
||||
max-width: 20px;
|
||||
min-height: 18px;
|
||||
max-height: 18px;
|
||||
}
|
||||
|
||||
#pocket-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
height: var(--toolbarbutton-height); /* Height must be equal to height of toolbarbutton padding-box */
|
||||
}
|
||||
|
||||
#pocket-button[open="true"][animationsenabled][cui-areatype="toolbar"]:not([overflowedItem="true"]) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Preload pocket-animation.svg and library-pocket-animation.svg to prevent
|
||||
a flicker at the start of either animation. The preloading of the library
|
||||
animation is triggered off of hovering the pocket button since the pocket
|
||||
button always animates before the library button. */
|
||||
#pocket-button[animationsenabled][cui-areatype="toolbar"]:not([overflowedItem="true"]):not([open="true"]):hover > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
background-image: url("chrome://pocket-shared/skin/pocket-animation.svg"),
|
||||
url("chrome://pocket-shared/skin/library-pocket-animation.svg");
|
||||
background-size: 0, 0;
|
||||
}
|
||||
|
||||
#pocket-button[open="true"][animationsenabled][cui-areatype="toolbar"]:not([overflowedItem="true"]) > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
animation-name: pocket-animation;
|
||||
animation-timing-function: steps(11);
|
||||
animation-duration: 184ms;
|
||||
background-image: url("chrome://pocket-shared/skin/pocket-animation.svg");
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
#pocket-button[open="true"][animationsenabled][cui-areatype="toolbar"]:not([overflowedItem="true"]):-moz-locale-dir(rtl) > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
animation-name: pocket-animation-rtl;
|
||||
}
|
||||
|
||||
#library-button[animate="pocket"] > .toolbarbutton-icon {
|
||||
fill: transparent;
|
||||
}
|
||||
|
||||
@keyframes library-pocket-animation {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
fill: inherit;
|
||||
}
|
||||
25% {
|
||||
fill: inherit;
|
||||
}
|
||||
50% {
|
||||
fill: rgb(213,32,20);
|
||||
}
|
||||
to {
|
||||
transform: translateX(-1056px);
|
||||
fill: rgb(213,32,20);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes library-pocket-animation-rtl {
|
||||
from {
|
||||
transform: scaleX(-1) translateX(0);
|
||||
fill: inherit;
|
||||
}
|
||||
25% {
|
||||
fill: inherit;
|
||||
}
|
||||
50% {
|
||||
fill: rgb(213,32,20);
|
||||
}
|
||||
to {
|
||||
transform: scaleX(-1) translateX(-1056px);
|
||||
fill: rgb(213,32,20);
|
||||
}
|
||||
}
|
||||
|
||||
/* The animations for the pocket-button and library-button are disabled
|
||||
outside of the nav-bar due to bug 1382894. */
|
||||
:-moz-any(#pocket-button, #library-button) > .toolbarbutton-animatable-box {
|
||||
display: none;
|
||||
}
|
||||
#nav-bar :-moz-any(#pocket-button, #library-button) > .toolbarbutton-animatable-box {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
/* We need to use an animation here instead of a transition
|
||||
to guarantee that the animation succeeds. With transitions
|
||||
if the starting value is already equal to the end value
|
||||
then no transition will occur and thus no transitionend event. */
|
||||
@keyframes library-pocket-fade {
|
||||
from {
|
||||
fill: rgb(213,32,20);
|
||||
}
|
||||
to {
|
||||
fill: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
#library-button[animate="pocket"] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#library-button[animate="pocket"] > .toolbarbutton-animatable-box {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: calc(50% - 27px); /* 27px is half the height of the sprite */
|
||||
/* Since .toolbarbutton-icon uses a different width than the animatable box,
|
||||
we need to set a padding relative to the difference in widths. */
|
||||
margin-inline-start: calc((16px + 2 * var(--toolbarbutton-inner-padding) - 22px) / 2);
|
||||
/* Set the min- and max- width and height of the box equal to that
|
||||
of each frame of the SVG sprite. Setting the width and height via
|
||||
the `width` and `height` CSS properties causes an assertion for
|
||||
`inline-size less than zero: 'aContainingBlockISize >= 0'` (bug 1379332). */
|
||||
min-width: 22px;
|
||||
max-width: 22px;
|
||||
/* Height of each frame within the SVG sprite. The sprite must have equal amount
|
||||
of space above and below the icon to allow it to vertically center with the
|
||||
sprite's icon on top of the toolbar icon when using position:absolute;. */
|
||||
min-height: 54px;
|
||||
max-height: 54px;
|
||||
}
|
||||
|
||||
#library-button[animate="pocket"] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
height: var(--toolbarbutton-height); /* Height must be equal to height of toolbarbutton padding-box */
|
||||
}
|
||||
|
||||
#library-button[animate="pocket"] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
background-image: url("chrome://pocket-shared/skin/library-pocket-animation.svg");
|
||||
width: 1078px;
|
||||
animation-name: library-pocket-animation;
|
||||
animation-duration: 768ms;
|
||||
animation-timing-function: steps(48);
|
||||
}
|
||||
|
||||
#library-button[animate="pocket"]:-moz-locale-dir(rtl) > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
animation-name: library-pocket-animation-rtl;
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
#library-button[animate="pocket"][fade] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
animation-name: library-pocket-fade;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
#pocket-button[cui-areatype="toolbar"][open] {
|
||||
fill: rgb(213,32,20);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
<em:type>2</em:type>
|
||||
<em:version>10.7.0</em:version>
|
||||
<em:version>10.8.0</em:version>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:homepageURL>https://pageshot.net/</em:homepageURL>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Firefox Screenshots",
|
||||
"version": "10.7.0",
|
||||
"version": "10.8.0",
|
||||
"description": "__MSG_addonDescription__",
|
||||
"author": "__MSG_addonAuthorsList__",
|
||||
"homepage_url": "https://github.com/mozilla-services/screenshots",
|
||||
|
@ -96,7 +96,7 @@ this.slides = (function() {
|
||||
};
|
||||
let linkUrls = {
|
||||
[termsSentinel]: "https://www.mozilla.org/about/legal/terms/services/",
|
||||
[privacySentinel]: "https://www.mozilla.org/privacy/firefox-cloud/"
|
||||
[privacySentinel]: "https://www.mozilla.org/privacy/firefox/"
|
||||
};
|
||||
let text = browser.i18n.getMessage(
|
||||
"termsAndPrivacyNoticeCloudServices",
|
||||
|
@ -164,7 +164,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
||||
initSizeWatch() {
|
||||
this.stopSizeWatch();
|
||||
this.sizeTracking.timer = setInterval(watchFunction(this.updateElementSize.bind(this)), 2000);
|
||||
window.addEventListener("resize", watchFunction(assertIsTrusted(this.onResize)), true);
|
||||
window.addEventListener("resize", this.onResize, true);
|
||||
},
|
||||
|
||||
stopSizeWatch() {
|
||||
@ -177,7 +177,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
||||
this.sizeTracking.windowDelayer = null;
|
||||
}
|
||||
this.sizeTracking.lastHeight = this.sizeTracking.lastWidth = null;
|
||||
window.removeEventListener("resize", watchFunction(assertIsTrusted(this.onResize)), true);
|
||||
window.removeEventListener("resize", this.onResize, true);
|
||||
},
|
||||
|
||||
getElementFromPoint(x, y) {
|
||||
@ -198,7 +198,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
||||
}
|
||||
};
|
||||
|
||||
iframeSelection.onResize = watchFunction(assertIsTrusted(onResize.bind(iframeSelection)));
|
||||
iframeSelection.onResize = watchFunction(assertIsTrusted(onResize.bind(iframeSelection)), true);
|
||||
|
||||
let iframePreSelection = exports.iframePreSelection = {
|
||||
element: null,
|
||||
@ -322,7 +322,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
||||
}
|
||||
};
|
||||
|
||||
iframePreSelection.onResize = watchFunction(onResize.bind(iframePreSelection));
|
||||
iframePreSelection.onResize = watchFunction(onResize.bind(iframePreSelection), true);
|
||||
|
||||
let iframe = exports.iframe = {
|
||||
currentIframe: iframePreSelection,
|
||||
|
@ -395,7 +395,9 @@
|
||||
@RESPATH@/components/nsSearchService.js
|
||||
@RESPATH@/components/nsSearchSuggestions.js
|
||||
@RESPATH@/components/nsSidebar.js
|
||||
#if defined(NIGHTLY_BUILD) && defined(MOZ_BUILD_APP_IS_BROWSER)
|
||||
@RESPATH@/components/payments.manifest
|
||||
#endif
|
||||
@RESPATH@/components/passwordmgr.manifest
|
||||
@RESPATH@/components/nsLoginInfo.js
|
||||
@RESPATH@/components/nsLoginManager.js
|
||||
|
@ -2,4 +2,4 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
uiDensity.menu-button-touch.acceltext=Tablet Mode Enabled
|
||||
uiDensity.menuitem-touch.acceltext=Tablet Mode Enabled
|
||||
|
@ -457,14 +457,14 @@ toolbarpaletteitem[place=toolbar] > toolbarspring {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.customization-uidensity-menu-button > .menu-iconic-left > .menu-iconic-icon,
|
||||
.customization-uidensity-menuitem > .menu-iconic-left > .menu-iconic-icon,
|
||||
.customization-lwtheme-menu-theme > .toolbarbutton-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.customization-uidensity-menu-button,
|
||||
.customization-uidensity-menuitem,
|
||||
.customization-lwtheme-menu-theme {
|
||||
-moz-appearance: none;
|
||||
border: 1px solid transparent;
|
||||
@ -475,7 +475,7 @@ toolbarpaletteitem[place=toolbar] > toolbarspring {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
.customization-uidensity-menu-button {
|
||||
.customization-uidensity-menuitem {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@ -484,35 +484,35 @@ toolbarpaletteitem[place=toolbar] > toolbarspring {
|
||||
}
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
#customization-uidensity-menu-button-normal {
|
||||
#customization-uidensity-menuitem-normal {
|
||||
list-style-image: url("chrome://browser/skin/customizableui/density-normal.svg");
|
||||
}
|
||||
|
||||
#customization-uidensity-menu-button-compact {
|
||||
#customization-uidensity-menuitem-compact {
|
||||
list-style-image: url("chrome://browser/skin/customizableui/density-compact.svg");
|
||||
}
|
||||
|
||||
#customization-uidensity-menu-button-touch {
|
||||
#customization-uidensity-menuitem-touch {
|
||||
list-style-image: url("chrome://browser/skin/customizableui/density-touch.svg");
|
||||
}
|
||||
%endif
|
||||
|
||||
.customization-uidensity-menu-button[active="true"],
|
||||
.customization-uidensity-menu-button:hover,
|
||||
.customization-uidensity-menuitem[active="true"],
|
||||
.customization-uidensity-menuitem:hover,
|
||||
.customization-lwtheme-menu-theme[active="true"],
|
||||
.customization-lwtheme-menu-theme:hover {
|
||||
background-color: var(--arrowpanel-dimmed);
|
||||
border-color: var(--panel-separator-color);
|
||||
}
|
||||
|
||||
.customization-uidensity-menu-button[active="true"],
|
||||
.customization-uidensity-menu-button:hover:active,
|
||||
.customization-uidensity-menuitem[active="true"],
|
||||
.customization-uidensity-menuitem:hover:active,
|
||||
.customization-lwtheme-menu-theme[active="true"],
|
||||
.customization-lwtheme-menu-theme:hover:active {
|
||||
background-color: var(--arrowpanel-dimmed-further);
|
||||
}
|
||||
|
||||
.customization-uidensity-menu-button > .menu-iconic-text,
|
||||
.customization-uidensity-menuitem > .menu-iconic-text,
|
||||
.customization-lwtheme-menu-theme > .toolbarbutton-text {
|
||||
text-align: start;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ toolbar[brighttext] .toolbarbutton-1 {
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
#forward-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
|
||||
#reload-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
|
||||
#library-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
|
||||
%endif
|
||||
#nav-bar-overflow-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
|
||||
#panic-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
|
||||
@ -37,6 +38,12 @@ toolbar[brighttext] .toolbarbutton-1 {
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
%ifdef MOZ_PHOTON_ANIMATIONS
|
||||
.toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: 1;
|
||||
list-style-image: none;
|
||||
}
|
||||
|
||||
#stop-reload-button[animate] > #reload-button > .toolbarbutton-icon,
|
||||
#stop-reload-button[animate] > #reload-button[displaystop] + #stop-button > .toolbarbutton-icon {
|
||||
fill: transparent;
|
||||
@ -104,9 +111,6 @@ toolbar[brighttext] .toolbarbutton-1 {
|
||||
#reload-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image,
|
||||
#stop-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
height: var(--toolbarbutton-height); /* Height must be equal to height of toolbarbutton padding-box */
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: 1;
|
||||
list-style-image: none;
|
||||
}
|
||||
|
||||
#stop-reload-button[animate] > #reload-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
@ -380,9 +384,6 @@ toolbar:not([brighttext]) #bookmarks-menu-button@attributeSelectorForToolbar@[st
|
||||
|
||||
#nav-bar-overflow-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
height: 24px; /* Height of each frame within the SVG sprite */
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: 1;
|
||||
list-style-image: none;
|
||||
}
|
||||
|
||||
#nav-bar-overflow-button[animate] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
|
||||
|
@ -16,7 +16,6 @@ struct JSContext;
|
||||
class JSObject;
|
||||
class nsIDocument;
|
||||
class nsStyleContext;
|
||||
class ServoComputedValues;
|
||||
struct RawServoDeclarationBlock;
|
||||
|
||||
namespace mozilla {
|
||||
@ -82,7 +81,7 @@ public:
|
||||
*
|
||||
* @param aKeyframes The input keyframes.
|
||||
* @param aElement The context element.
|
||||
* @param aStyleType The |ServoComputedValues| or |nsStyleContext| to use
|
||||
* @param aStyleType The |ServoStyleContext| or |GeckoStyleContext| to use
|
||||
* when computing values.
|
||||
* @param aEffectComposite The composite operation specified on the effect.
|
||||
* For any keyframes in |aKeyframes| that do not specify a composite
|
||||
|
@ -4467,6 +4467,26 @@ nsDOMWindowUtils::GetDirectionFromText(const nsAString& aString, int32_t* aRetva
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::EnsureDirtyRootFrame()
|
||||
{
|
||||
nsIDocument* doc = GetDocument();
|
||||
nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
|
||||
|
||||
if (!presShell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsIFrame* frame = presShell->GetRootFrame();
|
||||
if (!frame) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
presShell->FrameNeedsReflow(frame, nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetIsStyledByServo(bool* aStyledByServo)
|
||||
{
|
||||
|
@ -8810,11 +8810,8 @@ nsDocument::BlockOnload()
|
||||
}
|
||||
|
||||
// If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup
|
||||
// -- it's not ours. Also, if we're already in the COMPLETE state, that means
|
||||
// we already had our load event, conceptually, so there's no more need to
|
||||
// mess about with the load blocker.
|
||||
if (mOnloadBlockCount == 0 && mScriptGlobalObject &&
|
||||
GetReadyStateEnum() != READYSTATE_COMPLETE) {
|
||||
// -- it's not ours.
|
||||
if (mOnloadBlockCount == 0 && mScriptGlobalObject) {
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
// Because AddRequest may lead to OnStateChange calls in chrome,
|
||||
// block onload only when there are no script blockers.
|
||||
|
@ -3053,7 +3053,7 @@ CanvasRenderingContext2D::ParseFilter(const nsAString& aString,
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsStyleEffects* effects = computedValues->ComputedValues()->GetStyleEffects();
|
||||
const nsStyleEffects* effects = computedValues->ComputedData()->GetStyleEffects();
|
||||
// XXX: This mFilters is a one shot object, we probably could avoid copying.
|
||||
aFilterChain = effects->mFilters;
|
||||
return true;
|
||||
@ -3973,7 +3973,7 @@ CanvasRenderingContext2D::SetFontInternal(const nsAString& aFont,
|
||||
if (!computedValues) {
|
||||
return false;
|
||||
}
|
||||
fontStyle = computedValues->ComputedValues()->GetStyleFont();
|
||||
fontStyle = computedValues->ComputedData()->GetStyleFont();
|
||||
} else {
|
||||
sc = GetFontStyleContext(mCanvasElement,
|
||||
aFont,
|
||||
|
@ -5986,8 +5986,7 @@ bool HTMLMediaElement::CanActivateAutoplay()
|
||||
|
||||
bool hasData =
|
||||
(mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) ||
|
||||
(mSrcStream && mSrcStream->Active()) ||
|
||||
mMediaSource;
|
||||
(mSrcStream && mSrcStream->Active());
|
||||
|
||||
return hasData;
|
||||
}
|
||||
|
@ -2023,6 +2023,14 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
*/
|
||||
long getDirectionFromText(in AString aString);
|
||||
|
||||
/**
|
||||
* Calls FrameNeedsReflow on that root frame so that a layout flush
|
||||
* will be necessary.
|
||||
*
|
||||
* This should only be used for testing.
|
||||
*/
|
||||
void ensureDirtyRootFrame();
|
||||
|
||||
/**
|
||||
* Whether the current document is styled by Servo's style engine.
|
||||
*
|
||||
|
@ -84,8 +84,8 @@ ChromiumCDMAdapter::GMPGetAPI(const char* aAPIName,
|
||||
return GMPGenericErr;
|
||||
}
|
||||
|
||||
auto cdm = reinterpret_cast<cdm::ContentDecryptionModule*>(
|
||||
create(cdm::ContentDecryptionModule::kVersion,
|
||||
auto cdm = reinterpret_cast<cdm::ContentDecryptionModule_8*>(
|
||||
create(cdm::ContentDecryptionModule_8::kVersion,
|
||||
kEMEKeySystemWidevine.get(),
|
||||
kEMEKeySystemWidevine.Length(),
|
||||
&ChromiumCdmHost,
|
||||
@ -126,7 +126,7 @@ ChromiumCDMAdapter::Supports(int32_t aModuleVersion,
|
||||
int32_t aHostVersion)
|
||||
{
|
||||
return aModuleVersion == CDM_MODULE_VERSION &&
|
||||
aInterfaceVersion == cdm::ContentDecryptionModule::kVersion &&
|
||||
aInterfaceVersion == cdm::ContentDecryptionModule_8::kVersion &&
|
||||
aHostVersion == cdm::Host_8::kVersion;
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,8 @@ EXPORTS += [
|
||||
'GMPVideoi420FrameImpl.h',
|
||||
'GMPVideoPlaneImpl.h',
|
||||
'widevine-adapter/content_decryption_module.h',
|
||||
'widevine-adapter/content_decryption_module_export.h',
|
||||
'widevine-adapter/content_decryption_module_ext.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -97,8 +97,8 @@ WidevineAdapter::GMPGetAPI(const char* aAPIName,
|
||||
|
||||
auto* decryptor = new WidevineDecryptor();
|
||||
|
||||
auto cdm = reinterpret_cast<cdm::ContentDecryptionModule*>(
|
||||
create(cdm::ContentDecryptionModule::kVersion,
|
||||
auto cdm = reinterpret_cast<cdm::ContentDecryptionModule_8*>(
|
||||
create(cdm::ContentDecryptionModule_8::kVersion,
|
||||
kEMEKeySystemWidevine.get(),
|
||||
kEMEKeySystemWidevine.Length(),
|
||||
&GetCdmHost,
|
||||
|
@ -29,7 +29,7 @@ ToGMPErr(cdm::Status aStatus)
|
||||
case cdm::kSuccess: return GMPNoErr;
|
||||
case cdm::kNeedMoreData: return GMPGenericErr;
|
||||
case cdm::kNoKey: return GMPNoKeyErr;
|
||||
case cdm::kSessionError: return GMPGenericErr;
|
||||
case cdm::kInitializationError: return GMPGenericErr;
|
||||
case cdm::kDecryptError: return GMPCryptoErr;
|
||||
case cdm::kDecodeError: return GMPDecodeErr;
|
||||
case cdm::kDeferredInitialization: return GMPGenericErr;
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef CDM_CONTENT_DECRYPTION_MODULE_H_
|
||||
#define CDM_CONTENT_DECRYPTION_MODULE_H_
|
||||
|
||||
#include "content_decryption_module_export.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned int uint32_t;
|
||||
@ -14,25 +16,21 @@ typedef __int64 int64_t;
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
// Define CDM_EXPORT so that functionality implemented by the CDM module
|
||||
// can be exported to consumers.
|
||||
#if defined(WIN32)
|
||||
|
||||
#if defined(CDM_IMPLEMENTATION)
|
||||
#define CDM_EXPORT __declspec(dllexport)
|
||||
// Define CDM_CLASS_API to export class types. We have to add visibility
|
||||
// attributes to make sure virtual tables in CDM consumer and CDM implementation
|
||||
// are the same. Generally, it was always a good idea, as there're no guarantees
|
||||
// about that for the internal symbols, but it has only become a practical issue
|
||||
// after introduction of LTO devirtualization. See more details on
|
||||
// https://crbug.com/609564#c35
|
||||
#if defined(_WIN32)
|
||||
#if defined(__clang__)
|
||||
#define CDM_CLASS_API [[clang::lto_visibility_public]]
|
||||
#else
|
||||
#define CDM_EXPORT __declspec(dllimport)
|
||||
#endif // defined(CDM_IMPLEMENTATION)
|
||||
|
||||
#else // defined(WIN32)
|
||||
|
||||
#if defined(CDM_IMPLEMENTATION)
|
||||
#define CDM_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CDM_EXPORT
|
||||
#define CDM_CLASS_API
|
||||
#endif
|
||||
|
||||
#endif // defined(WIN32)
|
||||
#else // defined(_WIN32)
|
||||
#define CDM_CLASS_API __attribute__((visibility("default")))
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
// The version number must be rolled when the exported functions are updated!
|
||||
// If the CDM and the adapter use different versions of these functions, the
|
||||
@ -48,9 +46,9 @@ typedef __int64 int64_t;
|
||||
#define BUILD_ENTRYPOINT_NO_EXPANSION(name, version) name##_##version
|
||||
|
||||
extern "C" {
|
||||
CDM_EXPORT void INITIALIZE_CDM_MODULE();
|
||||
CDM_API void INITIALIZE_CDM_MODULE();
|
||||
|
||||
CDM_EXPORT void DeinitializeCdmModule();
|
||||
CDM_API void DeinitializeCdmModule();
|
||||
|
||||
// Returns a pointer to the requested CDM Host interface upon success.
|
||||
// Returns NULL if the requested CDM Host interface is not supported.
|
||||
@ -65,28 +63,28 @@ typedef void* (*GetCdmHostFunc)(int host_interface_version, void* user_data);
|
||||
// |cdm_interface_version|.
|
||||
// Caller retains ownership of arguments and must call Destroy() on the returned
|
||||
// object.
|
||||
CDM_EXPORT void* CreateCdmInstance(
|
||||
CDM_API void* CreateCdmInstance(
|
||||
int cdm_interface_version,
|
||||
const char* key_system, uint32_t key_system_size,
|
||||
GetCdmHostFunc get_cdm_host_func, void* user_data);
|
||||
|
||||
CDM_EXPORT const char* GetCdmVersion();
|
||||
CDM_API const char* GetCdmVersion();
|
||||
}
|
||||
|
||||
namespace cdm {
|
||||
|
||||
class AudioFrames;
|
||||
class DecryptedBlock;
|
||||
class VideoFrame;
|
||||
class CDM_CLASS_API AudioFrames;
|
||||
class CDM_CLASS_API DecryptedBlock;
|
||||
class CDM_CLASS_API VideoFrame;
|
||||
|
||||
class Host_7;
|
||||
class Host_8;
|
||||
class CDM_CLASS_API Host_8;
|
||||
class CDM_CLASS_API Host_9;
|
||||
|
||||
enum Status {
|
||||
kSuccess = 0,
|
||||
kNeedMoreData, // Decoder needs more data to produce a decoded frame/sample.
|
||||
kNoKey, // The required decryption key is not available.
|
||||
kSessionError, // Session management error.
|
||||
kInitializationError, // Initialization error.
|
||||
kDecryptError, // Decryption failed.
|
||||
kDecodeError, // Error decoding audio or video.
|
||||
kDeferredInitialization // Decoder is not ready for initialization.
|
||||
@ -97,6 +95,7 @@ enum Status {
|
||||
// The following starts with the list of DOM4 exceptions from:
|
||||
// http://www.w3.org/TR/dom/#domexception
|
||||
// Some DOM4 exceptions are not included as they are not expected to be used.
|
||||
// Should only be used on Host_8 and before.
|
||||
enum Error {
|
||||
kNotSupportedError = 9,
|
||||
kInvalidStateError = 11,
|
||||
@ -113,8 +112,20 @@ enum Error {
|
||||
kOutputError = 101
|
||||
};
|
||||
|
||||
// Time is defined as the number of seconds since the
|
||||
// Epoch (00:00:00 UTC, January 1, 1970).
|
||||
// Exceptions used by the CDM to reject promises.
|
||||
// https://w3c.github.io/encrypted-media/#exceptions
|
||||
enum Exception {
|
||||
kExceptionTypeError,
|
||||
kExceptionNotSupportedError,
|
||||
kExceptionInvalidStateError,
|
||||
kExceptionQuotaExceededError
|
||||
};
|
||||
|
||||
// Time is defined as the number of seconds since the Epoch
|
||||
// (00:00:00 UTC, January 1, 1970), not including any added leap second.
|
||||
// Also see Time definition in spec: https://w3c.github.io/encrypted-media/#time
|
||||
// Note that Time is defined in millisecond accuracy in the spec but in second
|
||||
// accuracy here.
|
||||
typedef double Time;
|
||||
|
||||
// An input buffer can be split into several continuous subsamples.
|
||||
@ -151,13 +162,13 @@ struct SubsampleEntry {
|
||||
// unencrypted.
|
||||
struct InputBuffer {
|
||||
InputBuffer()
|
||||
: data(NULL),
|
||||
: data(nullptr),
|
||||
data_size(0),
|
||||
key_id(NULL),
|
||||
key_id(nullptr),
|
||||
key_id_size(0),
|
||||
iv(NULL),
|
||||
iv(nullptr),
|
||||
iv_size(0),
|
||||
subsamples(NULL),
|
||||
subsamples(nullptr),
|
||||
num_subsamples(0),
|
||||
timestamp(0) {}
|
||||
|
||||
@ -188,7 +199,7 @@ struct AudioDecoderConfig {
|
||||
channel_count(0),
|
||||
bits_per_channel(0),
|
||||
samples_per_second(0),
|
||||
extra_data(NULL),
|
||||
extra_data(nullptr),
|
||||
extra_data_size(0) {}
|
||||
|
||||
AudioCodec codec;
|
||||
@ -214,10 +225,25 @@ enum AudioFormat {
|
||||
};
|
||||
|
||||
// Surface formats based on FOURCC labels, see: http://www.fourcc.org/yuv.php
|
||||
// Values are chosen to be consistent with Chromium's VideoPixelFormat values.
|
||||
enum VideoFormat {
|
||||
kUnknownVideoFormat = 0, // Unknown format value. Used for error reporting.
|
||||
kYv12, // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
|
||||
kI420 // 12bpp YVU planar 1x1 Y, 2x2 UV samples.
|
||||
kYv12 = 1, // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
|
||||
kI420 = 2, // 12bpp YUV planar 1x1 Y, 2x2 UV samples.
|
||||
|
||||
// In the following formats, each sample uses 16-bit in storage, while the
|
||||
// sample value is stored in the least significant N bits where N is
|
||||
// specified by the number after "P". For example, for YUV420P9, each Y, U,
|
||||
// and V sample is stored in the least significant 9 bits in a 2-byte block.
|
||||
kYUV420P9 = 16,
|
||||
kYUV420P10 = 17,
|
||||
kYUV422P9 = 18,
|
||||
kYUV422P10 = 19,
|
||||
kYUV444P9 = 20,
|
||||
kYUV444P10 = 21,
|
||||
kYUV420P12 = 22,
|
||||
kYUV422P12 = 23,
|
||||
kYUV444P12 = 24,
|
||||
};
|
||||
|
||||
struct Size {
|
||||
@ -245,14 +271,19 @@ struct VideoDecoderConfig {
|
||||
kH264ProfileHigh,
|
||||
kH264ProfileHigh10,
|
||||
kH264ProfileHigh422,
|
||||
kH264ProfileHigh444Predictive
|
||||
kH264ProfileHigh444Predictive,
|
||||
// VP9 Profiles are only passed in starting from CDM_9.
|
||||
kVP9Profile0,
|
||||
kVP9Profile1,
|
||||
kVP9Profile2,
|
||||
kVP9Profile3
|
||||
};
|
||||
|
||||
VideoDecoderConfig()
|
||||
: codec(kUnknownVideoCodec),
|
||||
profile(kUnknownVideoCodecProfile),
|
||||
format(kUnknownVideoFormat),
|
||||
extra_data(NULL),
|
||||
extra_data(nullptr),
|
||||
extra_data_size(0) {}
|
||||
|
||||
VideoCodec codec;
|
||||
@ -294,7 +325,7 @@ struct PlatformChallengeResponse {
|
||||
|
||||
// Used when passing arrays of binary data. Does not own the referenced data.
|
||||
struct BinaryData {
|
||||
BinaryData() : data(NULL), length(0) {}
|
||||
BinaryData() : data(nullptr), length(0) {}
|
||||
const uint8_t* data;
|
||||
uint32_t length;
|
||||
};
|
||||
@ -316,7 +347,10 @@ enum KeyStatus {
|
||||
// should be 0 when |status| == kUsable.
|
||||
struct KeyInformation {
|
||||
KeyInformation()
|
||||
: key_id(NULL), key_id_size(0), status(kInternalError), system_code(0) {}
|
||||
: key_id(nullptr),
|
||||
key_id_size(0),
|
||||
status(kInternalError),
|
||||
system_code(0) {}
|
||||
const uint8_t* key_id;
|
||||
uint32_t key_id_size;
|
||||
KeyStatus status;
|
||||
@ -372,6 +406,24 @@ enum MessageType {
|
||||
kLicenseRelease = 2
|
||||
};
|
||||
|
||||
enum HdcpVersion {
|
||||
kHdcpVersionNone,
|
||||
kHdcpVersion1_0,
|
||||
kHdcpVersion1_1,
|
||||
kHdcpVersion1_2,
|
||||
kHdcpVersion1_3,
|
||||
kHdcpVersion1_4,
|
||||
kHdcpVersion2_0,
|
||||
kHdcpVersion2_1,
|
||||
kHdcpVersion2_2
|
||||
};
|
||||
|
||||
struct Policy {
|
||||
Policy() : min_hdcp_version(kHdcpVersionNone) {}
|
||||
|
||||
HdcpVersion min_hdcp_version;
|
||||
};
|
||||
|
||||
// FileIO interface provides a way for the CDM to store data in a file in
|
||||
// persistent storage. This interface aims only at providing basic read/write
|
||||
// capabilities and should not be used as a full fledged file IO API.
|
||||
@ -381,7 +433,7 @@ enum MessageType {
|
||||
// Note to implementors of this interface:
|
||||
// Per-origin storage and the ability for users to clear it are important.
|
||||
// See http://www.w3.org/TR/encrypted-media/#privacy-storedinfo.
|
||||
class FileIO {
|
||||
class CDM_CLASS_API FileIO {
|
||||
public:
|
||||
// Opens the file with |file_name| for read and write.
|
||||
// FileIOClient::OnOpenComplete() will be called after the opening
|
||||
@ -421,7 +473,7 @@ class FileIO {
|
||||
// When kError is returned, the FileIO object could be in an error state. All
|
||||
// following calls (other than Close()) could return kError. The CDM should
|
||||
// still call Close() to destroy the FileIO object.
|
||||
class FileIOClient {
|
||||
class CDM_CLASS_API FileIOClient {
|
||||
public:
|
||||
enum Status {
|
||||
kSuccess = 0,
|
||||
@ -462,186 +514,7 @@ class FileIOClient {
|
||||
// provided in CreateCdmInstance() to allocate any Buffer that needs to
|
||||
// be passed back to the caller. Implementations must call Buffer::Destroy()
|
||||
// when a Buffer is created that will never be returned to the caller.
|
||||
class ContentDecryptionModule_7 {
|
||||
public:
|
||||
static const int kVersion = 7;
|
||||
typedef Host_7 Host;
|
||||
|
||||
// SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(),
|
||||
// UpdateSession(), CloseSession(), and RemoveSession() all accept a
|
||||
// |promise_id|, which must be passed to the completion Host method
|
||||
// (e.g. Host::OnResolveNewSessionPromise()).
|
||||
|
||||
// Provides a server certificate to be used to encrypt messages to the
|
||||
// license server. The CDM must respond by calling either
|
||||
// Host::OnResolvePromise() or Host::OnRejectPromise().
|
||||
virtual void SetServerCertificate(uint32_t promise_id,
|
||||
const uint8_t* server_certificate_data,
|
||||
uint32_t server_certificate_data_size) = 0;
|
||||
|
||||
// Creates a session given |session_type|, |init_data_type|, and |init_data|.
|
||||
// The CDM must respond by calling either Host::OnResolveNewSessionPromise()
|
||||
// or Host::OnRejectPromise().
|
||||
virtual void CreateSessionAndGenerateRequest(uint32_t promise_id,
|
||||
SessionType session_type,
|
||||
const char* init_data_type,
|
||||
uint32_t init_data_type_size,
|
||||
const uint8_t* init_data,
|
||||
uint32_t init_data_size) = 0;
|
||||
|
||||
// Loads the session of type |session_type| specified by |session_id|.
|
||||
// The CDM must respond by calling either Host::OnResolveNewSessionPromise()
|
||||
// or Host::OnRejectPromise(). If the session is not found, call
|
||||
// Host::OnResolveNewSessionPromise() with session_id = NULL.
|
||||
virtual void LoadSession(uint32_t promise_id,
|
||||
SessionType session_type,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Updates the session with |response|. The CDM must respond by calling
|
||||
// either Host::OnResolvePromise() or Host::OnRejectPromise().
|
||||
virtual void UpdateSession(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
const uint8_t* response,
|
||||
uint32_t response_size) = 0;
|
||||
|
||||
// Requests that the CDM close the session. The CDM must respond by calling
|
||||
// either Host::OnResolvePromise() or Host::OnRejectPromise() when the request
|
||||
// has been processed. This may be before the session is closed. Once the
|
||||
// session is closed, Host::OnSessionClosed() must also be called.
|
||||
virtual void CloseSession(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Removes any stored session data associated with this session. Will only be
|
||||
// called for persistent sessions. The CDM must respond by calling either
|
||||
// Host::OnResolvePromise() or Host::OnRejectPromise() when the request has
|
||||
// been processed.
|
||||
virtual void RemoveSession(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Performs scheduled operation with |context| when the timer fires.
|
||||
virtual void TimerExpired(void* context) = 0;
|
||||
|
||||
// Decrypts the |encrypted_buffer|.
|
||||
//
|
||||
// Returns kSuccess if decryption succeeded, in which case the callee
|
||||
// should have filled the |decrypted_buffer| and passed the ownership of
|
||||
// |data| in |decrypted_buffer| to the caller.
|
||||
// Returns kNoKey if the CDM did not have the necessary decryption key
|
||||
// to decrypt.
|
||||
// Returns kDecryptError if any other error happened.
|
||||
// If the return value is not kSuccess, |decrypted_buffer| should be ignored
|
||||
// by the caller.
|
||||
virtual Status Decrypt(const InputBuffer& encrypted_buffer,
|
||||
DecryptedBlock* decrypted_buffer) = 0;
|
||||
|
||||
// Initializes the CDM audio decoder with |audio_decoder_config|. This
|
||||
// function must be called before DecryptAndDecodeSamples() is called.
|
||||
//
|
||||
// Returns kSuccess if the |audio_decoder_config| is supported and the CDM
|
||||
// audio decoder is successfully initialized.
|
||||
// Returns kSessionError if |audio_decoder_config| is not supported. The CDM
|
||||
// may still be able to do Decrypt().
|
||||
// Returns kDeferredInitialization if the CDM is not ready to initialize the
|
||||
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
|
||||
// initialization is complete.
|
||||
virtual Status InitializeAudioDecoder(
|
||||
const AudioDecoderConfig& audio_decoder_config) = 0;
|
||||
|
||||
// Initializes the CDM video decoder with |video_decoder_config|. This
|
||||
// function must be called before DecryptAndDecodeFrame() is called.
|
||||
//
|
||||
// Returns kSuccess if the |video_decoder_config| is supported and the CDM
|
||||
// video decoder is successfully initialized.
|
||||
// Returns kSessionError if |video_decoder_config| is not supported. The CDM
|
||||
// may still be able to do Decrypt().
|
||||
// Returns kDeferredInitialization if the CDM is not ready to initialize the
|
||||
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
|
||||
// initialization is complete.
|
||||
virtual Status InitializeVideoDecoder(
|
||||
const VideoDecoderConfig& video_decoder_config) = 0;
|
||||
|
||||
// De-initializes the CDM decoder and sets it to an uninitialized state. The
|
||||
// caller can initialize the decoder again after this call to re-initialize
|
||||
// it. This can be used to reconfigure the decoder if the configuration
|
||||
// changes.
|
||||
virtual void DeinitializeDecoder(StreamType decoder_type) = 0;
|
||||
|
||||
// Resets the CDM decoder to an initialized clean state. All internal buffers
|
||||
// MUST be flushed.
|
||||
virtual void ResetDecoder(StreamType decoder_type) = 0;
|
||||
|
||||
// Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a
|
||||
// |video_frame|. Upon end-of-stream, the caller should call this function
|
||||
// repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
|
||||
// |video_frame| (|format| == kEmptyVideoFrame) is produced.
|
||||
//
|
||||
// Returns kSuccess if decryption and decoding both succeeded, in which case
|
||||
// the callee will have filled the |video_frame| and passed the ownership of
|
||||
// |frame_buffer| in |video_frame| to the caller.
|
||||
// Returns kNoKey if the CDM did not have the necessary decryption key
|
||||
// to decrypt.
|
||||
// Returns kNeedMoreData if more data was needed by the decoder to generate
|
||||
// a decoded frame (e.g. during initialization and end-of-stream).
|
||||
// Returns kDecryptError if any decryption error happened.
|
||||
// Returns kDecodeError if any decoding error happened.
|
||||
// If the return value is not kSuccess, |video_frame| should be ignored by
|
||||
// the caller.
|
||||
virtual Status DecryptAndDecodeFrame(const InputBuffer& encrypted_buffer,
|
||||
VideoFrame* video_frame) = 0;
|
||||
|
||||
// Decrypts the |encrypted_buffer| and decodes the decrypted buffer into
|
||||
// |audio_frames|. Upon end-of-stream, the caller should call this function
|
||||
// repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
|
||||
// |audio_frames| is produced.
|
||||
//
|
||||
// Returns kSuccess if decryption and decoding both succeeded, in which case
|
||||
// the callee will have filled |audio_frames| and passed the ownership of
|
||||
// |data| in |audio_frames| to the caller.
|
||||
// Returns kNoKey if the CDM did not have the necessary decryption key
|
||||
// to decrypt.
|
||||
// Returns kNeedMoreData if more data was needed by the decoder to generate
|
||||
// audio samples (e.g. during initialization and end-of-stream).
|
||||
// Returns kDecryptError if any decryption error happened.
|
||||
// Returns kDecodeError if any decoding error happened.
|
||||
// If the return value is not kSuccess, |audio_frames| should be ignored by
|
||||
// the caller.
|
||||
virtual Status DecryptAndDecodeSamples(const InputBuffer& encrypted_buffer,
|
||||
AudioFrames* audio_frames) = 0;
|
||||
|
||||
// Called by the host after a platform challenge was initiated via
|
||||
// Host::SendPlatformChallenge().
|
||||
virtual void OnPlatformChallengeResponse(
|
||||
const PlatformChallengeResponse& response) = 0;
|
||||
|
||||
// Called by the host after a call to Host::QueryOutputProtectionStatus(). The
|
||||
// |link_mask| is a bit mask of OutputLinkTypes and |output_protection_mask|
|
||||
// is a bit mask of OutputProtectionMethods. If |result| is kQueryFailed,
|
||||
// then |link_mask| and |output_protection_mask| are undefined and should
|
||||
// be ignored.
|
||||
virtual void OnQueryOutputProtectionStatus(
|
||||
QueryResult result,
|
||||
uint32_t link_mask,
|
||||
uint32_t output_protection_mask) = 0;
|
||||
|
||||
// Destroys the object in the same context as it was created.
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
protected:
|
||||
ContentDecryptionModule_7() {}
|
||||
virtual ~ContentDecryptionModule_7() {}
|
||||
};
|
||||
|
||||
// ContentDecryptionModule interface that all CDMs need to implement.
|
||||
// The interface is versioned for backward compatibility.
|
||||
// Note: ContentDecryptionModule implementations must use the allocator
|
||||
// provided in CreateCdmInstance() to allocate any Buffer that needs to
|
||||
// be passed back to the caller. Implementations must call Buffer::Destroy()
|
||||
// when a Buffer is created that will never be returned to the caller.
|
||||
class ContentDecryptionModule_8 {
|
||||
class CDM_CLASS_API ContentDecryptionModule_8 {
|
||||
public:
|
||||
static const int kVersion = 8;
|
||||
typedef Host_8 Host;
|
||||
@ -823,10 +696,210 @@ class ContentDecryptionModule_8 {
|
||||
virtual ~ContentDecryptionModule_8() {}
|
||||
};
|
||||
|
||||
typedef ContentDecryptionModule_8 ContentDecryptionModule;
|
||||
// ContentDecryptionModule interface that all CDMs need to implement.
|
||||
// The interface is versioned for backward compatibility.
|
||||
// Note: ContentDecryptionModule implementations must use the allocator
|
||||
// provided in CreateCdmInstance() to allocate any Buffer that needs to
|
||||
// be passed back to the caller. Implementations must call Buffer::Destroy()
|
||||
// when a Buffer is created that will never be returned to the caller.
|
||||
class CDM_CLASS_API ContentDecryptionModule_9 {
|
||||
public:
|
||||
static const int kVersion = 9;
|
||||
typedef Host_9 Host;
|
||||
|
||||
// Initializes the CDM instance, providing information about permitted
|
||||
// functionalities.
|
||||
// If |allow_distinctive_identifier| is false, messages from the CDM,
|
||||
// such as message events, must not contain a Distinctive Identifier,
|
||||
// even in an encrypted form.
|
||||
// If |allow_persistent_state| is false, the CDM must not attempt to
|
||||
// persist state. Calls to CreateFileIO() will fail.
|
||||
virtual void Initialize(bool allow_distinctive_identifier,
|
||||
bool allow_persistent_state) = 0;
|
||||
|
||||
// Gets the key status if the CDM has a hypothetical key with the |policy|.
|
||||
// The CDM must respond by calling either Host::OnResolveKeyStatusPromise()
|
||||
// with the result key status or Host::OnRejectPromise() if an unexpected
|
||||
// error happened or this method is not supported.
|
||||
virtual void GetStatusForPolicy(uint32_t promise_id,
|
||||
const Policy& policy) = 0;
|
||||
|
||||
// SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(),
|
||||
// UpdateSession(), CloseSession(), and RemoveSession() all accept a
|
||||
// |promise_id|, which must be passed to the completion Host method
|
||||
// (e.g. Host::OnResolveNewSessionPromise()).
|
||||
|
||||
// Provides a server certificate to be used to encrypt messages to the
|
||||
// license server. The CDM must respond by calling either
|
||||
// Host::OnResolvePromise() or Host::OnRejectPromise().
|
||||
virtual void SetServerCertificate(uint32_t promise_id,
|
||||
const uint8_t* server_certificate_data,
|
||||
uint32_t server_certificate_data_size) = 0;
|
||||
|
||||
// Creates a session given |session_type|, |init_data_type|, and |init_data|.
|
||||
// The CDM must respond by calling either Host::OnResolveNewSessionPromise()
|
||||
// or Host::OnRejectPromise().
|
||||
virtual void CreateSessionAndGenerateRequest(uint32_t promise_id,
|
||||
SessionType session_type,
|
||||
InitDataType init_data_type,
|
||||
const uint8_t* init_data,
|
||||
uint32_t init_data_size) = 0;
|
||||
|
||||
// Loads the session of type |session_type| specified by |session_id|.
|
||||
// The CDM must respond by calling either Host::OnResolveNewSessionPromise()
|
||||
// or Host::OnRejectPromise(). If the session is not found, call
|
||||
// Host::OnResolveNewSessionPromise() with session_id = NULL.
|
||||
virtual void LoadSession(uint32_t promise_id,
|
||||
SessionType session_type,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Updates the session with |response|. The CDM must respond by calling
|
||||
// either Host::OnResolvePromise() or Host::OnRejectPromise().
|
||||
virtual void UpdateSession(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
const uint8_t* response,
|
||||
uint32_t response_size) = 0;
|
||||
|
||||
// Requests that the CDM close the session. The CDM must respond by calling
|
||||
// either Host::OnResolvePromise() or Host::OnRejectPromise() when the request
|
||||
// has been processed. This may be before the session is closed. Once the
|
||||
// session is closed, Host::OnSessionClosed() must also be called.
|
||||
virtual void CloseSession(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Removes any stored session data associated with this session. Will only be
|
||||
// called for persistent sessions. The CDM must respond by calling either
|
||||
// Host::OnResolvePromise() or Host::OnRejectPromise() when the request has
|
||||
// been processed.
|
||||
virtual void RemoveSession(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Performs scheduled operation with |context| when the timer fires.
|
||||
virtual void TimerExpired(void* context) = 0;
|
||||
|
||||
// Decrypts the |encrypted_buffer|.
|
||||
//
|
||||
// Returns kSuccess if decryption succeeded, in which case the callee
|
||||
// should have filled the |decrypted_buffer| and passed the ownership of
|
||||
// |data| in |decrypted_buffer| to the caller.
|
||||
// Returns kNoKey if the CDM did not have the necessary decryption key
|
||||
// to decrypt.
|
||||
// Returns kDecryptError if any other error happened.
|
||||
// If the return value is not kSuccess, |decrypted_buffer| should be ignored
|
||||
// by the caller.
|
||||
virtual Status Decrypt(const InputBuffer& encrypted_buffer,
|
||||
DecryptedBlock* decrypted_buffer) = 0;
|
||||
|
||||
// Initializes the CDM audio decoder with |audio_decoder_config|. This
|
||||
// function must be called before DecryptAndDecodeSamples() is called.
|
||||
//
|
||||
// Returns kSuccess if the |audio_decoder_config| is supported and the CDM
|
||||
// audio decoder is successfully initialized.
|
||||
// Returns kSessionError if |audio_decoder_config| is not supported. The CDM
|
||||
// may still be able to do Decrypt().
|
||||
// Returns kDeferredInitialization if the CDM is not ready to initialize the
|
||||
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
|
||||
// initialization is complete.
|
||||
virtual Status InitializeAudioDecoder(
|
||||
const AudioDecoderConfig& audio_decoder_config) = 0;
|
||||
|
||||
// Initializes the CDM video decoder with |video_decoder_config|. This
|
||||
// function must be called before DecryptAndDecodeFrame() is called.
|
||||
//
|
||||
// Returns kSuccess if the |video_decoder_config| is supported and the CDM
|
||||
// video decoder is successfully initialized.
|
||||
// Returns kSessionError if |video_decoder_config| is not supported. The CDM
|
||||
// may still be able to do Decrypt().
|
||||
// Returns kDeferredInitialization if the CDM is not ready to initialize the
|
||||
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
|
||||
// initialization is complete.
|
||||
virtual Status InitializeVideoDecoder(
|
||||
const VideoDecoderConfig& video_decoder_config) = 0;
|
||||
|
||||
// De-initializes the CDM decoder and sets it to an uninitialized state. The
|
||||
// caller can initialize the decoder again after this call to re-initialize
|
||||
// it. This can be used to reconfigure the decoder if the configuration
|
||||
// changes.
|
||||
virtual void DeinitializeDecoder(StreamType decoder_type) = 0;
|
||||
|
||||
// Resets the CDM decoder to an initialized clean state. All internal buffers
|
||||
// MUST be flushed.
|
||||
virtual void ResetDecoder(StreamType decoder_type) = 0;
|
||||
|
||||
// Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a
|
||||
// |video_frame|. Upon end-of-stream, the caller should call this function
|
||||
// repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
|
||||
// |video_frame| (|format| == kEmptyVideoFrame) is produced.
|
||||
//
|
||||
// Returns kSuccess if decryption and decoding both succeeded, in which case
|
||||
// the callee will have filled the |video_frame| and passed the ownership of
|
||||
// |frame_buffer| in |video_frame| to the caller.
|
||||
// Returns kNoKey if the CDM did not have the necessary decryption key
|
||||
// to decrypt.
|
||||
// Returns kNeedMoreData if more data was needed by the decoder to generate
|
||||
// a decoded frame (e.g. during initialization and end-of-stream).
|
||||
// Returns kDecryptError if any decryption error happened.
|
||||
// Returns kDecodeError if any decoding error happened.
|
||||
// If the return value is not kSuccess, |video_frame| should be ignored by
|
||||
// the caller.
|
||||
virtual Status DecryptAndDecodeFrame(const InputBuffer& encrypted_buffer,
|
||||
VideoFrame* video_frame) = 0;
|
||||
|
||||
// Decrypts the |encrypted_buffer| and decodes the decrypted buffer into
|
||||
// |audio_frames|. Upon end-of-stream, the caller should call this function
|
||||
// repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
|
||||
// |audio_frames| is produced.
|
||||
//
|
||||
// Returns kSuccess if decryption and decoding both succeeded, in which case
|
||||
// the callee will have filled |audio_frames| and passed the ownership of
|
||||
// |data| in |audio_frames| to the caller.
|
||||
// Returns kNoKey if the CDM did not have the necessary decryption key
|
||||
// to decrypt.
|
||||
// Returns kNeedMoreData if more data was needed by the decoder to generate
|
||||
// audio samples (e.g. during initialization and end-of-stream).
|
||||
// Returns kDecryptError if any decryption error happened.
|
||||
// Returns kDecodeError if any decoding error happened.
|
||||
// If the return value is not kSuccess, |audio_frames| should be ignored by
|
||||
// the caller.
|
||||
virtual Status DecryptAndDecodeSamples(const InputBuffer& encrypted_buffer,
|
||||
AudioFrames* audio_frames) = 0;
|
||||
|
||||
// Called by the host after a platform challenge was initiated via
|
||||
// Host::SendPlatformChallenge().
|
||||
virtual void OnPlatformChallengeResponse(
|
||||
const PlatformChallengeResponse& response) = 0;
|
||||
|
||||
// Called by the host after a call to Host::QueryOutputProtectionStatus(). The
|
||||
// |link_mask| is a bit mask of OutputLinkTypes and |output_protection_mask|
|
||||
// is a bit mask of OutputProtectionMethods. If |result| is kQueryFailed,
|
||||
// then |link_mask| and |output_protection_mask| are undefined and should
|
||||
// be ignored.
|
||||
virtual void OnQueryOutputProtectionStatus(
|
||||
QueryResult result,
|
||||
uint32_t link_mask,
|
||||
uint32_t output_protection_mask) = 0;
|
||||
|
||||
// Called by the host after a call to Host::RequestStorageId(). If the storage
|
||||
// ID is not available, null/zero will be provided.
|
||||
virtual void OnStorageId(const uint8_t* storage_id,
|
||||
uint32_t storage_id_size) = 0;
|
||||
|
||||
// Destroys the object in the same context as it was created.
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
protected:
|
||||
ContentDecryptionModule_9() {}
|
||||
virtual ~ContentDecryptionModule_9() {}
|
||||
};
|
||||
|
||||
typedef ContentDecryptionModule_9 ContentDecryptionModule;
|
||||
|
||||
// Represents a buffer created by Allocator implementations.
|
||||
class Buffer {
|
||||
class CDM_CLASS_API Buffer {
|
||||
public:
|
||||
// Destroys the buffer in the same context as it was created.
|
||||
virtual void Destroy() = 0;
|
||||
@ -845,144 +918,7 @@ class Buffer {
|
||||
void operator=(const Buffer&);
|
||||
};
|
||||
|
||||
class Host_7 {
|
||||
public:
|
||||
static const int kVersion = 7;
|
||||
|
||||
// Returns a Buffer* containing non-zero members upon success, or NULL on
|
||||
// failure. The caller owns the Buffer* after this call. The buffer is not
|
||||
// guaranteed to be zero initialized. The capacity of the allocated Buffer
|
||||
// is guaranteed to be not less than |capacity|.
|
||||
virtual Buffer* Allocate(uint32_t capacity) = 0;
|
||||
|
||||
// Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms|
|
||||
// from now with |context|.
|
||||
virtual void SetTimer(int64_t delay_ms, void* context) = 0;
|
||||
|
||||
// Returns the current wall time in seconds.
|
||||
virtual Time GetCurrentWallTime() = 0;
|
||||
|
||||
// Called by the CDM when a session is created or loaded and the value for the
|
||||
// MediaKeySession's sessionId attribute is available (|session_id|).
|
||||
// This must be called before OnSessionMessage() or
|
||||
// OnSessionKeysChange() is called for the same session. |session_id_size|
|
||||
// should not include null termination.
|
||||
// When called in response to LoadSession(), the |session_id| must be the
|
||||
// same as the |session_id| passed in LoadSession(), or NULL if the
|
||||
// session could not be loaded.
|
||||
virtual void OnResolveNewSessionPromise(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Called by the CDM when a session is updated or released.
|
||||
virtual void OnResolvePromise(uint32_t promise_id) = 0;
|
||||
|
||||
// Called by the CDM when an error occurs as a result of one of the
|
||||
// ContentDecryptionModule calls that accept a |promise_id|.
|
||||
// |error| must be specified, |error_message| and |system_code|
|
||||
// are optional. |error_message_size| should not include null termination.
|
||||
virtual void OnRejectPromise(uint32_t promise_id,
|
||||
Error error,
|
||||
uint32_t system_code,
|
||||
const char* error_message,
|
||||
uint32_t error_message_size) = 0;
|
||||
|
||||
// Called by the CDM when it has a message for session |session_id|.
|
||||
// Size parameters should not include null termination.
|
||||
// |legacy_destination_url| is only for supporting the prefixed EME API and
|
||||
// is ignored by unprefixed EME. It should only be non-null if |message_type|
|
||||
// is kLicenseRenewal.
|
||||
virtual void OnSessionMessage(const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
MessageType message_type,
|
||||
const char* message,
|
||||
uint32_t message_size,
|
||||
const char* legacy_destination_url,
|
||||
uint32_t legacy_destination_url_length) = 0;
|
||||
|
||||
// Called by the CDM when there has been a change in keys or their status for
|
||||
// session |session_id|. |has_additional_usable_key| should be set if a
|
||||
// key is newly usable (e.g. new key available, previously expired key has
|
||||
// been renewed, etc.) and the browser should attempt to resume playback.
|
||||
// |key_ids| is the list of key ids for this session along with their
|
||||
// current status. |key_ids_count| is the number of entries in |key_ids|.
|
||||
// Size parameter for |session_id| should not include null termination.
|
||||
virtual void OnSessionKeysChange(const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
bool has_additional_usable_key,
|
||||
const KeyInformation* keys_info,
|
||||
uint32_t keys_info_count) = 0;
|
||||
|
||||
// Called by the CDM when there has been a change in the expiration time for
|
||||
// session |session_id|. This can happen as the result of an Update() call
|
||||
// or some other event. If this happens as a result of a call to Update(),
|
||||
// it must be called before resolving the Update() promise. |new_expiry_time|
|
||||
// can be 0 to represent "undefined". Size parameter should not include
|
||||
// null termination.
|
||||
virtual void OnExpirationChange(const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
Time new_expiry_time) = 0;
|
||||
|
||||
// Called by the CDM when session |session_id| is closed. Size
|
||||
// parameter should not include null termination.
|
||||
virtual void OnSessionClosed(const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Called by the CDM when an error occurs in session |session_id|
|
||||
// unrelated to one of the ContentDecryptionModule calls that accept a
|
||||
// |promise_id|. |error| must be specified, |error_message| and
|
||||
// |system_code| are optional. Length parameters should not include null
|
||||
// termination.
|
||||
// Note:
|
||||
// - This method is only for supporting prefixed EME API.
|
||||
// - This method will be ignored by unprefixed EME. All errors reported
|
||||
// in this method should probably also be reported by one of other methods.
|
||||
virtual void OnLegacySessionError(
|
||||
const char* session_id, uint32_t session_id_length,
|
||||
Error error,
|
||||
uint32_t system_code,
|
||||
const char* error_message, uint32_t error_message_length) = 0;
|
||||
|
||||
// The following are optional methods that may not be implemented on all
|
||||
// platforms.
|
||||
|
||||
// Sends a platform challenge for the given |service_id|. |challenge| is at
|
||||
// most 256 bits of data to be signed. Once the challenge has been completed,
|
||||
// the host will call ContentDecryptionModule::OnPlatformChallengeResponse()
|
||||
// with the signed challenge response and platform certificate. Size
|
||||
// parameters should not include null termination.
|
||||
virtual void SendPlatformChallenge(const char* service_id,
|
||||
uint32_t service_id_size,
|
||||
const char* challenge,
|
||||
uint32_t challenge_size) = 0;
|
||||
|
||||
// Attempts to enable output protection (e.g. HDCP) on the display link. The
|
||||
// |desired_protection_mask| is a bit mask of OutputProtectionMethods. No
|
||||
// status callback is issued, the CDM must call QueryOutputProtectionStatus()
|
||||
// periodically to ensure the desired protections are applied.
|
||||
virtual void EnableOutputProtection(uint32_t desired_protection_mask) = 0;
|
||||
|
||||
// Requests the current output protection status. Once the host has the status
|
||||
// it will call ContentDecryptionModule::OnQueryOutputProtectionStatus().
|
||||
virtual void QueryOutputProtectionStatus() = 0;
|
||||
|
||||
// Must be called by the CDM if it returned kDeferredInitialization during
|
||||
// InitializeAudioDecoder() or InitializeVideoDecoder().
|
||||
virtual void OnDeferredInitializationDone(StreamType stream_type,
|
||||
Status decoder_status) = 0;
|
||||
|
||||
// Creates a FileIO object from the host to do file IO operation. Returns NULL
|
||||
// if a FileIO object cannot be obtained. Once a valid FileIO object is
|
||||
// returned, |client| must be valid until FileIO::Close() is called. The
|
||||
// CDM can call this method multiple times to operate on different files.
|
||||
virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
|
||||
|
||||
protected:
|
||||
Host_7() {}
|
||||
virtual ~Host_7() {}
|
||||
};
|
||||
|
||||
class Host_8 {
|
||||
class CDM_CLASS_API Host_8 {
|
||||
public:
|
||||
static const int kVersion = 8;
|
||||
|
||||
@ -996,7 +932,7 @@ class Host_8 {
|
||||
// from now with |context|.
|
||||
virtual void SetTimer(int64_t delay_ms, void* context) = 0;
|
||||
|
||||
// Returns the current wall time in seconds.
|
||||
// Returns the current wall time.
|
||||
virtual Time GetCurrentWallTime() = 0;
|
||||
|
||||
// Called by the CDM when a session is created or loaded and the value for the
|
||||
@ -1054,8 +990,10 @@ class Host_8 {
|
||||
// session |session_id|. This can happen as the result of an Update() call
|
||||
// or some other event. If this happens as a result of a call to Update(),
|
||||
// it must be called before resolving the Update() promise. |new_expiry_time|
|
||||
// can be 0 to represent "undefined". Size parameter should not include
|
||||
// null termination.
|
||||
// represents the time after which the key(s) in the session will no longer
|
||||
// be usable for decryption. It can be 0 if no such time exists or if the
|
||||
// license explicitly never expires. Size parameter should not include null
|
||||
// termination.
|
||||
virtual void OnExpirationChange(const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
Time new_expiry_time) = 0;
|
||||
@ -1119,8 +1057,138 @@ class Host_8 {
|
||||
virtual ~Host_8() {}
|
||||
};
|
||||
|
||||
class CDM_CLASS_API Host_9 {
|
||||
public:
|
||||
static const int kVersion = 9;
|
||||
|
||||
// Returns a Buffer* containing non-zero members upon success, or NULL on
|
||||
// failure. The caller owns the Buffer* after this call. The buffer is not
|
||||
// guaranteed to be zero initialized. The capacity of the allocated Buffer
|
||||
// is guaranteed to be not less than |capacity|.
|
||||
virtual Buffer* Allocate(uint32_t capacity) = 0;
|
||||
|
||||
// Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms|
|
||||
// from now with |context|.
|
||||
virtual void SetTimer(int64_t delay_ms, void* context) = 0;
|
||||
|
||||
// Returns the current wall time.
|
||||
virtual Time GetCurrentWallTime() = 0;
|
||||
|
||||
// Called by the CDM when a key status is available in response to
|
||||
// GetStatusForPolicy().
|
||||
virtual void OnResolveKeyStatusPromise(uint32_t promise_id,
|
||||
KeyStatus key_status) = 0;
|
||||
|
||||
// Called by the CDM when a session is created or loaded and the value for the
|
||||
// MediaKeySession's sessionId attribute is available (|session_id|).
|
||||
// This must be called before OnSessionMessage() or
|
||||
// OnSessionKeysChange() is called for the same session. |session_id_size|
|
||||
// should not include null termination.
|
||||
// When called in response to LoadSession(), the |session_id| must be the
|
||||
// same as the |session_id| passed in LoadSession(), or NULL if the
|
||||
// session could not be loaded.
|
||||
virtual void OnResolveNewSessionPromise(uint32_t promise_id,
|
||||
const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// Called by the CDM when a session is updated or released.
|
||||
virtual void OnResolvePromise(uint32_t promise_id) = 0;
|
||||
|
||||
// Called by the CDM when an error occurs as a result of one of the
|
||||
// ContentDecryptionModule calls that accept a |promise_id|.
|
||||
// |exception| must be specified. |error_message| and |system_code|
|
||||
// are optional. |error_message_size| should not include null termination.
|
||||
virtual void OnRejectPromise(uint32_t promise_id,
|
||||
Exception exception,
|
||||
uint32_t system_code,
|
||||
const char* error_message,
|
||||
uint32_t error_message_size) = 0;
|
||||
|
||||
// Called by the CDM when it has a message for session |session_id|.
|
||||
// Size parameters should not include null termination.
|
||||
virtual void OnSessionMessage(const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
MessageType message_type,
|
||||
const char* message,
|
||||
uint32_t message_size) = 0;
|
||||
|
||||
// Called by the CDM when there has been a change in keys or their status for
|
||||
// session |session_id|. |has_additional_usable_key| should be set if a
|
||||
// key is newly usable (e.g. new key available, previously expired key has
|
||||
// been renewed, etc.) and the browser should attempt to resume playback.
|
||||
// |key_ids| is the list of key ids for this session along with their
|
||||
// current status. |key_ids_count| is the number of entries in |key_ids|.
|
||||
// Size parameter for |session_id| should not include null termination.
|
||||
virtual void OnSessionKeysChange(const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
bool has_additional_usable_key,
|
||||
const KeyInformation* keys_info,
|
||||
uint32_t keys_info_count) = 0;
|
||||
|
||||
// Called by the CDM when there has been a change in the expiration time for
|
||||
// session |session_id|. This can happen as the result of an Update() call
|
||||
// or some other event. If this happens as a result of a call to Update(),
|
||||
// it must be called before resolving the Update() promise. |new_expiry_time|
|
||||
// represents the time after which the key(s) in the session will no longer
|
||||
// be usable for decryption. It can be 0 if no such time exists or if the
|
||||
// license explicitly never expires. Size parameter should not include null
|
||||
// termination.
|
||||
virtual void OnExpirationChange(const char* session_id,
|
||||
uint32_t session_id_size,
|
||||
Time new_expiry_time) = 0;
|
||||
|
||||
// Called by the CDM when session |session_id| is closed. Size
|
||||
// parameter should not include null termination.
|
||||
virtual void OnSessionClosed(const char* session_id,
|
||||
uint32_t session_id_size) = 0;
|
||||
|
||||
// The following are optional methods that may not be implemented on all
|
||||
// platforms.
|
||||
|
||||
// Sends a platform challenge for the given |service_id|. |challenge| is at
|
||||
// most 256 bits of data to be signed. Once the challenge has been completed,
|
||||
// the host will call ContentDecryptionModule::OnPlatformChallengeResponse()
|
||||
// with the signed challenge response and platform certificate. Size
|
||||
// parameters should not include null termination.
|
||||
virtual void SendPlatformChallenge(const char* service_id,
|
||||
uint32_t service_id_size,
|
||||
const char* challenge,
|
||||
uint32_t challenge_size) = 0;
|
||||
|
||||
// Attempts to enable output protection (e.g. HDCP) on the display link. The
|
||||
// |desired_protection_mask| is a bit mask of OutputProtectionMethods. No
|
||||
// status callback is issued, the CDM must call QueryOutputProtectionStatus()
|
||||
// periodically to ensure the desired protections are applied.
|
||||
virtual void EnableOutputProtection(uint32_t desired_protection_mask) = 0;
|
||||
|
||||
// Requests the current output protection status. Once the host has the status
|
||||
// it will call ContentDecryptionModule::OnQueryOutputProtectionStatus().
|
||||
virtual void QueryOutputProtectionStatus() = 0;
|
||||
|
||||
// Must be called by the CDM if it returned kDeferredInitialization during
|
||||
// InitializeAudioDecoder() or InitializeVideoDecoder().
|
||||
virtual void OnDeferredInitializationDone(StreamType stream_type,
|
||||
Status decoder_status) = 0;
|
||||
|
||||
// Creates a FileIO object from the host to do file IO operation. Returns NULL
|
||||
// if a FileIO object cannot be obtained. Once a valid FileIO object is
|
||||
// returned, |client| must be valid until FileIO::Close() is called. The
|
||||
// CDM can call this method multiple times to operate on different files.
|
||||
virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
|
||||
|
||||
// Requests the storage ID. The ID will be returned by the host via
|
||||
// ContentDecryptionModule::OnStorageId(). A storage ID is a stable, device
|
||||
// specific ID used by the CDM to securely store persistent data. The CDM must
|
||||
// not expose the ID outside the client device, even in encrypted form.
|
||||
virtual void RequestStorageId() = 0;
|
||||
|
||||
protected:
|
||||
Host_9() {}
|
||||
virtual ~Host_9() {}
|
||||
};
|
||||
|
||||
// Represents a decrypted block that has not been decoded.
|
||||
class DecryptedBlock {
|
||||
class CDM_CLASS_API DecryptedBlock {
|
||||
public:
|
||||
virtual void SetDecryptedBuffer(Buffer* buffer) = 0;
|
||||
virtual Buffer* DecryptedBuffer() = 0;
|
||||
@ -1135,7 +1203,7 @@ class DecryptedBlock {
|
||||
virtual ~DecryptedBlock() {}
|
||||
};
|
||||
|
||||
class VideoFrame {
|
||||
class CDM_CLASS_API VideoFrame {
|
||||
public:
|
||||
enum VideoPlane {
|
||||
kYPlane = 0,
|
||||
@ -1178,7 +1246,7 @@ class VideoFrame {
|
||||
//
|
||||
// |<----------------- AudioFrames ------------------>|
|
||||
// | audio buffer 0 | audio buffer 1 | audio buffer 2 |
|
||||
class AudioFrames {
|
||||
class CDM_CLASS_API AudioFrames {
|
||||
public:
|
||||
virtual void SetFrameBuffer(Buffer* buffer) = 0;
|
||||
virtual Buffer* FrameBuffer() = 0;
|
||||
|
@ -0,0 +1,22 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
|
||||
#define CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
|
||||
|
||||
// Define CDM_API so that functionality implemented by the CDM module
|
||||
// can be exported to consumers.
|
||||
#if defined(_WIN32)
|
||||
|
||||
#if defined(CDM_IMPLEMENTATION)
|
||||
#define CDM_API __declspec(dllexport)
|
||||
#else
|
||||
#define CDM_API __declspec(dllimport)
|
||||
#endif // defined(CDM_IMPLEMENTATION)
|
||||
|
||||
#else // defined(_WIN32)
|
||||
#define CDM_API __attribute__((visibility("default")))
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#endif // CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
|
@ -0,0 +1,64 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
|
||||
#define CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "content_decryption_module_export.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
namespace cdm {
|
||||
|
||||
#if defined(_WIN32)
|
||||
typedef wchar_t FilePathCharType;
|
||||
typedef HANDLE PlatformFile;
|
||||
const PlatformFile kInvalidPlatformFile = INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
typedef char FilePathCharType;
|
||||
typedef int PlatformFile;
|
||||
const PlatformFile kInvalidPlatformFile = -1;
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
struct HostFile {
|
||||
HostFile(const FilePathCharType* file_path,
|
||||
PlatformFile file,
|
||||
PlatformFile sig_file)
|
||||
: file_path(file_path), file(file), sig_file(sig_file) {}
|
||||
|
||||
// File that is part of the host of the CDM.
|
||||
const FilePathCharType* file_path = nullptr;
|
||||
PlatformFile file = kInvalidPlatformFile;
|
||||
|
||||
// Signature file for |file|.
|
||||
PlatformFile sig_file = kInvalidPlatformFile;
|
||||
};
|
||||
|
||||
} // namespace cdm
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Functions in this file are dynamically retrieved by their versioned function
|
||||
// names. Increment the version number for any backward incompatible API
|
||||
// changes.
|
||||
|
||||
// Verifies CDM host. All files in |host_files| are opened in read-only mode.
|
||||
//
|
||||
// Returns false and closes all files if there is an immediate failure.
|
||||
// Otherwise returns true as soon as possible and processes the files
|
||||
// asynchronously. All files MUST be closed by the CDM after this one-time
|
||||
// processing is finished.
|
||||
CDM_API bool VerifyCdmHost_0(const cdm::HostFile* host_files,
|
||||
uint32_t num_files);
|
||||
}
|
||||
|
||||
#endif // CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
|
@ -306,12 +306,12 @@ MediaSourceDecoder::CanPlayThrough()
|
||||
} else if (duration <= currentPosition) {
|
||||
return true;
|
||||
}
|
||||
// If we have data up to the mediasource's duration or 30s ahead, we can
|
||||
// If we have data up to the mediasource's duration or 10s ahead, we can
|
||||
// assume that we can play without interruption.
|
||||
TimeIntervals buffered = GetBuffered();
|
||||
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ / 2);
|
||||
TimeUnit timeAhead =
|
||||
std::min(duration, currentPosition + TimeUnit::FromSeconds(30));
|
||||
std::min(duration, currentPosition + TimeUnit::FromSeconds(10));
|
||||
TimeInterval interval(currentPosition, timeAhead);
|
||||
return buffered.ContainsStrict(ClampIntervalToEnd(interval));
|
||||
}
|
||||
|
@ -105,6 +105,8 @@ skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not
|
||||
skip-if = android_version == '22' # bug 1359010
|
||||
[test_PlayEvents.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_PlayEventsAutoPlaying.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_ResumeAfterClearing_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_SeekableAfterEndOfStream.html]
|
||||
|
74
dom/media/mediasource/test/test_PlayEventsAutoPlaying.html
Normal file
74
dom/media/mediasource/test/test_PlayEventsAutoPlaying.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>MSE: basic functionality</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// This test checks that readyState is properly set and the appropriate events are being fired accordingly:
|
||||
// 1. Ensure that play/playing aren't fired before any media data been added.
|
||||
// 2. Load 1.6s of data and ensure that canplay, play and playing events are fired.
|
||||
|
||||
runWithMSE(function(ms, el) {
|
||||
el.controls = true;
|
||||
el.autoplay = true;
|
||||
var eventCounts = { play: 0, playing: 0};
|
||||
function ForbiddenEvents(e) {
|
||||
var v = e.target;
|
||||
ok(v.readyState >= v.HAVE_FUTURE_DATA, "Must not have received event too early");
|
||||
is(eventCounts[e.type], 0, "event should have only be fired once");
|
||||
eventCounts[e.type]++;
|
||||
}
|
||||
once(ms, 'sourceopen').then(function() {
|
||||
// Log events for debugging.
|
||||
var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
|
||||
"loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
|
||||
"waiting", "pause", "durationchange", "seeking", "seeked"];
|
||||
function logEvent(e) {
|
||||
info("got " + e.type + " event");
|
||||
}
|
||||
events.forEach(function(e) {
|
||||
el.addEventListener(e, logEvent);
|
||||
});
|
||||
el.addEventListener("play", ForbiddenEvents);
|
||||
el.addEventListener("playing", ForbiddenEvents);
|
||||
|
||||
ok(true, "Receive a sourceopen event");
|
||||
var videosb = ms.addSourceBuffer("video/mp4");
|
||||
is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
|
||||
var promises = [];
|
||||
promises.push(fetchAndLoad(videosb, 'bipbop/bipbop_video', ['init'], '.mp4'));
|
||||
promises.push(once(el, 'loadedmetadata'));
|
||||
Promise.all(promises)
|
||||
.then(function() {
|
||||
ok(true, "got loadedmetadata event");
|
||||
var promises = [];
|
||||
promises.push(once(el, 'loadeddata'));
|
||||
promises.push(once(el, 'canplay'));
|
||||
promises.push(once(el, 'play'));
|
||||
promises.push(once(el, 'playing'));
|
||||
promises.push(once(el, 'ended'));
|
||||
// We're only adding 1.6s worth of data, not enough for readyState to change to HAVE_ENOUGH_DATA
|
||||
// So we end the media source so that all the playable data is available.
|
||||
promises.push(fetchAndLoad(videosb, 'bipbop/bipbop_video', range(1, 3), '.m4s')
|
||||
.then(() => ms.endOfStream()));
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.then(function() {
|
||||
ok(true, "got all required event");
|
||||
SimpleTest.finish();
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
105
dom/webauthn/WebAuthnCBORUtil.cpp
Normal file
105
dom/webauthn/WebAuthnCBORUtil.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "cbor-cpp/src/cbor.h"
|
||||
#include "mozilla/dom/WebAuthnCBORUtil.h"
|
||||
#include "mozilla/dom/WebAuthnUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
nsresult
|
||||
CBOREncodePublicKeyObj(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aPubKeyObj)
|
||||
{
|
||||
mozilla::dom::CryptoBuffer xBuf, yBuf;
|
||||
nsresult rv = U2FDecomposeECKey(aPubKeyBuf, xBuf, yBuf);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
Public Key Object, encoded in CBOR (description is CDDL)
|
||||
|
||||
pubKey = $pubKeyFmt
|
||||
|
||||
pubKeyFmt /= eccPubKey
|
||||
eccPubKey = { alg: eccAlgName, x: biguint, y: biguint }
|
||||
eccAlgName = "ES256" / "ES384" / "ES512"
|
||||
*/
|
||||
cbor::output_dynamic cborPubKeyOut;
|
||||
cbor::encoder encoder(cborPubKeyOut);
|
||||
encoder.write_map(3);
|
||||
{
|
||||
encoder.write_string("alg");
|
||||
encoder.write_string(JWK_ALG_ECDSA_P_256); // Always ES256 for U2F
|
||||
|
||||
encoder.write_string("x");
|
||||
encoder.write_bytes(xBuf.Elements(), xBuf.Length());
|
||||
|
||||
encoder.write_string("y");
|
||||
encoder.write_bytes(yBuf.Elements(), yBuf.Length());
|
||||
}
|
||||
|
||||
if (!aPubKeyObj.Assign(cborPubKeyOut.data(), cborPubKeyOut.size())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CBOREncodeAttestationObj(const CryptoBuffer& aAuthDataBuf,
|
||||
const CryptoBuffer& aAttestationCertBuf,
|
||||
const CryptoBuffer& aSignatureBuf,
|
||||
/* out */ CryptoBuffer& aAttestationObj)
|
||||
{
|
||||
/*
|
||||
Attestation Object, encoded in CBOR (description is CDDL)
|
||||
|
||||
attObj = {
|
||||
authData: bytes,
|
||||
$$attStmtType
|
||||
}
|
||||
$$attStmtType //= (
|
||||
fmt: "fido-u2f",
|
||||
attStmt: u2fStmtFormat
|
||||
)
|
||||
u2fStmtFormat = {
|
||||
x5c: [ attestnCert: bytes, * (caCert: bytes) ],
|
||||
sig: bytes
|
||||
}
|
||||
*/
|
||||
cbor::output_dynamic cborAttOut;
|
||||
cbor::encoder encoder(cborAttOut);
|
||||
encoder.write_map(3);
|
||||
{
|
||||
encoder.write_string("authData");
|
||||
encoder.write_bytes(aAuthDataBuf.Elements(), aAuthDataBuf.Length());
|
||||
|
||||
encoder.write_string("fmt");
|
||||
encoder.write_string("fido-u2f");
|
||||
|
||||
encoder.write_string("attStmt");
|
||||
encoder.write_map(2);
|
||||
{
|
||||
encoder.write_string("x5c");
|
||||
// U2F wire protocol can only deliver 1 certificate, so it's never a chain
|
||||
encoder.write_array(1);
|
||||
encoder.write_bytes(aAttestationCertBuf.Elements(), aAttestationCertBuf.Length());
|
||||
|
||||
encoder.write_string("sig");
|
||||
encoder.write_bytes(aSignatureBuf.Elements(), aSignatureBuf.Length());
|
||||
}
|
||||
}
|
||||
|
||||
if (!aAttestationObj.Assign(cborAttOut.data(), cborAttOut.size())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
32
dom/webauthn/WebAuthnCBORUtil.h
Normal file
32
dom/webauthn/WebAuthnCBORUtil.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_WebAuthnCBORUtil_h
|
||||
#define mozilla_dom_WebAuthnCBORUtil_h
|
||||
|
||||
/*
|
||||
* Serialize and deserialize CBOR data formats for WebAuthn
|
||||
*/
|
||||
|
||||
#include "mozilla/dom/CryptoBuffer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
nsresult
|
||||
CBOREncodePublicKeyObj(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aPubKeyObj);
|
||||
|
||||
nsresult
|
||||
CBOREncodeAttestationObj(const CryptoBuffer& aAuthDataBuf,
|
||||
const CryptoBuffer& aAttestationCertBuf,
|
||||
const CryptoBuffer& aSignatureBuf,
|
||||
/* out */ CryptoBuffer& aAttestationObj);
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_WebAuthnCBORUtil_h
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/AuthenticatorAttestationResponse.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WebAuthnCBORUtil.h"
|
||||
#include "mozilla/dom/WebAuthnManager.h"
|
||||
#include "mozilla/dom/WebAuthnUtil.h"
|
||||
#include "mozilla/dom/PWebAuthnTransaction.h"
|
||||
@ -25,6 +26,13 @@ using namespace mozilla::ipc;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/***********************************************************************
|
||||
* Protocol Constants
|
||||
**********************************************************************/
|
||||
|
||||
const uint8_t FLAG_TUP = 0x01; // Test of User Presence required
|
||||
const uint8_t FLAG_AT = 0x40; // Authenticator Data is provided
|
||||
|
||||
/***********************************************************************
|
||||
* Statics
|
||||
**********************************************************************/
|
||||
@ -54,7 +62,10 @@ GetAlgorithmName(const OOS& aAlgorithm,
|
||||
// TODO: Coerce to string and extract name. See WebCryptoTask.cpp
|
||||
}
|
||||
|
||||
if (!NormalizeToken(aName, aName)) {
|
||||
// Only ES256 is currently supported
|
||||
if (NORMALIZED_EQUALS(aName, JWK_ALG_ECDSA_P_256)) {
|
||||
aName.AssignLiteral(JWK_ALG_ECDSA_P_256);
|
||||
} else {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
@ -393,7 +404,7 @@ WebAuthnManager::MakeCredential(nsPIDOMWindowInner* aParent,
|
||||
if (normalizedParams[a].mType == PublicKeyCredentialType::Public_key &&
|
||||
normalizedParams[a].mAlgorithm.IsString() &&
|
||||
normalizedParams[a].mAlgorithm.GetAsString().EqualsLiteral(
|
||||
WEBCRYPTO_NAMED_CURVE_P256)) {
|
||||
JWK_ALG_ECDSA_P_256)) {
|
||||
isValidCombination = true;
|
||||
break;
|
||||
}
|
||||
@ -654,22 +665,35 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
|
||||
|
||||
CryptoBuffer regData;
|
||||
if (NS_WARN_IF(!regData.Assign(aRegBuffer.Elements(), aRegBuffer.Length()))) {
|
||||
mTransactionPromise->MaybeReject(NS_ERROR_OUT_OF_MEMORY);
|
||||
Cancel(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::dom::CryptoBuffer aaguidBuf;
|
||||
if (NS_WARN_IF(!aaguidBuf.SetCapacity(16, mozilla::fallible))) {
|
||||
Cancel(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
// TODO: Adjust the AAGUID from all zeroes in Bug 1381575 (if needed)
|
||||
// See https://github.com/w3c/webauthn/issues/506
|
||||
for (int i=0; i<16; i++) {
|
||||
aaguidBuf.AppendElement(0x00, mozilla::fallible);
|
||||
}
|
||||
|
||||
// Decompose the U2F registration packet
|
||||
CryptoBuffer pubKeyBuf;
|
||||
CryptoBuffer keyHandleBuf;
|
||||
CryptoBuffer attestationCertBuf;
|
||||
CryptoBuffer signatureBuf;
|
||||
|
||||
// Only handles attestation cert chains of length=1.
|
||||
nsresult rv = U2FDecomposeRegistrationResponse(regData, pubKeyBuf, keyHandleBuf,
|
||||
attestationCertBuf, signatureBuf);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Cancel(rv);
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(keyHandleBuf.Length() <= 0xFFFF);
|
||||
|
||||
CryptoBuffer clientDataBuf;
|
||||
if (!clientDataBuf.Assign(mClientData.ref())) {
|
||||
@ -691,13 +715,64 @@ WebAuthnManager::FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer)
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct the public key object
|
||||
CryptoBuffer pubKeyObj;
|
||||
rv = CBOREncodePublicKeyObj(pubKeyBuf, pubKeyObj);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
// Format:
|
||||
// 32 bytes: SHA256 of the RP ID
|
||||
// 1 byte: flags (TUP & AT)
|
||||
// 4 bytes: sign counter
|
||||
// variable: attestation data struct
|
||||
// - 16 bytes: AAGUID
|
||||
// - 2 bytes: Length of Credential ID
|
||||
// - L bytes: Credential ID
|
||||
// - variable: CBOR-format public key
|
||||
// variable: CBOR-format extension auth data (optional, not flagged)
|
||||
|
||||
mozilla::dom::CryptoBuffer authDataBuf;
|
||||
if (NS_WARN_IF(!authDataBuf.SetCapacity(32 + 1 + 4 + aaguidBuf.Length() + 2 +
|
||||
keyHandleBuf.Length() +
|
||||
pubKeyObj.Length(),
|
||||
mozilla::fallible))) {
|
||||
Cancel(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
authDataBuf.AppendElements(rpIdHashBuf, mozilla::fallible);
|
||||
authDataBuf.AppendElement(FLAG_TUP | FLAG_AT, mozilla::fallible);
|
||||
// During create credential, counter is always 0 for U2F
|
||||
// See https://github.com/w3c/webauthn/issues/507
|
||||
authDataBuf.AppendElement(0x00, mozilla::fallible);
|
||||
authDataBuf.AppendElement(0x00, mozilla::fallible);
|
||||
authDataBuf.AppendElement(0x00, mozilla::fallible);
|
||||
authDataBuf.AppendElement(0x00, mozilla::fallible);
|
||||
|
||||
authDataBuf.AppendElements(aaguidBuf, mozilla::fallible);
|
||||
authDataBuf.AppendElement((keyHandleBuf.Length() >> 8) & 0xFF, mozilla::fallible);
|
||||
authDataBuf.AppendElement((keyHandleBuf.Length() >> 0) & 0xFF, mozilla::fallible);
|
||||
authDataBuf.AppendElements(keyHandleBuf, mozilla::fallible);
|
||||
authDataBuf.AppendElements(pubKeyObj, mozilla::fallible);
|
||||
|
||||
CryptoBuffer attObj;
|
||||
rv = CBOREncodeAttestationObj(authDataBuf, attestationCertBuf, signatureBuf,
|
||||
attObj);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new PublicKeyCredential object and populate its fields with the
|
||||
// values returned from the authenticator as well as the clientDataJSON
|
||||
// computed earlier.
|
||||
RefPtr<AuthenticatorAttestationResponse> attestation =
|
||||
new AuthenticatorAttestationResponse(mCurrentParent);
|
||||
attestation->SetClientDataJSON(clientDataBuf);
|
||||
attestation->SetAttestationObject(regData);
|
||||
attestation->SetAttestationObject(attObj);
|
||||
|
||||
RefPtr<PublicKeyCredential> credential = new PublicKeyCredential(mCurrentParent);
|
||||
credential->SetRawId(keyHandleBuf);
|
||||
|
@ -18,7 +18,9 @@ ReadToCryptoBuffer(pkix::Reader& aSrc, /* out */ CryptoBuffer& aDest,
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
aDest.ClearAndRetainStorage();
|
||||
if (!aDest.SetCapacity(aLen, mozilla::fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (uint32_t offset = 0; offset < aLen; ++offset) {
|
||||
uint8_t b;
|
||||
@ -104,7 +106,7 @@ U2FDecomposeRegistrationResponse(const CryptoBuffer& aResponse,
|
||||
// We have to parse the ASN.1 SEQUENCE on the outside to determine the cert's
|
||||
// length.
|
||||
pkix::Input cert;
|
||||
if (pkix::der::ExpectTagAndGetValue(input, pkix::der::SEQUENCE, cert)
|
||||
if (pkix::der::ExpectTagAndGetTLV(input, pkix::der::SEQUENCE, cert)
|
||||
!= pkix::Success) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
@ -124,6 +126,38 @@ U2FDecomposeRegistrationResponse(const CryptoBuffer& aResponse,
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(input.AtEnd());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
U2FDecomposeECKey(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aXcoord,
|
||||
/* out */ CryptoBuffer& aYcoord)
|
||||
{
|
||||
pkix::Input pubKey;
|
||||
pubKey.Init(aPubKeyBuf.Elements(), aPubKeyBuf.Length());
|
||||
|
||||
pkix::Reader input(pubKey);
|
||||
uint8_t b;
|
||||
if (input.Read(b) != pkix::Success) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
if (b != 0x04) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsresult rv = ReadToCryptoBuffer(input, aXcoord, 32);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = ReadToCryptoBuffer(input, aYcoord, 32);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(input.AtEnd());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,11 @@ nsresult
|
||||
ReadToCryptoBuffer(pkix::Reader& aSrc, /* out */ CryptoBuffer& aDest,
|
||||
uint32_t aLen);
|
||||
|
||||
nsresult
|
||||
U2FDecomposeECKey(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aXcoord,
|
||||
/* out */ CryptoBuffer& aYcoord);
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
35
dom/webauthn/cbor-cpp/README.md
Normal file
35
dom/webauthn/cbor-cpp/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
cbor-cpp
|
||||
========
|
||||
|
||||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/naphaso/cbor-cpp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
CBOR C++ serialization library
|
||||
|
||||
Just a simple SAX-like Concise Binary Object Representation (CBOR).
|
||||
|
||||
[http://tools.ietf.org/html/rfc7049](http://tools.ietf.org/html/rfc7049)
|
||||
|
||||
#### Examples
|
||||
|
||||
```C++
|
||||
cbor::output_dynamic output;
|
||||
|
||||
{ //encoding
|
||||
cbor::encoder encoder(output);
|
||||
encoder.write_array(5);
|
||||
{
|
||||
encoder.write_int(123);
|
||||
encoder.write_string("bar");
|
||||
encoder.write_int(321);
|
||||
encoder.write_int(321);
|
||||
encoder.write_string("foo");
|
||||
}
|
||||
}
|
||||
|
||||
{ // decoding
|
||||
cbor::input input(output.data(), output.size());
|
||||
cbor::listener_debug listener;
|
||||
cbor::decoder decoder(input, listener);
|
||||
decoder.run();
|
||||
}
|
||||
```
|
201
dom/webauthn/cbor-cpp/src/LICENSE
Normal file
201
dom/webauthn/cbor-cpp/src/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
5
dom/webauthn/cbor-cpp/src/README-MOZILLA
Normal file
5
dom/webauthn/cbor-cpp/src/README-MOZILLA
Normal file
@ -0,0 +1,5 @@
|
||||
This library [1] has been stripped down to only the CBOR encoding parts, as there are outstanding issues [2]
|
||||
related to memory safety for the decoder.
|
||||
|
||||
[1] https://github.com/naphaso/cbor-cpp/
|
||||
[2] https://github.com/naphaso/cbor-cpp/issues/8
|
23
dom/webauthn/cbor-cpp/src/cbor.h
Normal file
23
dom/webauthn/cbor-cpp/src/cbor.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2014-2015 Stanislav Ovsyannikov
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef CBOR_CPP_CBOR_H
|
||||
#define CBOR_CPP_CBOR_H
|
||||
|
||||
#include "encoder.h"
|
||||
#include "output_dynamic.h"
|
||||
|
||||
#endif //CBOR_CPP_CBOR_H
|
150
dom/webauthn/cbor-cpp/src/encoder.cpp
Normal file
150
dom/webauthn/cbor-cpp/src/encoder.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
Copyright 2014-2015 Stanislav Ovsyannikov
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "encoder.h"
|
||||
|
||||
using namespace cbor;
|
||||
|
||||
|
||||
encoder::encoder(output &out) {
|
||||
_out = &out;
|
||||
}
|
||||
|
||||
encoder::~encoder() {
|
||||
|
||||
}
|
||||
|
||||
void encoder::write_type_value(int major_type, unsigned int value) {
|
||||
major_type <<= 5;
|
||||
if(value < 24) {
|
||||
_out->put_byte((unsigned char) (major_type | value));
|
||||
} else if(value < 256) {
|
||||
_out->put_byte((unsigned char) (major_type | 24));
|
||||
_out->put_byte((unsigned char) value);
|
||||
} else if(value < 65536) {
|
||||
_out->put_byte((unsigned char) (major_type | 25));
|
||||
_out->put_byte((unsigned char) (value >> 8));
|
||||
_out->put_byte((unsigned char) value);
|
||||
} else {
|
||||
_out->put_byte((unsigned char) (major_type | 26));
|
||||
_out->put_byte((unsigned char) (value >> 24));
|
||||
_out->put_byte((unsigned char) (value >> 16));
|
||||
_out->put_byte((unsigned char) (value >> 8));
|
||||
_out->put_byte((unsigned char) value);
|
||||
}
|
||||
}
|
||||
|
||||
void encoder::write_type_value(int major_type, unsigned long long value) {
|
||||
major_type <<= 5;
|
||||
if(value < 24ULL) {
|
||||
_out->put_byte((unsigned char) (major_type | value));
|
||||
} else if(value < 256ULL) {
|
||||
_out->put_byte((unsigned char) (major_type | 24));
|
||||
_out->put_byte((unsigned char) value);
|
||||
} else if(value < 65536ULL) {
|
||||
_out->put_byte((unsigned char) (major_type | 25));
|
||||
_out->put_byte((unsigned char) (value >> 8));
|
||||
_out->put_byte((unsigned char) value);
|
||||
} else if(value < 4294967296ULL) {
|
||||
_out->put_byte((unsigned char) (major_type | 26));
|
||||
_out->put_byte((unsigned char) (value >> 24));
|
||||
_out->put_byte((unsigned char) (value >> 16));
|
||||
_out->put_byte((unsigned char) (value >> 8));
|
||||
_out->put_byte((unsigned char) value);
|
||||
} else {
|
||||
_out->put_byte((unsigned char) (major_type | 27));
|
||||
_out->put_byte((unsigned char) (value >> 56));
|
||||
_out->put_byte((unsigned char) (value >> 48));
|
||||
_out->put_byte((unsigned char) (value >> 40));
|
||||
_out->put_byte((unsigned char) (value >> 32));
|
||||
_out->put_byte((unsigned char) (value >> 24));
|
||||
_out->put_byte((unsigned char) (value >> 16));
|
||||
_out->put_byte((unsigned char) (value >> 8));
|
||||
_out->put_byte((unsigned char) value);
|
||||
}
|
||||
}
|
||||
|
||||
void encoder::write_int(unsigned int value) {
|
||||
write_type_value(0, value);
|
||||
}
|
||||
|
||||
void encoder::write_int(unsigned long long value) {
|
||||
write_type_value(0, value);
|
||||
}
|
||||
|
||||
void encoder::write_int(long long value) {
|
||||
if(value < 0) {
|
||||
write_type_value(1, (unsigned long long) -(value+1));
|
||||
} else {
|
||||
write_type_value(0, (unsigned long long) value);
|
||||
}
|
||||
}
|
||||
|
||||
void encoder::write_int(int value) {
|
||||
if(value < 0) {
|
||||
write_type_value(1, (unsigned int) -(value+1));
|
||||
} else {
|
||||
write_type_value(0, (unsigned int) value);
|
||||
}
|
||||
}
|
||||
|
||||
void encoder::write_bytes(const unsigned char *data, unsigned int size) {
|
||||
write_type_value(2, size);
|
||||
_out->put_bytes(data, size);
|
||||
}
|
||||
|
||||
void encoder::write_string(const char *data, unsigned int size) {
|
||||
write_type_value(3, size);
|
||||
_out->put_bytes((const unsigned char *) data, size);
|
||||
}
|
||||
|
||||
void encoder::write_string(const std::string str) {
|
||||
write_type_value(3, (unsigned int) str.size());
|
||||
_out->put_bytes((const unsigned char *) str.c_str(), (int) str.size());
|
||||
}
|
||||
|
||||
|
||||
void encoder::write_array(int size) {
|
||||
write_type_value(4, (unsigned int) size);
|
||||
}
|
||||
|
||||
void encoder::write_map(int size) {
|
||||
write_type_value(5, (unsigned int) size);
|
||||
}
|
||||
|
||||
void encoder::write_tag(const unsigned int tag) {
|
||||
write_type_value(6, tag);
|
||||
}
|
||||
|
||||
void encoder::write_special(int special) {
|
||||
write_type_value(7, (unsigned int) special);
|
||||
}
|
||||
|
||||
void encoder::write_bool(bool value) {
|
||||
if (value == true) {
|
||||
_out->put_byte((unsigned char) 0xf5);
|
||||
} else {
|
||||
_out->put_byte((unsigned char) 0xf4);
|
||||
}
|
||||
}
|
||||
|
||||
void encoder::write_null() {
|
||||
_out->put_byte((unsigned char) 0xf6);
|
||||
}
|
||||
|
||||
void encoder::write_undefined() {
|
||||
_out->put_byte((unsigned char) 0xf7);
|
||||
}
|
68
dom/webauthn/cbor-cpp/src/encoder.h
Normal file
68
dom/webauthn/cbor-cpp/src/encoder.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2014-2015 Stanislav Ovsyannikov
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CborEncoder_H_
|
||||
#define __CborEncoder_H_
|
||||
|
||||
#include "output.h"
|
||||
#include <string>
|
||||
|
||||
namespace cbor {
|
||||
class encoder {
|
||||
private:
|
||||
output *_out;
|
||||
public:
|
||||
explicit encoder(output &out);
|
||||
|
||||
~encoder();
|
||||
|
||||
void write_bool(bool value);
|
||||
|
||||
void write_int(int value);
|
||||
|
||||
void write_int(long long value);
|
||||
|
||||
void write_int(unsigned int value);
|
||||
|
||||
void write_int(unsigned long long value);
|
||||
|
||||
void write_bytes(const unsigned char *data, unsigned int size);
|
||||
|
||||
void write_string(const char *data, unsigned int size);
|
||||
|
||||
void write_string(const std::string str);
|
||||
|
||||
void write_array(int size);
|
||||
|
||||
void write_map(int size);
|
||||
|
||||
void write_tag(const unsigned int tag);
|
||||
|
||||
void write_special(int special);
|
||||
|
||||
void write_null();
|
||||
|
||||
void write_undefined();
|
||||
|
||||
private:
|
||||
void write_type_value(int major_type, unsigned int value);
|
||||
|
||||
void write_type_value(int major_type, unsigned long long value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__CborEncoder_H_
|
34
dom/webauthn/cbor-cpp/src/output.h
Normal file
34
dom/webauthn/cbor-cpp/src/output.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright 2014-2015 Stanislav Ovsyannikov
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CborOutput_H_
|
||||
#define __CborOutput_H_
|
||||
|
||||
namespace cbor {
|
||||
class output {
|
||||
public:
|
||||
virtual unsigned char *data() = 0;
|
||||
|
||||
virtual unsigned int size() = 0;
|
||||
|
||||
virtual void put_byte(unsigned char value) = 0;
|
||||
|
||||
virtual void put_bytes(const unsigned char *data, int size) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__CborOutput_H_
|
69
dom/webauthn/cbor-cpp/src/output_dynamic.cpp
Normal file
69
dom/webauthn/cbor-cpp/src/output_dynamic.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
Copyright 2014-2015 Stanislav Ovsyannikov
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "output_dynamic.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace cbor;
|
||||
|
||||
|
||||
void output_dynamic::init(unsigned int initalCapacity) {
|
||||
this->_capacity = initalCapacity;
|
||||
this->_buffer = new unsigned char[initalCapacity];
|
||||
this->_offset = 0;
|
||||
}
|
||||
|
||||
output_dynamic::output_dynamic() {
|
||||
init(256);
|
||||
}
|
||||
|
||||
output_dynamic::output_dynamic(unsigned int inital_capacity) {
|
||||
init(inital_capacity);
|
||||
}
|
||||
|
||||
output_dynamic::~output_dynamic() {
|
||||
delete _buffer;
|
||||
}
|
||||
|
||||
unsigned char *output_dynamic::data() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
unsigned int output_dynamic::size() {
|
||||
return _offset;
|
||||
}
|
||||
|
||||
void output_dynamic::put_byte(unsigned char value) {
|
||||
if(_offset < _capacity) {
|
||||
_buffer[_offset++] = value;
|
||||
} else {
|
||||
_capacity *= 2;
|
||||
_buffer = (unsigned char *) realloc(_buffer, _capacity);
|
||||
_buffer[_offset++] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void output_dynamic::put_bytes(const unsigned char *data, int size) {
|
||||
while(_offset + size > _capacity) {
|
||||
_capacity *= 2;
|
||||
_buffer = (unsigned char *) realloc(_buffer, _capacity);
|
||||
}
|
||||
|
||||
memcpy(_buffer + _offset, data, size);
|
||||
_offset += size;
|
||||
}
|
51
dom/webauthn/cbor-cpp/src/output_dynamic.h
Normal file
51
dom/webauthn/cbor-cpp/src/output_dynamic.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2014-2015 Stanislav Ovsyannikov
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CborDynamicOutput_H_
|
||||
#define __CborDynamicOutput_H_
|
||||
|
||||
|
||||
#include "output.h"
|
||||
|
||||
namespace cbor {
|
||||
class output_dynamic : public output {
|
||||
private:
|
||||
unsigned char *_buffer;
|
||||
unsigned int _capacity;
|
||||
unsigned int _offset;
|
||||
public:
|
||||
output_dynamic();
|
||||
|
||||
explicit output_dynamic(unsigned int inital_capacity);
|
||||
|
||||
~output_dynamic();
|
||||
|
||||
virtual unsigned char *data();
|
||||
|
||||
virtual unsigned int size();
|
||||
|
||||
virtual void put_byte(unsigned char value);
|
||||
|
||||
virtual void put_bytes(const unsigned char *data, int size);
|
||||
|
||||
private:
|
||||
void init(unsigned int initalCapacity);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //__CborDynamicOutput_H_
|
@ -21,26 +21,30 @@ EXPORTS.mozilla.dom += [
|
||||
'U2FSoftTokenManager.h',
|
||||
'U2FTokenManager.h',
|
||||
'U2FTokenTransport.h',
|
||||
'WebAuthnCBORUtil.h',
|
||||
'WebAuthnManager.h',
|
||||
'WebAuthnRequest.h',
|
||||
'WebAuthnTransactionChild.h',
|
||||
'WebAuthnTransactionParent.h',
|
||||
'WebAuthnUtil.h'
|
||||
'WebAuthnUtil.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AuthenticatorAssertionResponse.cpp',
|
||||
'AuthenticatorAttestationResponse.cpp',
|
||||
'AuthenticatorResponse.cpp',
|
||||
'cbor-cpp/src/encoder.cpp',
|
||||
'cbor-cpp/src/output_dynamic.cpp',
|
||||
'NSSU2FTokenRemote.cpp',
|
||||
'PublicKeyCredential.cpp',
|
||||
'U2FHIDTokenManager.cpp',
|
||||
'U2FSoftTokenManager.cpp',
|
||||
'U2FTokenManager.cpp',
|
||||
'WebAuthnCBORUtil.cpp',
|
||||
'WebAuthnManager.cpp',
|
||||
'WebAuthnTransactionChild.cpp',
|
||||
'WebAuthnTransactionParent.cpp',
|
||||
'WebAuthnUtil.cpp'
|
||||
'WebAuthnUtil.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
406
dom/webauthn/tests/cbor/cbor.js
Normal file
406
dom/webauthn/tests/cbor/cbor.js
Normal file
@ -0,0 +1,406 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2016 Patrick Gansterer <paroga@paroga.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
(function(global, undefined) { "use strict";
|
||||
var POW_2_24 = 5.960464477539063e-8,
|
||||
POW_2_32 = 4294967296,
|
||||
POW_2_53 = 9007199254740992;
|
||||
|
||||
function encode(value) {
|
||||
var data = new ArrayBuffer(256);
|
||||
var dataView = new DataView(data);
|
||||
var lastLength;
|
||||
var offset = 0;
|
||||
|
||||
function prepareWrite(length) {
|
||||
var newByteLength = data.byteLength;
|
||||
var requiredLength = offset + length;
|
||||
while (newByteLength < requiredLength)
|
||||
newByteLength <<= 1;
|
||||
if (newByteLength !== data.byteLength) {
|
||||
var oldDataView = dataView;
|
||||
data = new ArrayBuffer(newByteLength);
|
||||
dataView = new DataView(data);
|
||||
var uint32count = (offset + 3) >> 2;
|
||||
for (var i = 0; i < uint32count; ++i)
|
||||
dataView.setUint32(i << 2, oldDataView.getUint32(i << 2));
|
||||
}
|
||||
|
||||
lastLength = length;
|
||||
return dataView;
|
||||
}
|
||||
function commitWrite() {
|
||||
offset += lastLength;
|
||||
}
|
||||
function writeFloat64(value) {
|
||||
commitWrite(prepareWrite(8).setFloat64(offset, value));
|
||||
}
|
||||
function writeUint8(value) {
|
||||
commitWrite(prepareWrite(1).setUint8(offset, value));
|
||||
}
|
||||
function writeUint8Array(value) {
|
||||
var dataView = prepareWrite(value.length);
|
||||
for (var i = 0; i < value.length; ++i)
|
||||
dataView.setUint8(offset + i, value[i]);
|
||||
commitWrite();
|
||||
}
|
||||
function writeUint16(value) {
|
||||
commitWrite(prepareWrite(2).setUint16(offset, value));
|
||||
}
|
||||
function writeUint32(value) {
|
||||
commitWrite(prepareWrite(4).setUint32(offset, value));
|
||||
}
|
||||
function writeUint64(value) {
|
||||
var low = value % POW_2_32;
|
||||
var high = (value - low) / POW_2_32;
|
||||
var dataView = prepareWrite(8);
|
||||
dataView.setUint32(offset, high);
|
||||
dataView.setUint32(offset + 4, low);
|
||||
commitWrite();
|
||||
}
|
||||
function writeTypeAndLength(type, length) {
|
||||
if (length < 24) {
|
||||
writeUint8(type << 5 | length);
|
||||
} else if (length < 0x100) {
|
||||
writeUint8(type << 5 | 24);
|
||||
writeUint8(length);
|
||||
} else if (length < 0x10000) {
|
||||
writeUint8(type << 5 | 25);
|
||||
writeUint16(length);
|
||||
} else if (length < 0x100000000) {
|
||||
writeUint8(type << 5 | 26);
|
||||
writeUint32(length);
|
||||
} else {
|
||||
writeUint8(type << 5 | 27);
|
||||
writeUint64(length);
|
||||
}
|
||||
}
|
||||
|
||||
function encodeItem(value) {
|
||||
var i;
|
||||
|
||||
if (value === false)
|
||||
return writeUint8(0xf4);
|
||||
if (value === true)
|
||||
return writeUint8(0xf5);
|
||||
if (value === null)
|
||||
return writeUint8(0xf6);
|
||||
if (value === undefined)
|
||||
return writeUint8(0xf7);
|
||||
|
||||
switch (typeof value) {
|
||||
case "number":
|
||||
if (Math.floor(value) === value) {
|
||||
if (0 <= value && value <= POW_2_53)
|
||||
return writeTypeAndLength(0, value);
|
||||
if (-POW_2_53 <= value && value < 0)
|
||||
return writeTypeAndLength(1, -(value + 1));
|
||||
}
|
||||
writeUint8(0xfb);
|
||||
return writeFloat64(value);
|
||||
|
||||
case "string":
|
||||
var utf8data = [];
|
||||
for (i = 0; i < value.length; ++i) {
|
||||
var charCode = value.charCodeAt(i);
|
||||
if (charCode < 0x80) {
|
||||
utf8data.push(charCode);
|
||||
} else if (charCode < 0x800) {
|
||||
utf8data.push(0xc0 | charCode >> 6);
|
||||
utf8data.push(0x80 | charCode & 0x3f);
|
||||
} else if (charCode < 0xd800) {
|
||||
utf8data.push(0xe0 | charCode >> 12);
|
||||
utf8data.push(0x80 | (charCode >> 6) & 0x3f);
|
||||
utf8data.push(0x80 | charCode & 0x3f);
|
||||
} else {
|
||||
charCode = (charCode & 0x3ff) << 10;
|
||||
charCode |= value.charCodeAt(++i) & 0x3ff;
|
||||
charCode += 0x10000;
|
||||
|
||||
utf8data.push(0xf0 | charCode >> 18);
|
||||
utf8data.push(0x80 | (charCode >> 12) & 0x3f);
|
||||
utf8data.push(0x80 | (charCode >> 6) & 0x3f);
|
||||
utf8data.push(0x80 | charCode & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
writeTypeAndLength(3, utf8data.length);
|
||||
return writeUint8Array(utf8data);
|
||||
|
||||
default:
|
||||
var length;
|
||||
if (Array.isArray(value)) {
|
||||
length = value.length;
|
||||
writeTypeAndLength(4, length);
|
||||
for (i = 0; i < length; ++i)
|
||||
encodeItem(value[i]);
|
||||
} else if (value instanceof Uint8Array) {
|
||||
writeTypeAndLength(2, value.length);
|
||||
writeUint8Array(value);
|
||||
} else {
|
||||
var keys = Object.keys(value);
|
||||
length = keys.length;
|
||||
writeTypeAndLength(5, length);
|
||||
for (i = 0; i < length; ++i) {
|
||||
var key = keys[i];
|
||||
encodeItem(key);
|
||||
encodeItem(value[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encodeItem(value);
|
||||
|
||||
if ("slice" in data)
|
||||
return data.slice(0, offset);
|
||||
|
||||
var ret = new ArrayBuffer(offset);
|
||||
var retView = new DataView(ret);
|
||||
for (var i = 0; i < offset; ++i)
|
||||
retView.setUint8(i, dataView.getUint8(i));
|
||||
return ret;
|
||||
}
|
||||
|
||||
function decode(data, tagger, simpleValue) {
|
||||
var dataView = new DataView(data);
|
||||
var offset = 0;
|
||||
|
||||
if (typeof tagger !== "function")
|
||||
tagger = function(value) { return value; };
|
||||
if (typeof simpleValue !== "function")
|
||||
simpleValue = function() { return undefined; };
|
||||
|
||||
function commitRead(length, value) {
|
||||
offset += length;
|
||||
return value;
|
||||
}
|
||||
function readArrayBuffer(length) {
|
||||
return commitRead(length, new Uint8Array(data, offset, length));
|
||||
}
|
||||
function readFloat16() {
|
||||
var tempArrayBuffer = new ArrayBuffer(4);
|
||||
var tempDataView = new DataView(tempArrayBuffer);
|
||||
var value = readUint16();
|
||||
|
||||
var sign = value & 0x8000;
|
||||
var exponent = value & 0x7c00;
|
||||
var fraction = value & 0x03ff;
|
||||
|
||||
if (exponent === 0x7c00)
|
||||
exponent = 0xff << 10;
|
||||
else if (exponent !== 0)
|
||||
exponent += (127 - 15) << 10;
|
||||
else if (fraction !== 0)
|
||||
return (sign ? -1 : 1) * fraction * POW_2_24;
|
||||
|
||||
tempDataView.setUint32(0, sign << 16 | exponent << 13 | fraction << 13);
|
||||
return tempDataView.getFloat32(0);
|
||||
}
|
||||
function readFloat32() {
|
||||
return commitRead(4, dataView.getFloat32(offset));
|
||||
}
|
||||
function readFloat64() {
|
||||
return commitRead(8, dataView.getFloat64(offset));
|
||||
}
|
||||
function readUint8() {
|
||||
return commitRead(1, dataView.getUint8(offset));
|
||||
}
|
||||
function readUint16() {
|
||||
return commitRead(2, dataView.getUint16(offset));
|
||||
}
|
||||
function readUint32() {
|
||||
return commitRead(4, dataView.getUint32(offset));
|
||||
}
|
||||
function readUint64() {
|
||||
return readUint32() * POW_2_32 + readUint32();
|
||||
}
|
||||
function readBreak() {
|
||||
if (dataView.getUint8(offset) !== 0xff)
|
||||
return false;
|
||||
offset += 1;
|
||||
return true;
|
||||
}
|
||||
function readLength(additionalInformation) {
|
||||
if (additionalInformation < 24)
|
||||
return additionalInformation;
|
||||
if (additionalInformation === 24)
|
||||
return readUint8();
|
||||
if (additionalInformation === 25)
|
||||
return readUint16();
|
||||
if (additionalInformation === 26)
|
||||
return readUint32();
|
||||
if (additionalInformation === 27)
|
||||
return readUint64();
|
||||
if (additionalInformation === 31)
|
||||
return -1;
|
||||
throw "Invalid length encoding";
|
||||
}
|
||||
function readIndefiniteStringLength(majorType) {
|
||||
var initialByte = readUint8();
|
||||
if (initialByte === 0xff)
|
||||
return -1;
|
||||
var length = readLength(initialByte & 0x1f);
|
||||
if (length < 0 || (initialByte >> 5) !== majorType)
|
||||
throw "Invalid indefinite length element";
|
||||
return length;
|
||||
}
|
||||
|
||||
function appendUtf16Data(utf16data, length) {
|
||||
for (var i = 0; i < length; ++i) {
|
||||
var value = readUint8();
|
||||
if (value & 0x80) {
|
||||
if (value < 0xe0) {
|
||||
value = (value & 0x1f) << 6
|
||||
| (readUint8() & 0x3f);
|
||||
length -= 1;
|
||||
} else if (value < 0xf0) {
|
||||
value = (value & 0x0f) << 12
|
||||
| (readUint8() & 0x3f) << 6
|
||||
| (readUint8() & 0x3f);
|
||||
length -= 2;
|
||||
} else {
|
||||
value = (value & 0x0f) << 18
|
||||
| (readUint8() & 0x3f) << 12
|
||||
| (readUint8() & 0x3f) << 6
|
||||
| (readUint8() & 0x3f);
|
||||
length -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (value < 0x10000) {
|
||||
utf16data.push(value);
|
||||
} else {
|
||||
value -= 0x10000;
|
||||
utf16data.push(0xd800 | (value >> 10));
|
||||
utf16data.push(0xdc00 | (value & 0x3ff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function decodeItem() {
|
||||
var initialByte = readUint8();
|
||||
var majorType = initialByte >> 5;
|
||||
var additionalInformation = initialByte & 0x1f;
|
||||
var i;
|
||||
var length;
|
||||
|
||||
if (majorType === 7) {
|
||||
switch (additionalInformation) {
|
||||
case 25:
|
||||
return readFloat16();
|
||||
case 26:
|
||||
return readFloat32();
|
||||
case 27:
|
||||
return readFloat64();
|
||||
}
|
||||
}
|
||||
|
||||
length = readLength(additionalInformation);
|
||||
if (length < 0 && (majorType < 2 || 6 < majorType))
|
||||
throw "Invalid length";
|
||||
|
||||
switch (majorType) {
|
||||
case 0:
|
||||
return length;
|
||||
case 1:
|
||||
return -1 - length;
|
||||
case 2:
|
||||
if (length < 0) {
|
||||
var elements = [];
|
||||
var fullArrayLength = 0;
|
||||
while ((length = readIndefiniteStringLength(majorType)) >= 0) {
|
||||
fullArrayLength += length;
|
||||
elements.push(readArrayBuffer(length));
|
||||
}
|
||||
var fullArray = new Uint8Array(fullArrayLength);
|
||||
var fullArrayOffset = 0;
|
||||
for (i = 0; i < elements.length; ++i) {
|
||||
fullArray.set(elements[i], fullArrayOffset);
|
||||
fullArrayOffset += elements[i].length;
|
||||
}
|
||||
return fullArray;
|
||||
}
|
||||
return readArrayBuffer(length);
|
||||
case 3:
|
||||
var utf16data = [];
|
||||
if (length < 0) {
|
||||
while ((length = readIndefiniteStringLength(majorType)) >= 0)
|
||||
appendUtf16Data(utf16data, length);
|
||||
} else
|
||||
appendUtf16Data(utf16data, length);
|
||||
return String.fromCharCode.apply(null, utf16data);
|
||||
case 4:
|
||||
var retArray;
|
||||
if (length < 0) {
|
||||
retArray = [];
|
||||
while (!readBreak())
|
||||
retArray.push(decodeItem());
|
||||
} else {
|
||||
retArray = new Array(length);
|
||||
for (i = 0; i < length; ++i)
|
||||
retArray[i] = decodeItem();
|
||||
}
|
||||
return retArray;
|
||||
case 5:
|
||||
var retObject = {};
|
||||
for (i = 0; i < length || length < 0 && !readBreak(); ++i) {
|
||||
var key = decodeItem();
|
||||
retObject[key] = decodeItem();
|
||||
}
|
||||
return retObject;
|
||||
case 6:
|
||||
return tagger(decodeItem(), length);
|
||||
case 7:
|
||||
switch (length) {
|
||||
case 20:
|
||||
return false;
|
||||
case 21:
|
||||
return true;
|
||||
case 22:
|
||||
return null;
|
||||
case 23:
|
||||
return undefined;
|
||||
default:
|
||||
return simpleValue(length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ret = decodeItem();
|
||||
if (offset !== data.byteLength)
|
||||
throw "Remaining bytes";
|
||||
return ret;
|
||||
}
|
||||
|
||||
var obj = { encode: encode, decode: decode };
|
||||
|
||||
if (typeof define === "function" && define.amd)
|
||||
define("cbor/cbor", obj);
|
||||
else if (typeof module !== "undefined" && module.exports)
|
||||
module.exports = obj;
|
||||
else if (!global.CBOR)
|
||||
global.CBOR = obj;
|
||||
|
||||
})(this);
|
@ -1,5 +1,6 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
cbor/cbor.js
|
||||
pkijs/asn1.js
|
||||
pkijs/common.js
|
||||
pkijs/x509_schema.js
|
||||
|
@ -8,6 +8,7 @@
|
||||
<script type="text/javascript" src="pkijs/asn1.js"></script>
|
||||
<script type="text/javascript" src="pkijs/x509_schema.js"></script>
|
||||
<script type="text/javascript" src="pkijs/x509_simpl.js"></script>
|
||||
<script type="text/javascript" src="cbor/cbor.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
@ -39,26 +40,27 @@ function() {
|
||||
|
||||
testMakeCredential();
|
||||
|
||||
function checkCredentialValid(aCredInfo) {
|
||||
function decodeCreatedCredential(aCredInfo) {
|
||||
/* PublicKeyCredential : Credential
|
||||
- rawId: Key Handle buffer pulled from U2F Register() Response
|
||||
- response : AuthenticatorAttestationResponse : AuthenticatorResponse
|
||||
- attestationObject: RP ID Hash || U2F Sign() Response
|
||||
- attestationObject: CBOR object
|
||||
- clientDataJSON: serialized JSON
|
||||
- clientExtensionResults: (not yet supported)
|
||||
*/
|
||||
|
||||
ok(aCredInfo.rawId.length > 0, "Key ID exists");
|
||||
|
||||
is(aCredInfo.response.attestationObject[0], 0x05, "Reserved byte is correct");
|
||||
let clientData = JSON.parse(buffer2string(aCredInfo.response.clientDataJSON));
|
||||
is(clientData.challenge, bytesToBase64UrlSafe(gCredentialChallenge), "Challenge is correct");
|
||||
is(clientData.origin, window.location.origin, "Origin is correct");
|
||||
is(clientData.hashAlg, "S256", "Hash algorithm is correct");
|
||||
|
||||
return decodeU2FRegistration(aCredInfo.response.attestationObject)
|
||||
.then(function(u2fObj) {
|
||||
aCredInfo.u2fReg = u2fObj;
|
||||
return webAuthnDecodeAttestation(aCredInfo.response.attestationObject.buffer)
|
||||
.then(function(decodedResult) {
|
||||
aCredInfo.clientDataObj = clientData;
|
||||
aCredInfo.publicKeyHandle = decodedResult.publicKeyHandle;
|
||||
aCredInfo.attestationObject = decodedResult.attestationObject;
|
||||
return aCredInfo;
|
||||
});
|
||||
}
|
||||
@ -106,7 +108,7 @@ function() {
|
||||
function testMakeCredential() {
|
||||
let rp = {id: document.domain, name: "none", icon: "none"};
|
||||
let user = {id: "none", name: "none", icon: "none", displayName: "none"};
|
||||
let param = {type: "public-key", algorithm: "P-256"};
|
||||
let param = {type: "public-key", algorithm: "ES256"};
|
||||
let makeCredentialOptions = {
|
||||
rp: rp,
|
||||
user: user,
|
||||
@ -114,7 +116,7 @@ function() {
|
||||
parameters: [param]
|
||||
};
|
||||
credm.create({publicKey: makeCredentialOptions})
|
||||
.then(checkCredentialValid)
|
||||
.then(decodeCreatedCredential)
|
||||
.then(testMakeDuplicate)
|
||||
.catch(function(aReason) {
|
||||
ok(false, aReason);
|
||||
@ -125,7 +127,7 @@ function() {
|
||||
function testMakeDuplicate(aCredInfo) {
|
||||
let rp = {id: document.domain, name: "none", icon: "none"};
|
||||
let user = {id: "none", name: "none", icon: "none", displayName: "none"};
|
||||
let param = {type: "public-key", algorithm: "P-256"};
|
||||
let param = {type: "public-key", algorithm: "ES256"};
|
||||
let makeCredentialOptions = {
|
||||
rp: rp,
|
||||
user: user,
|
||||
@ -162,7 +164,7 @@ function() {
|
||||
credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(function(aAssertion) {
|
||||
/* Pass along the pubKey. */
|
||||
return checkAssertionAndSigValid(aCredInfo.u2fReg.publicKey, aAssertion);
|
||||
return checkAssertionAndSigValid(aCredInfo.publicKeyHandle, aAssertion);
|
||||
})
|
||||
.then(function(aSigVerifyResult) {
|
||||
ok(aSigVerifyResult, "Signing signature verified");
|
||||
|
@ -62,7 +62,7 @@
|
||||
|
||||
let rp = {id: document.domain, name: "none", icon: "none"};
|
||||
let user = {id: "none", name: "none", icon: "none", displayName: "none"};
|
||||
let param = {type: "public-key", algorithm: "p-256"};
|
||||
let param = {type: "public-key", algorithm: "es256"};
|
||||
let unsupportedParam = {type: "public-key", algorithm: "3DES"};
|
||||
let badParam = {type: "SimplePassword", algorithm: "MaxLength=2"};
|
||||
|
||||
|
@ -45,7 +45,7 @@ function() {
|
||||
function testMakeCredential() {
|
||||
let rp = {id: document.domain, name: "none", icon: "none"};
|
||||
let user = {id: "none", name: "none", icon: "none", displayName: "none"};
|
||||
let param = {type: "public-key", algorithm: "p-256"};
|
||||
let param = {type: "public-key", algorithm: "es256"};
|
||||
let makeCredentialOptions = {
|
||||
rp: rp, user: user, challenge: credentialChallenge, parameters: [param]
|
||||
};
|
||||
|
@ -61,7 +61,7 @@
|
||||
window.crypto.getRandomValues(chall);
|
||||
|
||||
let user = {id: "none", name: "none", icon: "none", displayName: "none"};
|
||||
let param = {type: "public-key", algorithm: "p-256"};
|
||||
let param = {type: "public-key", algorithm: "Es256"};
|
||||
|
||||
var testFuncs = [
|
||||
function() {
|
||||
|
@ -127,24 +127,53 @@ function hexDecode(str) {
|
||||
return new Uint8Array(str.match(/../g).map(x => parseInt(x, 16)));
|
||||
}
|
||||
|
||||
function decodeU2FRegistration(aRegData) {
|
||||
if (aRegData[0] != 0x05) {
|
||||
return Promise.reject("Sentinal byte != 0x05");
|
||||
function webAuthnDecodeAttestation(aAttestationBuf) {
|
||||
let attObj = CBOR.decode(aAttestationBuf);
|
||||
console.log("Attestation CBOR Object:", attObj);
|
||||
if (!("authData" in attObj && "fmt" in attObj && "attStmt" in attObj)) {
|
||||
throw "Invalid CBOR Attestation Object";
|
||||
}
|
||||
if (!("sig" in attObj.attStmt && "x5c" in attObj.attStmt)) {
|
||||
throw "Invalid CBOR Attestation Statement";
|
||||
}
|
||||
|
||||
let keyHandleLength = aRegData[66];
|
||||
let u2fRegObj = {
|
||||
publicKeyBytes: aRegData.slice(1, 66),
|
||||
keyHandleBytes: aRegData.slice(67, 67 + keyHandleLength),
|
||||
attestationBytes: aRegData.slice(67 + keyHandleLength)
|
||||
let rpIdHash = attObj.authData.slice(0, 32);
|
||||
let flags = attObj.authData.slice(32, 33);
|
||||
let counter = attObj.authData.slice(33, 37);
|
||||
let attData = {};
|
||||
attData.aaguid = attObj.authData.slice(37, 53);
|
||||
attData.credIdLen = (attObj.authData[53] << 8) + attObj.authData[54];
|
||||
attData.credId = attObj.authData.slice(55, 55 + attData.credIdLen);
|
||||
|
||||
console.log(":: CBOR Attestation Object Data ::");
|
||||
console.log("RP ID Hash: " + hexEncode(rpIdHash));
|
||||
console.log("Counter: " + hexEncode(counter) + " Flags: " + flags);
|
||||
console.log("AAGUID: " + hexEncode(attData.aaguid));
|
||||
|
||||
cborPubKey = attObj.authData.slice(55 + attData.credIdLen);
|
||||
var pubkeyObj = CBOR.decode(cborPubKey.buffer);
|
||||
if (!("alg" in pubkeyObj && "x" in pubkeyObj && "y" in pubkeyObj)) {
|
||||
throw "Invalid CBOR Public Key Object";
|
||||
}
|
||||
if (pubkeyObj.alg != "ES256") {
|
||||
throw "Unexpected public key algorithm";
|
||||
}
|
||||
|
||||
u2fRegObj.keyHandle = bytesToBase64UrlSafe(u2fRegObj.keyHandleBytes);
|
||||
let pubKeyBytes = assemblePublicKeyBytesData(pubkeyObj.x, pubkeyObj.y);
|
||||
console.log(":: CBOR Public Key Object Data ::");
|
||||
console.log("Algorithm: " + pubkeyObj.alg);
|
||||
console.log("X: " + pubkeyObj.x);
|
||||
console.log("Y: " + pubkeyObj.y);
|
||||
console.log("Uncompressed (hex): " + hexEncode(pubKeyBytes));
|
||||
|
||||
return importPublicKey(u2fRegObj.publicKeyBytes)
|
||||
.then(function(keyObj) {
|
||||
u2fRegObj.publicKey = keyObj;
|
||||
return u2fRegObj;
|
||||
return importPublicKey(pubKeyBytes)
|
||||
.then(function(aKeyHandle) {
|
||||
return {
|
||||
attestationObject: attObj,
|
||||
attestationAuthData: attData,
|
||||
publicKeyBytes: pubKeyBytes,
|
||||
publicKeyHandle: aKeyHandle,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@ -175,6 +204,19 @@ function deriveAppAndChallengeParam(appId, clientData) {
|
||||
});
|
||||
}
|
||||
|
||||
function assemblePublicKeyBytesData(xCoord, yCoord) {
|
||||
// Produce an uncompressed EC key point. These start with 0x04, and then
|
||||
// two 32-byte numbers denoting X and Y.
|
||||
if (xCoord.length != 32 || yCoord.length != 32) {
|
||||
throw ("Coordinates must be 32 bytes long");
|
||||
}
|
||||
let keyBytes = new Uint8Array(65);
|
||||
keyBytes[0] = 0x04;
|
||||
xCoord.map((x, i) => keyBytes[1 + i] = x);
|
||||
yCoord.map((x, i) => keyBytes[33 + i] = x);
|
||||
return keyBytes;
|
||||
}
|
||||
|
||||
function assembleSignedData(appParam, presenceAndCounter, challengeParam) {
|
||||
let signedData = new Uint8Array(32 + 1 + 4 + 32);
|
||||
appParam.map((x, i) => signedData[0 + i] = x);
|
||||
|
@ -31,6 +31,6 @@ if ! which mozmake 2>/dev/null; then
|
||||
export PATH="$PATH:$SOURCE/.."
|
||||
if ! which mozmake 2>/dev/null; then
|
||||
TT_SERVER=${TT_SERVER:-https://api.pub.build.mozilla.org/tooltool/}
|
||||
( cd $SOURCE/..; $SOURCE/mach artifact toolchain -v --tooltool-manifest $SOURCE/browser/config/tooltool-manifests/${platform:-win32}/releng.manifest --tooltool-url $TT_SERVER --retry 4${TOOLTOOL_CACHE:+ --cache-dir ${TOOLTOOL_CACHE}})
|
||||
( cd $SOURCE/..; $SOURCE/mach artifact toolchain -v --tooltool-manifest $SOURCE/browser/config/tooltool-manifests/${platform:-win32}/releng.manifest --tooltool-url $TT_SERVER --retry 4${TOOLTOOL_CACHE:+ --cache-dir ${TOOLTOOL_CACHE}}${MOZ_TOOLCHAINS:+ ${MOZ_TOOLCHAINS}})
|
||||
fi
|
||||
fi
|
||||
|
@ -451,7 +451,7 @@ Statistics::formatDetailedSliceDescription(unsigned i, const SliceData& slice) c
|
||||
Reason: %s\n\
|
||||
Reset: %s%s\n\
|
||||
State: %s -> %s\n\
|
||||
Page Faults: %ld\n\
|
||||
Page Faults: %" PRIu64 "\n\
|
||||
Pause: %.3fms of %s budget (@ %.3fms)\n\
|
||||
";
|
||||
char buffer[1024];
|
||||
|
@ -567,7 +567,7 @@ ServoRestyleManager::ProcessPostTraversal(
|
||||
}
|
||||
|
||||
// TODO(emilio): We could avoid some refcount traffic here, specially in the
|
||||
// ServoComputedValues case, which uses atomic refcounting.
|
||||
// ServoStyleContext case, which uses atomic refcounting.
|
||||
//
|
||||
// Hold the old style context alive, because it could become a dangling
|
||||
// pointer during the replacement. In practice it's not a huge deal, but
|
||||
@ -605,7 +605,7 @@ ServoRestyleManager::ProcessPostTraversal(
|
||||
MOZ_ASSERT(styleFrame || displayContentsNode);
|
||||
RefPtr<ServoStyleContext> currentContext =
|
||||
aRestyleState.StyleSet().ResolveServoStyle(aElement, aRestyleBehavior);
|
||||
MOZ_ASSERT(oldStyleContext->ComputedValues() != currentContext->ComputedValues());
|
||||
MOZ_ASSERT(oldStyleContext->ComputedData() != currentContext->ComputedData());
|
||||
|
||||
newContext = currentContext;
|
||||
newContext->UpdateWithElementState(aElement);
|
||||
|
@ -23,7 +23,7 @@ load 148245-1.html
|
||||
load 149014-1.html
|
||||
load 150431-1.html
|
||||
load 176915-1.html
|
||||
asserts-if(stylo,13) load 191272-1.html # bug 1324636
|
||||
load 191272-1.html
|
||||
load 199696-1.html
|
||||
load 217903-1.html
|
||||
load 223064-1.html
|
||||
|
@ -1929,7 +1929,7 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat
|
||||
ServoStyleContext* servoStyle = pseudoStyleContext->GetAsServo();
|
||||
if (servoStyle) {
|
||||
hasServoAnimations =
|
||||
Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle->ComputedValues());
|
||||
Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle);
|
||||
if (!hasServoAnimations) {
|
||||
Servo_SetExplicitStyle(container, servoStyle);
|
||||
}
|
||||
|
@ -178,17 +178,18 @@ nsImageFrame::AccessibleType()
|
||||
void
|
||||
nsImageFrame::DisconnectMap()
|
||||
{
|
||||
if (mImageMap) {
|
||||
if (!mImageMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
mImageMap->Destroy();
|
||||
mImageMap = nullptr;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsAccessibilityService* accService = GetAccService();
|
||||
if (accService) {
|
||||
if (nsAccessibilityService* accService = GetAccService()) {
|
||||
accService->RecreateAccessible(PresContext()->PresShell(), mContent);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1755,8 +1756,7 @@ nsImageFrame::PaintImage(gfxContext& aRenderingContext, nsPoint aPt,
|
||||
nsLayoutUtils::GetSamplingFilterForFrame(this), dest, aDirtyRect,
|
||||
svgContext, flags, &anchorPoint);
|
||||
|
||||
nsImageMap* map = GetImageMap();
|
||||
if (map) {
|
||||
if (nsImageMap* map = GetImageMap()) {
|
||||
gfxPoint devPixelOffset =
|
||||
nsLayoutUtils::PointToGfxPoint(dest.TopLeft(),
|
||||
PresContext()->AppUnitsPerDevPixel());
|
||||
@ -1929,8 +1929,7 @@ nsImageMap*
|
||||
nsImageFrame::GetImageMap()
|
||||
{
|
||||
if (!mImageMap) {
|
||||
nsIContent* map = GetMapElement();
|
||||
if (map) {
|
||||
if (nsIContent* map = GetMapElement()) {
|
||||
mImageMap = new nsImageMap();
|
||||
mImageMap->Init(this, map);
|
||||
}
|
||||
@ -2018,9 +2017,7 @@ nsImageFrame::GetContentForEvent(WidgetEvent* aEvent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsImageMap* map = GetImageMap();
|
||||
|
||||
if (nullptr != map) {
|
||||
if (nsImageMap* map = GetImageMap()) {
|
||||
nsIntPoint p;
|
||||
TranslateEventCoords(
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this), p);
|
||||
@ -2049,7 +2046,7 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
aEvent->mMessage == eMouseMove) {
|
||||
nsImageMap* map = GetImageMap();
|
||||
bool isServerMap = IsServerImageMap();
|
||||
if ((nullptr != map) || isServerMap) {
|
||||
if (map || isServerMap) {
|
||||
nsIntPoint p;
|
||||
TranslateEventCoords(
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this), p);
|
||||
@ -2106,8 +2103,7 @@ nsresult
|
||||
nsImageFrame::GetCursor(const nsPoint& aPoint,
|
||||
nsIFrame::Cursor& aCursor)
|
||||
{
|
||||
nsImageMap* map = GetImageMap();
|
||||
if (nullptr != map) {
|
||||
if (nsImageMap* map = GetImageMap()) {
|
||||
nsIntPoint p;
|
||||
TranslateEventCoords(aPoint, p);
|
||||
nsCOMPtr<nsIContent> area = map->GetArea(p.x, p.y);
|
||||
|
@ -713,9 +713,7 @@ nsImageMap::GetBoundsForAreaContent(nsIContent *aContent,
|
||||
void
|
||||
nsImageMap::FreeAreas()
|
||||
{
|
||||
uint32_t i, n = mAreas.Length();
|
||||
for (i = 0; i < n; i++) {
|
||||
Area* area = mAreas.ElementAt(i);
|
||||
for (auto* area : mAreas) {
|
||||
if (area->mArea->IsInUncomposedDoc()) {
|
||||
NS_ASSERTION(area->mArea->GetPrimaryFrame() == mImageFrame,
|
||||
"Unexpected primary frame");
|
||||
@ -729,31 +727,28 @@ nsImageMap::FreeAreas()
|
||||
false);
|
||||
delete area;
|
||||
}
|
||||
|
||||
mAreas.Clear();
|
||||
}
|
||||
|
||||
nsresult
|
||||
void
|
||||
nsImageMap::Init(nsImageFrame* aImageFrame, nsIContent* aMap)
|
||||
{
|
||||
NS_PRECONDITION(aMap, "null ptr");
|
||||
if (!aMap) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
mImageFrame = aImageFrame;
|
||||
MOZ_ASSERT(aMap);
|
||||
MOZ_ASSERT(aImageFrame);
|
||||
|
||||
mImageFrame = aImageFrame;
|
||||
mMap = aMap;
|
||||
mMap->AddMutationObserver(this);
|
||||
|
||||
// "Compile" the areas in the map into faster access versions
|
||||
return UpdateAreas();
|
||||
UpdateAreas();
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
void
|
||||
nsImageMap::SearchForAreas(nsIContent* aParent, bool& aFoundArea,
|
||||
bool& aFoundAnchor)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
uint32_t i, n = aParent->GetChildCount();
|
||||
|
||||
// Look for <area> or <a> elements. We'll use whichever type we find first.
|
||||
@ -764,8 +759,7 @@ nsImageMap::SearchForAreas(nsIContent* aParent, bool& aFoundArea,
|
||||
// <a> element yet, then look for <area>.
|
||||
if (!aFoundAnchor && child->IsHTMLElement(nsGkAtoms::area)) {
|
||||
aFoundArea = true;
|
||||
rv = AddArea(child);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
AddArea(child);
|
||||
|
||||
// Continue to next child. This stops mContainsBlockContents from
|
||||
// getting set. It also makes us ignore children of <area>s which
|
||||
@ -778,21 +772,17 @@ nsImageMap::SearchForAreas(nsIContent* aParent, bool& aFoundArea,
|
||||
// <area> element yet, then look for <a>.
|
||||
if (!aFoundArea && child->IsHTMLElement(nsGkAtoms::a)) {
|
||||
aFoundAnchor = true;
|
||||
rv = AddArea(child);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
AddArea(child);
|
||||
}
|
||||
|
||||
if (child->IsElement()) {
|
||||
mContainsBlockContents = true;
|
||||
rv = SearchForAreas(child, aFoundArea, aFoundAnchor);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
SearchForAreas(child, aFoundArea, aFoundAnchor);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
void
|
||||
nsImageMap::UpdateAreas()
|
||||
{
|
||||
// Get rid of old area data
|
||||
@ -802,19 +792,15 @@ nsImageMap::UpdateAreas()
|
||||
bool foundAnchor = false;
|
||||
mContainsBlockContents = false;
|
||||
|
||||
nsresult rv = SearchForAreas(mMap, foundArea, foundAnchor);
|
||||
SearchForAreas(mMap, foundArea, foundAnchor);
|
||||
#ifdef ACCESSIBILITY
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAccessibilityService* accService = GetAccService();
|
||||
if (accService) {
|
||||
if (nsAccessibilityService* accService = GetAccService()) {
|
||||
accService->UpdateImageMap(mImageFrame);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
void
|
||||
nsImageMap::AddArea(nsIContent* aArea)
|
||||
{
|
||||
static nsIContent::AttrValuesArray strings[] =
|
||||
@ -846,17 +832,13 @@ nsImageMap::AddArea(nsIContent* aArea)
|
||||
break;
|
||||
default:
|
||||
area = nullptr;
|
||||
NS_NOTREACHED("FindAttrValueIn returned an unexpected value.");
|
||||
MOZ_ASSERT_UNREACHABLE("FindAttrValueIn returned an unexpected value.");
|
||||
break;
|
||||
}
|
||||
if (!area)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
//Add focus listener to track area focus changes
|
||||
aArea->AddSystemEventListener(NS_LITERAL_STRING("focus"), this, false,
|
||||
false);
|
||||
aArea->AddSystemEventListener(NS_LITERAL_STRING("blur"), this, false,
|
||||
false);
|
||||
aArea->AddSystemEventListener(NS_LITERAL_STRING("focus"), this, false, false);
|
||||
aArea->AddSystemEventListener(NS_LITERAL_STRING("blur"), this, false, false);
|
||||
|
||||
// This is a nasty hack. It needs to go away: see bug 135040. Once this is
|
||||
// removed, the code added to RestyleManager::RestyleElement,
|
||||
@ -869,16 +851,13 @@ nsImageMap::AddArea(nsIContent* aArea)
|
||||
aArea->GetAttr(kNameSpaceID_None, nsGkAtoms::coords, coords);
|
||||
area->ParseCoords(coords);
|
||||
mAreas.AppendElement(area);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsImageMap::GetArea(nscoord aX, nscoord aY) const
|
||||
{
|
||||
NS_ASSERTION(mMap, "Not initialized");
|
||||
uint32_t i, n = mAreas.Length();
|
||||
for (i = 0; i < n; i++) {
|
||||
Area* area = mAreas.ElementAt(i);
|
||||
for (auto* area : mAreas) {
|
||||
if (area->IsInside(aX, aY)) {
|
||||
return area->mArea;
|
||||
}
|
||||
@ -1012,7 +991,7 @@ nsImageMap::HandleEvent(nsIDOMEvent* aEvent)
|
||||
}
|
||||
|
||||
void
|
||||
nsImageMap::Destroy(void)
|
||||
nsImageMap::Destroy()
|
||||
{
|
||||
FreeAreas();
|
||||
mImageFrame = nullptr;
|
||||
|
@ -31,7 +31,7 @@ class nsImageMap final : public nsStubMutationObserver,
|
||||
public:
|
||||
nsImageMap();
|
||||
|
||||
nsresult Init(nsImageFrame* aImageFrame, nsIContent* aMap);
|
||||
void Init(nsImageFrame* aImageFrame, nsIContent* aMap);
|
||||
|
||||
/**
|
||||
* Return the first area element (in content order) for the given aX,aY pixel
|
||||
@ -80,11 +80,12 @@ protected:
|
||||
|
||||
void FreeAreas();
|
||||
|
||||
nsresult UpdateAreas();
|
||||
nsresult SearchForAreas(nsIContent* aParent, bool& aFoundArea,
|
||||
void UpdateAreas();
|
||||
void SearchForAreas(nsIContent* aParent,
|
||||
bool& aFoundArea,
|
||||
bool& aFoundAnchor);
|
||||
|
||||
nsresult AddArea(nsIContent* aArea);
|
||||
void AddArea(nsIContent* aArea);
|
||||
|
||||
void MaybeUpdateAreas(nsIContent *aContent);
|
||||
|
||||
|
@ -272,8 +272,7 @@ inDOMUtils::GetCSSStyleRules(nsIDOMElement *aElement,
|
||||
|
||||
ServoStyleContext* servo = styleContext->AsServo();
|
||||
nsTArray<const RawServoStyleRule*> rawRuleList;
|
||||
Servo_ComputedValues_GetStyleRuleList(servo->ComputedValues(),
|
||||
&rawRuleList);
|
||||
Servo_ComputedValues_GetStyleRuleList(servo, &rawRuleList);
|
||||
|
||||
ServoStyleSet* styleSet = shell->StyleSet()->AsServo();
|
||||
ServoStyleRuleMap* map = styleSet->StyleRuleMap();
|
||||
|
@ -1,7 +1,7 @@
|
||||
include input/reftest.list
|
||||
include textarea/reftest.list
|
||||
|
||||
fuzzy-if(skiaContent,1,4) fails-if(styloVsGecko||stylo) == css-restrictions.html css-restrictions-ref.html
|
||||
fuzzy-if(skiaContent,1,4) == css-restrictions.html css-restrictions-ref.html
|
||||
== css-simple-styling.html css-simple-styling-ref.html
|
||||
!= css-background.html css-background-ref.html
|
||||
fuzzy-if(skiaContent,1,180) == ignore-pseudo-class.html ignore-pseudo-class-ref.html
|
||||
|
@ -25,12 +25,12 @@ load stress-7.html # assertion/crash test
|
||||
load stress-10.html # crash test
|
||||
== stress-11.xhtml stress-11-ref.xhtml
|
||||
|
||||
fails-if(styloVsGecko||stylo) == border-not-apply.html border-not-apply-ref.html
|
||||
== border-not-apply.html border-not-apply-ref.html
|
||||
fails-if(styloVsGecko||stylo) == 287088-1.html 287088-1-ref.html
|
||||
fails-if(styloVsGecko||stylo) == 287088-2.html 287088-2-ref.html
|
||||
fails-if(styloVsGecko) == 403177-1.html 403177-1-ref.html
|
||||
fails-if(styloVsGecko||stylo) == 469227-2.html 469227-2-ref.html
|
||||
fails-if(styloVsGecko||stylo) == 469227-3.html 469227-3-ref.html
|
||||
== 469227-2.html 469227-2-ref.html
|
||||
== 469227-3.html 469227-3-ref.html
|
||||
|
||||
fails-if(styloVsGecko||stylo) == restyle-inside-first-line.html restyle-inside-first-line-ref.html
|
||||
fails-if(styloVsGecko||stylo) == font-styles.html font-styles-ref.html
|
||||
|
@ -235,7 +235,7 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_ExtractAnimationValue,
|
||||
ServoStyleContextBorrowed computed_values,
|
||||
nsCSSPropertyID property)
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_SpecifiesAnimationsOrTransitions, bool,
|
||||
ServoComputedValuesBorrowed computed_values)
|
||||
ServoStyleContextBorrowed computed_values)
|
||||
SERVO_BINDING_FUNC(Servo_Property_IsAnimatable, bool,
|
||||
nsCSSPropertyID property)
|
||||
SERVO_BINDING_FUNC(Servo_Property_IsTransitionable, bool,
|
||||
@ -472,15 +472,15 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoStyleContextStrong,
|
||||
ServoStyleContextBorrowedOrNull parent_style,
|
||||
mozilla::InheritTarget target)
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleBits, uint64_t,
|
||||
ServoComputedValuesBorrowed values)
|
||||
ServoStyleContextBorrowed values)
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_EqualCustomProperties, bool,
|
||||
ServoComputedValuesBorrowed first,
|
||||
ServoComputedValuesBorrowed second)
|
||||
ServoComputedDataBorrowed first,
|
||||
ServoComputedDataBorrowed second)
|
||||
// Gets the source style rules for the computed values. This returns
|
||||
// the result via rules, which would include a list of unowned pointers
|
||||
// to RawServoStyleRule.
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleRuleList, void,
|
||||
ServoComputedValuesBorrowed values,
|
||||
ServoStyleContextBorrowed values,
|
||||
RawGeckoServoStyleRuleListBorrowedMut rules)
|
||||
|
||||
// Initialize Servo components. Should be called exactly once at startup.
|
||||
@ -563,14 +563,14 @@ SERVO_BINDING_FUNC(Servo_SerializeFontValueForCanvas, void,
|
||||
|
||||
// Get custom property value.
|
||||
SERVO_BINDING_FUNC(Servo_GetCustomPropertyValue, bool,
|
||||
ServoComputedValuesBorrowed computed_values,
|
||||
ServoStyleContextBorrowed computed_values,
|
||||
const nsAString* name, nsAString* value)
|
||||
|
||||
SERVO_BINDING_FUNC(Servo_GetCustomPropertiesCount, uint32_t,
|
||||
ServoComputedValuesBorrowed computed_values)
|
||||
ServoStyleContextBorrowed computed_values)
|
||||
|
||||
SERVO_BINDING_FUNC(Servo_GetCustomPropertyNameAt, bool,
|
||||
ServoComputedValuesBorrowed, uint32_t index,
|
||||
ServoStyleContextBorrowed, uint32_t index,
|
||||
nsAString* name)
|
||||
|
||||
SERVO_BINDING_FUNC(Servo_GetEmptyVariables, const nsStyleVariables*)
|
||||
|
@ -107,8 +107,7 @@ typedef mozilla::dom::StyleChildrenIterator RawGeckoStyleChildrenIterator;
|
||||
|
||||
typedef mozilla::ServoStyleContext const* ServoStyleContextBorrowed;
|
||||
typedef mozilla::ServoStyleContext const* ServoStyleContextBorrowedOrNull;
|
||||
typedef ServoComputedValues const* ServoComputedValuesBorrowed;
|
||||
typedef ServoComputedValues const* ServoComputedValuesBorrowedOrNull;
|
||||
typedef ServoComputedData const* ServoComputedDataBorrowed;
|
||||
|
||||
struct MOZ_MUST_USE_TYPE ServoStyleContextStrong
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ Gecko_ServoStyleContext_Init(
|
||||
ServoStyleContext* aContext,
|
||||
const ServoStyleContext* aParentContext,
|
||||
RawGeckoPresContextBorrowed aPresContext,
|
||||
const ServoComputedValues* aValues,
|
||||
const ServoComputedData* aValues,
|
||||
mozilla::CSSPseudoElementType aPseudoType,
|
||||
nsIAtom* aPseudoTag)
|
||||
{
|
||||
@ -224,16 +224,17 @@ Gecko_ServoStyleContext_Init(
|
||||
auto presContext = const_cast<nsPresContext*>(aPresContext);
|
||||
new (KnownNotNull, aContext) ServoStyleContext(
|
||||
parent, presContext, aPseudoTag, aPseudoType,
|
||||
ServoComputedValuesForgotten(aValues));
|
||||
ServoComputedDataForgotten(aValues));
|
||||
}
|
||||
|
||||
ServoComputedValues::ServoComputedValues(
|
||||
const ServoComputedValuesForgotten aValue)
|
||||
ServoComputedData::ServoComputedData(
|
||||
const ServoComputedDataForgotten aValue)
|
||||
{
|
||||
PodAssign(this, aValue.mPtr);
|
||||
}
|
||||
|
||||
const nsStyleVariables* ServoComputedValues::GetStyleVariables() const
|
||||
const nsStyleVariables*
|
||||
ServoComputedData::GetStyleVariables() const
|
||||
{
|
||||
return Servo_GetEmptyVariables();
|
||||
}
|
||||
@ -398,8 +399,8 @@ Gecko_GetImplementedPseudo(RawGeckoElementBorrowed aElement)
|
||||
}
|
||||
|
||||
nsChangeHint
|
||||
Gecko_CalcStyleDifference(const ServoStyleContext* aOldStyle,
|
||||
const ServoStyleContext* aNewStyle,
|
||||
Gecko_CalcStyleDifference(ServoStyleContextBorrowed aOldStyle,
|
||||
ServoStyleContextBorrowed aNewStyle,
|
||||
uint64_t aOldStyleBits,
|
||||
bool* aAnyStyleChanged)
|
||||
{
|
||||
@ -416,7 +417,6 @@ Gecko_CalcStyleDifference(const ServoStyleContext* aOldStyle,
|
||||
&equalStructs,
|
||||
&samePointerStructs,
|
||||
relevantStructs);
|
||||
|
||||
*aAnyStyleChanged = equalStructs != NS_STYLE_INHERIT_MASK;
|
||||
return result;
|
||||
}
|
||||
@ -648,8 +648,8 @@ Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
|
||||
|
||||
void
|
||||
Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
|
||||
ServoStyleContextBorrowedOrNull aOldComputedValues,
|
||||
ServoStyleContextBorrowedOrNull aComputedValues,
|
||||
ServoStyleContextBorrowedOrNull aOldComputedData,
|
||||
ServoStyleContextBorrowedOrNull aComputedData,
|
||||
UpdateAnimationsTasks aTasks)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -670,30 +670,30 @@ Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
|
||||
if (aTasks & UpdateAnimationsTasks::CSSAnimations) {
|
||||
presContext->AnimationManager()->
|
||||
UpdateAnimations(const_cast<dom::Element*>(aElement), pseudoType,
|
||||
aComputedValues);
|
||||
aComputedData);
|
||||
}
|
||||
|
||||
// aComputedValues might be nullptr if the target element is now in a
|
||||
// aComputedData might be nullptr if the target element is now in a
|
||||
// display:none subtree. We still call Gecko_UpdateAnimations in this case
|
||||
// because we need to stop CSS animations in the display:none subtree.
|
||||
// However, we don't need to update transitions since they are stopped by
|
||||
// RestyleManager::AnimationsWithDestroyedFrame so we just return early
|
||||
// here.
|
||||
if (!aComputedValues) {
|
||||
if (!aComputedData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTasks & UpdateAnimationsTasks::CSSTransitions) {
|
||||
MOZ_ASSERT(aOldComputedValues);
|
||||
MOZ_ASSERT(aOldComputedData);
|
||||
presContext->TransitionManager()->
|
||||
UpdateTransitions(const_cast<dom::Element*>(aElement), pseudoType,
|
||||
aOldComputedValues,
|
||||
aComputedValues);
|
||||
aOldComputedData,
|
||||
aComputedData);
|
||||
}
|
||||
|
||||
if (aTasks & UpdateAnimationsTasks::EffectProperties) {
|
||||
presContext->EffectCompositor()->UpdateEffectProperties(
|
||||
aComputedValues, const_cast<dom::Element*>(aElement), pseudoType);
|
||||
aComputedData, const_cast<dom::Element*>(aElement), pseudoType);
|
||||
}
|
||||
|
||||
if (aTasks & UpdateAnimationsTasks::CascadeResults) {
|
||||
|
@ -75,7 +75,7 @@ namespace mozilla {
|
||||
}
|
||||
|
||||
#define STYLE_STRUCT(name_, checkdata_cb_) \
|
||||
const nsStyle##name_* ServoComputedValues::GetStyle##name_() const { return &name_.mPtr->gecko; }
|
||||
const nsStyle##name_* ServoComputedData::GetStyle##name_() const { return &name_.mPtr->gecko; }
|
||||
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
@ -150,7 +150,7 @@ void Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* anon_content);
|
||||
|
||||
void Gecko_ServoStyleContext_Init(mozilla::ServoStyleContext* context,
|
||||
ServoStyleContextBorrowedOrNull parent_context,
|
||||
RawGeckoPresContextBorrowed pres_context, ServoComputedValuesBorrowed values,
|
||||
RawGeckoPresContextBorrowed pres_context, ServoComputedDataBorrowed values,
|
||||
mozilla::CSSPseudoElementType pseudo_type, nsIAtom* pseudo_tag);
|
||||
void Gecko_ServoStyleContext_Destroy(mozilla::ServoStyleContext* context);
|
||||
|
||||
@ -378,8 +378,8 @@ void Gecko_SetOwnerDocumentNeedsStyleFlush(RawGeckoElementBorrowed element);
|
||||
nsStyleContext* Gecko_GetStyleContext(RawGeckoElementBorrowed element,
|
||||
nsIAtom* aPseudoTagOrNull);
|
||||
mozilla::CSSPseudoElementType Gecko_GetImplementedPseudo(RawGeckoElementBorrowed element);
|
||||
nsChangeHint Gecko_CalcStyleDifference(const mozilla::ServoStyleContext* old_style,
|
||||
const mozilla::ServoStyleContext* new_style,
|
||||
nsChangeHint Gecko_CalcStyleDifference(ServoStyleContextBorrowed old_style,
|
||||
ServoStyleContextBorrowed new_style,
|
||||
uint64_t old_style_bits,
|
||||
bool* any_style_changed);
|
||||
nsChangeHint Gecko_HintsHandledForDescendants(nsChangeHint aHint);
|
||||
|
@ -247,9 +247,8 @@ whitelist-types = [
|
||||
"Runnable",
|
||||
"ServoAttrSnapshot",
|
||||
"ServoBundledURI",
|
||||
"ServoComputedValues",
|
||||
"ServoComputedValuesBorrowed",
|
||||
"ServoComputedValuesBorrowedOrNull",
|
||||
"ServoComputedData",
|
||||
"ServoComputedDataBorrowed",
|
||||
"ServoElementSnapshot",
|
||||
"ServoStyleContextStrong",
|
||||
"ServoStyleContextBorrowed",
|
||||
@ -320,12 +319,12 @@ mapped-generic-types = [
|
||||
{ generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
|
||||
{ generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
|
||||
{ generic = false, gecko = "mozilla::ServoFontComputationData", servo = "::properties::FontComputationData" },
|
||||
{ generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>" },
|
||||
{ generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>" },
|
||||
{ generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
|
||||
{ generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::stylearc::RawOffsetArc<::properties::ComputedValues>>" },
|
||||
{ generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::servo_arc::RawOffsetArc<::properties::ComputedValues>>" },
|
||||
{ generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
|
||||
{ generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::stylearc::RawOffsetArc" },
|
||||
{ generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>" },
|
||||
{ generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::servo_arc::RawOffsetArc" },
|
||||
{ generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>" },
|
||||
]
|
||||
fixups = [
|
||||
{ pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
|
||||
@ -345,10 +344,9 @@ raw-lines = [
|
||||
"use gecko_bindings::structs::nsTArray;",
|
||||
"type nsACString_internal = nsACString;",
|
||||
"type nsAString_internal = nsAString;",
|
||||
"pub type ServoStyleContextBorrowed<'a> = &'a ServoStyleContext;",
|
||||
"pub type ServoStyleContextBorrowed<'a> = &'a ::properties::ComputedValues;",
|
||||
"pub type ServoStyleContextBorrowedOrNull<'a> = Option<&'a ::properties::ComputedValues>;",
|
||||
"pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;",
|
||||
"pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;",
|
||||
"pub type ServoComputedDataBorrowed<'a> = &'a ServoComputedData;",
|
||||
]
|
||||
whitelist-functions = ["Servo_.*", "Gecko_.*"]
|
||||
structs-types = [
|
||||
@ -476,7 +474,7 @@ structs-types = [
|
||||
"Loader",
|
||||
"LoaderReusableStyleSheets",
|
||||
"ServoStyleSheet",
|
||||
"ServoComputedValues",
|
||||
"ServoComputedData",
|
||||
"ServoStyleContext",
|
||||
"ServoStyleContextStrong",
|
||||
"EffectCompositor_CascadeLevel",
|
||||
|
@ -20,17 +20,17 @@ ServoStyleContext::ServoStyleContext(
|
||||
nsPresContext* aPresContext,
|
||||
nsIAtom* aPseudoTag,
|
||||
CSSPseudoElementType aPseudoType,
|
||||
ServoComputedValuesForgotten aComputedValues)
|
||||
ServoComputedDataForgotten aComputedValues)
|
||||
: nsStyleContext(aParent, aPseudoTag, aPseudoType)
|
||||
, mSource(aComputedValues)
|
||||
{
|
||||
mPresContext = aPresContext;
|
||||
AddStyleBit(Servo_ComputedValues_GetStyleBits(&mSource));
|
||||
AddStyleBit(Servo_ComputedValues_GetStyleBits(this));
|
||||
|
||||
FinishConstruction();
|
||||
|
||||
// No need to call ApplyStyleFixups here, since fixups are handled by Servo when
|
||||
// producing the ServoComputedValues.
|
||||
// producing the ServoComputedData.
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -22,17 +22,17 @@ public:
|
||||
nsPresContext* aPresContext,
|
||||
nsIAtom* aPseudoTag,
|
||||
CSSPseudoElementType aPseudoType,
|
||||
ServoComputedValuesForgotten aComputedValues);
|
||||
ServoComputedDataForgotten aComputedValues);
|
||||
|
||||
nsPresContext* PresContext() const { return mPresContext; }
|
||||
const ServoComputedValues* ComputedValues() const { return &mSource; }
|
||||
const ServoComputedData* ComputedData() const { return &mSource; }
|
||||
|
||||
void AddRef() { Servo_StyleContext_AddRef(this); }
|
||||
void Release() { Servo_StyleContext_Release(this); }
|
||||
|
||||
ServoStyleContext* GetStyleIfVisited() const
|
||||
{
|
||||
return ComputedValues()->visited_style.mPtr;
|
||||
return ComputedData()->visited_style.mPtr;
|
||||
}
|
||||
|
||||
// Update visited state for a given element, and set the prescontext's
|
||||
@ -47,7 +47,7 @@ public:
|
||||
|
||||
private:
|
||||
nsPresContext* mPresContext;
|
||||
ServoComputedValues mSource;
|
||||
ServoComputedData mSource;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -24,7 +24,7 @@ ServoStyleContext::ResolveSameStructsAs(const ServoStyleContext* aOther)
|
||||
|
||||
#define STYLE_STRUCT(name_, checkdata_cb) \
|
||||
if (nsStyle##name_::kHasFinishStyle && newBits & NS_STYLE_INHERIT_BIT(name_)) { \
|
||||
const nsStyle##name_* data = ComputedValues()->GetStyle##name_(); \
|
||||
const nsStyle##name_* data = ComputedData()->GetStyle##name_(); \
|
||||
const_cast<nsStyle##name_*>(data)->FinishStyle(mPresContext); \
|
||||
}
|
||||
#include "nsStyleStructList.h"
|
||||
|
@ -782,8 +782,8 @@ ServoStyleSet::ProbePseudoElementStyle(Element* aOriginatingElement,
|
||||
bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
|
||||
aType == CSSPseudoElementType::after;
|
||||
if (isBeforeOrAfter) {
|
||||
const nsStyleDisplay* display = computedValues->ComputedValues()->GetStyleDisplay();
|
||||
const nsStyleContent* content = computedValues->ComputedValues()->GetStyleContent();
|
||||
const nsStyleDisplay* display = computedValues->ComputedData()->GetStyleDisplay();
|
||||
const nsStyleContent* content = computedValues->ComputedData()->GetStyleContent();
|
||||
// XXXldb What is contentCount for |content: ""|?
|
||||
if (display->mDisplay == StyleDisplay::None ||
|
||||
content->ContentCount() == 0) {
|
||||
|
@ -192,7 +192,7 @@ public:
|
||||
StyleRuleInclusion aRules =
|
||||
StyleRuleInclusion::All);
|
||||
|
||||
// Similar to ResolveTransientStyle() but returns ServoComputedValues.
|
||||
// Similar to ResolveTransientStyle() but doesn't update the context state
|
||||
// Unlike ResolveServoStyle() this function calls PreTraverseSync().
|
||||
already_AddRefed<ServoStyleContext>
|
||||
ResolveTransientServoStyle(dom::Element* aElement,
|
||||
|
@ -176,7 +176,7 @@ class ServoStyleContext;
|
||||
|
||||
struct ServoVisitedStyle {
|
||||
// This is actually a strong reference
|
||||
// but ServoComputedValues' destructor is
|
||||
// but ServoComputedData's destructor is
|
||||
// managed by the Rust code so we just use a
|
||||
// regular pointer
|
||||
ServoStyleContext* mPtr;
|
||||
@ -201,14 +201,14 @@ struct ServoComputedValueFlags {
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
class ServoComputedValues;
|
||||
class ServoComputedData;
|
||||
|
||||
struct ServoComputedValuesForgotten
|
||||
struct ServoComputedDataForgotten
|
||||
{
|
||||
// Make sure you manually mem::forget the backing ServoComputedValues
|
||||
// Make sure you manually mem::forget the backing ServoComputedData
|
||||
// after calling this
|
||||
explicit ServoComputedValuesForgotten(const ServoComputedValues* aValue) : mPtr(aValue) {}
|
||||
const ServoComputedValues* mPtr;
|
||||
explicit ServoComputedDataForgotten(const ServoComputedData* aValue) : mPtr(aValue) {}
|
||||
const ServoComputedData* mPtr;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -216,13 +216,13 @@ struct ServoComputedValuesForgotten
|
||||
* so we define this type on the C++ side and use the bindgenned version
|
||||
* on the Rust side.
|
||||
*/
|
||||
class ServoComputedValues
|
||||
class ServoComputedData
|
||||
{
|
||||
friend class mozilla::ServoStyleContext;
|
||||
|
||||
public:
|
||||
// Constructs via memcpy. Will not move out of aValue.
|
||||
explicit ServoComputedValues(const ServoComputedValuesForgotten aValue);
|
||||
explicit ServoComputedData(const ServoComputedDataForgotten aValue);
|
||||
|
||||
#define STYLE_STRUCT(name_, checkdata_cb_) \
|
||||
mozilla::ServoRawOffsetArc<mozilla::Gecko##name_> name_; \
|
||||
@ -261,10 +261,10 @@ private:
|
||||
// We remove the move ctor/assignment operator as well, because
|
||||
// moves in C++ don't prevent destructors from being called,
|
||||
// which will lead to double frees.
|
||||
ServoComputedValues& operator=(const ServoComputedValues&) = delete;
|
||||
ServoComputedValues(const ServoComputedValues&) = delete;
|
||||
ServoComputedValues&& operator=(const ServoComputedValues&&) = delete;
|
||||
ServoComputedValues(const ServoComputedValues&&) = delete;
|
||||
ServoComputedData& operator=(const ServoComputedData&) = delete;
|
||||
ServoComputedData(const ServoComputedData&) = delete;
|
||||
ServoComputedData&& operator=(const ServoComputedData&&) = delete;
|
||||
ServoComputedData(const ServoComputedData&&) = delete;
|
||||
};
|
||||
|
||||
#endif // mozilla_ServoTypes_h
|
||||
|
@ -1035,7 +1035,7 @@ nsAnimationManager::UpdateAnimations(
|
||||
ServoCSSAnimationBuilder builder(aStyleContext);
|
||||
|
||||
const nsStyleDisplay *disp =
|
||||
aStyleContext->ComputedValues()->GetStyleDisplay();
|
||||
aStyleContext->ComputedData()->GetStyleDisplay();
|
||||
DoUpdateAnimations(target, *disp, builder);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
class nsIGlobalObject;
|
||||
class nsStyleContext;
|
||||
class ServoComputedValues;
|
||||
class ServoComputedData;
|
||||
struct nsStyleDisplay;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -354,7 +354,7 @@ nsComputedDOMStyle::GetLength(uint32_t* aLength)
|
||||
UpdateCurrentStyleSources(false);
|
||||
if (mStyleContext) {
|
||||
length += mStyleContext->IsServo()
|
||||
? Servo_GetCustomPropertiesCount(mStyleContext->ComputedValues())
|
||||
? Servo_GetCustomPropertiesCount(mStyleContext->AsServo())
|
||||
: StyleVariables()->mVariables.Count();
|
||||
}
|
||||
|
||||
@ -1094,7 +1094,7 @@ nsComputedDOMStyle::IndexedGetter(uint32_t aIndex,
|
||||
: StyleVariables();
|
||||
|
||||
const uint32_t count = isServo
|
||||
? Servo_GetCustomPropertiesCount(mStyleContext->ComputedValues())
|
||||
? Servo_GetCustomPropertiesCount(mStyleContext->AsServo())
|
||||
: variables->mVariables.Count();
|
||||
|
||||
const uint32_t index = aIndex - length;
|
||||
@ -1102,8 +1102,7 @@ nsComputedDOMStyle::IndexedGetter(uint32_t aIndex,
|
||||
aFound = true;
|
||||
nsString varName;
|
||||
if (isServo) {
|
||||
Servo_GetCustomPropertyNameAt(mStyleContext->ComputedValues(),
|
||||
index, &varName);
|
||||
Servo_GetCustomPropertyNameAt(mStyleContext->AsServo(), index, &varName);
|
||||
} else {
|
||||
variables->mVariables.GetVariableAt(index, varName);
|
||||
}
|
||||
@ -6949,8 +6948,7 @@ nsComputedDOMStyle::DoGetCustomProperty(const nsAString& aPropertyName)
|
||||
const nsAString& name = Substring(aPropertyName,
|
||||
CSS_CUSTOM_NAME_PREFIX_LENGTH);
|
||||
bool present = mStyleContext->IsServo()
|
||||
? Servo_GetCustomPropertyValue(mStyleContext->ComputedValues(),
|
||||
&name, &variableValue)
|
||||
? Servo_GetCustomPropertyValue(mStyleContext->AsServo(), &name, &variableValue)
|
||||
: StyleVariables()->mVariables.Get(name, variableValue);
|
||||
if (!present) {
|
||||
return nullptr;
|
||||
|
@ -116,7 +116,7 @@ nsStyleContext::FinishConstruction()
|
||||
|
||||
#ifdef DEBUG
|
||||
if (auto servo = GetAsServo()) {
|
||||
MOZ_ASSERT(servo->ComputedValues());
|
||||
MOZ_ASSERT(servo->ComputedData());
|
||||
} else {
|
||||
MOZ_ASSERT(RuleNode());
|
||||
}
|
||||
@ -234,8 +234,8 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext,
|
||||
}
|
||||
} else {
|
||||
if (Servo_ComputedValues_EqualCustomProperties(
|
||||
ComputedValues(),
|
||||
aNewContext->ComputedValues())) {
|
||||
AsServo()->ComputedData(),
|
||||
aNewContext->ComputedData())) {
|
||||
*aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
|
||||
}
|
||||
}
|
||||
@ -257,7 +257,7 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext,
|
||||
(IsGecko() \
|
||||
? PeekStyle##struct_() \
|
||||
: ((aRelevantStructs & NS_STYLE_INHERIT_BIT(struct_)) \
|
||||
? AsServo()->ComputedValues()->GetStyle##struct_() \
|
||||
? AsServo()->ComputedData()->GetStyle##struct_() \
|
||||
: nullptr))
|
||||
|
||||
#define EXPAND(...) __VA_ARGS__
|
||||
@ -270,7 +270,7 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext,
|
||||
structsFound |= NS_STYLE_INHERIT_BIT(struct_); \
|
||||
} else if (checkUnrequestedServoStructs) { \
|
||||
this##struct_ = \
|
||||
AsServo()->ComputedValues()->GetStyle##struct_(); \
|
||||
AsServo()->ComputedData()->GetStyle##struct_(); \
|
||||
unrequestedStruct = true; \
|
||||
} else { \
|
||||
unrequestedStruct = false; \
|
||||
@ -487,7 +487,7 @@ void nsStyleContext::List(FILE* out, int32_t aIndent, bool aListDescendants)
|
||||
}
|
||||
|
||||
if (IsServo()) {
|
||||
fprintf_stderr(out, "%s{ServoComputedValues}\n", str.get());
|
||||
fprintf_stderr(out, "%s{ServoComputedData}\n", str.get());
|
||||
} else if (nsRuleNode* ruleNode = AsGecko()->RuleNode()) {
|
||||
fprintf_stderr(out, "%s{\n", str.get());
|
||||
str.Truncate();
|
||||
|
@ -212,7 +212,7 @@ public:
|
||||
}
|
||||
|
||||
inline nsRuleNode* RuleNode();
|
||||
inline const ServoComputedValues* ComputedValues();
|
||||
inline const ServoComputedData* ComputedData();
|
||||
|
||||
void AddStyleBit(const uint64_t& aBit) { mBits |= aBit; }
|
||||
|
||||
@ -343,8 +343,6 @@ protected:
|
||||
|
||||
void SetStyleBits();
|
||||
|
||||
inline const void* StyleStructFromServoComputedValues(nsStyleStructID aSID);
|
||||
|
||||
// Helper functions for GetStyle* and PeekStyle*
|
||||
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
|
||||
template<bool aComputeData> \
|
||||
|
@ -31,11 +31,11 @@ nsStyleContext::RuleNode()
|
||||
return AsGecko()->RuleNode();
|
||||
}
|
||||
|
||||
const ServoComputedValues*
|
||||
nsStyleContext::ComputedValues()
|
||||
const ServoComputedData*
|
||||
nsStyleContext::ComputedData()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsServo());
|
||||
return AsServo()->ComputedValues();
|
||||
return AsServo()->ComputedData();
|
||||
}
|
||||
|
||||
void
|
||||
@ -58,7 +58,7 @@ nsStyleContext::Style##name_() { \
|
||||
const nsStyle##name_ * \
|
||||
nsStyleContext::ThreadsafeStyle##name_() { \
|
||||
if (mozilla::ServoStyleSet::IsInServoTraversal()) { \
|
||||
return AsServo()->ComputedValues()->GetStyle##name_(); \
|
||||
return AsServo()->ComputedData()->GetStyle##name_(); \
|
||||
} \
|
||||
return Style##name_(); \
|
||||
} \
|
||||
@ -131,7 +131,7 @@ const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() { \
|
||||
} \
|
||||
\
|
||||
const nsStyle##name_* data = \
|
||||
servo->ComputedValues()->GetStyle##name_(); \
|
||||
servo->ComputedData()->GetStyle##name_(); \
|
||||
/* perform any remaining main thread work on the struct */ \
|
||||
if (needToCompute) { \
|
||||
MOZ_ASSERT(NS_IsMainThread()); \
|
||||
@ -164,7 +164,7 @@ const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() { \
|
||||
return nullptr; \
|
||||
} \
|
||||
const nsStyle##name_* data = \
|
||||
servo->ComputedValues()->GetStyle##name_(); \
|
||||
servo->ComputedData()->GetStyle##name_(); \
|
||||
/* perform any remaining main thread work on the struct */ \
|
||||
if (needToCompute) { \
|
||||
const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext()); \
|
||||
@ -216,20 +216,4 @@ nsStyleContext::StartBackgroundImageLoads()
|
||||
StyleBackground();
|
||||
}
|
||||
|
||||
const void*
|
||||
nsStyleContext::StyleStructFromServoComputedValues(nsStyleStructID aSID)
|
||||
{
|
||||
switch (aSID) {
|
||||
#define STYLE_STRUCT(name_, checkdata_cb_) \
|
||||
case eStyleStruct_##name_: \
|
||||
return ComputedValues()->GetStyle##name_();
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected nsStyleStructID value");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // nsStyleContextInlines_h
|
||||
|
@ -635,7 +635,7 @@ nsTransitionManager::UpdateTransitions(
|
||||
CSSTransitionCollection* collection =
|
||||
CSSTransitionCollection::GetAnimationCollection(aElement, aPseudoType);
|
||||
const nsStyleDisplay *disp =
|
||||
aNewStyle->ComputedValues()->GetStyleDisplay();
|
||||
aNewStyle->ComputedData()->GetStyleDisplay();
|
||||
return DoUpdateTransitions(disp,
|
||||
aElement, aPseudoType,
|
||||
collection,
|
||||
|
@ -334,3 +334,6 @@ skip-if = toolkit == 'android' # TIMED_OUT for android
|
||||
skip-if = toolkit == 'android' # TIMED_OUT for android
|
||||
[test_webkit_device_pixel_ratio.html]
|
||||
[test_webkit_flex_display.html]
|
||||
[test_first_letter_restrictions.html]
|
||||
[test_first_line_restrictions.html]
|
||||
[test_placeholder_restrictions.html]
|
File diff suppressed because it is too large
Load Diff
@ -43,10 +43,6 @@ to mochitest command.
|
||||
* SVG-in-OpenType values not supported servo/servo#15211 bug 1338764
|
||||
* test_value_storage.html `context-` [7]
|
||||
* test_bug798843_pref.html [3]
|
||||
* Incorrect parsing
|
||||
* different parsing bug 1364260
|
||||
* test_supports_rules.html [1]
|
||||
* test_condition_text.html [1]
|
||||
* Incorrect serialization
|
||||
* place-{content,items,self} shorthands bug 1363971
|
||||
* test_align_shorthand_serialization.html [6]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user