Improve organization in completions.js
Also added a few new completions
This commit is contained in:
parent
1df3f4b76f
commit
d8e8c0ab25
773
completions.js
773
completions.js
|
@ -9,15 +9,18 @@ const blank = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAAAAAByaaZ
|
||||||
|
|
||||||
var completions = {};
|
var completions = {};
|
||||||
|
|
||||||
|
// ****** Arch Linux ****** //
|
||||||
|
|
||||||
|
// Arch Linux official repos
|
||||||
completions.al = {
|
completions.al = {
|
||||||
alias: 'al',
|
alias: 'al',
|
||||||
name: 'archlinux',
|
name: 'archlinux',
|
||||||
search: 'https://www.archlinux.org/packages/?arch=x86_64&q=',
|
search: 'https://www.archlinux.org/packages/?arch=x86_64&q=',
|
||||||
compl: '',
|
compl: google_cx_url('al'),
|
||||||
|
callback: google_cx_callback,
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.al.callback = function() {};
|
// Arch Linux AUR
|
||||||
|
|
||||||
completions.au = {
|
completions.au = {
|
||||||
alias: 'au',
|
alias: 'au',
|
||||||
name: 'AUR',
|
name: 'AUR',
|
||||||
|
@ -35,6 +38,7 @@ completions.au.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Arch Linux Wiki
|
||||||
completions.aw = {
|
completions.aw = {
|
||||||
alias: 'aw',
|
alias: 'aw',
|
||||||
name: 'archwiki',
|
name: 'archwiki',
|
||||||
|
@ -46,6 +50,27 @@ completions.aw.callback = function(response) {
|
||||||
Omnibar.listWords(JSON.parse(response.text)[1]);
|
Omnibar.listWords(JSON.parse(response.text)[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Arch Linux Forums
|
||||||
|
completions.af = {
|
||||||
|
alias: 'af',
|
||||||
|
name: 'archforums',
|
||||||
|
search: google_cx_publicurl('af'),
|
||||||
|
compl: google_cx_url('af'),
|
||||||
|
callback: google_cx_callback,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ****** Technical Resources ****** //
|
||||||
|
|
||||||
|
// Chrome Webstore
|
||||||
|
completions.cs = {
|
||||||
|
alias: 'cs',
|
||||||
|
name: 'chromestore',
|
||||||
|
search: 'https://chrome.google.com/webstore/search/',
|
||||||
|
compl: google_cx_url('cs'),
|
||||||
|
callback: google_cx_callback,
|
||||||
|
};
|
||||||
|
|
||||||
|
// OWASP Wiki
|
||||||
completions.ow = {
|
completions.ow = {
|
||||||
alias: 'ow',
|
alias: 'ow',
|
||||||
name: 'owasp',
|
name: 'owasp',
|
||||||
|
@ -57,6 +82,124 @@ completions.ow.callback = function(response) {
|
||||||
Omnibar.listWords(JSON.parse(response.text)[1]);
|
Omnibar.listWords(JSON.parse(response.text)[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// StackOverflow
|
||||||
|
completions.so = {
|
||||||
|
alias: 'so',
|
||||||
|
name: 'stackoverflow',
|
||||||
|
search: 'https://stackoverflow.com/search?q=',
|
||||||
|
compl: 'https://api.stackexchange.com/2.2/search/advanced?pagesize=10&order=desc&sort=relevance&site=stackoverflow&q=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.so.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text).items;
|
||||||
|
Omnibar.listResults(res, function(s) {
|
||||||
|
return Omnibar.createURLItem({
|
||||||
|
title: "[" + s.score + "] " + s.title,
|
||||||
|
url: s.link
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// DockerHub repo search
|
||||||
|
completions.dh = {
|
||||||
|
alias: 'dh',
|
||||||
|
name: 'dockerhub',
|
||||||
|
search: 'https://hub.docker.com/search/?page=1&q=',
|
||||||
|
compl: 'https://hub.docker.com/v2/search/repositories/?page_size=20&query=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.dh.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text);
|
||||||
|
Omnibar.listResults(res.results, function(s) {
|
||||||
|
var meta = ""
|
||||||
|
, repo = s.repo_name;
|
||||||
|
meta += "[★" + s.star_count + "] ";
|
||||||
|
meta += "[↓" + s.pull_count + "] ";
|
||||||
|
if (repo.indexOf("/") === -1) {
|
||||||
|
repo = "_/" + repo;
|
||||||
|
}
|
||||||
|
var li = $('<li/>').html(`
|
||||||
|
<div>
|
||||||
|
<div class="title"><strong>${s.repo_name}</strong></div>
|
||||||
|
<div>${meta}</div>
|
||||||
|
<div>${s.short_description}</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
li.data('url', "https://hub.docker.com/r/" + repo);
|
||||||
|
return li;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// GitHub
|
||||||
|
completions.gh = {
|
||||||
|
alias: 'gh',
|
||||||
|
name: 'github',
|
||||||
|
search: 'https://github.com/search?q=',
|
||||||
|
compl: 'https://api.github.com/search/repositories?sort=stars&order=desc&q=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.gh.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text).items;
|
||||||
|
Omnibar.listResults(res, function(s) {
|
||||||
|
var prefix = "";
|
||||||
|
if (s.stargazers_count) {
|
||||||
|
prefix += "[★" + s.stargazers_count + "] ";
|
||||||
|
}
|
||||||
|
return Omnibar.createURLItem({
|
||||||
|
title: prefix + s.full_name,
|
||||||
|
url: s.html_url
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Domainr domain search
|
||||||
|
completions.do = {
|
||||||
|
alias: 'do',
|
||||||
|
name: 'domainr',
|
||||||
|
search: 'https://domainr.com/?q=',
|
||||||
|
compl: `https://api.domainr.com/v2/search?client_id=${keys.domainr}&query=%s`,
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.do.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text).results;
|
||||||
|
var domains = [];
|
||||||
|
res.map(function(r){
|
||||||
|
var d = {
|
||||||
|
id: r.domain.replace('.', '-'),
|
||||||
|
domain: r.domain
|
||||||
|
};
|
||||||
|
domains.push(d);
|
||||||
|
});
|
||||||
|
|
||||||
|
var domainQuery = domains.map(function(d) { return d.domain; }).join(',');
|
||||||
|
|
||||||
|
runtime.command({
|
||||||
|
action: 'request',
|
||||||
|
method: 'get',
|
||||||
|
url: `https://api.domainr.com/v2/status?client_id=${keys.domainr}&domain=${domainQuery}`
|
||||||
|
}, function(sresponse) {
|
||||||
|
var sres = JSON.parse(sresponse.text).status;
|
||||||
|
sres.map(function(s) {
|
||||||
|
var id = "#sk-domain-" + s.domain.replace('.', '-')
|
||||||
|
, available = s.summary === "inactive"
|
||||||
|
, color = available ? "#23b000" : "#ff4d00"
|
||||||
|
, symbol = available ? "✔ " : "✘ ";
|
||||||
|
$(id).text(symbol + $(id).text()).css("color", color);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Omnibar.listResults(domains, function(d) {
|
||||||
|
var li = $('<li/>').html(`
|
||||||
|
<div id="sk-domain-${d.id}">
|
||||||
|
<div class="title"><strong>${d.domain}</strong></div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
li.data('url', `https://domainr.com/${d.domain}`);
|
||||||
|
return li;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vim Wiki
|
||||||
completions.vw = {
|
completions.vw = {
|
||||||
alias: 'vw',
|
alias: 'vw',
|
||||||
name: 'vimwikia',
|
name: 'vimwikia',
|
||||||
|
@ -68,6 +211,9 @@ completions.vw.callback = function(response) {
|
||||||
Omnibar.listWords(JSON.parse(response.text)[1]);
|
Omnibar.listWords(JSON.parse(response.text)[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ****** Shopping & Food ****** //
|
||||||
|
|
||||||
|
// Amazon
|
||||||
completions.az = {
|
completions.az = {
|
||||||
alias: 'az',
|
alias: 'az',
|
||||||
name: 'amazon',
|
name: 'amazon',
|
||||||
|
@ -80,6 +226,7 @@ completions.az.callback = function(response) {
|
||||||
Omnibar.listWords(res);
|
Omnibar.listWords(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Craigslist
|
||||||
completions.cl = {
|
completions.cl = {
|
||||||
alias: 'cl',
|
alias: 'cl',
|
||||||
name: 'craigslist',
|
name: 'craigslist',
|
||||||
|
@ -91,6 +238,112 @@ completions.cl.callback = function(response) {
|
||||||
Omnibar.listWords(JSON.parse(response.text));
|
Omnibar.listWords(JSON.parse(response.text));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Yelp
|
||||||
|
completions.yp = {
|
||||||
|
alias: 'yp',
|
||||||
|
name: 'yelp',
|
||||||
|
search: 'https://www.yelp.com/search?find_desc=',
|
||||||
|
compl: 'https://www.yelp.com/search_suggest/v2/prefetch?prefix=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.yp.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text).response;
|
||||||
|
var words = [];
|
||||||
|
res.map(function(r){
|
||||||
|
r.suggestions.map(function(s) {
|
||||||
|
var w = s.query;
|
||||||
|
if (words.indexOf(w) === -1) {
|
||||||
|
words.push(w);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Omnibar.listWords(words);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ****** General References, Calculators & Utilities ****** //
|
||||||
|
|
||||||
|
// Dictionary
|
||||||
|
completions.de = {
|
||||||
|
alias: 'de',
|
||||||
|
name: 'define',
|
||||||
|
search: 'http://onelook.com/?w=',
|
||||||
|
compl: 'https://api.datamuse.com/words?md=d&sp=%s*',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.de.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text);
|
||||||
|
var defs = [];
|
||||||
|
res.map(function(r){
|
||||||
|
if (!r.defs || r.defs.length === 0) {
|
||||||
|
defs.push([r.word, "", ""]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r.defs.map(function(d) {
|
||||||
|
d = d.split("\t");
|
||||||
|
|
||||||
|
var sp = "(" + d[0] + ")",
|
||||||
|
def = d[1];
|
||||||
|
|
||||||
|
defs.push([r.word, sp, def]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Omnibar.listResults(defs, function(d) {
|
||||||
|
var li = $('<li/>').html(`<div class="title"><strong>${d[0]}</strong> <em>${d[1]}</em> ${d[2]}</div>`);
|
||||||
|
li.data('url', "http://onelook.com/?w=" + d[0]);
|
||||||
|
return li;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Thesaurus
|
||||||
|
completions.th = {
|
||||||
|
alias: 'th',
|
||||||
|
name: 'thesaurus',
|
||||||
|
search: 'https://www.onelook.com/reverse-dictionary.shtml?s=',
|
||||||
|
compl: 'https://api.datamuse.com/words?md=d&ml=%s',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.th.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text);
|
||||||
|
var defs = [];
|
||||||
|
res.map(function(r){
|
||||||
|
if (!r.defs || r.defs.length === 0) {
|
||||||
|
defs.push([r.word, "", ""]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r.defs.map(function(d) {
|
||||||
|
d = d.split("\t");
|
||||||
|
|
||||||
|
var sp = "(" + d[0] + ")",
|
||||||
|
def = d[1];
|
||||||
|
|
||||||
|
defs.push([r.word, sp, def]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Omnibar.listResults(defs, function(d) {
|
||||||
|
var li = $('<li/>').html(`<div class="title"><strong>${d[0]}</strong> <em>${d[1]}</em> ${d[2]}</div>`);
|
||||||
|
li.data('url', "http://onelook.com/?w=" + d[0]);
|
||||||
|
return li;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wikipedia
|
||||||
|
completions.wp = {
|
||||||
|
alias: 'wp',
|
||||||
|
name: 'wikipedia',
|
||||||
|
search: 'https://en.wikipedia.org/w/index.php?search=',
|
||||||
|
compl: 'https://en.wikipedia.org/w/api.php?action=query&format=json&list=prefixsearch&utf8&pssearch=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.wp.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text).query.prefixsearch
|
||||||
|
.map(function(r){
|
||||||
|
return r.title;
|
||||||
|
});
|
||||||
|
Omnibar.listWords(res);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// WolframAlpha
|
||||||
completions.wa = {
|
completions.wa = {
|
||||||
alias: 'wa',
|
alias: 'wa',
|
||||||
name: 'wolframalpha',
|
name: 'wolframalpha',
|
||||||
|
@ -176,6 +429,9 @@ completions.wa.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ****** Business Utilities & References ****** //
|
||||||
|
|
||||||
|
// Crunchbase Organization Search
|
||||||
completions.co = {
|
completions.co = {
|
||||||
alias: 'co',
|
alias: 'co',
|
||||||
name: 'crunchbase-orgs',
|
name: 'crunchbase-orgs',
|
||||||
|
@ -234,6 +490,7 @@ completions.co.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Crunchbase People Search
|
||||||
completions.cp = {
|
completions.cp = {
|
||||||
alias: 'cp',
|
alias: 'cp',
|
||||||
name: 'crunchbase-people',
|
name: 'crunchbase-people',
|
||||||
|
@ -294,77 +551,9 @@ completions.cp.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.cs = {
|
// ****** Search Engines ****** //
|
||||||
alias: 'cs',
|
|
||||||
name: 'chromestore',
|
|
||||||
search: 'https://chrome.google.com/webstore/search/',
|
|
||||||
compl: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.cs.callback = function() {};
|
|
||||||
|
|
||||||
completions.th = {
|
|
||||||
alias: 'th',
|
|
||||||
name: 'thesaurus',
|
|
||||||
search: 'https://www.onelook.com/reverse-dictionary.shtml?s=',
|
|
||||||
compl: 'https://api.datamuse.com/words?md=d&ml=%s',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.th.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text);
|
|
||||||
var defs = [];
|
|
||||||
res.map(function(r){
|
|
||||||
if (!r.defs || r.defs.length === 0) {
|
|
||||||
defs.push([r.word, "", ""]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r.defs.map(function(d) {
|
|
||||||
d = d.split("\t");
|
|
||||||
|
|
||||||
var sp = "(" + d[0] + ")",
|
|
||||||
def = d[1];
|
|
||||||
|
|
||||||
defs.push([r.word, sp, def]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Omnibar.listResults(defs, function(d) {
|
|
||||||
var li = $('<li/>').html(`<div class="title"><strong>${d[0]}</strong> <em>${d[1]}</em> ${d[2]}</div>`);
|
|
||||||
li.data('url', "http://onelook.com/?w=" + d[0]);
|
|
||||||
return li;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.de = {
|
|
||||||
alias: 'de',
|
|
||||||
name: 'define',
|
|
||||||
search: 'http://onelook.com/?w=',
|
|
||||||
compl: 'https://api.datamuse.com/words?md=d&sp=%s*',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.de.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text);
|
|
||||||
var defs = [];
|
|
||||||
res.map(function(r){
|
|
||||||
if (!r.defs || r.defs.length === 0) {
|
|
||||||
defs.push([r.word, "", ""]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r.defs.map(function(d) {
|
|
||||||
d = d.split("\t");
|
|
||||||
|
|
||||||
var sp = "(" + d[0] + ")",
|
|
||||||
def = d[1];
|
|
||||||
|
|
||||||
defs.push([r.word, sp, def]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Omnibar.listResults(defs, function(d) {
|
|
||||||
var li = $('<li/>').html(`<div class="title"><strong>${d[0]}</strong> <em>${d[1]}</em> ${d[2]}</div>`);
|
|
||||||
li.data('url', "http://onelook.com/?w=" + d[0]);
|
|
||||||
return li;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// DuckDuckGo
|
||||||
completions.dg = {
|
completions.dg = {
|
||||||
alias: 'dg',
|
alias: 'dg',
|
||||||
name: 'duckduckgo',
|
name: 'duckduckgo',
|
||||||
|
@ -379,86 +568,118 @@ completions.dg.callback = function(response) {
|
||||||
Omnibar.listWords(res);
|
Omnibar.listWords(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.dh = {
|
// Google
|
||||||
alias: 'dh',
|
completions.go = {
|
||||||
name: 'dockerhub',
|
alias: 'go',
|
||||||
search: 'https://hub.docker.com/search/?page=1&q=',
|
name: 'google',
|
||||||
compl: 'https://hub.docker.com/v2/search/repositories/?page_size=20&query=',
|
search: 'https://www.google.com/search?q=',
|
||||||
|
compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=',
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.dh.callback = function(response) {
|
completions.go.callback = function(response) {
|
||||||
|
Omnibar.listWords(JSON.parse(response.text)[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Google - I'm Feeling Lucky
|
||||||
|
completions.gl = {
|
||||||
|
alias: 'gl',
|
||||||
|
name: 'google-lucky',
|
||||||
|
search: 'https://www.google.com/search?btnI=1&q=',
|
||||||
|
compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.gl.callback = function(response) {
|
||||||
|
Omnibar.listWords(JSON.parse(response.text)[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ****** Elixir ****** //
|
||||||
|
|
||||||
|
// Hex.pm
|
||||||
|
completions.hx = {
|
||||||
|
alias: 'hx',
|
||||||
|
name: 'hex',
|
||||||
|
search: 'https://hex.pm/packages?sort=downloads&search=',
|
||||||
|
compl: 'https://hex.pm/api/packages?sort=downloads&search=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.hx.callback = function(response) {
|
||||||
var res = JSON.parse(response.text);
|
var res = JSON.parse(response.text);
|
||||||
Omnibar.listResults(res.results, function(s) {
|
Omnibar.listResults(res, function(s) {
|
||||||
var meta = ""
|
var dls = ""
|
||||||
, repo = s.repo_name;
|
, desc = ""
|
||||||
meta += "[★" + s.star_count + "] ";
|
, liscs = "";
|
||||||
meta += "[↓" + s.pull_count + "] ";
|
if (s.downloads && s.downloads.all) {
|
||||||
if (repo.indexOf("/") === -1) {
|
dls = "[↓" + s.downloads.all + "] ";
|
||||||
repo = "_/" + repo;
|
}
|
||||||
|
if(s.meta) {
|
||||||
|
if (s.meta.description) {
|
||||||
|
desc = s.meta.description;
|
||||||
|
}
|
||||||
|
if (s.meta.licenses) {
|
||||||
|
s.meta.licenses.forEach(function(l) {
|
||||||
|
liscs += "[©" + l + "] ";
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var li = $('<li/>').html(`
|
var li = $('<li/>').html(`
|
||||||
<div>
|
<div>
|
||||||
<div class="title"><strong>${s.repo_name}</strong></div>
|
<div class="title">${s.repository}/<strong>${s.name}</strong></div>
|
||||||
<div>${meta}</div>
|
<div>${dls}${liscs}</div>
|
||||||
<div>${s.short_description}</div>
|
<div>${desc}</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
li.data('url', "https://hub.docker.com/r/" + repo);
|
li.data('url', s.html_url);
|
||||||
return li;
|
return li;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.do = {
|
// hexdocs
|
||||||
alias: 'do',
|
// Same as hex but links to documentation pages
|
||||||
name: 'domainr',
|
completions.hd = {
|
||||||
search: 'https://domainr.com/?q=',
|
alias: 'hd',
|
||||||
compl: `https://api.domainr.com/v2/search?client_id=${keys.domainr}&query=%s`,
|
name: 'hexdocs',
|
||||||
|
search: 'https://hex.pm/packages?sort=downloads&search=',
|
||||||
|
compl: 'https://hex.pm/api/packages?sort=downloads&search=',
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.do.callback = function(response) {
|
completions.hd.callback = function(response) {
|
||||||
var res = JSON.parse(response.text).results;
|
var res = JSON.parse(response.text);
|
||||||
var domains = [];
|
Omnibar.listResults(res, function(s) {
|
||||||
res.map(function(r){
|
var dls = ""
|
||||||
var d = {
|
, desc = ""
|
||||||
id: r.domain.replace('.', '-'),
|
, liscs = "";
|
||||||
domain: r.domain
|
if (s.downloads && s.downloads.all) {
|
||||||
};
|
dls = "[↓" + s.downloads.all + "]";
|
||||||
domains.push(d);
|
}
|
||||||
|
if(s.meta) {
|
||||||
|
if (s.meta.description) {
|
||||||
|
desc = s.meta.description;
|
||||||
|
}
|
||||||
|
if (s.meta.licenses) {
|
||||||
|
s.meta.licenses.forEach(function(l) {
|
||||||
|
liscs += "[©" + l + "] ";
|
||||||
});
|
});
|
||||||
|
}
|
||||||
var domainQuery = domains.map(function(d) { return d.domain; }).join(',');
|
}
|
||||||
|
|
||||||
runtime.command({
|
|
||||||
action: 'request',
|
|
||||||
method: 'get',
|
|
||||||
url: `https://api.domainr.com/v2/status?client_id=${keys.domainr}&domain=${domainQuery}`
|
|
||||||
}, function(sresponse) {
|
|
||||||
var sres = JSON.parse(sresponse.text).status;
|
|
||||||
sres.map(function(s) {
|
|
||||||
var id = "#sk-domain-" + s.domain.replace('.', '-')
|
|
||||||
, available = s.summary === "inactive"
|
|
||||||
, color = available ? "#23b000" : "#ff4d00"
|
|
||||||
, symbol = available ? "✔ " : "✘ ";
|
|
||||||
$(id).text(symbol + $(id).text()).css("color", color);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Omnibar.listResults(domains, function(d) {
|
|
||||||
var li = $('<li/>').html(`
|
var li = $('<li/>').html(`
|
||||||
<div id="sk-domain-${d.id}">
|
<div>
|
||||||
<div class="title"><strong>${d.domain}</strong></div>
|
<div class="title">${s.repository}/<strong>${s.name}</strong></div>
|
||||||
|
<div>${dls}${liscs}</div>
|
||||||
|
<div>${desc}</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
li.data('url', `https://domainr.com/${d.domain}`);
|
li.data('url', "https://hexdocs.pm/" + s.name);
|
||||||
return li;
|
return li;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Exdocs
|
||||||
|
// Similar to `hd` but searches inside docs using Google Custom Search
|
||||||
completions.ex = {
|
completions.ex = {
|
||||||
alias: 'ex', // Similar to `hd` but searches inside docs using Google Custom Search,
|
alias: 'ex',
|
||||||
name: 'exdocs',
|
name: 'exdocs',
|
||||||
search: 'https://hex.pm/packages?sort=downloads&search=',
|
search: 'https://hex.pm/packages?sort=downloads&search=',
|
||||||
compl: `https://www.googleapis.com/customsearch/v1?key=${keys.google_ex}&cx=${keys.google_ex_cx}&q=`,
|
compl: google_cx_url('ex'),
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.ex.callback = function(response) {
|
completions.ex.callback = function(response) {
|
||||||
|
@ -528,6 +749,9 @@ completions.ex.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ****** Golang ****** //
|
||||||
|
|
||||||
|
// Godoc
|
||||||
completions.gd = {
|
completions.gd = {
|
||||||
alias: 'gd',
|
alias: 'gd',
|
||||||
name: 'godoc',
|
name: 'godoc',
|
||||||
|
@ -552,49 +776,7 @@ completions.gd.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.gh = {
|
// Go-Search
|
||||||
alias: 'gh',
|
|
||||||
name: 'github',
|
|
||||||
search: 'https://github.com/search?q=',
|
|
||||||
compl: 'https://api.github.com/search/repositories?sort=stars&order=desc&q=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.gh.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text).items;
|
|
||||||
Omnibar.listResults(res, function(s) {
|
|
||||||
var prefix = "";
|
|
||||||
if (s.stargazers_count) {
|
|
||||||
prefix += "[★" + s.stargazers_count + "] ";
|
|
||||||
}
|
|
||||||
return Omnibar.createURLItem({
|
|
||||||
title: prefix + s.full_name,
|
|
||||||
url: s.html_url
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.go = {
|
|
||||||
alias: 'go',
|
|
||||||
name: 'google',
|
|
||||||
search: 'https://www.google.com/search?q=',
|
|
||||||
compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.go.callback = function(response) {
|
|
||||||
Omnibar.listWords(JSON.parse(response.text)[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.gl = {
|
|
||||||
alias: 'gl',
|
|
||||||
name: 'google-lucky',
|
|
||||||
search: 'https://www.google.com/search?btnI=1&q=',
|
|
||||||
compl: 'https://www.google.com/complete/search?client=chrome-omni&gs_ri=chrome-ext&oit=1&cp=1&pgcl=7&q=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.gl.callback = function(response) {
|
|
||||||
Omnibar.listWords(JSON.parse(response.text)[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.gs = {
|
completions.gs = {
|
||||||
alias: 'gs',
|
alias: 'gs',
|
||||||
name: 'go-search',
|
name: 'go-search',
|
||||||
|
@ -610,6 +792,9 @@ completions.gs.callback = function(response) {
|
||||||
Omnibar.listWords(res);
|
Omnibar.listWords(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ****** Haskell ****** //
|
||||||
|
|
||||||
|
// Hackage
|
||||||
completions.ha = {
|
completions.ha = {
|
||||||
alias: 'ha',
|
alias: 'ha',
|
||||||
name: 'hackage',
|
name: 'hackage',
|
||||||
|
@ -627,79 +812,7 @@ completions.ha.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.hd = {
|
// Hoogle
|
||||||
alias: 'hd', // Same as hex but links to documentation pages,
|
|
||||||
name: 'hexdocs',
|
|
||||||
search: 'https://hex.pm/packages?sort=downloads&search=',
|
|
||||||
compl: 'https://hex.pm/api/packages?sort=downloads&search=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.hd.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text);
|
|
||||||
Omnibar.listResults(res, function(s) {
|
|
||||||
var dls = ""
|
|
||||||
, desc = ""
|
|
||||||
, liscs = "";
|
|
||||||
if (s.downloads && s.downloads.all) {
|
|
||||||
dls = "[↓" + s.downloads.all + "]";
|
|
||||||
}
|
|
||||||
if(s.meta) {
|
|
||||||
if (s.meta.description) {
|
|
||||||
desc = s.meta.description;
|
|
||||||
}
|
|
||||||
if (s.meta.licenses) {
|
|
||||||
s.meta.licenses.forEach(function(l) {
|
|
||||||
liscs += "[©" + l + "] ";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var li = $('<li/>').html(`
|
|
||||||
<div>
|
|
||||||
<div class="title">${s.repository}/<strong>${s.name}</strong></div>
|
|
||||||
<div>${dls}${liscs}</div>
|
|
||||||
<div>${desc}</div>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
li.data('url', "https://hexdocs.pm/" + s.name);
|
|
||||||
return li;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.hn = {
|
|
||||||
alias: 'hn',
|
|
||||||
name: 'hackernews',
|
|
||||||
search: 'https://hn.algolia.com/?query=',
|
|
||||||
compl: 'https://hn.algolia.com/api/v1/search?tags=(story,comment)&query=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.hn.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text).hits;
|
|
||||||
Omnibar.listResults(res, function(s) {
|
|
||||||
var title = "";
|
|
||||||
var prefix = "";
|
|
||||||
if (s.points) {
|
|
||||||
prefix += "[↑" + s.points + "] ";
|
|
||||||
}
|
|
||||||
if (s.num_comments) {
|
|
||||||
prefix += "[↲" + s.num_comments + "] ";
|
|
||||||
}
|
|
||||||
switch(s._tags[0]) {
|
|
||||||
case "story":
|
|
||||||
title = s.title;
|
|
||||||
break;
|
|
||||||
case "comment":
|
|
||||||
title = s.comment_text;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
title = s.objectID;
|
|
||||||
}
|
|
||||||
return Omnibar.createURLItem({
|
|
||||||
title: prefix + title,
|
|
||||||
url: "https://news.ycombinator.com/item?id=" + s.objectID
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.ho = {
|
completions.ho = {
|
||||||
alias: 'ho',
|
alias: 'ho',
|
||||||
name: 'hoogle',
|
name: 'hoogle',
|
||||||
|
@ -719,6 +832,7 @@ completions.ho.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Haskell Wiki
|
||||||
completions.hw = {
|
completions.hw = {
|
||||||
alias: 'hw',
|
alias: 'hw',
|
||||||
name: 'haskellwiki',
|
name: 'haskellwiki',
|
||||||
|
@ -730,44 +844,7 @@ completions.hw.callback = function(response) {
|
||||||
Omnibar.listWords(JSON.parse(response.text)[1]);
|
Omnibar.listWords(JSON.parse(response.text)[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.hx = {
|
// Hayoo
|
||||||
alias: 'hx',
|
|
||||||
name: 'hex',
|
|
||||||
search: 'https://hex.pm/packages?sort=downloads&search=',
|
|
||||||
compl: 'https://hex.pm/api/packages?sort=downloads&search=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.hx.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text);
|
|
||||||
Omnibar.listResults(res, function(s) {
|
|
||||||
var dls = ""
|
|
||||||
, desc = ""
|
|
||||||
, liscs = "";
|
|
||||||
if (s.downloads && s.downloads.all) {
|
|
||||||
dls = "[↓" + s.downloads.all + "] ";
|
|
||||||
}
|
|
||||||
if(s.meta) {
|
|
||||||
if (s.meta.description) {
|
|
||||||
desc = s.meta.description;
|
|
||||||
}
|
|
||||||
if (s.meta.licenses) {
|
|
||||||
s.meta.licenses.forEach(function(l) {
|
|
||||||
liscs += "[©" + l + "] ";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var li = $('<li/>').html(`
|
|
||||||
<div>
|
|
||||||
<div class="title">${s.repository}/<strong>${s.name}</strong></div>
|
|
||||||
<div>${dls}${liscs}</div>
|
|
||||||
<div>${desc}</div>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
li.data('url', s.html_url);
|
|
||||||
return li;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.hy = {
|
completions.hy = {
|
||||||
alias: 'hy',
|
alias: 'hy',
|
||||||
name: 'hayoo',
|
name: 'hayoo',
|
||||||
|
@ -785,6 +862,18 @@ completions.hy.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ****** HTML, CSS, JavaScript, NodeJS, ... ****** //
|
||||||
|
|
||||||
|
// NodeJS standard library documentation
|
||||||
|
completions.no = {
|
||||||
|
alias: 'no',
|
||||||
|
name: 'node',
|
||||||
|
search: google_cx_publicurl('no'),
|
||||||
|
compl: google_cx_url('no'),
|
||||||
|
callback: google_cx_callback,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mozilla Developer Network (MDN)
|
||||||
completions.md = {
|
completions.md = {
|
||||||
alias: 'md',
|
alias: 'md',
|
||||||
name: 'mdn',
|
name: 'mdn',
|
||||||
|
@ -814,6 +903,7 @@ completions.md.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NPM registry search
|
||||||
completions.np = {
|
completions.np = {
|
||||||
alias: 'np',
|
alias: 'np',
|
||||||
name: 'npm',
|
name: 'npm',
|
||||||
|
@ -861,6 +951,45 @@ completions.np.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ****** Social Media & Entertainment ****** //
|
||||||
|
|
||||||
|
// Hacker News (YCombinator)
|
||||||
|
completions.hn = {
|
||||||
|
alias: 'hn',
|
||||||
|
name: 'hackernews',
|
||||||
|
search: 'https://hn.algolia.com/?query=',
|
||||||
|
compl: 'https://hn.algolia.com/api/v1/search?tags=(story,comment)&query=',
|
||||||
|
};
|
||||||
|
|
||||||
|
completions.hn.callback = function(response) {
|
||||||
|
var res = JSON.parse(response.text).hits;
|
||||||
|
Omnibar.listResults(res, function(s) {
|
||||||
|
var title = "";
|
||||||
|
var prefix = "";
|
||||||
|
if (s.points) {
|
||||||
|
prefix += "[↑" + s.points + "] ";
|
||||||
|
}
|
||||||
|
if (s.num_comments) {
|
||||||
|
prefix += "[↲" + s.num_comments + "] ";
|
||||||
|
}
|
||||||
|
switch(s._tags[0]) {
|
||||||
|
case "story":
|
||||||
|
title = s.title;
|
||||||
|
break;
|
||||||
|
case "comment":
|
||||||
|
title = s.comment_text;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
title = s.objectID;
|
||||||
|
}
|
||||||
|
return Omnibar.createURLItem({
|
||||||
|
title: prefix + title,
|
||||||
|
url: "https://news.ycombinator.com/item?id=" + s.objectID
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reddit
|
||||||
completions.re = {
|
completions.re = {
|
||||||
alias: 're',
|
alias: 're',
|
||||||
name: 'reddit',
|
name: 'reddit',
|
||||||
|
@ -879,59 +1008,7 @@ completions.re.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
completions.so = {
|
// YouTube
|
||||||
alias: 'so',
|
|
||||||
name: 'stackoverflow',
|
|
||||||
search: 'https://stackoverflow.com/search?q=',
|
|
||||||
compl: 'https://api.stackexchange.com/2.2/search/advanced?pagesize=10&order=desc&sort=relevance&site=stackoverflow&q=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.so.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text).items;
|
|
||||||
Omnibar.listResults(res, function(s) {
|
|
||||||
return Omnibar.createURLItem({
|
|
||||||
title: "[" + s.score + "] " + s.title,
|
|
||||||
url: s.link
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.wp = {
|
|
||||||
alias: 'wp',
|
|
||||||
name: 'wikipedia',
|
|
||||||
search: 'https://en.wikipedia.org/w/index.php?search=',
|
|
||||||
compl: 'https://en.wikipedia.org/w/api.php?action=query&format=json&list=prefixsearch&utf8&pssearch=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.wp.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text).query.prefixsearch
|
|
||||||
.map(function(r){
|
|
||||||
return r.title;
|
|
||||||
});
|
|
||||||
Omnibar.listWords(res);
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.yp = {
|
|
||||||
alias: 'yp',
|
|
||||||
name: 'yelp',
|
|
||||||
search: 'https://www.yelp.com/search?find_desc=',
|
|
||||||
compl: 'https://www.yelp.com/search_suggest/v2/prefetch?prefix=',
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.yp.callback = function(response) {
|
|
||||||
var res = JSON.parse(response.text).response;
|
|
||||||
var words = [];
|
|
||||||
res.map(function(r){
|
|
||||||
r.suggestions.map(function(s) {
|
|
||||||
var w = s.query;
|
|
||||||
if (words.indexOf(w) === -1) {
|
|
||||||
words.push(w);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Omnibar.listWords(words);
|
|
||||||
};
|
|
||||||
|
|
||||||
completions.yt = {
|
completions.yt = {
|
||||||
alias: 'yt',
|
alias: 'yt',
|
||||||
name: 'youtube',
|
name: 'youtube',
|
||||||
|
@ -957,6 +1034,32 @@ completions.yt.callback = function(response) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ****** Helper Functions ****** //
|
||||||
|
|
||||||
|
function google_cx_callback(response) {
|
||||||
|
var res = JSON.parse(response.text).items;
|
||||||
|
Omnibar.listResults(res, function(s) {
|
||||||
|
var li = $('<li/>').html(`
|
||||||
|
<div>
|
||||||
|
<div class="title"><strong>${s.htmlTitle}</strong></div>
|
||||||
|
<div>${s.htmlSnippet}</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
li.data('url', s.link);
|
||||||
|
return li;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function google_cx_url(alias) {
|
||||||
|
var key = `google_cx_${alias}`;
|
||||||
|
return `https://www.googleapis.com/customsearch/v1?key=${keys.google_cs}&cx=${keys[key]}&q=`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function google_cx_publicurl(alias) {
|
||||||
|
var key = `google_cx_${alias}`;
|
||||||
|
return `https://cse.google.com/cse/publicurl?cx=${keys[key]}&q=`;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||||
module.exports = completions;
|
module.exports = completions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,6 @@
|
||||||
// Copy this file to a new file named "conf.priv.js" and update
|
// Copy this file to a new file named "conf.priv.js" and update
|
||||||
// the API keys as needed.
|
// the API keys as needed.
|
||||||
//
|
//
|
||||||
// You can also place any additional variables here and they will
|
|
||||||
// be included before the rest of your configuration script.
|
|
||||||
// Running `gulp build` will generate the final configuration by concatenating
|
|
||||||
// this file with your main configuration file.
|
|
||||||
//
|
|
||||||
// WARNING: Don't `git commit` your actual "conf.priv.js" file if you
|
// WARNING: Don't `git commit` your actual "conf.priv.js" file if you
|
||||||
// add real API keys to it! Malicious parties frequently scan GitHub for
|
// add real API keys to it! Malicious parties frequently scan GitHub for
|
||||||
// these keys and use them for bad stuff. The "conf.priv.js" file is already
|
// these keys and use them for bad stuff. The "conf.priv.js" file is already
|
||||||
|
@ -15,16 +10,32 @@
|
||||||
|
|
||||||
// These are private API keys which are required for certain search completions.
|
// These are private API keys which are required for certain search completions.
|
||||||
// You can obtain them all for free at the supplied links.
|
// You can obtain them all for free at the supplied links.
|
||||||
//
|
var keys = {
|
||||||
|
crunchbase: "", // https://about.crunchbase.com/crunchbase-basic-access/
|
||||||
|
google_cs: "", // https://developers.google.com/custom-search/json-api/v1/overview?hl=en_US
|
||||||
|
google_yt: "", // https://developers.google.com/youtube/v3/docs/
|
||||||
|
wolframalpha: "", // https://products.wolframalpha.com/api/
|
||||||
|
|
||||||
// Note:
|
// Note:
|
||||||
// The Domainr API is configured for High-Volume usage, not Mashape.
|
// The Domainr API is configured for High-Volume usage, not Mashape.
|
||||||
// You will need to modify the code in completions.js to work with the Mashape API if desired.
|
// You will need to modify the code in completions.js to work with the Mashape API if desired.
|
||||||
// Open an issue if you can't figure this out and I'll help out.
|
// Open an issue if you can't figure this out and I'd be happy to help.
|
||||||
var keys =
|
domainr: "", // https://domainr.build/docs/overview#section-try-it-for-free
|
||||||
{ crunchbase: "foo" // https://about.crunchbase.com/crunchbase-basic-access/
|
|
||||||
, domainr: "bar" // https://domainr.build/docs/overview#section-try-it-for-free
|
//*** Google Custom Search Engines ***//
|
||||||
, google_ex: "qux" // https://developers.google.com/custom-search/json-api/v1/overview?hl=en_US
|
// Can be created at https://cse.google.com/cse
|
||||||
, google_ex_cx: "ham" // This is the Search Engine ID (cx) from your Google Custom Search
|
// Simply create a separate Custom Search Engine for each of the following entries,
|
||||||
, google_yt: "spam" // https://developers.google.com/youtube/v3/docs/
|
// pasting the provided URL string in the "Sites to Search" field.
|
||||||
, wolframalpha: "lorem" // https://products.wolframalpha.com/api/
|
// Then, after creation, go to the control panel for the new Search Engine and copy the
|
||||||
|
// Search Engine ID (cx) into the appropriate configuration variable below:
|
||||||
|
google_cx_ex: "", // hexdocs.pm/*/master/*.html
|
||||||
|
google_cx_af: "", // bbs.archlinux.org/*
|
||||||
|
google_cx_al: "", // www.archlinux.org/packages/*/x86_64/*
|
||||||
|
google_cx_no: "", // nodejs.org/dist/latest-v9.x/docs/api/*
|
||||||
|
google_cx_cs: "", // chrome.google.com/webstore/*
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// You can place any additional private/sensitive variables here and they will
|
||||||
|
// be included before the rest of your configuration scripts.
|
||||||
|
// Running `gulp build` will generate the final configuration by concatenating
|
||||||
|
// this file with your main configuration files.
|
||||||
|
|
Loading…
Reference in New Issue