mirror of https://github.com/pixelfed/pixelfed
commit
82102376fe
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,13 +1,14 @@
|
||||
{
|
||||
"/js/activity.js": "/js/activity.js?id=7915246c3bc2b7e9770e",
|
||||
"/js/app.js": "/js/app.js?id=a51da95c2b9df7cf8de2",
|
||||
"/css/app.css": "/css/app.css?id=20dc108f4dbbc76c9827",
|
||||
"/css/appdark.css": "/css/appdark.css?id=08d0a92912b101bb7457",
|
||||
"/js/components.js": "/js/components.js?id=793c50b76d7f9028f550",
|
||||
"/js/compose.js": "/js/compose.js?id=aff84cf29322124685cf",
|
||||
"/js/app.js": "/js/app.js?id=3cd2f5b91d50cb028347",
|
||||
"/css/app.css": "/css/app.css?id=cc8780fa2f1c0e8156cc",
|
||||
"/css/appdark.css": "/css/appdark.css?id=c98702344aa5c1af2dda",
|
||||
"/css/landing.css": "/css/landing.css?id=36c1fca7fbdc4cdf5e7c",
|
||||
"/js/components.js": "/js/components.js?id=ae830db50efb9df181df",
|
||||
"/js/compose.js": "/js/compose.js?id=e988873b96c16cd9b764",
|
||||
"/js/discover.js": "/js/discover.js?id=75fb12b06ee23fa05186",
|
||||
"/js/landing.js": "/js/landing.js?id=328c8bec8bde1e516430",
|
||||
"/js/profile.js": "/js/profile.js?id=69fd7039c50660f4e34d",
|
||||
"/js/status.js": "/js/status.js?id=a8289051dc914ddc013f",
|
||||
"/js/timeline.js": "/js/timeline.js?id=c6a7953a0751f12efe0d"
|
||||
"/js/profile.js": "/js/profile.js?id=be1a00c4bf3ad5449ba9",
|
||||
"/js/search.js": "/js/search.js?id=df9027d746934eb442f0",
|
||||
"/js/status.js": "/js/status.js?id=305d8cb21b4c817bbcb7",
|
||||
"/js/timeline.js": "/js/timeline.js?id=3f82696a8664e306a8d0"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,71 +0,0 @@
|
||||
$(document).ready(function() {
|
||||
|
||||
let queryEngine = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
remote: {
|
||||
url: process.env.MIX_API_SEARCH + '/%QUERY%',
|
||||
wildcard: '%QUERY%'
|
||||
}
|
||||
});
|
||||
|
||||
$('.search-form .search-form-input').typeahead(null, {
|
||||
name: 'search',
|
||||
display: 'value',
|
||||
source: queryEngine,
|
||||
limit: 40,
|
||||
templates: {
|
||||
empty: [
|
||||
'<div class="alert alert-info mb-0 font-weight-bold">',
|
||||
'No Results Found',
|
||||
'</div>'
|
||||
].join('\n'),
|
||||
suggestion: function(data) {
|
||||
let type = data.type;
|
||||
let res = false;
|
||||
switch(type) {
|
||||
case 'hashtag':
|
||||
res = '<a href="'+data.url+'?src=search">' +
|
||||
'<div class="media d-flex align-items-center">' +
|
||||
'<div class="mr-3 h4 text-muted"><span class="fas fa-hashtag"></span></div>' +
|
||||
'<div class="media-body text-truncate">' +
|
||||
'<p class="mt-0 mb-0 font-weight-bold">'+data.value+'</p>' +
|
||||
'<p class="text-muted mb-0">'+data.count+' posts</p>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</a>';
|
||||
break;
|
||||
case 'profile':
|
||||
res = '<a href="'+data.url+'?src=search">' +
|
||||
'<div class="media d-flex align-items-center">' +
|
||||
'<div class="mr-3 h4 text-muted"><span class="far fa-user"></span></div>' +
|
||||
'<div class="media-body text-truncate">' +
|
||||
'<p class="mt-0 mb-0 font-weight-bold">'+data.name+'</p>' +
|
||||
'<p class="text-muted mb-0">'+data.value+'</p>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</a>';
|
||||
break;
|
||||
case 'status':
|
||||
res = '<a href="'+data.url+'?src=search">' +
|
||||
'<div class="media d-flex align-items-center">' +
|
||||
'<div class="mr-3 h4 text-muted"><img src="'+data.thumb+'" width="32px"></div>' +
|
||||
'<div class="media-body text-truncate">' +
|
||||
'<p class="mt-0 mb-0 font-weight-bold">'+data.name+'</p>' +
|
||||
'<p class="text-muted mb-0 small">'+data.value+'</p>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</a>';
|
||||
break;
|
||||
default:
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
if(res !== false) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@ -1,10 +0,0 @@
|
||||
window.Vue = require('vue');
|
||||
|
||||
Vue.component(
|
||||
'landing-page',
|
||||
require('./components/LandingPage.vue').default
|
||||
);
|
||||
|
||||
new Vue({
|
||||
el: '#content'
|
||||
});
|
||||
@ -1,952 +0,0 @@
|
||||
/*!
|
||||
* typeahead.js 1.2.0
|
||||
* https://github.com/twitter/typeahead.js
|
||||
* Copyright 2013-2017 Twitter, Inc. and other contributors; Licensed MIT
|
||||
*/
|
||||
|
||||
(function(root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define([ "jquery" ], function(a0) {
|
||||
return root["Bloodhound"] = factory(a0);
|
||||
});
|
||||
} else if (typeof exports === "object") {
|
||||
module.exports = factory(require("jquery"));
|
||||
} else {
|
||||
root["Bloodhound"] = factory(root["jQuery"]);
|
||||
}
|
||||
})(this, function($) {
|
||||
var _ = function() {
|
||||
"use strict";
|
||||
return {
|
||||
isMsie: function() {
|
||||
return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
|
||||
},
|
||||
isBlankString: function(str) {
|
||||
return !str || /^\s*$/.test(str);
|
||||
},
|
||||
escapeRegExChars: function(str) {
|
||||
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
},
|
||||
isString: function(obj) {
|
||||
return typeof obj === "string";
|
||||
},
|
||||
isNumber: function(obj) {
|
||||
return typeof obj === "number";
|
||||
},
|
||||
isArray: $.isArray,
|
||||
isFunction: $.isFunction,
|
||||
isObject: $.isPlainObject,
|
||||
isUndefined: function(obj) {
|
||||
return typeof obj === "undefined";
|
||||
},
|
||||
isElement: function(obj) {
|
||||
return !!(obj && obj.nodeType === 1);
|
||||
},
|
||||
isJQuery: function(obj) {
|
||||
return obj instanceof $;
|
||||
},
|
||||
toStr: function toStr(s) {
|
||||
return _.isUndefined(s) || s === null ? "" : s + "";
|
||||
},
|
||||
bind: $.proxy,
|
||||
each: function(collection, cb) {
|
||||
$.each(collection, reverseArgs);
|
||||
function reverseArgs(index, value) {
|
||||
return cb(value, index);
|
||||
}
|
||||
},
|
||||
map: $.map,
|
||||
filter: $.grep,
|
||||
every: function(obj, test) {
|
||||
var result = true;
|
||||
if (!obj) {
|
||||
return result;
|
||||
}
|
||||
$.each(obj, function(key, val) {
|
||||
if (!(result = test.call(null, val, key, obj))) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return !!result;
|
||||
},
|
||||
some: function(obj, test) {
|
||||
var result = false;
|
||||
if (!obj) {
|
||||
return result;
|
||||
}
|
||||
$.each(obj, function(key, val) {
|
||||
if (result = test.call(null, val, key, obj)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return !!result;
|
||||
},
|
||||
mixin: $.extend,
|
||||
identity: function(x) {
|
||||
return x;
|
||||
},
|
||||
clone: function(obj) {
|
||||
return $.extend(true, {}, obj);
|
||||
},
|
||||
getIdGenerator: function() {
|
||||
var counter = 0;
|
||||
return function() {
|
||||
return counter++;
|
||||
};
|
||||
},
|
||||
templatify: function templatify(obj) {
|
||||
return $.isFunction(obj) ? obj : template;
|
||||
function template() {
|
||||
return String(obj);
|
||||
}
|
||||
},
|
||||
defer: function(fn) {
|
||||
setTimeout(fn, 0);
|
||||
},
|
||||
debounce: function(func, wait, immediate) {
|
||||
var timeout, result;
|
||||
return function() {
|
||||
var context = this, args = arguments, later, callNow;
|
||||
later = function() {
|
||||
timeout = null;
|
||||
if (!immediate) {
|
||||
result = func.apply(context, args);
|
||||
}
|
||||
};
|
||||
callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) {
|
||||
result = func.apply(context, args);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
},
|
||||
throttle: function(func, wait) {
|
||||
var context, args, timeout, result, previous, later;
|
||||
previous = 0;
|
||||
later = function() {
|
||||
previous = new Date();
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
};
|
||||
return function() {
|
||||
var now = new Date(), remaining = wait - (now - previous);
|
||||
context = this;
|
||||
args = arguments;
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
} else if (!timeout) {
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
},
|
||||
stringify: function(val) {
|
||||
return _.isString(val) ? val : JSON.stringify(val);
|
||||
},
|
||||
guid: function() {
|
||||
function _p8(s) {
|
||||
var p = (Math.random().toString(16) + "000000000").substr(2, 8);
|
||||
return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
|
||||
}
|
||||
return "tt-" + _p8() + _p8(true) + _p8(true) + _p8();
|
||||
},
|
||||
noop: function() {}
|
||||
};
|
||||
}();
|
||||
var VERSION = "1.2.0";
|
||||
var tokenizers = function() {
|
||||
"use strict";
|
||||
return {
|
||||
nonword: nonword,
|
||||
whitespace: whitespace,
|
||||
ngram: ngram,
|
||||
obj: {
|
||||
nonword: getObjTokenizer(nonword),
|
||||
whitespace: getObjTokenizer(whitespace),
|
||||
ngram: getObjTokenizer(ngram)
|
||||
}
|
||||
};
|
||||
function whitespace(str) {
|
||||
str = _.toStr(str);
|
||||
return str ? str.split(/\s+/) : [];
|
||||
}
|
||||
function nonword(str) {
|
||||
str = _.toStr(str);
|
||||
return str ? str.split(/\W+/) : [];
|
||||
}
|
||||
function ngram(str) {
|
||||
str = _.toStr(str);
|
||||
var tokens = [], word = "";
|
||||
_.each(str.split(""), function(char) {
|
||||
if (char.match(/\s+/)) {
|
||||
word = "";
|
||||
} else {
|
||||
tokens.push(word + char);
|
||||
word += char;
|
||||
}
|
||||
});
|
||||
return tokens;
|
||||
}
|
||||
function getObjTokenizer(tokenizer) {
|
||||
return function setKey(keys) {
|
||||
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
|
||||
return function tokenize(o) {
|
||||
var tokens = [];
|
||||
_.each(keys, function(k) {
|
||||
tokens = tokens.concat(tokenizer(_.toStr(o[k])));
|
||||
});
|
||||
return tokens;
|
||||
};
|
||||
};
|
||||
}
|
||||
}();
|
||||
var LruCache = function() {
|
||||
"use strict";
|
||||
function LruCache(maxSize) {
|
||||
this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
|
||||
this.reset();
|
||||
if (this.maxSize <= 0) {
|
||||
this.set = this.get = $.noop;
|
||||
}
|
||||
}
|
||||
_.mixin(LruCache.prototype, {
|
||||
set: function set(key, val) {
|
||||
var tailItem = this.list.tail, node;
|
||||
if (this.size >= this.maxSize) {
|
||||
this.list.remove(tailItem);
|
||||
delete this.hash[tailItem.key];
|
||||
this.size--;
|
||||
}
|
||||
if (node = this.hash[key]) {
|
||||
node.val = val;
|
||||
this.list.moveToFront(node);
|
||||
} else {
|
||||
node = new Node(key, val);
|
||||
this.list.add(node);
|
||||
this.hash[key] = node;
|
||||
this.size++;
|
||||
}
|
||||
},
|
||||
get: function get(key) {
|
||||
var node = this.hash[key];
|
||||
if (node) {
|
||||
this.list.moveToFront(node);
|
||||
return node.val;
|
||||
}
|
||||
},
|
||||
reset: function reset() {
|
||||
this.size = 0;
|
||||
this.hash = {};
|
||||
this.list = new List();
|
||||
}
|
||||
});
|
||||
function List() {
|
||||
this.head = this.tail = null;
|
||||
}
|
||||
_.mixin(List.prototype, {
|
||||
add: function add(node) {
|
||||
if (this.head) {
|
||||
node.next = this.head;
|
||||
this.head.prev = node;
|
||||
}
|
||||
this.head = node;
|
||||
this.tail = this.tail || node;
|
||||
},
|
||||
remove: function remove(node) {
|
||||
node.prev ? node.prev.next = node.next : this.head = node.next;
|
||||
node.next ? node.next.prev = node.prev : this.tail = node.prev;
|
||||
},
|
||||
moveToFront: function(node) {
|
||||
this.remove(node);
|
||||
this.add(node);
|
||||
}
|
||||
});
|
||||
function Node(key, val) {
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
this.prev = this.next = null;
|
||||
}
|
||||
return LruCache;
|
||||
}();
|
||||
var PersistentStorage = function() {
|
||||
"use strict";
|
||||
var LOCAL_STORAGE;
|
||||
try {
|
||||
LOCAL_STORAGE = window.localStorage;
|
||||
LOCAL_STORAGE.setItem("~~~", "!");
|
||||
LOCAL_STORAGE.removeItem("~~~");
|
||||
} catch (err) {
|
||||
LOCAL_STORAGE = null;
|
||||
}
|
||||
function PersistentStorage(namespace, override) {
|
||||
this.prefix = [ "__", namespace, "__" ].join("");
|
||||
this.ttlKey = "__ttl__";
|
||||
this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
|
||||
this.ls = override || LOCAL_STORAGE;
|
||||
!this.ls && this._noop();
|
||||
}
|
||||
_.mixin(PersistentStorage.prototype, {
|
||||
_prefix: function(key) {
|
||||
return this.prefix + key;
|
||||
},
|
||||
_ttlKey: function(key) {
|
||||
return this._prefix(key) + this.ttlKey;
|
||||
},
|
||||
_noop: function() {
|
||||
this.get = this.set = this.remove = this.clear = this.isExpired = _.noop;
|
||||
},
|
||||
_safeSet: function(key, val) {
|
||||
try {
|
||||
this.ls.setItem(key, val);
|
||||
} catch (err) {
|
||||
if (err.name === "QuotaExceededError") {
|
||||
this.clear();
|
||||
this._noop();
|
||||
}
|
||||
}
|
||||
},
|
||||
get: function(key) {
|
||||
if (this.isExpired(key)) {
|
||||
this.remove(key);
|
||||
}
|
||||
return decode(this.ls.getItem(this._prefix(key)));
|
||||
},
|
||||
set: function(key, val, ttl) {
|
||||
if (_.isNumber(ttl)) {
|
||||
this._safeSet(this._ttlKey(key), encode(now() + ttl));
|
||||
} else {
|
||||
this.ls.removeItem(this._ttlKey(key));
|
||||
}
|
||||
return this._safeSet(this._prefix(key), encode(val));
|
||||
},
|
||||
remove: function(key) {
|
||||
this.ls.removeItem(this._ttlKey(key));
|
||||
this.ls.removeItem(this._prefix(key));
|
||||
return this;
|
||||
},
|
||||
clear: function() {
|
||||
var i, keys = gatherMatchingKeys(this.keyMatcher);
|
||||
for (i = keys.length; i--; ) {
|
||||
this.remove(keys[i]);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
isExpired: function(key) {
|
||||
var ttl = decode(this.ls.getItem(this._ttlKey(key)));
|
||||
return _.isNumber(ttl) && now() > ttl ? true : false;
|
||||
}
|
||||
});
|
||||
return PersistentStorage;
|
||||
function now() {
|
||||
return new Date().getTime();
|
||||
}
|
||||
function encode(val) {
|
||||
return JSON.stringify(_.isUndefined(val) ? null : val);
|
||||
}
|
||||
function decode(val) {
|
||||
return $.parseJSON(val);
|
||||
}
|
||||
function gatherMatchingKeys(keyMatcher) {
|
||||
var i, key, keys = [], len = LOCAL_STORAGE.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) {
|
||||
keys.push(key.replace(keyMatcher, ""));
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}();
|
||||
var Transport = function() {
|
||||
"use strict";
|
||||
var pendingRequestsCount = 0, pendingRequests = {}, sharedCache = new LruCache(10);
|
||||
function Transport(o) {
|
||||
o = o || {};
|
||||
this.maxPendingRequests = o.maxPendingRequests || 6;
|
||||
this.cancelled = false;
|
||||
this.lastReq = null;
|
||||
this._send = o.transport;
|
||||
this._get = o.limiter ? o.limiter(this._get) : this._get;
|
||||
this._cache = o.cache === false ? new LruCache(0) : sharedCache;
|
||||
}
|
||||
Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
|
||||
this.maxPendingRequests = num;
|
||||
};
|
||||
Transport.resetCache = function resetCache() {
|
||||
sharedCache.reset();
|
||||
};
|
||||
_.mixin(Transport.prototype, {
|
||||
_fingerprint: function fingerprint(o) {
|
||||
o = o || {};
|
||||
return o.url + o.type + $.param(o.data || {});
|
||||
},
|
||||
_get: function(o, cb) {
|
||||
var that = this, fingerprint, jqXhr;
|
||||
fingerprint = this._fingerprint(o);
|
||||
if (this.cancelled || fingerprint !== this.lastReq) {
|
||||
return;
|
||||
}
|
||||
if (jqXhr = pendingRequests[fingerprint]) {
|
||||
jqXhr.done(done).fail(fail);
|
||||
} else if (pendingRequestsCount < this.maxPendingRequests) {
|
||||
pendingRequestsCount++;
|
||||
pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);
|
||||
} else {
|
||||
this.onDeckRequestArgs = [].slice.call(arguments, 0);
|
||||
}
|
||||
function done(resp) {
|
||||
cb(null, resp);
|
||||
that._cache.set(fingerprint, resp);
|
||||
}
|
||||
function fail() {
|
||||
cb(true);
|
||||
}
|
||||
function always() {
|
||||
pendingRequestsCount--;
|
||||
delete pendingRequests[fingerprint];
|
||||
if (that.onDeckRequestArgs) {
|
||||
that._get.apply(that, that.onDeckRequestArgs);
|
||||
that.onDeckRequestArgs = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
get: function(o, cb) {
|
||||
var resp, fingerprint;
|
||||
cb = cb || $.noop;
|
||||
o = _.isString(o) ? {
|
||||
url: o
|
||||
} : o || {};
|
||||
fingerprint = this._fingerprint(o);
|
||||
this.cancelled = false;
|
||||
this.lastReq = fingerprint;
|
||||
if (resp = this._cache.get(fingerprint)) {
|
||||
cb(null, resp);
|
||||
} else {
|
||||
this._get(o, cb);
|
||||
}
|
||||
},
|
||||
cancel: function() {
|
||||
this.cancelled = true;
|
||||
}
|
||||
});
|
||||
return Transport;
|
||||
}();
|
||||
var SearchIndex = window.SearchIndex = function() {
|
||||
"use strict";
|
||||
var CHILDREN = "c", IDS = "i";
|
||||
function SearchIndex(o) {
|
||||
o = o || {};
|
||||
if (!o.datumTokenizer || !o.queryTokenizer) {
|
||||
$.error("datumTokenizer and queryTokenizer are both required");
|
||||
}
|
||||
this.identify = o.identify || _.stringify;
|
||||
this.datumTokenizer = o.datumTokenizer;
|
||||
this.queryTokenizer = o.queryTokenizer;
|
||||
this.matchAnyQueryToken = o.matchAnyQueryToken;
|
||||
this.reset();
|
||||
}
|
||||
_.mixin(SearchIndex.prototype, {
|
||||
bootstrap: function bootstrap(o) {
|
||||
this.datums = o.datums;
|
||||
this.trie = o.trie;
|
||||
},
|
||||
add: function(data) {
|
||||
var that = this;
|
||||
data = _.isArray(data) ? data : [ data ];
|
||||
_.each(data, function(datum) {
|
||||
var id, tokens;
|
||||
that.datums[id = that.identify(datum)] = datum;
|
||||
tokens = normalizeTokens(that.datumTokenizer(datum));
|
||||
_.each(tokens, function(token) {
|
||||
var node, chars, ch;
|
||||
node = that.trie;
|
||||
chars = token.split("");
|
||||
while (ch = chars.shift()) {
|
||||
node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode());
|
||||
node[IDS].push(id);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
get: function get(ids) {
|
||||
var that = this;
|
||||
return _.map(ids, function(id) {
|
||||
return that.datums[id];
|
||||
});
|
||||
},
|
||||
search: function search(query) {
|
||||
var that = this, tokens, matches;
|
||||
tokens = normalizeTokens(this.queryTokenizer(query));
|
||||
_.each(tokens, function(token) {
|
||||
var node, chars, ch, ids;
|
||||
if (matches && matches.length === 0 && !that.matchAnyQueryToken) {
|
||||
return false;
|
||||
}
|
||||
node = that.trie;
|
||||
chars = token.split("");
|
||||
while (node && (ch = chars.shift())) {
|
||||
node = node[CHILDREN][ch];
|
||||
}
|
||||
if (node && chars.length === 0) {
|
||||
ids = node[IDS].slice(0);
|
||||
matches = matches ? getIntersection(matches, ids) : ids;
|
||||
} else {
|
||||
if (!that.matchAnyQueryToken) {
|
||||
matches = [];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
return matches ? _.map(unique(matches), function(id) {
|
||||
return that.datums[id];
|
||||
}) : [];
|
||||
},
|
||||
all: function all() {
|
||||
var values = [];
|
||||
for (var key in this.datums) {
|
||||
values.push(this.datums[key]);
|
||||
}
|
||||
return values;
|
||||
},
|
||||
reset: function reset() {
|
||||
this.datums = {};
|
||||
this.trie = newNode();
|
||||
},
|
||||
serialize: function serialize() {
|
||||
return {
|
||||
datums: this.datums,
|
||||
trie: this.trie
|
||||
};
|
||||
}
|
||||
});
|
||||
return SearchIndex;
|
||||
function normalizeTokens(tokens) {
|
||||
tokens = _.filter(tokens, function(token) {
|
||||
return !!token;
|
||||
});
|
||||
tokens = _.map(tokens, function(token) {
|
||||
return token.toLowerCase();
|
||||
});
|
||||
return tokens;
|
||||
}
|
||||
function newNode() {
|
||||
var node = {};
|
||||
node[IDS] = [];
|
||||
node[CHILDREN] = {};
|
||||
return node;
|
||||
}
|
||||
function unique(array) {
|
||||
var seen = {}, uniques = [];
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
if (!seen[array[i]]) {
|
||||
seen[array[i]] = true;
|
||||
uniques.push(array[i]);
|
||||
}
|
||||
}
|
||||
return uniques;
|
||||
}
|
||||
function getIntersection(arrayA, arrayB) {
|
||||
var ai = 0, bi = 0, intersection = [];
|
||||
arrayA = arrayA.sort();
|
||||
arrayB = arrayB.sort();
|
||||
var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
|
||||
while (ai < lenArrayA && bi < lenArrayB) {
|
||||
if (arrayA[ai] < arrayB[bi]) {
|
||||
ai++;
|
||||
} else if (arrayA[ai] > arrayB[bi]) {
|
||||
bi++;
|
||||
} else {
|
||||
intersection.push(arrayA[ai]);
|
||||
ai++;
|
||||
bi++;
|
||||
}
|
||||
}
|
||||
return intersection;
|
||||
}
|
||||
}();
|
||||
var Prefetch = function() {
|
||||
"use strict";
|
||||
var keys;
|
||||
keys = {
|
||||
data: "data",
|
||||
protocol: "protocol",
|
||||
thumbprint: "thumbprint"
|
||||
};
|
||||
function Prefetch(o) {
|
||||
this.url = o.url;
|
||||
this.ttl = o.ttl;
|
||||
this.cache = o.cache;
|
||||
this.prepare = o.prepare;
|
||||
this.transform = o.transform;
|
||||
this.transport = o.transport;
|
||||
this.thumbprint = o.thumbprint;
|
||||
this.storage = new PersistentStorage(o.cacheKey);
|
||||
}
|
||||
_.mixin(Prefetch.prototype, {
|
||||
_settings: function settings() {
|
||||
return {
|
||||
url: this.url,
|
||||
type: "GET",
|
||||
dataType: "json"
|
||||
};
|
||||
},
|
||||
store: function store(data) {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.storage.set(keys.data, data, this.ttl);
|
||||
this.storage.set(keys.protocol, location.protocol, this.ttl);
|
||||
this.storage.set(keys.thumbprint, this.thumbprint, this.ttl);
|
||||
},
|
||||
fromCache: function fromCache() {
|
||||
var stored = {}, isExpired;
|
||||
if (!this.cache) {
|
||||
return null;
|
||||
}
|
||||
stored.data = this.storage.get(keys.data);
|
||||
stored.protocol = this.storage.get(keys.protocol);
|
||||
stored.thumbprint = this.storage.get(keys.thumbprint);
|
||||
isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol;
|
||||
return stored.data && !isExpired ? stored.data : null;
|
||||
},
|
||||
fromNetwork: function(cb) {
|
||||
var that = this, settings;
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
settings = this.prepare(this._settings());
|
||||
this.transport(settings).fail(onError).done(onResponse);
|
||||
function onError() {
|
||||
cb(true);
|
||||
}
|
||||
function onResponse(resp) {
|
||||
cb(null, that.transform(resp));
|
||||
}
|
||||
},
|
||||
clear: function clear() {
|
||||
this.storage.clear();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
return Prefetch;
|
||||
}();
|
||||
var Remote = function() {
|
||||
"use strict";
|
||||
function Remote(o) {
|
||||
this.url = o.url;
|
||||
this.prepare = o.prepare;
|
||||
this.transform = o.transform;
|
||||
this.indexResponse = o.indexResponse;
|
||||
this.transport = new Transport({
|
||||
cache: o.cache,
|
||||
limiter: o.limiter,
|
||||
transport: o.transport,
|
||||
maxPendingRequests: o.maxPendingRequests
|
||||
});
|
||||
}
|
||||
_.mixin(Remote.prototype, {
|
||||
_settings: function settings() {
|
||||
return {
|
||||
url: this.url,
|
||||
type: "GET",
|
||||
dataType: "json"
|
||||
};
|
||||
},
|
||||
get: function get(query, cb) {
|
||||
var that = this, settings;
|
||||
if (!cb) {
|
||||
return;
|
||||
}
|
||||
query = query || "";
|
||||
settings = this.prepare(query, this._settings());
|
||||
return this.transport.get(settings, onResponse);
|
||||
function onResponse(err, resp) {
|
||||
err ? cb([]) : cb(that.transform(resp));
|
||||
}
|
||||
},
|
||||
cancelLastRequest: function cancelLastRequest() {
|
||||
this.transport.cancel();
|
||||
}
|
||||
});
|
||||
return Remote;
|
||||
}();
|
||||
var oParser = function() {
|
||||
"use strict";
|
||||
return function parse(o) {
|
||||
var defaults, sorter;
|
||||
defaults = {
|
||||
initialize: true,
|
||||
identify: _.stringify,
|
||||
datumTokenizer: null,
|
||||
queryTokenizer: null,
|
||||
matchAnyQueryToken: false,
|
||||
sufficient: 5,
|
||||
indexRemote: false,
|
||||
sorter: null,
|
||||
local: [],
|
||||
prefetch: null,
|
||||
remote: null
|
||||
};
|
||||
o = _.mixin(defaults, o || {});
|
||||
!o.datumTokenizer && $.error("datumTokenizer is required");
|
||||
!o.queryTokenizer && $.error("queryTokenizer is required");
|
||||
sorter = o.sorter;
|
||||
o.sorter = sorter ? function(x) {
|
||||
return x.sort(sorter);
|
||||
} : _.identity;
|
||||
o.local = _.isFunction(o.local) ? o.local() : o.local;
|
||||
o.prefetch = parsePrefetch(o.prefetch);
|
||||
o.remote = parseRemote(o.remote);
|
||||
return o;
|
||||
};
|
||||
function parsePrefetch(o) {
|
||||
var defaults;
|
||||
if (!o) {
|
||||
return null;
|
||||
}
|
||||
defaults = {
|
||||
url: null,
|
||||
ttl: 24 * 60 * 60 * 1e3,
|
||||
cache: true,
|
||||
cacheKey: null,
|
||||
thumbprint: "",
|
||||
prepare: _.identity,
|
||||
transform: _.identity,
|
||||
transport: null
|
||||
};
|
||||
o = _.isString(o) ? {
|
||||
url: o
|
||||
} : o;
|
||||
o = _.mixin(defaults, o);
|
||||
!o.url && $.error("prefetch requires url to be set");
|
||||
o.transform = o.filter || o.transform;
|
||||
o.cacheKey = o.cacheKey || o.url;
|
||||
o.thumbprint = VERSION + o.thumbprint;
|
||||
o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
|
||||
return o;
|
||||
}
|
||||
function parseRemote(o) {
|
||||
var defaults;
|
||||
if (!o) {
|
||||
return;
|
||||
}
|
||||
defaults = {
|
||||
url: null,
|
||||
cache: true,
|
||||
prepare: null,
|
||||
replace: null,
|
||||
wildcard: null,
|
||||
limiter: null,
|
||||
rateLimitBy: "debounce",
|
||||
rateLimitWait: 300,
|
||||
transform: _.identity,
|
||||
transport: null
|
||||
};
|
||||
o = _.isString(o) ? {
|
||||
url: o
|
||||
} : o;
|
||||
o = _.mixin(defaults, o);
|
||||
!o.url && $.error("remote requires url to be set");
|
||||
o.transform = o.filter || o.transform;
|
||||
o.prepare = toRemotePrepare(o);
|
||||
o.limiter = toLimiter(o);
|
||||
o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
|
||||
delete o.replace;
|
||||
delete o.wildcard;
|
||||
delete o.rateLimitBy;
|
||||
delete o.rateLimitWait;
|
||||
return o;
|
||||
}
|
||||
function toRemotePrepare(o) {
|
||||
var prepare, replace, wildcard;
|
||||
prepare = o.prepare;
|
||||
replace = o.replace;
|
||||
wildcard = o.wildcard;
|
||||
if (prepare) {
|
||||
return prepare;
|
||||
}
|
||||
if (replace) {
|
||||
prepare = prepareByReplace;
|
||||
} else if (o.wildcard) {
|
||||
prepare = prepareByWildcard;
|
||||
} else {
|
||||
prepare = identityPrepare;
|
||||
}
|
||||
return prepare;
|
||||
function prepareByReplace(query, settings) {
|
||||
settings.url = replace(settings.url, query);
|
||||
return settings;
|
||||
}
|
||||
function prepareByWildcard(query, settings) {
|
||||
settings.url = settings.url.replace(wildcard, encodeURIComponent(query));
|
||||
return settings;
|
||||
}
|
||||
function identityPrepare(query, settings) {
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
function toLimiter(o) {
|
||||
var limiter, method, wait;
|
||||
limiter = o.limiter;
|
||||
method = o.rateLimitBy;
|
||||
wait = o.rateLimitWait;
|
||||
if (!limiter) {
|
||||
limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait);
|
||||
}
|
||||
return limiter;
|
||||
function debounce(wait) {
|
||||
return function debounce(fn) {
|
||||
return _.debounce(fn, wait);
|
||||
};
|
||||
}
|
||||
function throttle(wait) {
|
||||
return function throttle(fn) {
|
||||
return _.throttle(fn, wait);
|
||||
};
|
||||
}
|
||||
}
|
||||
function callbackToDeferred(fn) {
|
||||
return function wrapper(o) {
|
||||
var deferred = $.Deferred();
|
||||
fn(o, onSuccess, onError);
|
||||
return deferred;
|
||||
function onSuccess(resp) {
|
||||
_.defer(function() {
|
||||
deferred.resolve(resp);
|
||||
});
|
||||
}
|
||||
function onError(err) {
|
||||
_.defer(function() {
|
||||
deferred.reject(err);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}();
|
||||
var Bloodhound = function() {
|
||||
"use strict";
|
||||
var old;
|
||||
old = window && window.Bloodhound;
|
||||
function Bloodhound(o) {
|
||||
o = oParser(o);
|
||||
this.sorter = o.sorter;
|
||||
this.identify = o.identify;
|
||||
this.sufficient = o.sufficient;
|
||||
this.indexRemote = o.indexRemote;
|
||||
this.local = o.local;
|
||||
this.remote = o.remote ? new Remote(o.remote) : null;
|
||||
this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;
|
||||
this.index = new SearchIndex({
|
||||
identify: this.identify,
|
||||
datumTokenizer: o.datumTokenizer,
|
||||
queryTokenizer: o.queryTokenizer
|
||||
});
|
||||
o.initialize !== false && this.initialize();
|
||||
}
|
||||
Bloodhound.noConflict = function noConflict() {
|
||||
window && (window.Bloodhound = old);
|
||||
return Bloodhound;
|
||||
};
|
||||
Bloodhound.tokenizers = tokenizers;
|
||||
_.mixin(Bloodhound.prototype, {
|
||||
__ttAdapter: function ttAdapter() {
|
||||
var that = this;
|
||||
return this.remote ? withAsync : withoutAsync;
|
||||
function withAsync(query, sync, async) {
|
||||
return that.search(query, sync, async);
|
||||
}
|
||||
function withoutAsync(query, sync) {
|
||||
return that.search(query, sync);
|
||||
}
|
||||
},
|
||||
_loadPrefetch: function loadPrefetch() {
|
||||
var that = this, deferred, serialized;
|
||||
deferred = $.Deferred();
|
||||
if (!this.prefetch) {
|
||||
deferred.resolve();
|
||||
} else if (serialized = this.prefetch.fromCache()) {
|
||||
this.index.bootstrap(serialized);
|
||||
deferred.resolve();
|
||||
} else {
|
||||
this.prefetch.fromNetwork(done);
|
||||
}
|
||||
return deferred.promise();
|
||||
function done(err, data) {
|
||||
if (err) {
|
||||
return deferred.reject();
|
||||
}
|
||||
that.add(data);
|
||||
that.prefetch.store(that.index.serialize());
|
||||
deferred.resolve();
|
||||
}
|
||||
},
|
||||
_initialize: function initialize() {
|
||||
var that = this, deferred;
|
||||
this.clear();
|
||||
(this.initPromise = this._loadPrefetch()).done(addLocalToIndex);
|
||||
return this.initPromise;
|
||||
function addLocalToIndex() {
|
||||
that.add(that.local);
|
||||
}
|
||||
},
|
||||
initialize: function initialize(force) {
|
||||
return !this.initPromise || force ? this._initialize() : this.initPromise;
|
||||
},
|
||||
add: function add(data) {
|
||||
this.index.add(data);
|
||||
return this;
|
||||
},
|
||||
get: function get(ids) {
|
||||
ids = _.isArray(ids) ? ids : [].slice.call(arguments);
|
||||
return this.index.get(ids);
|
||||
},
|
||||
search: function search(query, sync, async) {
|
||||
var that = this, local;
|
||||
sync = sync || _.noop;
|
||||
async = async || _.noop;
|
||||
local = this.sorter(this.index.search(query));
|
||||
sync(this.remote ? local.slice() : local);
|
||||
if (this.remote && local.length < this.sufficient) {
|
||||
this.remote.get(query, processRemote);
|
||||
} else if (this.remote) {
|
||||
this.remote.cancelLastRequest();
|
||||
}
|
||||
return this;
|
||||
function processRemote(remote) {
|
||||
var nonDuplicates = [];
|
||||
_.each(remote, function(r) {
|
||||
!_.some(local, function(l) {
|
||||
return that.identify(r) === that.identify(l);
|
||||
}) && nonDuplicates.push(r);
|
||||
});
|
||||
that.indexRemote && that.add(nonDuplicates);
|
||||
async(nonDuplicates);
|
||||
}
|
||||
},
|
||||
all: function all() {
|
||||
return this.index.all();
|
||||
},
|
||||
clear: function clear() {
|
||||
this.index.reset();
|
||||
return this;
|
||||
},
|
||||
clearPrefetchCache: function clearPrefetchCache() {
|
||||
this.prefetch && this.prefetch.clear();
|
||||
return this;
|
||||
},
|
||||
clearRemoteCache: function clearRemoteCache() {
|
||||
Transport.resetCache();
|
||||
return this;
|
||||
},
|
||||
ttAdapter: function ttAdapter() {
|
||||
return this.__ttAdapter();
|
||||
}
|
||||
});
|
||||
return Bloodhound;
|
||||
}();
|
||||
return Bloodhound;
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,4 @@
|
||||
Vue.component(
|
||||
'search-results',
|
||||
require('./components/SearchResults.vue').default
|
||||
);
|
||||
@ -0,0 +1,13 @@
|
||||
// Landing Page bundle
|
||||
|
||||
@import 'variables';
|
||||
@import '~bootstrap/scss/bootstrap';
|
||||
@import 'custom';
|
||||
@import 'landing/carousel';
|
||||
@import 'landing/devices';
|
||||
|
||||
.container.slim {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
@-webkit-keyframes iosDeviceCarousel {
|
||||
0% {
|
||||
opacity:1;
|
||||
}
|
||||
17% {
|
||||
opacity:1;
|
||||
}
|
||||
25% {
|
||||
opacity:0;
|
||||
}
|
||||
92% {
|
||||
opacity:0;
|
||||
}
|
||||
100% {
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes iosDeviceCarousel {
|
||||
0% {
|
||||
opacity:1;
|
||||
}
|
||||
17% {
|
||||
opacity:1;
|
||||
}
|
||||
25% {
|
||||
opacity:0;
|
||||
}
|
||||
92% {
|
||||
opacity:0;
|
||||
}
|
||||
100% {
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes iosDeviceCarousel {
|
||||
0% {
|
||||
opacity:1;
|
||||
}
|
||||
17% {
|
||||
opacity:1;
|
||||
}
|
||||
25% {
|
||||
opacity:0;
|
||||
}
|
||||
92% {
|
||||
opacity:0;
|
||||
}
|
||||
100% {
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes iosDeviceCarousel {
|
||||
0% {
|
||||
opacity:1;
|
||||
}
|
||||
17% {
|
||||
opacity:1;
|
||||
}
|
||||
25% {
|
||||
opacity:0;
|
||||
}
|
||||
92% {
|
||||
opacity:0;
|
||||
}
|
||||
100% {
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
|
||||
#iosDevice {
|
||||
position:relative;
|
||||
margin:0 auto;
|
||||
}
|
||||
#iosDevice img {
|
||||
position:absolute;
|
||||
left:0;
|
||||
}
|
||||
|
||||
#iosDevice img {
|
||||
-webkit-animation-name: iosDeviceCarousel;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
-webkit-animation-duration: 16s;
|
||||
|
||||
-moz-animation-name: iosDeviceCarousel;
|
||||
-moz-animation-timing-function: ease-in-out;
|
||||
-moz-animation-iteration-count: infinite;
|
||||
-moz-animation-duration: 16s;
|
||||
|
||||
-o-animation-name: iosDeviceCarousel;
|
||||
-o-animation-timing-function: ease-in-out;
|
||||
-o-animation-iteration-count: infinite;
|
||||
-o-animation-duration: 16s;
|
||||
|
||||
animation-name: iosDeviceCarousel;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
animation-duration: 16s;
|
||||
}
|
||||
#iosDevice img:nth-of-type(1) {
|
||||
-webkit-animation-delay: 12s;
|
||||
-moz-animation-delay: 12s;
|
||||
-o-animation-delay: 12s;
|
||||
animation-delay: 12s;
|
||||
}
|
||||
#iosDevice img:nth-of-type(2) {
|
||||
-webkit-animation-delay: 8s;
|
||||
-moz-animation-delay: 8s;
|
||||
-o-animation-delay: 8s;
|
||||
animation-delay: 8s;
|
||||
}
|
||||
#iosDevice img:nth-of-type(3) {
|
||||
-webkit-animation-delay: 4s;
|
||||
-moz-animation-delay: 4s;
|
||||
-o-animation-delay: 4s;
|
||||
animation-delay: 4s;
|
||||
}
|
||||
#iosDevice img:nth-of-type(4) {
|
||||
-webkit-animation-delay: 0;
|
||||
-moz-animation-delay: 0;
|
||||
-o-animation-delay: 0;
|
||||
animation-delay: 0;
|
||||
}
|
||||
@ -0,0 +1,593 @@
|
||||
.marvel-device {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
-webkit-box-sizing: content-box !important;
|
||||
box-sizing: content-box !important
|
||||
}
|
||||
|
||||
.marvel-device .screen {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
z-index: 3;
|
||||
background: white;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
border-radius: 1px;
|
||||
-webkit-box-shadow: 0 0 0 3px #111;
|
||||
box-shadow: 0 0 0 3px #111
|
||||
}
|
||||
|
||||
.marvel-device .top-bar,
|
||||
.marvel-device .bottom-bar {
|
||||
height: 3px;
|
||||
background: black;
|
||||
width: 100%;
|
||||
display: block
|
||||
}
|
||||
|
||||
.marvel-device .middle-bar {
|
||||
width: 3px;
|
||||
height: 4px;
|
||||
top: 0px;
|
||||
left: 90px;
|
||||
background: black;
|
||||
position: absolute
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x {
|
||||
width: 375px;
|
||||
height: 812px;
|
||||
padding: 26px;
|
||||
background: #fdfdfd;
|
||||
-webkit-box-shadow: inset 0 0 11px 0 black;
|
||||
box-shadow: inset 0 0 11px 0 black;
|
||||
border-radius: 66px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .overflow {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 66px;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .shadow {
|
||||
border-radius: 100%;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
position: absolute;
|
||||
background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.6) 0%, rgba(255, 255, 255, 0) 60%)
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .shadow--tl {
|
||||
top: -20px;
|
||||
left: -20px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .shadow--tr {
|
||||
top: -20px;
|
||||
right: -20px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .shadow--bl {
|
||||
bottom: -20px;
|
||||
left: -20px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .shadow--br {
|
||||
bottom: -20px;
|
||||
right: -20px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x:before {
|
||||
width: calc(100% - 10px);
|
||||
height: calc(100% - 10px);
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
content: '';
|
||||
left: 5px;
|
||||
border-radius: 61px;
|
||||
background: black;
|
||||
z-index: 1
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .inner-shadow {
|
||||
width: calc(100% - 20px);
|
||||
height: calc(100% - 20px);
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
overflow: hidden;
|
||||
left: 10px;
|
||||
border-radius: 56px;
|
||||
-webkit-box-shadow: inset 0 0 15px 0 rgba(255, 255, 255, 0.66);
|
||||
box-shadow: inset 0 0 15px 0 rgba(255, 255, 255, 0.66);
|
||||
z-index: 1
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .inner-shadow:before {
|
||||
-webkit-box-shadow: inset 0 0 20px 0 #FFFFFF;
|
||||
box-shadow: inset 0 0 20px 0 #FFFFFF;
|
||||
width: 100%;
|
||||
height: 116%;
|
||||
position: absolute;
|
||||
top: -8%;
|
||||
content: '';
|
||||
left: 0;
|
||||
border-radius: 200px / 112px;
|
||||
z-index: 2
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .screen {
|
||||
border-radius: 40px;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .top-bar,
|
||||
.marvel-device.iphone-x .bottom-bar {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
height: 8px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
left: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .top-bar {
|
||||
top: 80px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .bottom-bar {
|
||||
bottom: 80px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .volume,
|
||||
.marvel-device.iphone-x .volume:before,
|
||||
.marvel-device.iphone-x .volume:after,
|
||||
.marvel-device.iphone-x .sleep {
|
||||
width: 3px;
|
||||
background: #b5b5b5;
|
||||
position: absolute
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .volume {
|
||||
left: -3px;
|
||||
top: 116px;
|
||||
height: 32px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .volume:before {
|
||||
height: 62px;
|
||||
top: 62px;
|
||||
content: '';
|
||||
left: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .volume:after {
|
||||
height: 62px;
|
||||
top: 140px;
|
||||
content: '';
|
||||
left: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .sleep {
|
||||
height: 96px;
|
||||
top: 200px;
|
||||
right: -3px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .camera {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
top: 9px;
|
||||
border-radius: 100%;
|
||||
position: absolute;
|
||||
left: 154px;
|
||||
background: #0d4d71
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .speaker {
|
||||
height: 6px;
|
||||
width: 60px;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
margin-left: -30px;
|
||||
background: #171818;
|
||||
border-radius: 6px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .notch {
|
||||
position: absolute;
|
||||
width: 210px;
|
||||
height: 30px;
|
||||
top: 26px;
|
||||
left: 108px;
|
||||
z-index: 4;
|
||||
background: black;
|
||||
border-bottom-left-radius: 24px;
|
||||
border-bottom-right-radius: 24px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .notch:before,
|
||||
.marvel-device.iphone-x .notch:after {
|
||||
content: '';
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 8px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .notch:after {
|
||||
background: radial-gradient(circle at bottom left, transparent 0, transparent 70%, black 70%, black 100%);
|
||||
left: -8px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x .notch:before {
|
||||
background: radial-gradient(circle at bottom right, transparent 0, transparent 70%, black 70%, black 100%);
|
||||
right: -8px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape {
|
||||
height: 375px;
|
||||
width: 812px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .top-bar,
|
||||
.marvel-device.iphone-x.landscape .bottom-bar {
|
||||
width: 8px;
|
||||
height: 100%;
|
||||
top: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .top-bar {
|
||||
left: 80px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .bottom-bar {
|
||||
right: 80px;
|
||||
bottom: auto;
|
||||
left: auto
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .volume,
|
||||
.marvel-device.iphone-x.landscape .volume:before,
|
||||
.marvel-device.iphone-x.landscape .volume:after,
|
||||
.marvel-device.iphone-x.landscape .sleep {
|
||||
height: 3px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .inner-shadow:before {
|
||||
height: 100%;
|
||||
width: 116%;
|
||||
left: -8%;
|
||||
top: 0;
|
||||
border-radius: 112px / 200px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .volume {
|
||||
bottom: -3px;
|
||||
top: auto;
|
||||
left: 116px;
|
||||
width: 32px
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .volume:before {
|
||||
width: 62px;
|
||||
left: 62px;
|
||||
top: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .volume:after {
|
||||
width: 62px;
|
||||
left: 140px;
|
||||
top: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .sleep {
|
||||
width: 96px;
|
||||
left: 200px;
|
||||
top: -3px;
|
||||
right: auto
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .camera {
|
||||
left: 9px;
|
||||
bottom: 154px;
|
||||
top: auto
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .speaker {
|
||||
width: 6px;
|
||||
height: 60px;
|
||||
left: 9px;
|
||||
top: 50%;
|
||||
margin-top: -30px;
|
||||
margin-left: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .notch {
|
||||
height: 210px;
|
||||
width: 30px;
|
||||
left: 26px;
|
||||
bottom: 108px;
|
||||
top: auto;
|
||||
border-top-right-radius: 24px;
|
||||
border-bottom-right-radius: 24px;
|
||||
border-bottom-left-radius: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .notch:before,
|
||||
.marvel-device.iphone-x.landscape .notch:after {
|
||||
left: 0
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .notch:after {
|
||||
background: radial-gradient(circle at bottom right, transparent 0, transparent 70%, black 70%, black 100%);
|
||||
bottom: -8px;
|
||||
top: auto
|
||||
}
|
||||
|
||||
.marvel-device.iphone-x.landscape .notch:before {
|
||||
background: radial-gradient(circle at top right, transparent 0, transparent 70%, black 70%, black 100%);
|
||||
top: -8px
|
||||
}
|
||||
|
||||
.marvel-device.note8 {
|
||||
width: 400px;
|
||||
height: 822px;
|
||||
background: black;
|
||||
border-radius: 34px;
|
||||
padding: 45px 10px
|
||||
}
|
||||
|
||||
.marvel-device.note8 .overflow {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 34px;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.marvel-device.note8 .speaker {
|
||||
height: 8px;
|
||||
width: 56px;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
margin-left: -28px;
|
||||
background: #171818;
|
||||
z-index: 1;
|
||||
border-radius: 8px
|
||||
}
|
||||
|
||||
.marvel-device.note8 .camera {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
left: 86px;
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
background: #212b36;
|
||||
z-index: 1;
|
||||
border-radius: 100%
|
||||
}
|
||||
|
||||
.marvel-device.note8 .camera:before {
|
||||
content: '';
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
left: -22px;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
background: #212b36;
|
||||
z-index: 1;
|
||||
border-radius: 100%
|
||||
}
|
||||
|
||||
.marvel-device.note8 .sensors {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
left: 120px;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
background: #1d233b;
|
||||
z-index: 1;
|
||||
border-radius: 100%
|
||||
}
|
||||
|
||||
.marvel-device.note8 .sensors:before {
|
||||
content: '';
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
left: 18px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background: #1d233b;
|
||||
z-index: 1;
|
||||
border-radius: 100%
|
||||
}
|
||||
|
||||
.marvel-device.note8 .more-sensors {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 285px;
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
background: #33244a;
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.1);
|
||||
z-index: 1;
|
||||
border-radius: 100%
|
||||
}
|
||||
|
||||
.marvel-device.note8 .more-sensors:before {
|
||||
content: '';
|
||||
height: 11px;
|
||||
width: 11px;
|
||||
left: 40px;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
background: #214a61;
|
||||
z-index: 1;
|
||||
border-radius: 100%
|
||||
}
|
||||
|
||||
.marvel-device.note8 .sleep {
|
||||
width: 2px;
|
||||
height: 56px;
|
||||
background: black;
|
||||
position: absolute;
|
||||
top: 288px;
|
||||
right: -2px
|
||||
}
|
||||
|
||||
.marvel-device.note8 .volume {
|
||||
width: 2px;
|
||||
height: 120px;
|
||||
background: black;
|
||||
position: absolute;
|
||||
top: 168px;
|
||||
left: -2px
|
||||
}
|
||||
|
||||
.marvel-device.note8 .volume:before {
|
||||
content: '';
|
||||
top: 168px;
|
||||
width: 2px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
background: black;
|
||||
height: 56px
|
||||
}
|
||||
|
||||
.marvel-device.note8 .inner {
|
||||
width: 100%;
|
||||
height: calc(100% - 8px);
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
content: '';
|
||||
left: 0px;
|
||||
border-radius: 34px;
|
||||
border-top: 2px solid #9fa0a2;
|
||||
border-bottom: 2px solid #9fa0a2;
|
||||
background: black;
|
||||
z-index: 1;
|
||||
-webkit-box-shadow: inset 0 0 6px 0 rgba(255, 255, 255, 0.5);
|
||||
box-shadow: inset 0 0 6px 0 rgba(255, 255, 255, 0.5)
|
||||
}
|
||||
|
||||
.marvel-device.note8 .shadow {
|
||||
-webkit-box-shadow: inset 0 0 60px 0 white, inset 0 0 30px 0 rgba(255, 255, 255, 0.5), 0 0 20px 0 white, 0 0 20px 0 rgba(255, 255, 255, 0.5);
|
||||
box-shadow: inset 0 0 60px 0 white, inset 0 0 30px 0 rgba(255, 255, 255, 0.5), 0 0 20px 0 white, 0 0 20px 0 rgba(255, 255, 255, 0.5);
|
||||
height: 101%;
|
||||
position: absolute;
|
||||
top: -0.5%;
|
||||
content: '';
|
||||
width: calc(100% - 20px);
|
||||
left: 10px;
|
||||
border-radius: 38px;
|
||||
z-index: 5;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.marvel-device.note8 .screen {
|
||||
border-radius: 14px;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape {
|
||||
height: 400px;
|
||||
width: 822px;
|
||||
padding: 10px 45px
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .speaker {
|
||||
height: 56px;
|
||||
width: 8px;
|
||||
top: 50%;
|
||||
margin-top: -28px;
|
||||
margin-left: 0;
|
||||
right: 25px;
|
||||
left: auto
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .camera {
|
||||
top: 86px;
|
||||
right: 18px;
|
||||
left: auto
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .camera:before {
|
||||
top: -22px;
|
||||
left: 5px
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .sensors {
|
||||
top: 120px;
|
||||
right: 22px;
|
||||
left: auto
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .sensors:before {
|
||||
top: 18px;
|
||||
left: 0
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .more-sensors {
|
||||
top: 285px;
|
||||
right: 18px;
|
||||
left: auto
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .more-sensors:before {
|
||||
top: 40px;
|
||||
left: 4px
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .sleep {
|
||||
bottom: -2px;
|
||||
top: auto;
|
||||
right: 288px;
|
||||
width: 56px;
|
||||
height: 2px
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .volume {
|
||||
width: 120px;
|
||||
height: 2px;
|
||||
top: -2px;
|
||||
right: 168px;
|
||||
left: auto
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .volume:before {
|
||||
right: 168px;
|
||||
left: auto;
|
||||
top: 0;
|
||||
width: 56px;
|
||||
height: 2px
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .inner {
|
||||
height: 100%;
|
||||
width: calc(100% - 8px);
|
||||
left: 2px;
|
||||
top: 0;
|
||||
border-top: 0;
|
||||
border-bottom: 0;
|
||||
border-left: 2px solid #9fa0a2;
|
||||
border-right: 2px solid #9fa0a2
|
||||
}
|
||||
|
||||
.marvel-device.note8.landscape .shadow {
|
||||
width: 101%;
|
||||
height: calc(100% - 20px);
|
||||
left: -0.5%;
|
||||
top: 10px
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
@endsection
|
||||
Loading…
Reference in New Issue