From 565aa900f3a9aaa05dc1f363688e194446143ea4 Mon Sep 17 00:00:00 2001 From: skygragon Date: Tue, 7 Nov 2017 04:46:26 -0600 Subject: [PATCH 01/48] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e5f7803..8df8b4d 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,17 @@ You can install the plugins in either ways below: ### Quick Install - $ leetcode plugin -i +Install from GitHub: + + $ leetcode plugin -i + +*Example* + + $ leetcode plugin -i company + +Install from local file: + +    $ leetcode plugin -i To manage the installed plugins, please check [leetcode-cli's user guide](https://skygragon.github.io/leetcode-cli/commands#plugin). From 36a36f97188567b3cbabb1c3c74478d81d490278 Mon Sep 17 00:00:00 2001 From: skygragon Date: Tue, 7 Nov 2017 04:47:35 -0600 Subject: [PATCH 02/48] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8df8b4d..7e795bc 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Install from GitHub: Install from local file: -    $ leetcode plugin -i +    $ leetcode plugin -i To manage the installed plugins, please check [leetcode-cli's user guide](https://skygragon.github.io/leetcode-cli/commands#plugin). From f45ef867f4da3333229003c67c9058c64481dd61 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 18 Dec 2017 11:54:11 +0800 Subject: [PATCH 03/48] [company] update list. Signed-off-by: Eric Wang --- plugins/company.js | 920 ++++++++++++++++++++++++--------------------- 1 file changed, 501 insertions(+), 419 deletions(-) diff --git a/plugins/company.js b/plugins/company.js index a383bf0..2bdf8cb 100644 --- a/plugins/company.js +++ b/plugins/company.js @@ -4,7 +4,7 @@ var Plugin = require('../plugin'); // // [config] // -var plugin = new Plugin(100, 'company', '2017.07.25', +var plugin = new Plugin(100, 'company', '2017.12.18', 'Plugin to query by company for free user.'); // NOTE: those data is collected from different websites that has similar questions: @@ -13,424 +13,506 @@ var plugin = new Plugin(100, 'company', '2017.07.25', // * 1point3acres.com // * other results from google search var DATA = { - '1': ['adobe', 'airbnb', 'amazon', 'apple', 'bloomberg', 'dropbox', 'facebook', 'linkedin', 'microsoft', 'uber', 'yahoo', 'yelp'], - '2': ['adobe', 'airbnb', 'amazon', 'bloomberg', 'microsoft'], - '3': ['adobe', 'amazon', 'bloomberg', 'yelp'], - '4': ['adobe', 'apple', 'dropbox', 'google', 'microsoft', 'yahoo', 'zenefits'], - '5': ['amazon', 'bloomberg', 'microsoft'], - '7': ['apple', 'bloomberg'], - '8': ['amazon', 'bloomberg', 'microsoft', 'uber'], - '10': ['airbnb', 'facebook', 'google', 'twitter', 'uber'], - '11': ['bloomberg'], - '12': ['twitter'], - '13': ['bloomberg', 'facebook', 'microsoft', 'uber', 'yahoo'], - '14': ['yelp'], - '15': ['adobe', 'amazon', 'bloomberg', 'facebook', 'microsoft'], - '16': ['bloomberg'], - '17': ['amazon', 'dropbox', 'facebook', 'google', 'uber'], - '18': ['linkedin'], - '20': ['airbnb', 'amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'zenefits'], - '21': ['amazon', 'apple', 'linkedin', 'microsoft'], - '22': ['google', 'uber', 'zenefits'], - '23': ['airbnb', 'amazon', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'uber'], - '24': ['bloomberg', 'microsoft', 'uber'], - '25': ['facebook', 'microsoft'], - '26': ['bloomberg', 'facebook', 'microsoft'], - '28': ['apple', 'facebook', 'microsoft', 'pocketgems'], - '31': ['google'], - '33': ['bloomberg', 'facebook', 'linkedin', 'microsoft', 'uber'], - '34': ['linkedin'], - '36': ['apple', 'snapchat', 'uber'], - '37': ['snapchat', 'uber'], - '38': ['facebook'], - '39': ['snapchat', 'uber'], - '40': ['snapchat'], - '42': ['amazon', 'apple', 'bloomberg', 'google', 'twitter', 'zenefits'], - '43': ['facebook', 'twitter'], - '44': ['facebook', 'google', 'snapchat', 'twitter', 'twosigma'], - '46': ['linkedin', 'microsoft'], - '47': ['linkedin', 'microsoft'], - '48': ['amazon', 'apple', 'microsoft'], - '49': ['amazon', 'bloomberg', 'facebook', 'uber', 'yelp'], - '50': ['bloomberg', 'facebook', 'google', 'linkedin'], - '52': ['zenefits'], - '53': ['bloomberg', 'linkedin', 'microsoft'], - '54': ['google', 'microsoft', 'uber'], - '55': ['microsoft'], - '56': ['bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'yelp'], - '57': ['facebook', 'google', 'linkedin'], - '60': ['twitter'], - '62': ['bloomberg'], - '63': ['bloomberg'], - '65': ['linkedin'], - '66': ['google'], - '67': ['facebook'], - '68': ['airbnb', 'facebook', 'linkedin'], - '69': ['apple', 'bloomberg', 'facebook'], - '70': ['adobe', 'apple'], - '71': ['facebook', 'microsoft'], - '73': ['amazon', 'microsoft'], - '75': ['facebook', 'microsoft', 'pocketgems'], - '76': ['facebook', 'linkedin', 'snapchat', 'uber'], - '78': ['amazon', 'facebook', 'uber'], - '79': ['bloomberg', 'facebook', 'microsoft'], - '80': ['facebook'], - '85': ['facebook'], - '88': ['bloomberg', 'facebook', 'microsoft'], - '89': ['amazon'], - '90': ['facebook'], - '91': ['facebook', 'microsoft', 'uber'], - '94': ['microsoft'], - '96': ['snapchat'], - '98': ['amazon', 'bloomberg', 'facebook', 'microsoft'], - '100': ['bloomberg'], - '101': ['bloomberg', 'linkedin', 'microsoft'], - '102': ['amazon', 'apple', 'bloomberg', 'facebook', 'linkedin', 'microsoft'], - '103': ['bloomberg', 'linkedin', 'microsoft'], - '104': ['apple', 'linkedin', 'uber', 'yahoo'], - '105': ['bloomberg'], - '106': ['microsoft'], - '108': ['airbnb'], - '109': ['zenefits'], - '110': ['bloomberg'], - '112': ['microsoft'], - '113': ['bloomberg'], - '114': ['microsoft'], - '116': ['microsoft'], - '117': ['bloomberg', 'facebook', 'microsoft'], - '118': ['apple', 'twitter'], - '119': ['amazon'], - '121': ['amazon', 'bloomberg', 'facebook', 'microsoft', 'uber'], - '122': ['bloomberg'], - '124': ['baidu', 'microsoft'], - '125': ['facebook', 'microsoft', 'uber', 'zenefits'], - '126': ['amazon', 'yelp'], - '127': ['amazon', 'facebook', 'linkedin', 'snapchat', 'yelp'], - '128': ['facebook', 'google'], - '131': ['bloomberg'], - '133': ['facebook', 'google', 'pocketgems', 'uber'], - '136': ['airbnb', 'palantir'], - '138': ['amazon', 'bloomberg', 'microsoft', 'uber'], - '139': ['amazon', 'bloomberg', 'facebook', 'google', 'pocketgems', 'uber', 'yahoo'], - '140': ['dropbox', 'google', 'snapchat', 'twitter', 'uber'], - '141': ['amazon', 'bloomberg', 'microsoft', 'yahoo'], - '146': ['amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'palantir', 'snapchat', 'twitter', 'uber', 'yahoo', 'zenefits'], - '149': ['apple', 'linkedin', 'twitter'], - '150': ['linkedin'], - '151': ['apple', 'bloomberg', 'microsoft', 'snapchat', 'yelp'], - '152': ['linkedin'], - '153': ['microsoft'], - '155': ['amazon', 'bloomberg', 'google', 'snapchat', 'uber', 'zenefits'], - '156': ['linkedin'], - '157': ['facebook'], - '158': ['bloomberg', 'facebook', 'google'], - '159': ['google'], - '160': ['airbnb', 'amazon', 'bloomberg', 'microsoft'], - '161': ['facebook', 'snapchat', 'twitter', 'uber'], - '162': ['google', 'microsoft'], - '163': ['google'], - '165': ['apple', 'microsoft'], - '166': ['google'], - '167': ['amazon'], - '168': ['facebook', 'microsoft', 'zenefits'], - '169': ['adobe', 'zenefits'], - '170': ['linkedin'], - '171': ['microsoft', 'uber'], - '172': ['bloomberg'], - '173': ['facebook', 'google', 'linkedin', 'microsoft'], - '174': ['microsoft'], - '186': ['amazon', 'microsoft', 'uber'], - '187': ['linkedin'], - '189': ['bloomberg', 'microsoft'], - '190': ['airbnb', 'apple'], - '191': ['apple', 'microsoft'], - '195': ['adobe'], - '198': ['airbnb', 'linkedin'], - '199': ['amazon'], - '200': ['amazon', 'facebook', 'google', 'microsoft', 'zenefits'], - '202': ['airbnb', 'twitter', 'uber'], - '204': ['amazon', 'microsoft'], - '205': ['linkedin'], - '206': ['adobe', 'amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'snapchat', 'twitter', 'uber', 'yahoo', 'yelp', 'zenefits'], - '207': ['apple', 'yelp', 'zenefits'], - '208': ['bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'uber'], - '209': ['facebook'], - '210': ['facebook', 'zenefits'], - '211': ['facebook'], - '212': ['airbnb', 'google', 'microsoft'], - '213': ['microsoft'], - '214': ['google', 'pocketgems'], - '215': ['amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'pocketgems'], - '217': ['airbnb', 'palantir', 'yahoo'], - '218': ['facebook', 'google', 'microsoft', 'twitter', 'yelp'], - '219': ['airbnb', 'palantir'], - '220': ['airbnb', 'palantir'], - '221': ['airbnb', 'apple', 'facebook'], - '224': ['google'], - '225': ['bloomberg'], - '227': ['airbnb'], - '228': ['google'], - '229': ['zenefits'], - '230': ['bloomberg', 'google', 'uber'], - '231': ['google'], - '232': ['bloomberg', 'microsoft'], - '234': ['amazon', 'facebook'], - '235': ['amazon', 'facebook', 'microsoft', 'twitter'], - '236': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], - '237': ['adobe', 'apple', 'microsoft'], - '238': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], - '239': ['amazon', 'google', 'zenefits'], - '240': ['amazon', 'apple', 'google'], - '242': ['amazon', 'uber', 'yelp'], - '243': ['linkedin'], - '244': ['linkedin'], - '245': ['linkedin'], - '246': ['google'], - '247': ['google'], - '249': ['google', 'uber'], - '251': ['airbnb', 'google', 'twitter', 'zenefits'], - '252': ['facebook'], - '253': ['facebook', 'google', 'snapchat'], - '254': ['linkedin', 'uber'], - '255': ['zenefits'], - '256': ['linkedin'], - '257': ['apple', 'facebook', 'google'], - '258': ['adobe', 'microsoft'], - '259': ['google'], - '261': ['facebook', 'google', 'zenefits'], - '262': ['uber'], - '265': ['facebook'], - '266': ['bloomberg', 'google', 'uber'], - '268': ['bloomberg', 'microsoft'], - '269': ['airbnb', 'facebook', 'google', 'pocketgems', 'snapchat', 'twitter'], - '270': ['google', 'microsoft', 'snapchat'], - '271': ['google'], - '272': ['google'], - '273': ['facebook', 'microsoft'], - '274': ['bloomberg', 'facebook', 'google'], - '275': ['facebook'], - '276': ['google'], - '277': ['facebook', 'linkedin'], - '278': ['facebook'], - '279': ['google'], - '280': ['google'], - '281': ['google'], - '282': ['facebook', 'google'], - '283': ['bloomberg', 'facebook'], - '284': ['apple', 'google', 'yahoo'], - '285': ['facebook', 'microsoft', 'pocketgems'], - '286': ['facebook', 'google'], - '287': ['bloomberg'], - '288': ['google'], - '289': ['dropbox', 'google', 'snapchat', 'twosigma'], - '290': ['dropbox', 'uber'], - '291': ['dropbox', 'uber'], - '292': ['adobe'], - '293': ['google'], - '294': ['google'], - '295': ['google'], - '296': ['twitter'], - '297': ['amazon', 'bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'uber', 'yahoo'], - '298': ['google'], - '300': ['microsoft'], - '301': ['facebook'], - '302': ['google'], - '303': ['palantir'], - '305': ['google'], - '308': ['google'], - '309': ['google'], - '310': ['google'], - '311': ['facebook', 'linkedin'], - '312': ['google', 'snapchat'], - '313': ['google'], - '314': ['facebook', 'google', 'snapchat'], - '315': ['google'], - '316': ['google'], - '317': ['google', 'zenefits'], - '318': ['google'], - '320': ['google'], - '321': ['google'], - '323': ['google', 'twitter'], - '324': ['google'], - '325': ['facebook', 'palantir'], - '326': ['google'], - '327': ['google'], - '329': ['google'], - '330': ['google'], - '331': ['google'], - '332': ['google'], - '333': ['microsoft'], - '334': ['facebook'], - '336': ['airbnb', 'google'], - '337': ['uber'], - '339': ['linkedin'], - '340': ['google'], - '341': ['facebook', 'google', 'twitter'], - '342': ['twosigma'], - '345': ['google'], - '346': ['google'], - '347': ['pocketgems', 'yelp'], - '348': ['google', 'microsoft'], - '349': ['twosigma'], - '351': ['google'], - '353': ['google'], - '354': ['google'], - '355': ['amazon', 'twitter'], - '356': ['google'], - '357': ['google'], - '358': ['google'], - '359': ['google'], - '360': ['google'], - '361': ['google'], - '362': ['dropbox', 'google'], - '363': ['google'], - '364': ['linkedin'], - '365': ['microsoft'], - '366': ['linkedin'], - '367': ['linkedin'], - '368': ['google'], - '369': ['google'], - '370': ['google'], - '373': ['google', 'uber'], - '374': ['google'], - '375': ['google'], - '377': ['facebook', 'google', 'snapchat'], - '378': ['google', 'twitter'], - '379': ['google'], - '380': ['amazon', 'facebook', 'google', 'pocketgems', 'twitter', 'uber', 'yelp'], - '381': ['yelp'], - '382': ['google'], - '383': ['apple'], - '385': ['airbnb'], - '386': ['bloomberg'], - '387': ['amazon', 'bloomberg', 'microsoft'], - '388': ['google'], - '389': ['google'], - '391': ['google'], - '393': ['google'], - '394': ['google'], - '395': ['baidu'], - '396': ['amazon'], - '397': ['baidu', 'google'], - '398': ['facebook'], - '399': ['google'], - '400': ['google'], - '401': ['google'], - '402': ['google', 'snapchat'], - '403': ['snapchat'], - '404': ['facebook'], - '406': ['google'], - '407': ['google', 'twitter'], - '408': ['google'], - '409': ['google'], - '410': ['baidu', 'facebook'], - '411': ['google'], - '413': ['baidu'], - '414': ['amazon'], - '415': ['airbnb', 'google'], - '416': ['ebay'], - '417': ['google'], - '418': ['google'], - '419': ['microsoft'], - '421': ['google'], - '422': ['google'], - '424': ['pocketgems'], - '425': ['google'], - '432': ['uber'], - '433': ['twitter'], - '438': ['amazon'], - '439': ['snapchat'], - '442': ['pocketgems'], - '444': ['google'], - '445': ['bloomberg', 'microsoft'], - '446': ['baidu'], - '447': ['google'], - '448': ['google'], - '449': ['amazon'], - '450': ['uber'], - '451': ['amazon', 'google'], - '452': ['microsoft'], - '453': ['indeed'], - '459': ['amazon', 'google'], - '460': ['amazon', 'google'], - '461': ['facebook'], - '463': ['google'], - '464': ['linkedin'], - '465': ['google'], - '468': ['twitter'], - '469': ['google'], - '471': ['google'], - '474': ['google'], - '475': ['google'], - '477': ['facebook'], - '479': ['yahoo'], - '480': ['google'], - '481': ['google'], - '482': ['google'], - '483': ['google'], - '484': ['google'], - '485': ['google'], - '486': ['google'], - '487': ['google'], - '488': ['baidu'], - '490': ['google'], - '491': ['yahoo'], - '493': ['google'], - '494': ['facebook', 'google'], - '498': ['google'], - '500': ['mathworks'], - '501': ['google'], - '503': ['google'], - '505': ['google'], - '506': ['google'], - '508': ['amazon'], - '513': ['microsoft'], - '514': ['google'], - '515': ['linkedin'], - '516': ['amazon', 'uber'], - '517': ['amazon'], - '520': ['google'], - '521': ['google'], - '522': ['google'], - '523': ['facebook'], - '524': ['google'], - '525': ['facebook'], - '526': ['google'], - '527': ['google', 'snapchat'], - '529': ['amazon'], - '530': ['google'], - '531': ['google'], - '532': ['amazon'], - '533': ['google'], - '534': ['amazon', 'facebook', 'google', 'uber'], - '535': ['amazon', 'facebook', 'google', 'uber'], - '536': ['amazon'], - '537': ['amazon'], - '538': ['amazon'], - '541': ['google'], - '542': ['google'], - '543': ['facebook', 'google'], - '544': ['google'], - '545': ['amazon', 'google'], - '547': ['twosigma'], - '548': ['alibaba'], - '551': ['google'], - '552': ['google'], - '554': ['facebook'], - '555': ['alibaba'], - '556': ['bloomberg'], - '557': ['zappos'], - '560': ['google'], - '562': ['google'], - '563': ['indeed'], - '564': ['yelp'], - '566': ['mathworks'], - '567': ['microsoft'], - '568': ['google'], - '569': ['google'], - '572': ['ebay', 'google'], - '576': ['baidu'], - '579': ['amazon'] + '1': ['adobe', 'airbnb', 'amazon', 'apple', 'bloomberg', 'dropbox', 'facebook', 'linkedin', 'microsoft', 'uber', 'yahoo', 'yelp'], + '2': ['adobe', 'airbnb', 'amazon', 'bloomberg', 'microsoft'], + '3': ['adobe', 'amazon', 'bloomberg', 'yelp'], + '4': ['adobe', 'apple', 'dropbox', 'google', 'microsoft', 'yahoo', 'zenefits'], + '5': ['amazon', 'bloomberg', 'microsoft'], + '7': ['apple', 'bloomberg'], + '8': ['amazon', 'bloomberg', 'microsoft', 'uber'], + '10': ['airbnb', 'facebook', 'google', 'twitter', 'uber'], + '11': ['bloomberg'], + '12': ['twitter'], + '13': ['bloomberg', 'facebook', 'microsoft', 'uber', 'yahoo'], + '14': ['yelp'], + '15': ['adobe', 'amazon', 'bloomberg', 'facebook', 'microsoft'], + '16': ['bloomberg'], + '17': ['amazon', 'dropbox', 'facebook', 'google', 'uber'], + '18': ['linkedin'], + '20': ['airbnb', 'amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'zenefits'], + '21': ['amazon', 'apple', 'linkedin', 'microsoft'], + '22': ['google', 'uber', 'zenefits'], + '23': ['airbnb', 'amazon', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'uber'], + '24': ['bloomberg', 'microsoft', 'uber'], + '25': ['facebook', 'microsoft'], + '26': ['bloomberg', 'facebook', 'microsoft'], + '28': ['apple', 'facebook', 'microsoft', 'pocketgems'], + '31': ['google'], + '33': ['bloomberg', 'facebook', 'linkedin', 'microsoft', 'uber'], + '34': ['linkedin'], + '36': ['apple', 'snapchat', 'uber'], + '37': ['snapchat', 'uber'], + '38': ['facebook'], + '39': ['snapchat', 'uber'], + '40': ['snapchat'], + '42': ['amazon', 'apple', 'bloomberg', 'google', 'twitter', 'zenefits'], + '43': ['facebook', 'twitter'], + '44': ['facebook', 'google', 'snapchat', 'twitter', 'twosigma'], + '46': ['linkedin', 'microsoft'], + '47': ['linkedin', 'microsoft'], + '48': ['amazon', 'apple', 'microsoft'], + '49': ['amazon', 'bloomberg', 'facebook', 'uber', 'yelp'], + '50': ['bloomberg', 'facebook', 'google', 'linkedin'], + '52': ['zenefits'], + '53': ['bloomberg', 'linkedin', 'microsoft'], + '54': ['google', 'microsoft', 'uber'], + '55': ['microsoft'], + '56': ['bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'yelp'], + '57': ['facebook', 'google', 'linkedin'], + '60': ['twitter'], + '62': ['bloomberg'], + '63': ['bloomberg'], + '65': ['linkedin'], + '66': ['google'], + '67': ['facebook'], + '68': ['airbnb', 'facebook', 'linkedin'], + '69': ['apple', 'bloomberg', 'facebook'], + '70': ['adobe', 'apple'], + '71': ['facebook', 'microsoft'], + '73': ['amazon', 'microsoft'], + '75': ['facebook', 'microsoft', 'pocketgems'], + '76': ['facebook', 'linkedin', 'snapchat', 'uber'], + '78': ['amazon', 'bloomberg', 'facebook', 'uber'], + '79': ['bloomberg', 'facebook', 'microsoft'], + '80': ['facebook'], + '85': ['facebook'], + '88': ['bloomberg', 'facebook', 'microsoft'], + '89': ['amazon'], + '90': ['facebook'], + '91': ['facebook', 'microsoft', 'uber'], + '94': ['microsoft'], + '96': ['snapchat'], + '98': ['amazon', 'bloomberg', 'facebook', 'microsoft'], + '100': ['bloomberg'], + '101': ['bloomberg', 'linkedin', 'microsoft'], + '102': ['amazon', 'apple', 'bloomberg', 'facebook', 'linkedin', 'microsoft'], + '103': ['bloomberg', 'linkedin', 'microsoft'], + '104': ['apple', 'linkedin', 'uber', 'yahoo'], + '105': ['bloomberg'], + '106': ['microsoft'], + '108': ['airbnb'], + '109': ['zenefits'], + '110': ['bloomberg'], + '112': ['microsoft'], + '113': ['bloomberg'], + '114': ['microsoft'], + '116': ['microsoft'], + '117': ['bloomberg', 'facebook', 'microsoft'], + '118': ['apple', 'twitter'], + '119': ['amazon'], + '121': ['amazon', 'bloomberg', 'facebook', 'microsoft', 'uber'], + '122': ['bloomberg'], + '124': ['baidu', 'microsoft'], + '125': ['facebook', 'microsoft', 'uber', 'zenefits'], + '126': ['amazon', 'yelp'], + '127': ['amazon', 'facebook', 'linkedin', 'snapchat', 'yelp'], + '128': ['facebook', 'google'], + '131': ['bloomberg'], + '133': ['facebook', 'google', 'pocketgems', 'uber'], + '136': ['airbnb', 'palantir'], + '138': ['amazon', 'bloomberg', 'microsoft', 'uber'], + '139': ['amazon', 'bloomberg', 'facebook', 'google', 'pocketgems', 'uber', 'yahoo'], + '140': ['dropbox', 'google', 'snapchat', 'twitter', 'uber'], + '141': ['amazon', 'bloomberg', 'microsoft', 'yahoo'], + '146': ['amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'palantir', 'snapchat', 'twitter', 'uber', 'yahoo', 'zenefits'], + '149': ['apple', 'linkedin', 'twitter'], + '150': ['linkedin'], + '151': ['apple', 'bloomberg', 'microsoft', 'snapchat', 'yelp'], + '152': ['linkedin'], + '153': ['microsoft'], + '155': ['amazon', 'bloomberg', 'google', 'snapchat', 'uber', 'zenefits'], + '156': ['linkedin'], + '157': ['facebook'], + '158': ['bloomberg', 'facebook', 'google'], + '159': ['google'], + '160': ['airbnb', 'amazon', 'bloomberg', 'microsoft'], + '161': ['facebook', 'snapchat', 'twitter', 'uber'], + '162': ['google', 'microsoft'], + '163': ['google'], + '165': ['apple', 'microsoft'], + '166': ['google'], + '167': ['amazon'], + '168': ['facebook', 'microsoft', 'zenefits'], + '169': ['adobe', 'zenefits'], + '170': ['linkedin'], + '171': ['microsoft', 'uber'], + '172': ['bloomberg'], + '173': ['facebook', 'google', 'linkedin', 'microsoft'], + '174': ['microsoft'], + '186': ['amazon', 'microsoft', 'uber'], + '187': ['linkedin'], + '189': ['amazon', 'bloomberg', 'microsoft'], + '190': ['airbnb', 'apple'], + '191': ['apple', 'microsoft'], + '195': ['adobe'], + '198': ['airbnb', 'linkedin'], + '199': ['amazon'], + '200': ['amazon', 'facebook', 'google', 'microsoft', 'zenefits'], + '202': ['airbnb', 'twitter', 'uber'], + '204': ['amazon', 'microsoft'], + '205': ['linkedin'], + '206': ['adobe', 'amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'snapchat', 'twitter', 'uber', 'yahoo', 'yelp', 'zenefits'], + '207': ['apple', 'uber', 'yelp', 'zenefits'], + '208': ['bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'uber'], + '209': ['facebook'], + '210': ['facebook', 'zenefits'], + '211': ['facebook'], + '212': ['airbnb', 'google', 'microsoft'], + '213': ['microsoft'], + '214': ['google', 'pocketgems'], + '215': ['amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'pocketgems'], + '217': ['airbnb', 'palantir', 'yahoo'], + '218': ['facebook', 'google', 'microsoft', 'twitter', 'yelp'], + '219': ['airbnb', 'palantir'], + '220': ['airbnb', 'palantir'], + '221': ['airbnb', 'apple', 'facebook'], + '224': ['google'], + '225': ['bloomberg'], + '227': ['airbnb'], + '228': ['google'], + '229': ['zenefits'], + '230': ['bloomberg', 'google', 'uber'], + '231': ['google'], + '232': ['bloomberg', 'microsoft'], + '234': ['amazon', 'facebook'], + '235': ['amazon', 'facebook', 'microsoft', 'twitter'], + '236': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], + '237': ['adobe', 'apple', 'microsoft'], + '238': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], + '239': ['amazon', 'google', 'zenefits'], + '240': ['amazon', 'apple', 'google'], + '242': ['amazon', 'uber', 'yelp'], + '243': ['linkedin'], + '244': ['linkedin'], + '245': ['linkedin'], + '246': ['google'], + '247': ['google'], + '249': ['google', 'uber'], + '251': ['airbnb', 'google', 'twitter', 'zenefits'], + '252': ['facebook'], + '253': ['facebook', 'google', 'snapchat'], + '254': ['linkedin', 'uber'], + '255': ['zenefits'], + '256': ['linkedin'], + '257': ['apple', 'facebook', 'google'], + '258': ['adobe', 'microsoft'], + '259': ['google'], + '261': ['facebook', 'google', 'zenefits'], + '262': ['uber'], + '265': ['facebook'], + '266': ['bloomberg', 'google', 'uber'], + '268': ['bloomberg', 'microsoft'], + '269': ['airbnb', 'facebook', 'google', 'pocketgems', 'snapchat', 'twitter'], + '270': ['google', 'microsoft', 'snapchat'], + '271': ['google'], + '272': ['google'], + '273': ['facebook', 'microsoft'], + '274': ['bloomberg', 'facebook', 'google'], + '275': ['facebook'], + '276': ['google'], + '277': ['facebook', 'linkedin'], + '278': ['facebook'], + '279': ['google'], + '280': ['google'], + '281': ['google'], + '282': ['facebook', 'google'], + '283': ['bloomberg', 'facebook'], + '284': ['apple', 'google', 'yahoo'], + '285': ['facebook', 'microsoft', 'pocketgems'], + '286': ['facebook', 'google'], + '287': ['bloomberg'], + '288': ['google'], + '289': ['dropbox', 'google', 'snapchat', 'twosigma'], + '290': ['dropbox', 'uber'], + '291': ['dropbox', 'uber'], + '292': ['adobe'], + '293': ['google'], + '294': ['google'], + '295': ['google'], + '296': ['twitter'], + '297': ['amazon', 'bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'uber', 'yahoo'], + '298': ['google'], + '300': ['microsoft'], + '301': ['facebook'], + '302': ['google'], + '303': ['palantir'], + '305': ['google'], + '308': ['google'], + '309': ['google'], + '310': ['google'], + '311': ['facebook', 'linkedin'], + '312': ['google', 'snapchat'], + '313': ['google'], + '314': ['facebook', 'google', 'snapchat'], + '315': ['google'], + '316': ['google'], + '317': ['google', 'zenefits'], + '318': ['google'], + '320': ['google'], + '321': ['google'], + '323': ['google', 'twitter'], + '324': ['google'], + '325': ['facebook', 'palantir'], + '326': ['google'], + '327': ['google'], + '329': ['google'], + '330': ['google'], + '331': ['google'], + '332': ['google'], + '333': ['microsoft'], + '334': ['facebook'], + '336': ['airbnb', 'google'], + '337': ['uber'], + '339': ['linkedin'], + '340': ['google'], + '341': ['facebook', 'google', 'twitter'], + '342': ['twosigma'], + '345': ['google'], + '346': ['google'], + '347': ['pocketgems', 'yelp'], + '348': ['google', 'microsoft'], + '349': ['twosigma'], + '351': ['google'], + '353': ['google'], + '354': ['google'], + '355': ['amazon', 'twitter'], + '356': ['google'], + '357': ['google'], + '358': ['google'], + '359': ['google'], + '360': ['google'], + '361': ['google'], + '362': ['dropbox', 'google'], + '363': ['google'], + '364': ['linkedin'], + '365': ['microsoft'], + '366': ['linkedin'], + '367': ['linkedin'], + '368': ['google'], + '369': ['google'], + '370': ['google'], + '373': ['google', 'uber'], + '374': ['google'], + '375': ['google'], + '377': ['facebook', 'google', 'snapchat'], + '378': ['google', 'twitter'], + '379': ['google'], + '380': ['amazon', 'facebook', 'google', 'pocketgems', 'twitter', 'uber', 'yelp'], + '381': ['yelp'], + '382': ['google'], + '383': ['apple'], + '385': ['airbnb'], + '386': ['bloomberg'], + '387': ['amazon', 'bloomberg', 'microsoft'], + '388': ['google'], + '389': ['google'], + '391': ['google'], + '393': ['google'], + '394': ['google'], + '395': ['baidu'], + '396': ['amazon'], + '397': ['baidu', 'google'], + '398': ['facebook'], + '399': ['google'], + '400': ['google'], + '401': ['google'], + '402': ['google', 'snapchat'], + '403': ['snapchat'], + '404': ['facebook'], + '406': ['google'], + '407': ['google', 'twitter'], + '408': ['google'], + '409': ['google'], + '410': ['baidu', 'facebook'], + '411': ['google'], + '413': ['baidu'], + '414': ['amazon'], + '415': ['airbnb', 'google'], + '416': ['ebay'], + '417': ['google'], + '418': ['google'], + '419': ['microsoft'], + '421': ['google'], + '422': ['google'], + '424': ['pocketgems'], + '425': ['google'], + '432': ['uber'], + '433': ['twitter'], + '438': ['amazon'], + '439': ['snapchat'], + '442': ['pocketgems'], + '443': ['bloomberg', 'microsoft'], + '444': ['google'], + '445': ['bloomberg', 'microsoft'], + '446': ['baidu'], + '447': ['google'], + '448': ['google'], + '449': ['amazon'], + '450': ['uber'], + '451': ['amazon', 'google'], + '452': ['microsoft'], + '453': ['indeed'], + '459': ['amazon', 'google'], + '460': ['amazon', 'google'], + '461': ['facebook'], + '463': ['google'], + '464': ['linkedin'], + '465': ['google'], + '468': ['twitter'], + '469': ['google'], + '471': ['google'], + '474': ['google'], + '475': ['google'], + '477': ['facebook'], + '479': ['yahoo'], + '480': ['google'], + '481': ['google'], + '482': ['google'], + '483': ['google'], + '484': ['google'], + '485': ['google'], + '486': ['google'], + '487': ['google'], + '488': ['baidu'], + '490': ['google'], + '491': ['yahoo'], + '493': ['google'], + '494': ['facebook', 'google'], + '498': ['google'], + '500': ['mathworks'], + '501': ['google'], + '503': ['google'], + '505': ['google'], + '506': ['google'], + '508': ['amazon'], + '513': ['microsoft'], + '514': ['google'], + '515': ['linkedin'], + '516': ['amazon', 'uber'], + '517': ['amazon'], + '520': ['google'], + '521': ['google'], + '522': ['google'], + '523': ['facebook'], + '524': ['google'], + '525': ['facebook'], + '526': ['google'], + '527': ['google', 'snapchat'], + '529': ['amazon'], + '530': ['google'], + '531': ['google'], + '532': ['amazon'], + '533': ['google'], + '534': ['amazon', 'facebook', 'google', 'uber'], + '535': ['amazon', 'facebook', 'google', 'uber'], + '536': ['amazon'], + '537': ['amazon'], + '538': ['amazon'], + '541': ['google'], + '542': ['google'], + '543': ['facebook', 'google'], + '544': ['google'], + '545': ['amazon', 'google'], + '547': ['bloomberg', 'twosigma'], + '548': ['alibaba'], + '549': ['google'], + '551': ['google'], + '552': ['google'], + '553': ['amazon'], + '554': ['facebook'], + '555': ['alibaba'], + '556': ['bloomberg'], + '557': ['zappos'], + '560': ['google'], + '562': ['google'], + '563': ['indeed'], + '564': ['yelp'], + '566': ['mathworks'], + '567': ['microsoft'], + '568': ['google'], + '569': ['google'], + '570': ['bloomberg'], + '572': ['ebay', 'facebook', 'google'], + '576': ['baidu'], + '578': ['facebook'], + '579': ['amazon'], + '581': ['google'], + '582': ['bloomberg'], + '583': ['google'], + '587': ['google'], + '591': ['microsoft'], + '597': ['facebook'], + '602': ['facebook'], + '604': ['google'], + '605': ['linkedin'], + '606': ['amazon'], + '616': ['google'], + '617': ['amazon'], + '621': ['facebook'], + '631': ['microsoft'], + '633': ['linkedin'], + '636': ['facebook', 'uber'], + '637': ['facebook'], + '638': ['google'], + '639': ['facebook'], + '640': ['amazon'], + '642': ['facebook', 'microsoft'], + '643': ['google'], + '644': ['google'], + '645': ['amazon'], + '646': ['amazon'], + '647': ['facebook', 'linkedin'], + '648': ['uber'], + '650': ['microsoft'], + '651': ['google', 'microsoft'], + '652': ['google'], + '653': ['facebook'], + '654': ['microsoft'], + '656': ['google'], + '657': ['google'], + '658': ['google'], + '659': ['google'], + '661': ['amazon'], + '662': ['amazon'], + '663': ['amazon'], + '665': ['google'], + '667': ['google'], + '668': ['google'], + '669': ['bloomberg'], + '670': ['facebook'], + '671': ['linkedin'], + '672': ['microsoft'], + '673': ['facebook'], + '674': ['facebook'], + '675': ['amazon'], + '676': ['google'], + '679': ['google'], + '680': ['facebook'], + '681': ['google'], + '682': ['amazon'], + '683': ['google'], + '684': ['google'], + '685': ['google'], + '686': ['google'], + '687': ['google'], + '689': ['facebook', 'google'], + '690': ['uber'], + '692': ['amazon', 'bloomberg', 'uber'], + '694': ['amazon'], + '698': ['linkedin'], + '699': ['uber'], + '711': ['amazon'], + '714': ['bloomberg', 'facebook'], + '716': ['linkedin'], + '719': ['google'], + '721': ['facebook'], + '722': ['microsoft'], + '725': ['amazon'], + '726': ['google'], + '727': ['google'], + '729': ['google'], + '730': ['linkedin'], + '731': ['google'] }; plugin.getProblems = function(cb) { From 9f5644c52d62225e6bd0ef6d4fc59762e7716f9b Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 18 Dec 2017 12:30:39 +0800 Subject: [PATCH 04/48] [company] updated list. Signed-off-by: Eric Wang --- plugins/company.js | 1006 ++++++++++++++++++++++---------------------- 1 file changed, 506 insertions(+), 500 deletions(-) diff --git a/plugins/company.js b/plugins/company.js index 2bdf8cb..fcee83c 100644 --- a/plugins/company.js +++ b/plugins/company.js @@ -13,506 +13,512 @@ var plugin = new Plugin(100, 'company', '2017.12.18', // * 1point3acres.com // * other results from google search var DATA = { - '1': ['adobe', 'airbnb', 'amazon', 'apple', 'bloomberg', 'dropbox', 'facebook', 'linkedin', 'microsoft', 'uber', 'yahoo', 'yelp'], - '2': ['adobe', 'airbnb', 'amazon', 'bloomberg', 'microsoft'], - '3': ['adobe', 'amazon', 'bloomberg', 'yelp'], - '4': ['adobe', 'apple', 'dropbox', 'google', 'microsoft', 'yahoo', 'zenefits'], - '5': ['amazon', 'bloomberg', 'microsoft'], - '7': ['apple', 'bloomberg'], - '8': ['amazon', 'bloomberg', 'microsoft', 'uber'], - '10': ['airbnb', 'facebook', 'google', 'twitter', 'uber'], - '11': ['bloomberg'], - '12': ['twitter'], - '13': ['bloomberg', 'facebook', 'microsoft', 'uber', 'yahoo'], - '14': ['yelp'], - '15': ['adobe', 'amazon', 'bloomberg', 'facebook', 'microsoft'], - '16': ['bloomberg'], - '17': ['amazon', 'dropbox', 'facebook', 'google', 'uber'], - '18': ['linkedin'], - '20': ['airbnb', 'amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'zenefits'], - '21': ['amazon', 'apple', 'linkedin', 'microsoft'], - '22': ['google', 'uber', 'zenefits'], - '23': ['airbnb', 'amazon', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'uber'], - '24': ['bloomberg', 'microsoft', 'uber'], - '25': ['facebook', 'microsoft'], - '26': ['bloomberg', 'facebook', 'microsoft'], - '28': ['apple', 'facebook', 'microsoft', 'pocketgems'], - '31': ['google'], - '33': ['bloomberg', 'facebook', 'linkedin', 'microsoft', 'uber'], - '34': ['linkedin'], - '36': ['apple', 'snapchat', 'uber'], - '37': ['snapchat', 'uber'], - '38': ['facebook'], - '39': ['snapchat', 'uber'], - '40': ['snapchat'], - '42': ['amazon', 'apple', 'bloomberg', 'google', 'twitter', 'zenefits'], - '43': ['facebook', 'twitter'], - '44': ['facebook', 'google', 'snapchat', 'twitter', 'twosigma'], - '46': ['linkedin', 'microsoft'], - '47': ['linkedin', 'microsoft'], - '48': ['amazon', 'apple', 'microsoft'], - '49': ['amazon', 'bloomberg', 'facebook', 'uber', 'yelp'], - '50': ['bloomberg', 'facebook', 'google', 'linkedin'], - '52': ['zenefits'], - '53': ['bloomberg', 'linkedin', 'microsoft'], - '54': ['google', 'microsoft', 'uber'], - '55': ['microsoft'], - '56': ['bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'yelp'], - '57': ['facebook', 'google', 'linkedin'], - '60': ['twitter'], - '62': ['bloomberg'], - '63': ['bloomberg'], - '65': ['linkedin'], - '66': ['google'], - '67': ['facebook'], - '68': ['airbnb', 'facebook', 'linkedin'], - '69': ['apple', 'bloomberg', 'facebook'], - '70': ['adobe', 'apple'], - '71': ['facebook', 'microsoft'], - '73': ['amazon', 'microsoft'], - '75': ['facebook', 'microsoft', 'pocketgems'], - '76': ['facebook', 'linkedin', 'snapchat', 'uber'], - '78': ['amazon', 'bloomberg', 'facebook', 'uber'], - '79': ['bloomberg', 'facebook', 'microsoft'], - '80': ['facebook'], - '85': ['facebook'], - '88': ['bloomberg', 'facebook', 'microsoft'], - '89': ['amazon'], - '90': ['facebook'], - '91': ['facebook', 'microsoft', 'uber'], - '94': ['microsoft'], - '96': ['snapchat'], - '98': ['amazon', 'bloomberg', 'facebook', 'microsoft'], - '100': ['bloomberg'], - '101': ['bloomberg', 'linkedin', 'microsoft'], - '102': ['amazon', 'apple', 'bloomberg', 'facebook', 'linkedin', 'microsoft'], - '103': ['bloomberg', 'linkedin', 'microsoft'], - '104': ['apple', 'linkedin', 'uber', 'yahoo'], - '105': ['bloomberg'], - '106': ['microsoft'], - '108': ['airbnb'], - '109': ['zenefits'], - '110': ['bloomberg'], - '112': ['microsoft'], - '113': ['bloomberg'], - '114': ['microsoft'], - '116': ['microsoft'], - '117': ['bloomberg', 'facebook', 'microsoft'], - '118': ['apple', 'twitter'], - '119': ['amazon'], - '121': ['amazon', 'bloomberg', 'facebook', 'microsoft', 'uber'], - '122': ['bloomberg'], - '124': ['baidu', 'microsoft'], - '125': ['facebook', 'microsoft', 'uber', 'zenefits'], - '126': ['amazon', 'yelp'], - '127': ['amazon', 'facebook', 'linkedin', 'snapchat', 'yelp'], - '128': ['facebook', 'google'], - '131': ['bloomberg'], - '133': ['facebook', 'google', 'pocketgems', 'uber'], - '136': ['airbnb', 'palantir'], - '138': ['amazon', 'bloomberg', 'microsoft', 'uber'], - '139': ['amazon', 'bloomberg', 'facebook', 'google', 'pocketgems', 'uber', 'yahoo'], - '140': ['dropbox', 'google', 'snapchat', 'twitter', 'uber'], - '141': ['amazon', 'bloomberg', 'microsoft', 'yahoo'], - '146': ['amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'palantir', 'snapchat', 'twitter', 'uber', 'yahoo', 'zenefits'], - '149': ['apple', 'linkedin', 'twitter'], - '150': ['linkedin'], - '151': ['apple', 'bloomberg', 'microsoft', 'snapchat', 'yelp'], - '152': ['linkedin'], - '153': ['microsoft'], - '155': ['amazon', 'bloomberg', 'google', 'snapchat', 'uber', 'zenefits'], - '156': ['linkedin'], - '157': ['facebook'], - '158': ['bloomberg', 'facebook', 'google'], - '159': ['google'], - '160': ['airbnb', 'amazon', 'bloomberg', 'microsoft'], - '161': ['facebook', 'snapchat', 'twitter', 'uber'], - '162': ['google', 'microsoft'], - '163': ['google'], - '165': ['apple', 'microsoft'], - '166': ['google'], - '167': ['amazon'], - '168': ['facebook', 'microsoft', 'zenefits'], - '169': ['adobe', 'zenefits'], - '170': ['linkedin'], - '171': ['microsoft', 'uber'], - '172': ['bloomberg'], - '173': ['facebook', 'google', 'linkedin', 'microsoft'], - '174': ['microsoft'], - '186': ['amazon', 'microsoft', 'uber'], - '187': ['linkedin'], - '189': ['amazon', 'bloomberg', 'microsoft'], - '190': ['airbnb', 'apple'], - '191': ['apple', 'microsoft'], - '195': ['adobe'], - '198': ['airbnb', 'linkedin'], - '199': ['amazon'], - '200': ['amazon', 'facebook', 'google', 'microsoft', 'zenefits'], - '202': ['airbnb', 'twitter', 'uber'], - '204': ['amazon', 'microsoft'], - '205': ['linkedin'], - '206': ['adobe', 'amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'snapchat', 'twitter', 'uber', 'yahoo', 'yelp', 'zenefits'], - '207': ['apple', 'uber', 'yelp', 'zenefits'], - '208': ['bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'uber'], - '209': ['facebook'], - '210': ['facebook', 'zenefits'], - '211': ['facebook'], - '212': ['airbnb', 'google', 'microsoft'], - '213': ['microsoft'], - '214': ['google', 'pocketgems'], - '215': ['amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'pocketgems'], - '217': ['airbnb', 'palantir', 'yahoo'], - '218': ['facebook', 'google', 'microsoft', 'twitter', 'yelp'], - '219': ['airbnb', 'palantir'], - '220': ['airbnb', 'palantir'], - '221': ['airbnb', 'apple', 'facebook'], - '224': ['google'], - '225': ['bloomberg'], - '227': ['airbnb'], - '228': ['google'], - '229': ['zenefits'], - '230': ['bloomberg', 'google', 'uber'], - '231': ['google'], - '232': ['bloomberg', 'microsoft'], - '234': ['amazon', 'facebook'], - '235': ['amazon', 'facebook', 'microsoft', 'twitter'], - '236': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], - '237': ['adobe', 'apple', 'microsoft'], - '238': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], - '239': ['amazon', 'google', 'zenefits'], - '240': ['amazon', 'apple', 'google'], - '242': ['amazon', 'uber', 'yelp'], - '243': ['linkedin'], - '244': ['linkedin'], - '245': ['linkedin'], - '246': ['google'], - '247': ['google'], - '249': ['google', 'uber'], - '251': ['airbnb', 'google', 'twitter', 'zenefits'], - '252': ['facebook'], - '253': ['facebook', 'google', 'snapchat'], - '254': ['linkedin', 'uber'], - '255': ['zenefits'], - '256': ['linkedin'], - '257': ['apple', 'facebook', 'google'], - '258': ['adobe', 'microsoft'], - '259': ['google'], - '261': ['facebook', 'google', 'zenefits'], - '262': ['uber'], - '265': ['facebook'], - '266': ['bloomberg', 'google', 'uber'], - '268': ['bloomberg', 'microsoft'], - '269': ['airbnb', 'facebook', 'google', 'pocketgems', 'snapchat', 'twitter'], - '270': ['google', 'microsoft', 'snapchat'], - '271': ['google'], - '272': ['google'], - '273': ['facebook', 'microsoft'], - '274': ['bloomberg', 'facebook', 'google'], - '275': ['facebook'], - '276': ['google'], - '277': ['facebook', 'linkedin'], - '278': ['facebook'], - '279': ['google'], - '280': ['google'], - '281': ['google'], - '282': ['facebook', 'google'], - '283': ['bloomberg', 'facebook'], - '284': ['apple', 'google', 'yahoo'], - '285': ['facebook', 'microsoft', 'pocketgems'], - '286': ['facebook', 'google'], - '287': ['bloomberg'], - '288': ['google'], - '289': ['dropbox', 'google', 'snapchat', 'twosigma'], - '290': ['dropbox', 'uber'], - '291': ['dropbox', 'uber'], - '292': ['adobe'], - '293': ['google'], - '294': ['google'], - '295': ['google'], - '296': ['twitter'], - '297': ['amazon', 'bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'uber', 'yahoo'], - '298': ['google'], - '300': ['microsoft'], - '301': ['facebook'], - '302': ['google'], - '303': ['palantir'], - '305': ['google'], - '308': ['google'], - '309': ['google'], - '310': ['google'], - '311': ['facebook', 'linkedin'], - '312': ['google', 'snapchat'], - '313': ['google'], - '314': ['facebook', 'google', 'snapchat'], - '315': ['google'], - '316': ['google'], - '317': ['google', 'zenefits'], - '318': ['google'], - '320': ['google'], - '321': ['google'], - '323': ['google', 'twitter'], - '324': ['google'], - '325': ['facebook', 'palantir'], - '326': ['google'], - '327': ['google'], - '329': ['google'], - '330': ['google'], - '331': ['google'], - '332': ['google'], - '333': ['microsoft'], - '334': ['facebook'], - '336': ['airbnb', 'google'], - '337': ['uber'], - '339': ['linkedin'], - '340': ['google'], - '341': ['facebook', 'google', 'twitter'], - '342': ['twosigma'], - '345': ['google'], - '346': ['google'], - '347': ['pocketgems', 'yelp'], - '348': ['google', 'microsoft'], - '349': ['twosigma'], - '351': ['google'], - '353': ['google'], - '354': ['google'], - '355': ['amazon', 'twitter'], - '356': ['google'], - '357': ['google'], - '358': ['google'], - '359': ['google'], - '360': ['google'], - '361': ['google'], - '362': ['dropbox', 'google'], - '363': ['google'], - '364': ['linkedin'], - '365': ['microsoft'], - '366': ['linkedin'], - '367': ['linkedin'], - '368': ['google'], - '369': ['google'], - '370': ['google'], - '373': ['google', 'uber'], - '374': ['google'], - '375': ['google'], - '377': ['facebook', 'google', 'snapchat'], - '378': ['google', 'twitter'], - '379': ['google'], - '380': ['amazon', 'facebook', 'google', 'pocketgems', 'twitter', 'uber', 'yelp'], - '381': ['yelp'], - '382': ['google'], - '383': ['apple'], - '385': ['airbnb'], - '386': ['bloomberg'], - '387': ['amazon', 'bloomberg', 'microsoft'], - '388': ['google'], - '389': ['google'], - '391': ['google'], - '393': ['google'], - '394': ['google'], - '395': ['baidu'], - '396': ['amazon'], - '397': ['baidu', 'google'], - '398': ['facebook'], - '399': ['google'], - '400': ['google'], - '401': ['google'], - '402': ['google', 'snapchat'], - '403': ['snapchat'], - '404': ['facebook'], - '406': ['google'], - '407': ['google', 'twitter'], - '408': ['google'], - '409': ['google'], - '410': ['baidu', 'facebook'], - '411': ['google'], - '413': ['baidu'], - '414': ['amazon'], - '415': ['airbnb', 'google'], - '416': ['ebay'], - '417': ['google'], - '418': ['google'], - '419': ['microsoft'], - '421': ['google'], - '422': ['google'], - '424': ['pocketgems'], - '425': ['google'], - '432': ['uber'], - '433': ['twitter'], - '438': ['amazon'], - '439': ['snapchat'], - '442': ['pocketgems'], - '443': ['bloomberg', 'microsoft'], - '444': ['google'], - '445': ['bloomberg', 'microsoft'], - '446': ['baidu'], - '447': ['google'], - '448': ['google'], - '449': ['amazon'], - '450': ['uber'], - '451': ['amazon', 'google'], - '452': ['microsoft'], - '453': ['indeed'], - '459': ['amazon', 'google'], - '460': ['amazon', 'google'], - '461': ['facebook'], - '463': ['google'], - '464': ['linkedin'], - '465': ['google'], - '468': ['twitter'], - '469': ['google'], - '471': ['google'], - '474': ['google'], - '475': ['google'], - '477': ['facebook'], - '479': ['yahoo'], - '480': ['google'], - '481': ['google'], - '482': ['google'], - '483': ['google'], - '484': ['google'], - '485': ['google'], - '486': ['google'], - '487': ['google'], - '488': ['baidu'], - '490': ['google'], - '491': ['yahoo'], - '493': ['google'], - '494': ['facebook', 'google'], - '498': ['google'], - '500': ['mathworks'], - '501': ['google'], - '503': ['google'], - '505': ['google'], - '506': ['google'], - '508': ['amazon'], - '513': ['microsoft'], - '514': ['google'], - '515': ['linkedin'], - '516': ['amazon', 'uber'], - '517': ['amazon'], - '520': ['google'], - '521': ['google'], - '522': ['google'], - '523': ['facebook'], - '524': ['google'], - '525': ['facebook'], - '526': ['google'], - '527': ['google', 'snapchat'], - '529': ['amazon'], - '530': ['google'], - '531': ['google'], - '532': ['amazon'], - '533': ['google'], - '534': ['amazon', 'facebook', 'google', 'uber'], - '535': ['amazon', 'facebook', 'google', 'uber'], - '536': ['amazon'], - '537': ['amazon'], - '538': ['amazon'], - '541': ['google'], - '542': ['google'], - '543': ['facebook', 'google'], - '544': ['google'], - '545': ['amazon', 'google'], - '547': ['bloomberg', 'twosigma'], - '548': ['alibaba'], - '549': ['google'], - '551': ['google'], - '552': ['google'], - '553': ['amazon'], - '554': ['facebook'], - '555': ['alibaba'], - '556': ['bloomberg'], - '557': ['zappos'], - '560': ['google'], - '562': ['google'], - '563': ['indeed'], - '564': ['yelp'], - '566': ['mathworks'], - '567': ['microsoft'], - '568': ['google'], - '569': ['google'], - '570': ['bloomberg'], - '572': ['ebay', 'facebook', 'google'], - '576': ['baidu'], - '578': ['facebook'], - '579': ['amazon'], - '581': ['google'], - '582': ['bloomberg'], - '583': ['google'], - '587': ['google'], - '591': ['microsoft'], - '597': ['facebook'], - '602': ['facebook'], - '604': ['google'], - '605': ['linkedin'], - '606': ['amazon'], - '616': ['google'], - '617': ['amazon'], - '621': ['facebook'], - '631': ['microsoft'], - '633': ['linkedin'], - '636': ['facebook', 'uber'], - '637': ['facebook'], - '638': ['google'], - '639': ['facebook'], - '640': ['amazon'], - '642': ['facebook', 'microsoft'], - '643': ['google'], - '644': ['google'], - '645': ['amazon'], - '646': ['amazon'], - '647': ['facebook', 'linkedin'], - '648': ['uber'], - '650': ['microsoft'], - '651': ['google', 'microsoft'], - '652': ['google'], - '653': ['facebook'], - '654': ['microsoft'], - '656': ['google'], - '657': ['google'], - '658': ['google'], - '659': ['google'], - '661': ['amazon'], - '662': ['amazon'], - '663': ['amazon'], - '665': ['google'], - '667': ['google'], - '668': ['google'], - '669': ['bloomberg'], - '670': ['facebook'], - '671': ['linkedin'], - '672': ['microsoft'], - '673': ['facebook'], - '674': ['facebook'], - '675': ['amazon'], - '676': ['google'], - '679': ['google'], - '680': ['facebook'], - '681': ['google'], - '682': ['amazon'], - '683': ['google'], - '684': ['google'], - '685': ['google'], - '686': ['google'], - '687': ['google'], - '689': ['facebook', 'google'], - '690': ['uber'], - '692': ['amazon', 'bloomberg', 'uber'], - '694': ['amazon'], - '698': ['linkedin'], - '699': ['uber'], - '711': ['amazon'], - '714': ['bloomberg', 'facebook'], - '716': ['linkedin'], - '719': ['google'], - '721': ['facebook'], - '722': ['microsoft'], - '725': ['amazon'], - '726': ['google'], - '727': ['google'], - '729': ['google'], - '730': ['linkedin'], - '731': ['google'] + '1': ['adobe', 'airbnb', 'amazon', 'apple', 'bloomberg', 'dropbox', 'facebook', 'linkedin', 'microsoft', 'uber', 'yahoo', 'yelp'], + '2': ['adobe', 'airbnb', 'amazon', 'bloomberg', 'microsoft'], + '3': ['adobe', 'amazon', 'bloomberg', 'yelp'], + '4': ['adobe', 'apple', 'dropbox', 'google', 'microsoft', 'yahoo', 'zenefits'], + '5': ['amazon', 'bloomberg', 'microsoft'], + '7': ['apple', 'bloomberg'], + '8': ['amazon', 'bloomberg', 'microsoft', 'uber'], + '10': ['airbnb', 'facebook', 'google', 'twitter', 'uber'], + '11': ['bloomberg'], + '12': ['twitter'], + '13': ['bloomberg', 'facebook', 'microsoft', 'uber', 'yahoo'], + '14': ['yelp'], + '15': ['adobe', 'amazon', 'bloomberg', 'facebook', 'microsoft'], + '16': ['bloomberg'], + '17': ['amazon', 'dropbox', 'facebook', 'google', 'uber'], + '18': ['linkedin'], + '20': ['airbnb', 'amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'zenefits'], + '21': ['amazon', 'apple', 'linkedin', 'microsoft'], + '22': ['google', 'uber', 'zenefits'], + '23': ['airbnb', 'amazon', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'uber'], + '24': ['bloomberg', 'microsoft', 'uber'], + '25': ['facebook', 'microsoft'], + '26': ['bloomberg', 'facebook', 'microsoft'], + '28': ['apple', 'facebook', 'microsoft', 'pocketgems'], + '31': ['google'], + '33': ['bloomberg', 'facebook', 'linkedin', 'microsoft', 'uber'], + '34': ['linkedin'], + '36': ['apple', 'snapchat', 'uber'], + '37': ['snapchat', 'uber'], + '38': ['facebook'], + '39': ['snapchat', 'uber'], + '40': ['snapchat'], + '42': ['amazon', 'apple', 'bloomberg', 'google', 'twitter', 'zenefits'], + '43': ['facebook', 'twitter'], + '44': ['facebook', 'google', 'snapchat', 'twitter', 'twosigma'], + '46': ['linkedin', 'microsoft'], + '47': ['linkedin', 'microsoft'], + '48': ['amazon', 'apple', 'microsoft'], + '49': ['amazon', 'bloomberg', 'facebook', 'uber', 'yelp'], + '50': ['bloomberg', 'facebook', 'google', 'linkedin'], + '52': ['zenefits'], + '53': ['bloomberg', 'linkedin', 'microsoft'], + '54': ['google', 'microsoft', 'uber'], + '55': ['microsoft'], + '56': ['bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'twitter', 'yelp'], + '57': ['facebook', 'google', 'linkedin'], + '60': ['twitter'], + '62': ['bloomberg'], + '63': ['bloomberg'], + '65': ['linkedin'], + '66': ['google'], + '67': ['facebook'], + '68': ['airbnb', 'facebook', 'linkedin'], + '69': ['apple', 'bloomberg', 'facebook'], + '70': ['adobe', 'apple'], + '71': ['facebook', 'microsoft'], + '73': ['amazon', 'microsoft'], + '75': ['facebook', 'microsoft', 'pocketgems'], + '76': ['facebook', 'linkedin', 'snapchat', 'uber'], + '78': ['amazon', 'bloomberg', 'facebook', 'uber'], + '79': ['bloomberg', 'facebook', 'microsoft'], + '80': ['facebook'], + '85': ['facebook'], + '88': ['bloomberg', 'facebook', 'microsoft'], + '89': ['amazon'], + '90': ['facebook'], + '91': ['facebook', 'microsoft', 'uber'], + '94': ['microsoft'], + '96': ['snapchat'], + '98': ['amazon', 'bloomberg', 'facebook', 'microsoft'], + '100': ['bloomberg'], + '101': ['bloomberg', 'linkedin', 'microsoft'], + '102': ['amazon', 'apple', 'bloomberg', 'facebook', 'linkedin', 'microsoft'], + '103': ['bloomberg', 'linkedin', 'microsoft'], + '104': ['apple', 'linkedin', 'uber', 'yahoo'], + '105': ['bloomberg'], + '106': ['microsoft'], + '108': ['airbnb'], + '109': ['zenefits'], + '110': ['bloomberg'], + '112': ['microsoft'], + '113': ['bloomberg'], + '114': ['microsoft'], + '116': ['microsoft'], + '117': ['bloomberg', 'facebook', 'microsoft'], + '118': ['apple', 'twitter'], + '119': ['amazon'], + '121': ['amazon', 'bloomberg', 'facebook', 'microsoft', 'uber'], + '122': ['bloomberg'], + '124': ['baidu', 'microsoft'], + '125': ['facebook', 'microsoft', 'uber', 'zenefits'], + '126': ['amazon', 'yelp'], + '127': ['amazon', 'facebook', 'linkedin', 'snapchat', 'yelp'], + '128': ['facebook', 'google'], + '131': ['bloomberg'], + '133': ['facebook', 'google', 'pocketgems', 'uber'], + '136': ['airbnb', 'palantir'], + '138': ['amazon', 'bloomberg', 'microsoft', 'uber'], + '139': ['amazon', 'bloomberg', 'facebook', 'google', 'pocketgems', 'uber', 'yahoo'], + '140': ['dropbox', 'google', 'snapchat', 'twitter', 'uber'], + '141': ['amazon', 'bloomberg', 'microsoft', 'yahoo'], + '146': ['amazon', 'bloomberg', 'facebook', 'google', 'microsoft', 'palantir', 'snapchat', 'twitter', 'uber', 'yahoo', 'zenefits'], + '149': ['apple', 'linkedin', 'twitter'], + '150': ['linkedin'], + '151': ['apple', 'bloomberg', 'microsoft', 'snapchat', 'yelp'], + '152': ['linkedin'], + '153': ['microsoft'], + '155': ['amazon', 'bloomberg', 'google', 'snapchat', 'uber', 'zenefits'], + '156': ['linkedin'], + '157': ['facebook'], + '158': ['bloomberg', 'facebook', 'google'], + '159': ['google'], + '160': ['airbnb', 'amazon', 'bloomberg', 'microsoft'], + '161': ['facebook', 'snapchat', 'twitter', 'uber'], + '162': ['google', 'microsoft'], + '163': ['google'], + '165': ['apple', 'microsoft'], + '166': ['google'], + '167': ['amazon'], + '168': ['facebook', 'microsoft', 'zenefits'], + '169': ['adobe', 'zenefits'], + '170': ['linkedin'], + '171': ['microsoft', 'uber'], + '172': ['bloomberg'], + '173': ['facebook', 'google', 'linkedin', 'microsoft'], + '174': ['microsoft'], + '186': ['amazon', 'microsoft', 'uber'], + '187': ['linkedin'], + '189': ['amazon', 'bloomberg', 'microsoft'], + '190': ['airbnb', 'apple'], + '191': ['apple', 'microsoft'], + '195': ['adobe'], + '198': ['airbnb', 'linkedin'], + '199': ['amazon'], + '200': ['amazon', 'facebook', 'google', 'microsoft', 'zenefits'], + '202': ['airbnb', 'twitter', 'uber'], + '204': ['amazon', 'microsoft'], + '205': ['linkedin'], + '206': ['adobe', 'amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'snapchat', 'twitter', 'uber', 'yahoo', 'yelp', 'zenefits'], + '207': ['apple', 'uber', 'yelp', 'zenefits'], + '208': ['bloomberg', 'facebook', 'google', 'microsoft', 'twitter', 'uber'], + '209': ['facebook'], + '210': ['facebook', 'zenefits'], + '211': ['facebook'], + '212': ['airbnb', 'google', 'microsoft'], + '213': ['microsoft'], + '214': ['google', 'pocketgems'], + '215': ['amazon', 'apple', 'bloomberg', 'facebook', 'microsoft', 'pocketgems'], + '217': ['airbnb', 'palantir', 'yahoo'], + '218': ['facebook', 'google', 'microsoft', 'twitter', 'yelp'], + '219': ['airbnb', 'palantir'], + '220': ['airbnb', 'palantir'], + '221': ['airbnb', 'apple', 'facebook'], + '224': ['google'], + '225': ['bloomberg'], + '227': ['airbnb'], + '228': ['google'], + '229': ['zenefits'], + '230': ['bloomberg', 'google', 'uber'], + '231': ['google'], + '232': ['bloomberg', 'microsoft'], + '234': ['amazon', 'facebook'], + '235': ['amazon', 'facebook', 'microsoft', 'twitter'], + '236': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], + '237': ['adobe', 'apple', 'microsoft'], + '238': ['amazon', 'apple', 'facebook', 'linkedin', 'microsoft'], + '239': ['amazon', 'google', 'zenefits'], + '240': ['amazon', 'apple', 'google'], + '242': ['amazon', 'uber', 'yelp'], + '243': ['linkedin'], + '244': ['linkedin'], + '245': ['linkedin'], + '246': ['google'], + '247': ['google'], + '249': ['google', 'uber'], + '251': ['airbnb', 'google', 'twitter', 'zenefits'], + '252': ['facebook'], + '253': ['facebook', 'google', 'snapchat'], + '254': ['linkedin', 'uber'], + '255': ['zenefits'], + '256': ['linkedin'], + '257': ['apple', 'facebook', 'google'], + '258': ['adobe', 'microsoft'], + '259': ['google'], + '261': ['facebook', 'google', 'zenefits'], + '262': ['uber'], + '265': ['facebook'], + '266': ['bloomberg', 'google', 'uber'], + '268': ['bloomberg', 'microsoft'], + '269': ['airbnb', 'facebook', 'google', 'pocketgems', 'snapchat', 'twitter'], + '270': ['google', 'microsoft', 'snapchat'], + '271': ['google'], + '272': ['google'], + '273': ['facebook', 'microsoft'], + '274': ['bloomberg', 'facebook', 'google'], + '275': ['facebook'], + '276': ['google'], + '277': ['facebook', 'linkedin'], + '278': ['facebook'], + '279': ['google'], + '280': ['google'], + '281': ['google'], + '282': ['facebook', 'google'], + '283': ['bloomberg', 'facebook'], + '284': ['apple', 'google', 'yahoo'], + '285': ['facebook', 'microsoft', 'pocketgems'], + '286': ['facebook', 'google'], + '287': ['bloomberg'], + '288': ['google'], + '289': ['dropbox', 'google', 'snapchat', 'twosigma'], + '290': ['dropbox', 'uber'], + '291': ['dropbox', 'uber'], + '292': ['adobe'], + '293': ['google'], + '294': ['google'], + '295': ['google'], + '296': ['twitter'], + '297': ['amazon', 'bloomberg', 'facebook', 'google', 'linkedin', 'microsoft', 'uber', 'yahoo'], + '298': ['google'], + '300': ['microsoft'], + '301': ['facebook'], + '302': ['google'], + '303': ['palantir'], + '305': ['google'], + '308': ['google'], + '309': ['google'], + '310': ['google'], + '311': ['facebook', 'linkedin'], + '312': ['google', 'snapchat'], + '313': ['google'], + '314': ['facebook', 'google', 'snapchat'], + '315': ['google'], + '316': ['google'], + '317': ['google', 'zenefits'], + '318': ['google'], + '320': ['google'], + '321': ['google'], + '323': ['google', 'twitter'], + '324': ['google'], + '325': ['facebook', 'palantir'], + '326': ['google'], + '327': ['google'], + '329': ['google'], + '330': ['google'], + '331': ['google'], + '332': ['google'], + '333': ['microsoft'], + '334': ['facebook'], + '336': ['airbnb', 'google'], + '337': ['uber'], + '339': ['linkedin'], + '340': ['google'], + '341': ['facebook', 'google', 'twitter'], + '342': ['twosigma'], + '345': ['google'], + '346': ['google'], + '347': ['pocketgems', 'yelp'], + '348': ['google', 'microsoft'], + '349': ['twosigma'], + '351': ['google'], + '353': ['google'], + '354': ['google'], + '355': ['amazon', 'twitter'], + '356': ['google'], + '357': ['google'], + '358': ['google'], + '359': ['google'], + '360': ['google'], + '361': ['google'], + '362': ['dropbox', 'google'], + '363': ['google'], + '364': ['linkedin'], + '365': ['microsoft'], + '366': ['linkedin'], + '367': ['linkedin'], + '368': ['google'], + '369': ['google'], + '370': ['google'], + '373': ['google', 'uber'], + '374': ['google'], + '375': ['google'], + '377': ['facebook', 'google', 'snapchat'], + '378': ['google', 'twitter'], + '379': ['google'], + '380': ['amazon', 'facebook', 'google', 'pocketgems', 'twitter', 'uber', 'yelp'], + '381': ['yelp'], + '382': ['google'], + '383': ['apple'], + '385': ['airbnb'], + '386': ['bloomberg'], + '387': ['amazon', 'bloomberg', 'microsoft'], + '388': ['google'], + '389': ['google'], + '391': ['google'], + '393': ['google'], + '394': ['google', 'yelp'], + '395': ['baidu'], + '396': ['amazon'], + '397': ['baidu', 'google'], + '398': ['facebook'], + '399': ['google'], + '400': ['google'], + '401': ['google'], + '402': ['google', 'snapchat'], + '403': ['snapchat'], + '404': ['facebook'], + '406': ['google'], + '407': ['google', 'twitter'], + '408': ['google'], + '409': ['google'], + '410': ['baidu', 'facebook'], + '411': ['google'], + '413': ['baidu'], + '414': ['amazon'], + '415': ['airbnb', 'google'], + '416': ['ebay'], + '417': ['google'], + '418': ['google'], + '419': ['microsoft'], + '421': ['google'], + '422': ['google'], + '424': ['pocketgems'], + '425': ['google'], + '432': ['uber'], + '433': ['twitter'], + '438': ['amazon'], + '439': ['snapchat'], + '442': ['pocketgems'], + '443': ['bloomberg', 'microsoft', 'snapchat', 'yelp'], + '444': ['google'], + '445': ['bloomberg', 'microsoft'], + '446': ['baidu'], + '447': ['google'], + '448': ['google'], + '449': ['amazon'], + '450': ['uber'], + '451': ['amazon', 'google'], + '452': ['microsoft'], + '453': ['indeed'], + '459': ['amazon', 'google'], + '460': ['amazon', 'google'], + '461': ['facebook'], + '463': ['google'], + '464': ['linkedin'], + '465': ['google'], + '468': ['twitter'], + '469': ['google'], + '471': ['google'], + '474': ['google'], + '475': ['google'], + '477': ['facebook'], + '479': ['yahoo'], + '480': ['google'], + '481': ['google'], + '482': ['google'], + '483': ['google'], + '484': ['google'], + '485': ['google'], + '486': ['google'], + '487': ['google'], + '488': ['baidu'], + '490': ['google'], + '491': ['yahoo'], + '493': ['google'], + '494': ['facebook', 'google'], + '498': ['google'], + '500': ['mathworks'], + '501': ['google'], + '503': ['google'], + '505': ['google'], + '506': ['google'], + '508': ['amazon'], + '513': ['microsoft'], + '514': ['google'], + '515': ['linkedin'], + '516': ['amazon', 'uber'], + '517': ['amazon'], + '520': ['google'], + '521': ['google'], + '522': ['google'], + '523': ['facebook'], + '524': ['google'], + '525': ['facebook'], + '526': ['google'], + '527': ['google', 'snapchat'], + '529': ['amazon'], + '530': ['google'], + '531': ['google'], + '532': ['amazon'], + '533': ['google'], + '534': ['amazon', 'facebook', 'google', 'uber'], + '535': ['amazon', 'facebook', 'google', 'uber'], + '536': ['amazon'], + '537': ['amazon'], + '538': ['amazon'], + '541': ['google'], + '542': ['google'], + '543': ['facebook', 'google'], + '544': ['google'], + '545': ['amazon', 'google'], + '547': ['bloomberg', 'twosigma'], + '548': ['alibaba'], + '549': ['google'], + '551': ['google'], + '552': ['google'], + '553': ['amazon'], + '554': ['facebook'], + '555': ['alibaba'], + '556': ['bloomberg'], + '557': ['zappos'], + '560': ['google'], + '562': ['google'], + '563': ['indeed'], + '564': ['yelp'], + '566': ['mathworks'], + '567': ['microsoft'], + '568': ['google'], + '569': ['google'], + '570': ['bloomberg'], + '572': ['ebay', 'facebook', 'google'], + '576': ['baidu'], + '578': ['facebook'], + '579': ['amazon'], + '580': ['twitter'], + '581': ['google'], + '582': ['bloomberg'], + '583': ['google'], + '585': ['twitter'], + '586': ['twitter'], + '587': ['google'], + '591': ['microsoft'], + '597': ['facebook'], + '599': ['yelp'], + '602': ['facebook'], + '604': ['google'], + '605': ['linkedin'], + '606': ['amazon'], + '608': ['twitter'], + '616': ['google'], + '617': ['amazon'], + '621': ['facebook'], + '631': ['microsoft'], + '633': ['linkedin'], + '635': ['snapchat'], + '636': ['facebook', 'uber'], + '637': ['facebook'], + '638': ['google'], + '639': ['facebook'], + '640': ['amazon'], + '642': ['facebook', 'microsoft'], + '643': ['google'], + '644': ['google'], + '645': ['amazon'], + '646': ['amazon'], + '647': ['facebook', 'linkedin'], + '648': ['uber'], + '650': ['microsoft'], + '651': ['google', 'microsoft'], + '652': ['google'], + '653': ['facebook'], + '654': ['microsoft'], + '656': ['google'], + '657': ['google'], + '658': ['google'], + '659': ['google'], + '661': ['amazon'], + '662': ['amazon'], + '663': ['amazon'], + '665': ['google'], + '667': ['google'], + '668': ['google'], + '669': ['bloomberg'], + '670': ['facebook'], + '671': ['linkedin'], + '672': ['microsoft'], + '673': ['facebook'], + '674': ['facebook'], + '675': ['amazon'], + '676': ['google'], + '679': ['google'], + '680': ['facebook'], + '681': ['google'], + '682': ['amazon'], + '683': ['google'], + '684': ['google'], + '685': ['google'], + '686': ['google'], + '687': ['google'], + '689': ['facebook', 'google'], + '690': ['uber'], + '692': ['amazon', 'bloomberg', 'uber', 'yelp'], + '694': ['amazon'], + '698': ['linkedin'], + '699': ['uber'], + '711': ['amazon'], + '714': ['bloomberg', 'facebook'], + '716': ['linkedin'], + '719': ['google'], + '721': ['facebook'], + '722': ['microsoft'], + '725': ['amazon'], + '726': ['google'], + '727': ['google'], + '729': ['google'], + '730': ['linkedin'], + '731': ['google'] }; plugin.getProblems = function(cb) { From 016b0ab3e3656d0026130f146d29996bb19a478b Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 18 Dec 2017 15:06:47 +0800 Subject: [PATCH 05/48] [company] update tags list. refs #6 Signed-off-by: Eric Wang --- plugins/company.js | 650 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 645 insertions(+), 5 deletions(-) diff --git a/plugins/company.js b/plugins/company.js index fcee83c..acdd158 100644 --- a/plugins/company.js +++ b/plugins/company.js @@ -12,7 +12,7 @@ var plugin = new Plugin(100, 'company', '2017.12.18', // * lintcode.com // * 1point3acres.com // * other results from google search -var DATA = { +var COMPONIES = { '1': ['adobe', 'airbnb', 'amazon', 'apple', 'bloomberg', 'dropbox', 'facebook', 'linkedin', 'microsoft', 'uber', 'yahoo', 'yelp'], '2': ['adobe', 'airbnb', 'amazon', 'bloomberg', 'microsoft'], '3': ['adobe', 'amazon', 'bloomberg', 'yelp'], @@ -521,17 +521,657 @@ var DATA = { '731': ['google'] }; +var TAGS = { + '1': ['array', 'hash-table'], + '2': ['linked-list', 'math'], + '3': ['hash-table', 'string', 'two-pointers'], + '4': ['array', 'binary-search', 'divide-and-conquer'], + '5': ['string'], + '6': ['string'], + '7': ['math'], + '8': ['math', 'string'], + '9': ['math'], + '10': ['backtracking', 'dynamic-programming', 'string'], + '11': ['array', 'two-pointers'], + '12': ['math', 'string'], + '13': ['math', 'string'], + '14': ['string'], + '15': ['array', 'two-pointers'], + '16': ['array', 'two-pointers'], + '17': ['backtracking', 'string'], + '18': ['array', 'hash-table', 'two-pointers'], + '19': ['linked-list', 'two-pointers'], + '20': ['stack', 'string'], + '21': ['linked-list'], + '22': ['backtracking', 'string'], + '23': ['divide-and-conquer', 'heap', 'linked-list'], + '24': ['linked-list'], + '25': ['linked-list'], + '26': ['array', 'two-pointers'], + '27': ['array', 'two-pointers'], + '28': ['string', 'two-pointers'], + '29': ['binary-search', 'math'], + '30': ['hash-table', 'string', 'two-pointers'], + '31': ['array'], + '32': ['dynamic-programming', 'string'], + '33': ['array', 'binary-search'], + '34': ['array', 'binary-search'], + '35': ['array', 'binary-search'], + '36': ['hash-table'], + '37': ['backtracking', 'hash-table'], + '38': ['string'], + '39': ['array', 'backtracking'], + '40': ['array', 'backtracking'], + '41': ['array'], + '42': ['array', 'stack', 'two-pointers'], + '43': ['math', 'string'], + '44': ['backtracking', 'dynamic-programming', 'greedy', 'string'], + '45': ['array', 'greedy'], + '46': ['backtracking'], + '47': ['backtracking'], + '48': ['array'], + '49': ['hash-table', 'string'], + '50': ['binary-search', 'math'], + '51': ['backtracking'], + '52': ['backtracking'], + '53': ['array', 'divide-and-conquer', 'dynamic-programming'], + '54': ['array'], + '55': ['array', 'greedy'], + '56': ['array', 'sort'], + '57': ['array', 'sort'], + '58': ['string'], + '59': ['array'], + '60': ['backtracking', 'math'], + '61': ['linked-list', 'two-pointers'], + '62': ['array', 'dynamic-programming'], + '63': ['array', 'dynamic-programming'], + '64': ['array', 'dynamic-programming'], + '65': ['math', 'string'], + '66': ['array', 'math'], + '67': ['math', 'string'], + '68': ['string'], + '69': ['binary-search', 'math'], + '70': ['dynamic-programming'], + '71': ['stack', 'string'], + '72': ['dynamic-programming', 'string'], + '73': ['array'], + '74': ['array', 'binary-search'], + '75': ['array', 'sort', 'two-pointers'], + '76': ['hash-table', 'string', 'two-pointers'], + '77': ['backtracking'], + '78': ['array', 'backtracking', 'bit-manipulation'], + '79': ['array', 'backtracking'], + '80': ['array', 'two-pointers'], + '81': ['array', 'binary-search'], + '82': ['linked-list'], + '83': ['linked-list'], + '84': ['array', 'stack'], + '85': ['array', 'dynamic-programming', 'hash-table', 'stack'], + '86': ['linked-list', 'two-pointers'], + '87': ['dynamic-programming', 'string'], + '88': ['array', 'two-pointers'], + '89': ['backtracking'], + '90': ['array', 'backtracking'], + '91': ['dynamic-programming', 'string'], + '92': ['linked-list'], + '93': ['backtracking', 'string'], + '94': ['hash-table', 'stack', 'tree'], + '95': ['dynamic-programming', 'tree'], + '96': ['dynamic-programming', 'tree'], + '97': ['dynamic-programming', 'string'], + '98': ['depth-first-search', 'tree'], + '99': ['depth-first-search', 'tree'], + '100': ['depth-first-search', 'tree'], + '101': ['breadth-first-search', 'depth-first-search', 'tree'], + '102': ['breadth-first-search', 'tree'], + '103': ['breadth-first-search', 'stack', 'tree'], + '104': ['depth-first-search', 'tree'], + '105': ['array', 'depth-first-search', 'tree'], + '106': ['array', 'depth-first-search', 'tree'], + '107': ['breadth-first-search', 'tree'], + '108': ['depth-first-search', 'tree'], + '109': ['depth-first-search', 'linked-list'], + '110': ['depth-first-search', 'tree'], + '111': ['breadth-first-search', 'depth-first-search', 'tree'], + '112': ['depth-first-search', 'tree'], + '113': ['depth-first-search', 'tree'], + '114': ['depth-first-search', 'tree'], + '115': ['dynamic-programming', 'string'], + '116': ['depth-first-search', 'tree'], + '117': ['depth-first-search', 'tree'], + '118': ['array'], + '119': ['array'], + '120': ['array', 'dynamic-programming'], + '121': ['array', 'dynamic-programming'], + '122': ['array', 'greedy'], + '123': ['array', 'dynamic-programming'], + '124': ['depth-first-search', 'tree'], + '125': ['string', 'two-pointers'], + '126': ['array', 'backtracking', 'breadth-first-search', 'string'], + '127': ['breadth-first-search'], + '128': ['array', 'union-find'], + '129': ['depth-first-search', 'tree'], + '130': ['breadth-first-search', 'depth-first-search', 'union-find'], + '131': ['backtracking'], + '132': ['dynamic-programming'], + '133': ['breadth-first-search', 'depth-first-search', 'graph'], + '134': ['greedy'], + '135': ['greedy'], + '136': ['bit-manipulation', 'hash-table'], + '137': ['bit-manipulation'], + '138': ['hash-table', 'linked-list'], + '139': ['dynamic-programming'], + '140': ['backtracking', 'dynamic-programming'], + '141': ['linked-list', 'two-pointers'], + '142': ['linked-list', 'two-pointers'], + '143': ['linked-list'], + '144': ['stack', 'tree'], + '145': ['stack', 'tree'], + '146': ['design'], + '147': ['linked-list', 'sort'], + '148': ['linked-list', 'sort'], + '149': ['hash-table', 'math'], + '150': ['stack'], + '151': ['string'], + '152': ['array', 'dynamic-programming'], + '153': ['array', 'binary-search'], + '154': ['array', 'binary-search'], + '155': ['design', 'stack'], + '156': ['tree'], + '157': ['string'], + '158': ['string'], + '159': ['hash-table', 'string', 'two-pointers'], + '160': ['linked-list'], + '161': ['string'], + '162': ['array', 'binary-search'], + '163': ['array'], + '164': ['sort'], + '165': ['string'], + '166': ['hash-table', 'math'], + '167': ['array', 'binary-search', 'two-pointers'], + '168': ['math'], + '169': ['array', 'bit-manipulation', 'divide-and-conquer'], + '170': ['design', 'hash-table'], + '171': ['math'], + '172': ['math'], + '173': ['design', 'stack', 'tree'], + '174': ['binary-search', 'dynamic-programming'], + '179': ['sort'], + '186': ['string'], + '187': ['bit-manipulation', 'hash-table'], + '188': ['dynamic-programming'], + '189': ['array'], + '190': ['bit-manipulation'], + '191': ['bit-manipulation'], + '198': ['dynamic-programming'], + '199': ['breadth-first-search', 'depth-first-search', 'tree'], + '200': ['breadth-first-search', 'depth-first-search', 'union-find'], + '201': ['bit-manipulation'], + '202': ['hash-table', 'math'], + '203': ['linked-list'], + '204': ['hash-table', 'math'], + '205': ['hash-table'], + '206': ['linked-list'], + '207': ['breadth-first-search', 'depth-first-search', 'graph', 'topological-sort'], + '208': ['design', 'trie'], + '209': ['array', 'binary-search', 'two-pointers'], + '210': ['breadth-first-search', 'depth-first-search', 'graph', 'topological-sort'], + '211': ['backtracking', 'design', 'trie'], + '212': ['backtracking', 'trie'], + '213': ['dynamic-programming'], + '214': ['string'], + '215': ['divide-and-conquer', 'heap'], + '216': ['array', 'backtracking'], + '217': ['array', 'hash-table'], + '218': ['binary-indexed-tree', 'divide-and-conquer', 'heap', 'segment-tree'], + '219': ['array', 'hash-table'], + '221': ['dynamic-programming'], + '222': ['binary-search', 'tree'], + '223': ['math'], + '224': ['math', 'stack'], + '225': ['design', 'stack'], + '226': ['tree'], + '227': ['string'], + '228': ['array'], + '229': ['array'], + '230': ['binary-search', 'tree'], + '231': ['bit-manipulation', 'math'], + '232': ['design', 'stack'], + '233': ['math'], + '234': ['linked-list', 'two-pointers'], + '235': ['tree'], + '236': ['tree'], + '237': ['linked-list'], + '238': ['array'], + '239': ['heap'], + '240': ['binary-search', 'divide-and-conquer'], + '241': ['divide-and-conquer'], + '242': ['hash-table', 'sort'], + '243': ['array'], + '244': ['design', 'hash-table'], + '245': ['array'], + '246': ['hash-table', 'math'], + '247': ['math'], + '248': ['math'], + '249': ['hash-table', 'string'], + '250': ['tree'], + '251': ['design'], + '252': ['sort'], + '253': ['greedy', 'heap', 'sort'], + '254': ['backtracking'], + '255': ['stack', 'tree'], + '256': ['dynamic-programming'], + '257': ['depth-first-search', 'tree'], + '258': ['math'], + '259': ['array', 'two-pointers'], + '260': ['bit-manipulation'], + '261': ['breadth-first-search', 'depth-first-search', 'graph', 'union-find'], + '263': ['math'], + '264': ['dynamic-programming', 'heap', 'math'], + '265': ['dynamic-programming'], + '266': ['hash-table'], + '267': ['backtracking'], + '268': ['array', 'bit-manipulation', 'math'], + '269': ['graph', 'topological-sort'], + '270': ['binary-search', 'tree'], + '271': ['string'], + '272': ['stack', 'tree'], + '273': ['math', 'string'], + '274': ['hash-table', 'sort'], + '275': ['binary-search'], + '276': ['dynamic-programming'], + '277': ['array'], + '278': ['binary-search'], + '279': ['breadth-first-search', 'dynamic-programming', 'math'], + '280': ['array', 'sort'], + '281': ['design'], + '282': ['divide-and-conquer'], + '283': ['array', 'two-pointers'], + '284': ['design'], + '285': ['tree'], + '286': ['breadth-first-search'], + '287': ['array', 'binary-search', 'two-pointers'], + '288': ['design', 'hash-table'], + '289': ['array'], + '290': ['hash-table'], + '291': ['backtracking'], + '293': ['string'], + '294': ['backtracking'], + '295': ['design', 'heap'], + '296': ['math', 'sort'], + '297': ['design', 'tree'], + '298': ['tree'], + '299': ['hash-table'], + '300': ['binary-search', 'dynamic-programming'], + '301': ['breadth-first-search', 'depth-first-search'], + '302': ['binary-search'], + '303': ['dynamic-programming'], + '304': ['dynamic-programming'], + '305': ['union-find'], + '307': ['binary-indexed-tree', 'segment-tree'], + '308': ['binary-indexed-tree', 'segment-tree'], + '309': ['dynamic-programming'], + '310': ['breadth-first-search', 'graph'], + '311': ['hash-table'], + '312': ['divide-and-conquer', 'dynamic-programming'], + '313': ['heap', 'math'], + '314': ['hash-table'], + '315': ['binary-indexed-tree', 'divide-and-conquer', 'segment-tree'], + '316': ['greedy', 'stack'], + '317': ['breadth-first-search'], + '318': ['bit-manipulation'], + '319': ['math'], + '320': ['backtracking', 'bit-manipulation'], + '321': ['dynamic-programming', 'greedy'], + '322': ['dynamic-programming'], + '323': ['breadth-first-search', 'depth-first-search', 'graph', 'union-find'], + '324': ['sort'], + '325': ['hash-table'], + '326': ['math'], + '327': ['divide-and-conquer'], + '328': ['linked-list'], + '329': ['depth-first-search', 'topological-sort'], + '330': ['greedy'], + '331': ['stack'], + '332': ['depth-first-search', 'graph'], + '333': ['tree'], + '335': ['math'], + '336': ['hash-table', 'string', 'trie'], + '337': ['depth-first-search', 'tree'], + '338': ['bit-manipulation', 'dynamic-programming'], + '339': ['depth-first-search'], + '340': ['hash-table', 'string'], + '341': ['design', 'stack'], + '342': ['bit-manipulation'], + '343': ['dynamic-programming', 'math'], + '344': ['string', 'two-pointers'], + '345': ['string', 'two-pointers'], + '346': ['design', 'queue'], + '347': ['hash-table', 'heap'], + '348': ['design'], + '349': ['binary-search', 'hash-table', 'sort', 'two-pointers'], + '350': ['binary-search', 'hash-table', 'sort', 'two-pointers'], + '351': ['backtracking', 'dynamic-programming'], + '353': ['design', 'queue'], + '354': ['binary-search', 'dynamic-programming'], + '355': ['design', 'hash-table', 'heap'], + '356': ['hash-table', 'math'], + '357': ['backtracking', 'dynamic-programming', 'math'], + '358': ['greedy', 'hash-table', 'heap'], + '359': ['design', 'hash-table'], + '360': ['math', 'two-pointers'], + '361': ['dynamic-programming'], + '362': ['design'], + '363': ['binary-search', 'dynamic-programming', 'queue'], + '364': ['depth-first-search'], + '365': ['math'], + '366': ['depth-first-search', 'tree'], + '367': ['binary-search', 'math'], + '368': ['dynamic-programming', 'math'], + '369': ['linked-list'], + '370': ['array'], + '371': ['bit-manipulation'], + '372': ['math'], + '373': ['heap'], + '374': ['binary-search'], + '375': ['dynamic-programming'], + '376': ['dynamic-programming', 'greedy'], + '377': ['dynamic-programming'], + '378': ['binary-search', 'heap'], + '379': ['design', 'linked-list'], + '380': ['array', 'design', 'hash-table'], + '381': ['array', 'design', 'hash-table'], + '382': ['reservoir-sampling'], + '383': ['string'], + '385': ['stack', 'string'], + '387': ['hash-table', 'string'], + '389': ['bit-manipulation', 'hash-table'], + '392': ['binary-search', 'dynamic-programming', 'greedy'], + '393': ['bit-manipulation'], + '394': ['depth-first-search', 'stack'], + '396': ['math'], + '397': ['bit-manipulation', 'math'], + '398': ['reservoir-sampling'], + '399': ['graph'], + '400': ['math'], + '401': ['backtracking', 'bit-manipulation'], + '402': ['greedy', 'stack'], + '403': ['dynamic-programming'], + '404': ['tree'], + '405': ['bit-manipulation'], + '406': ['greedy'], + '407': ['breadth-first-search', 'heap'], + '408': ['string'], + '409': ['hash-table'], + '410': ['binary-search', 'dynamic-programming'], + '411': ['backtracking', 'bit-manipulation'], + '413': ['dynamic-programming', 'math'], + '414': ['array'], + '415': ['math'], + '416': ['dynamic-programming'], + '417': ['breadth-first-search', 'depth-first-search'], + '418': ['dynamic-programming'], + '421': ['bit-manipulation', 'trie'], + '423': ['math'], + '425': ['backtracking', 'trie'], + '432': ['design'], + '434': ['string'], + '435': ['greedy'], + '436': ['binary-search'], + '437': ['tree'], + '438': ['hash-table'], + '439': ['depth-first-search', 'stack'], + '441': ['binary-search', 'math'], + '442': ['array'], + '443': ['string'], + '444': ['graph', 'topological-sort'], + '445': ['linked-list'], + '446': ['dynamic-programming'], + '447': ['hash-table'], + '448': ['array'], + '449': ['tree'], + '450': ['tree'], + '451': ['hash-table', 'heap'], + '452': ['greedy'], + '453': ['math'], + '454': ['binary-search', 'hash-table'], + '455': ['greedy'], + '456': ['stack'], + '459': ['string'], + '460': ['design'], + '461': ['bit-manipulation'], + '462': ['math'], + '463': ['hash-table'], + '464': ['dynamic-programming'], + '466': ['dynamic-programming'], + '467': ['dynamic-programming'], + '468': ['string'], + '469': ['math'], + '471': ['dynamic-programming'], + '472': ['depth-first-search', 'dynamic-programming', 'trie'], + '473': ['depth-first-search'], + '474': ['dynamic-programming'], + '475': ['binary-search'], + '476': ['bit-manipulation'], + '477': ['bit-manipulation'], + '483': ['binary-search', 'math'], + '484': ['greedy'], + '485': ['array'], + '486': ['dynamic-programming'], + '487': ['two-pointers'], + '488': ['depth-first-search'], + '490': ['breadth-first-search', 'depth-first-search'], + '491': ['depth-first-search'], + '493': ['binary-indexed-tree', 'divide-and-conquer', 'segment-tree'], + '494': ['depth-first-search', 'dynamic-programming'], + '495': ['array'], + '496': ['stack'], + '499': ['breadth-first-search', 'depth-first-search'], + '500': ['hash-table'], + '501': ['tree'], + '502': ['greedy', 'heap'], + '503': ['stack'], + '505': ['breadth-first-search', 'depth-first-search'], + '507': ['math'], + '508': ['hash-table', 'tree'], + '513': ['breadth-first-search', 'depth-first-search', 'tree'], + '514': ['depth-first-search', 'divide-and-conquer', 'dynamic-programming'], + '515': ['breadth-first-search', 'depth-first-search', 'tree'], + '516': ['dynamic-programming'], + '517': ['dynamic-programming', 'math'], + '520': ['string'], + '521': ['string'], + '522': ['string'], + '523': ['dynamic-programming', 'math'], + '524': ['sort', 'two-pointers'], + '525': ['hash-table'], + '526': ['backtracking'], + '527': ['sort', 'string'], + '529': ['breadth-first-search', 'depth-first-search'], + '531': ['array', 'depth-first-search'], + '532': ['array', 'two-pointers'], + '533': ['array', 'depth-first-search'], + '535': ['hash-table', 'math'], + '536': ['string', 'tree'], + '537': ['math', 'string'], + '538': ['tree'], + '539': ['string'], + '541': ['string'], + '542': ['breadth-first-search', 'depth-first-search'], + '543': ['tree'], + '544': ['string'], + '545': ['tree'], + '546': ['depth-first-search', 'dynamic-programming'], + '547': ['depth-first-search', 'union-find'], + '548': ['array'], + '549': ['tree'], + '551': ['string'], + '552': ['dynamic-programming'], + '553': ['math', 'string'], + '554': ['hash-table'], + '555': ['string'], + '556': ['string'], + '557': ['string'], + '560': ['array', 'map'], + '561': ['array'], + '562': ['array'], + '563': ['tree'], + '564': ['string'], + '565': ['array'], + '566': ['array'], + '567': ['two-pointers'], + '568': ['dynamic-programming'], + '572': ['tree'], + '573': ['math'], + '575': ['hash-table'], + '576': ['depth-first-search', 'dynamic-programming'], + '581': ['array'], + '582': ['queue', 'tree'], + '583': ['string'], + '588': ['design'], + '591': ['stack', 'string'], + '592': ['math'], + '593': ['math'], + '594': ['hash-table'], + '598': ['math'], + '599': ['hash-table'], + '600': ['dynamic-programming'], + '604': ['design'], + '605': ['array'], + '606': ['string', 'tree'], + '609': ['hash-table', 'string'], + '611': ['array'], + '616': ['string'], + '617': ['tree'], + '621': ['array', 'greedy', 'queue'], + '623': ['tree'], + '624': ['array', 'hash-table'], + '625': ['math'], + '628': ['array', 'math'], + '629': ['dynamic-programming'], + '630': ['greedy'], + '631': ['design'], + '632': ['hash-table', 'string', 'two-pointers'], + '633': ['math'], + '634': ['math'], + '635': ['design', 'string'], + '636': ['stack'], + '637': ['tree'], + '638': ['depth-first-search', 'dynamic-programming'], + '639': ['dynamic-programming'], + '640': ['math'], + '642': ['design', 'trie'], + '643': ['array'], + '644': ['array', 'binary-search'], + '645': ['hash-table', 'math'], + '646': ['dynamic-programming'], + '647': ['dynamic-programming', 'string'], + '648': ['hash-table', 'trie'], + '649': ['greedy'], + '650': ['dynamic-programming'], + '651': ['dynamic-programming', 'greedy', 'math'], + '652': ['tree'], + '653': ['tree'], + '654': ['tree'], + '655': ['tree'], + '656': ['dynamic-programming'], + '657': ['string'], + '658': ['binary-search'], + '659': ['greedy', 'heap'], + '660': ['math'], + '661': ['array'], + '662': ['tree'], + '663': ['tree'], + '664': ['depth-first-search', 'dynamic-programming'], + '665': ['array'], + '666': ['tree'], + '667': ['array'], + '668': ['binary-search'], + '669': ['tree'], + '670': ['array', 'math'], + '671': ['tree'], + '672': ['math'], + '673': ['dynamic-programming'], + '674': ['array'], + '675': ['breadth-first-search'], + '676': ['hash-table', 'trie'], + '677': ['trie'], + '678': ['string'], + '679': ['depth-first-search'], + '680': ['string'], + '681': ['string'], + '682': ['stack'], + '683': ['array'], + '684': ['graph', 'tree', 'union-find'], + '685': ['depth-first-search', 'graph', 'tree', 'union-find'], + '686': ['string'], + '687': ['tree'], + '688': ['dynamic-programming'], + '689': ['array', 'dynamic-programming'], + '690': ['breadth-first-search', 'depth-first-search', 'hash-table'], + '691': ['backtracking', 'dynamic-programming'], + '692': ['hash-table', 'heap', 'trie'], + '693': ['bit-manipulation'], + '694': ['depth-first-search', 'hash-table'], + '695': ['array', 'depth-first-search'], + '696': ['string'], + '697': ['array'], + '698': ['dynamic-programming'], + '699': ['segment-tree'], + '711': ['depth-first-search', 'hash-table'], + '712': ['dynamic-programming'], + '713': ['array', 'two-pointers'], + '714': ['array', 'dynamic-programming', 'greedy'], + '715': ['array', 'segment-tree'], + '716': ['design'], + '717': ['array'], + '718': ['array', 'binary-search', 'dynamic-programming', 'hash-table'], + '719': ['array', 'binary-search', 'heap'], + '720': ['hash-table', 'trie'], + '721': ['depth-first-search', 'union-find'], + '722': ['string'], + '723': ['array', 'two-pointers'], + '724': ['array'], + '725': ['linked-list'], + '726': ['hash-table', 'stack'], + '727': ['dynamic-programming'], + '728': ['math'], + '729': ['array'], + '730': ['dynamic-programming', 'string'], + '731': ['array'], + '732': ['segment-tree'], + '733': ['depth-first-search'], + '734': ['hash-table'], + '735': ['stack'], + '736': ['string'], + '737': ['depth-first-search', 'union-find'], + '738': ['greedy'], + '739': ['hash-table', 'stack'], + '740': ['dynamic-programming'], + '741': ['dynamic-programming'], + '742': ['tree'], + '743': ['breadth-first-search', 'depth-first-search', 'graph', 'heap'], + '744': ['binary-search'], + '745': ['trie'], + '746': ['array', 'dynamic-programming'], + '748': ['hash-table'], + '749': ['depth-first-search'], + '750': ['dynamic-programming'] +}; + plugin.getProblems = function(cb) { plugin.next.getProblems(function(e, problems) { if (e) return cb(e); problems.forEach(function(problem) { var id = String(problem.id); - if (!(id in DATA)) return; - - problem.companies = DATA[id]; + if (id in COMPONIES) { + problem.companies = (problem.companies || []).concat(COMPONIES[id]); + } + if (id in TAGS) { + problem.tags = (problem.tags || []).concat(TAGS[id]); + } }); - return cb(null, problems); }); }; From 6ffbfd55c270ff20832d5afc437b8f6c1b7a4e03 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Wed, 20 Dec 2017 22:22:34 +0800 Subject: [PATCH 06/48] Update docs for leetcode 2.2.0 Signed-off-by: Eric Wang --- docs/cpp.lint.md | 15 ++++++++++++--- docs/cpp.run.md | 2 +- docs/github.md | 15 ++++++++++++++- plugins/company.js | 5 +++-- plugins/cpp.lint.js | 17 ++--------------- plugins/cpp.run.js | 5 +++-- plugins/github.js | 11 ++--------- plugins/lintcode.js | 4 ++++ plugins/solution.discuss.js | 5 +++++ 9 files changed, 46 insertions(+), 33 deletions(-) diff --git a/docs/cpp.lint.md b/docs/cpp.lint.md index f5bfb3f..5ad4d57 100644 --- a/docs/cpp.lint.md +++ b/docs/cpp.lint.md @@ -4,7 +4,7 @@ Run cpplint to check c++ code syntax before running `test` against leetcode.com. ## Requirement -* `cpplint.py`: [download](https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py) +* need install`cpplint.py`: [download](https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py) ## Config @@ -13,12 +13,21 @@ Run cpplint to check c++ code syntax before running `test` against leetcode.com. * `+` to enable specific checking. * `-` to disable specific checking. +*Set Config* + + $ leetcode config plugins:cpp.lint:bin + $ leetcode config plugins:cpp.lint:flags '["-whitespace/indent"]' + +*Unset Config* + + $ leetcode config -d plugins:cpp.lint + *Example* { - "PLUGINS": { + "plugins": { "cpp.lint": { - "bin": "", + "bin": "/usr/bin/cpplint.py", "flags": [ "-whitespace/indent" ] diff --git a/docs/cpp.run.md b/docs/cpp.run.md index 53e55ae..2f0c0c2 100644 --- a/docs/cpp.run.md +++ b/docs/cpp.run.md @@ -10,7 +10,7 @@ NOTE: not fully support all the questions! ## Requirement -* `g++` with c++11 support. +* need install `g++` with c++11 support. ## Usage diff --git a/docs/github.md b/docs/github.md index d6fcd33..0b49a32 100644 --- a/docs/github.md +++ b/docs/github.md @@ -2,15 +2,28 @@ Auto commit the accepted code to your own (public) GitHub repo. +## Requirement + +* create an access token for your github repo. + ## Config * `repo`: your GitHub repo to persistent accpeted code. * `token`: the access token to your repo, see [how to get token](#generate-token). +*Set Config* + + $ leetcode config plugins:github:repo + $ leetcode config plugins:github:token + +*Unset Config* + + $ leetcode config -f plugins:github + *Example* { - "PLUGINS": { + "plugins": { "github": { "repo": "https://github.com/skygragon/test", "token": "xxxxxxxxxxxxx" diff --git a/plugins/company.js b/plugins/company.js index acdd158..711d8a6 100644 --- a/plugins/company.js +++ b/plugins/company.js @@ -1,8 +1,9 @@ var Plugin = require('../plugin'); -// [prerequisite] // -// [config] +// [Usage] +// +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/company.md // var plugin = new Plugin(100, 'company', '2017.12.18', 'Plugin to query by company for free user.'); diff --git a/plugins/cpp.lint.js b/plugins/cpp.lint.js index b8cdeca..5f12348 100644 --- a/plugins/cpp.lint.js +++ b/plugins/cpp.lint.js @@ -3,24 +3,11 @@ var cp = require('child_process'); var log = require('../log'); var Plugin = require('../plugin'); -// [prerequisite] // -// Need install cpplint: -// https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py +// [Usage] // -// [config] +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cpp.lint.md // -// You can disable/enable some checks in "flags" section. -// -// "PLUGINS": { -// "cpp.lint": { -// "bin": "", -// "flags": [ -// "-whitespace/indent", -// -// ] -// } -// } var plugin = new Plugin(100, 'cpp.lint', '2017.07.27', 'Plugin to do static code check on c++ code.'); diff --git a/plugins/cpp.run.js b/plugins/cpp.run.js index d9113e0..6f206f8 100644 --- a/plugins/cpp.run.js +++ b/plugins/cpp.run.js @@ -11,9 +11,10 @@ var session = require('../session'); // // Only works for those problems could be easily tested. // -// [prerequisite] +// [Usage] +// +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cpp.run.md // -// - g++ (support c++11) var plugin = new Plugin(100, 'cpp.run', '2017.07.29', 'Plugin to run cpp code locally for debugging.'); diff --git a/plugins/github.js b/plugins/github.js index 4344ff1..62f0500 100644 --- a/plugins/github.js +++ b/plugins/github.js @@ -5,18 +5,11 @@ var h = require('../helper'); var log = require('../log'); var Plugin = require('../plugin'); -// [prerequisite] // -// - create a new access token on your github repo setting. (TBD) +// [Usage] // -// [config] +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/github.md // -// "PLUGINS": { -// "github": { -// "repo": "https://github.com///", -// "token": "" -// } -// } var plugin = new Plugin(100, 'github', '2017.08.10', 'Plugin to commit accepted code to your own github repo.', ['github']); diff --git a/plugins/lintcode.js b/plugins/lintcode.js index bf0c950..55e3aa4 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -14,6 +14,10 @@ var session = require('../session'); // TODO: star/submissions/submission // FIXME: why [ERROR] Error: read ECONNRESET [0]?? // +// [Usage] +// +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/lintcode.md +// var plugin = new Plugin(15, 'lintcode', '2017.08.04', 'Plugin to talk with lintcode APIs.'); diff --git a/plugins/solution.discuss.js b/plugins/solution.discuss.js index abab796..73f7f8b 100644 --- a/plugins/solution.discuss.js +++ b/plugins/solution.discuss.js @@ -6,6 +6,11 @@ var chalk = require('../chalk'); var Plugin = require('../plugin'); var session = require('../session'); +// +// [Usage] +// +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/solution.discuss.md +// var plugin = new Plugin(200, 'solution.discuss', '2017.07.29', 'Plugin to fetch most voted solution in discussions.'); From 820c6e21bcdc0a880189bc102df7676eb51b81d6 Mon Sep 17 00:00:00 2001 From: skygragon Date: Wed, 20 Dec 2017 22:24:29 +0800 Subject: [PATCH 07/48] Update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 7e795bc..255559c 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,6 @@ Install from GitHub: *Example* $ leetcode plugin -i company - -Install from local file: - -    $ leetcode plugin -i To manage the installed plugins, please check [leetcode-cli's user guide](https://skygragon.github.io/leetcode-cli/commands#plugin). From 12dca72b04bd7fe4aedc02d019f6593721c5885f Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 21 Dec 2017 16:26:35 +0800 Subject: [PATCH 08/48] [solution] fixes TypeError in some problems. refs #2 Signed-off-by: Eric Wang --- plugins/solution.discuss.js | 88 +++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/plugins/solution.discuss.js b/plugins/solution.discuss.js index 73f7f8b..5786983 100644 --- a/plugins/solution.discuss.js +++ b/plugins/solution.discuss.js @@ -1,4 +1,5 @@ var _ = require('underscore'); +var cheerio = require('cheerio'); var request = require('request'); var log = require('../log'); @@ -16,49 +17,72 @@ var plugin = new Plugin(200, 'solution.discuss', '2017.07.29', var URL_DISCUSSES = 'https://discuss.leetcode.com/api/category/'; var URL_DISCUSS_TOPIC = 'https://discuss.leetcode.com/topic/'; +var URL_DISCUSS_TOPIC_API = 'https://discuss.leetcode.com/api/topic/'; -plugin.getProblem = function(problem, cb) { - plugin.next.getProblem(problem, function(e, problem) { - if (e || !session.argv.solution) return cb(e, problem); +function getSolutionDetail(solution, cb) { + if (!solution) return cb(); - var opts = { - url: URL_DISCUSSES + problem.discuss - }; - request(opts, function(e, resp, body) { - if (e) return cb(e); - if (resp.statusCode !== 200) - return cb({msg: 'http error', statusCode: resp.statusCode}); + request(URL_DISCUSS_TOPIC_API + solution.slug, function(e, resp, body) { + if (e) return cb(e); + if (resp.statusCode !== 200) + return cb({msg: 'http error', statusCode: resp.statusCode}); - var lang = session.argv.lang; - var langs = [lang]; - // try to find more compatible langs - if (lang === 'cpp') langs.push('c++'); - if (lang === 'csharp') langs.push('c#'); - if (lang === 'golang') langs.push('go'); - if (lang === 'javascript') langs.push('js'); - if (lang === 'python3') langs.push('python'); + var data = JSON.parse(body); + solution.title = data.titleRaw; + var $ = cheerio.load(data.posts[0].content); + solution.content = $.root().text(); + return cb(null, solution); + }); +} - var data = JSON.parse(body); - var solution = _.find(data.topics, function(x) { - var keys = x.title.toLowerCase().split(' '); - for (var i = 0; i < keys.length; ++i) { - if (langs.indexOf(keys[i]) >= 0) return true; - } - return false; - }); +function getSolution(problem, lang, cb) { + if (!problem) return cb(); - if (!solution) { - return log.error('Solution not found for ' + lang); + request(URL_DISCUSSES + problem.discuss, function(e, resp, body) { + if (e) return cb(e); + if (resp.statusCode !== 200) + return cb({msg: 'http error', statusCode: resp.statusCode}); + + var langs = [lang]; + // try to find more compatible langs + if (lang === 'cpp') langs.push('c++'); + if (lang === 'csharp') langs.push('c#'); + if (lang === 'golang') langs.push('go'); + if (lang === 'javascript') langs.push('js'); + if (lang === 'python3') langs.push('python'); + + var data = JSON.parse(body); + var solution = _.find(data.topics, function(x) { + var keys = x.title.toLowerCase().split(' '); + for (var i = 0; i < keys.length; ++i) { + if (langs.indexOf(keys[i]) >= 0) return true; } + return false; + }); - log.info(solution._imported_title); + return getSolutionDetail(solution, cb); + }); +} + +plugin.getProblem = function(problem, cb) { + plugin.next.getProblem(problem, function(e, problem) { + if (e || !session.argv.solution) return cb(e, problem); + + var lang = session.argv.lang; + getSolution(problem, lang, function(e, solution) { + if (e) return cb(e); + if (!solution) return log.error('Solution not found for ' + lang); + + log.info(); + log.info(solution.title); log.info(); log.info(chalk.underline(URL_DISCUSS_TOPIC + solution.slug)); log.info(); - log.info('* Lang: ' + lang); - log.info('* Votes: ' + solution.votes); + log.info('* Lang: ' + lang); + log.info('* Author: ' + solution.user.username); + log.info('* Votes: ' + solution.votes); log.info(); - log.info(chalk.yellow(solution._imported_content)); + log.info(solution.content); }); }); }; From 07e31ffb9135faafa6f081fb888d51cca59fd4fa Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 21 Dec 2017 16:29:32 +0800 Subject: [PATCH 09/48] [solution] update plugin version. fixes #2 Signed-off-by: Eric Wang --- plugins/solution.discuss.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/solution.discuss.js b/plugins/solution.discuss.js index 5786983..fac9c1b 100644 --- a/plugins/solution.discuss.js +++ b/plugins/solution.discuss.js @@ -12,7 +12,7 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/solution.discuss.md // -var plugin = new Plugin(200, 'solution.discuss', '2017.07.29', +var plugin = new Plugin(200, 'solution.discuss', '2017.12.21', 'Plugin to fetch most voted solution in discussions.'); var URL_DISCUSSES = 'https://discuss.leetcode.com/api/category/'; From 876f17c45fe107dc9b9b17889618b4d06b8a179c Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Fri, 22 Dec 2017 23:39:04 +0800 Subject: [PATCH 10/48] [WIP] reuse chrome cookie for leetcode.com * inspired by https://github.com/skygragon/leetcode-cli/issues/71 Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 118 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 plugins/cookie.chrome.js diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js new file mode 100644 index 0000000..5d169ed --- /dev/null +++ b/plugins/cookie.chrome.js @@ -0,0 +1,118 @@ +var log = require('../log'); +var Plugin = require('../plugin'); + +// [Usage] +// +// TODO: still WIP +// +var plugin = new Plugin(100, 'cookie.chrome', '2017.12.22', + 'Plugin to reuse Chrome\'s leetcode cookie.', + ['keytar', 'sqlite3']); + +var Chrome = {}; + +var ChromeMAC = { + db: process.env.HOME + '/Library/Application Support/Google/Chrome/Default/Cookies', + iterations: 1003, + getPassword: function(cb) { + var keytar = require('keytar'); + keytar.getPassword('Chrome Safe Storage', 'Chrome').then(cb); + } +}; + +// TODO: test this +var ChromeLinux = { + db: process.env.HOME + '/.config/google-chrome/Default/Cookies', + iterations: 1, + getPassword: function(cb) { cb('peanuts'); } +}; + +var ChromeWindows = { + // TODO +}; + +Object.setPrototypeOf(ChromeMAC, Chrome); +Object.setPrototypeOf(ChromeLinux, Chrome); +Object.setPrototypeOf(ChromeWindows, Chrome); + +Chrome.getInstance = function() { + switch (process.platform) { + case 'darwin': return ChromeMAC; + case 'linux': return ChromeLinux; + case 'win32': return ChromeWindows; + } +}; +var my = Chrome.getInstance(); + +Chrome.decodeCookie = function(cookie, cb) { + var crypto = require('crypto'); + crypto.pbkdf2(my.password, 'saltysalt', my.iterations, 16, 'sha1', function(e, key) { + if (e) return cb(e); + + var iv = new Buffer(' '.repeat(16)); + var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv); + decipher.setAutoPadding(false); + + var buf = decipher.update(cookie.slice(3)); // remove prefix "v10" or "v11" + var final = decipher.final(); + final.copy(buf, buf.length - 1); + + var padding = buf[buf.length - 1]; + if (padding) buf = buf.slice(0, buf.length - padding); + + return cb(null, buf.toString('utf8')); + }); +}; + +Chrome.decodeCookies = function(keys, cb) { + if (keys.length === 0) return cb(null, my.cookies); + + var k = keys.pop(); + var v = my.cookies[k]; + if (!v) return cb('Not found cookie: ' + k); + + my.decodeCookie(v, function(e, cookie) { + my.cookies[k] = cookie; + my.decodeCookies(keys, cb); + }); +}; + +var KEYS = ['csrftoken', 'LEETCODE_SESSION']; +Chrome.getCookies = function(cb) { + var sqlite3 = require('sqlite3'); + var db = new sqlite3.Database(my.db); + + db.serialize(function() { + my.cookies = {}; + var sql = 'select name, encrypted_value from cookies where host_key like "%leetcode.com"'; + db.each(sql, function(e, x) { + if (e) return cb(e); + if (KEYS.indexOf(x.name) < 0) return; + my.cookies[x.name] = x.encrypted_value; + }); + + db.close(function() { + my.getPassword(function(password) { + my.password = password; + my.decodeCookies(KEYS, cb); + }); + }); + }); +}; + +plugin.signin = function(user, cb) { + log.debug('try to copy leetcode cookies from chrome ...'); + my.getCookies(function(e, cookie) { + if (e) { + log.error('failed to get cookies: ' + e); + return plugin.next.signin(user, cb); + } + + log.debug('Successfully copied leetcode cookies!'); + user.sessionId = cookie.LEETCODE_SESSION; + user.sessionCSRF = cookie.csrftoken; + return cb(null, user); + }); +}; + +module.exports = plugin; From 4b86c408415a9c5a592ae23411c24230d93f201a Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 23 Dec 2017 09:38:31 +0800 Subject: [PATCH 11/48] [cookie.chrome] WIP Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index 5d169ed..1c6bcb1 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -1,11 +1,12 @@ var log = require('../log'); var Plugin = require('../plugin'); +var session = require('../session'); // [Usage] // // TODO: still WIP // -var plugin = new Plugin(100, 'cookie.chrome', '2017.12.22', +var plugin = new Plugin(13, 'cookie.chrome', '2017.12.23', 'Plugin to reuse Chrome\'s leetcode cookie.', ['keytar', 'sqlite3']); @@ -101,18 +102,28 @@ Chrome.getCookies = function(cb) { }; plugin.signin = function(user, cb) { + log.debug('running cookie.chrome.signin'); log.debug('try to copy leetcode cookies from chrome ...'); my.getCookies(function(e, cookie) { if (e) { - log.error('failed to get cookies: ' + e); + log.error('failed to copy cookies: ' + e); return plugin.next.signin(user, cb); } log.debug('Successfully copied leetcode cookies!'); user.sessionId = cookie.LEETCODE_SESSION; user.sessionCSRF = cookie.csrftoken; + session.saveUser(user); return cb(null, user); }); }; +plugin.login = function(user, cb) { + log.debug('running cookie.chrome.login'); + plugin.signin(user, function(e, user) { + if (e) return cb(e); + plugin.getUser(user, cb); + }); +}; + module.exports = plugin; From f99ff3d143483f151f9489b8b0cd8605a723e1e8 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 23 Dec 2017 22:49:34 +0800 Subject: [PATCH 12/48] [cookie.chrome] add linux support. Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index 1c6bcb1..01dc758 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -8,7 +8,13 @@ var session = require('../session'); // var plugin = new Plugin(13, 'cookie.chrome', '2017.12.23', 'Plugin to reuse Chrome\'s leetcode cookie.', - ['keytar', 'sqlite3']); + ['keytar:darwin', 'sqlite3']); + +plugin.help = function() { + if (os.platform === 'linux') { + log.info('To complete the install: sudo apt install libsecret-tools'); + } +}; var Chrome = {}; @@ -21,11 +27,15 @@ var ChromeMAC = { } }; -// TODO: test this var ChromeLinux = { db: process.env.HOME + '/.config/google-chrome/Default/Cookies', iterations: 1, - getPassword: function(cb) { cb('peanuts'); } + getPassword: function(cb) { + // FIXME: keytar failed to read gnome-keyring on ubuntu?? + var cmd = 'secret-tool lookup application chrome'; + var password = require('child_process').execSync(cmd).toString(); + return cb(password); + } }; var ChromeWindows = { From af2caa2017057a1213717d00ce0945a1e61bccf7 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 23 Dec 2017 22:55:59 +0800 Subject: [PATCH 13/48] [cookie.chrome] fixes type. Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index 01dc758..938a11c 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -11,7 +11,7 @@ var plugin = new Plugin(13, 'cookie.chrome', '2017.12.23', ['keytar:darwin', 'sqlite3']); plugin.help = function() { - if (os.platform === 'linux') { + if (process.platform === 'linux') { log.info('To complete the install: sudo apt install libsecret-tools'); } }; From 499c48fdc6926af5c1c71b0c3c1cd1cda7f97ab8 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 23 Dec 2017 23:47:40 +0800 Subject: [PATCH 14/48] [cookie.chrome] add windows support. Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 49 ++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index 938a11c..665d348 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -1,3 +1,5 @@ +var path = require('path'); + var log = require('../log'); var Plugin = require('../plugin'); var session = require('../session'); @@ -8,11 +10,17 @@ var session = require('../session'); // var plugin = new Plugin(13, 'cookie.chrome', '2017.12.23', 'Plugin to reuse Chrome\'s leetcode cookie.', - ['keytar:darwin', 'sqlite3']); + ['ffi:win32', 'keytar:darwin', 'ref:win32', 'ref-struct:win32', 'sqlite3']); plugin.help = function() { - if (process.platform === 'linux') { - log.info('To complete the install: sudo apt install libsecret-tools'); + switch (process.platform) { + case 'darwin': + break; + case 'linux': + log.info('To complete the install: sudo apt install libsecret-tools'); + break; + case 'win32': + break; } }; @@ -39,7 +47,8 @@ var ChromeLinux = { }; var ChromeWindows = { - // TODO + db: path.resolve(process.env.APPDATA || '', '../Local/Google/Chrome/User Data/Default/Cookies'), + getPassword: function(cb) { cb(); } }; Object.setPrototypeOf(ChromeMAC, Chrome); @@ -55,6 +64,32 @@ Chrome.getInstance = function() { }; var my = Chrome.getInstance(); +ChromeWindows.decodeCookie = function(cookie, cb) { + var ref = require('ref'); + var ffi = require('ffi'); + var Struct = require('ref-struct'); + + var DATA_BLOB = Struct({ + cbData: ref.types.uint32, + pbData: ref.refType(ref.types.byte) + }); + var PDATA_BLOB = new ref.refType(DATA_BLOB); + var Crypto = new ffi.Library('Crypt32', { + 'CryptUnprotectData': ['bool', [PDATA_BLOB, 'string', 'string', 'void *', 'string', 'int', PDATA_BLOB]] + }); + + var inBlob = new DATA_BLOB(); + inBlob.pbData = cookie; + inBlob.cbData = cookie.length; + var outBlob = ref.alloc(DATA_BLOB); + + Crypto.CryptUnprotectData(inBlob.ref(), null, null, null, null, 0, outBlob); + var outDeref = outBlob.deref(); + var buf = ref.reinterpret(outDeref.pbData, outDeref.cbData, 0); + + return cb(null, buf.toString('utf8')); +}; + Chrome.decodeCookie = function(cookie, cb) { var crypto = require('crypto'); crypto.pbkdf2(my.password, 'saltysalt', my.iterations, 16, 'sha1', function(e, key) { @@ -114,15 +149,15 @@ Chrome.getCookies = function(cb) { plugin.signin = function(user, cb) { log.debug('running cookie.chrome.signin'); log.debug('try to copy leetcode cookies from chrome ...'); - my.getCookies(function(e, cookie) { + my.getCookies(function(e, cookies) { if (e) { log.error('failed to copy cookies: ' + e); return plugin.next.signin(user, cb); } log.debug('Successfully copied leetcode cookies!'); - user.sessionId = cookie.LEETCODE_SESSION; - user.sessionCSRF = cookie.csrftoken; + user.sessionId = cookies.LEETCODE_SESSION; + user.sessionCSRF = cookies.csrftoken; session.saveUser(user); return cb(null, user); }); From 747e00f2827fb608388cdf6c3273ac04148db970 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 24 Dec 2017 10:31:31 +0800 Subject: [PATCH 15/48] Update README.md Signed-off-by: Eric Wang --- README.md | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 255559c..85e507e 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,9 @@ 3rd party plugins for leetcode-cli. |Plugin|Description|Enhanced Commands| -|-|-|-| -|[company](/docs/company.md)|Filter questions by company|`list`| +|------|-----------|-----------------| +|[company](/docs/company.md)|Filter questions by company or tags|`list`| +|[cookie.chrome](/docs/cookie.chrome.md)|Don't expire Chrome's session on same computer|`login`| |[cpp.lint](/docs/cpp.lint.md)|C++ code syntax check|`test`| |[cpp.run](/docs/cpp.run.md)|Test C++ code locally|`test`| |[github](/docs/github.md)|Commit accpeted code to GitHub|`submit`| @@ -12,22 +13,51 @@ ## HOWTO -You can install the plugins in either ways below: +### Install -### Quick Install +Install plugin from this GitHub repo: -Install from GitHub: - - $ leetcode plugin -i + $ leetcode plugin -i *Example* $ leetcode plugin -i company -To manage the installed plugins, please check [leetcode-cli's user guide](https://skygragon.github.io/leetcode-cli/commands#plugin). +**NOTE: Check [leetcode-cli's plugin guide](https://skygragon.github.io/leetcode-cli/commands#plugin) for more details.** ### Configuration -Some plugins could be configured with your customized options. +Some plugins could be configured with your customized options. Please read plugin's doc to see the details. + +*Example* + +Take `gitHub` plugin for example: + +Set configs: + + $ leetcode config plugins.github.token 12345678 + +Show configs: + + $ leetcode config plugins.github + $ leetcode plugin -c github + +Delete configs: + + $ leetcode config -d plugins.github + +**NOTE: Check [leetcode-cli's configuration guide](https://skygragon.github.io/leetcode-cli/advanced#configuration) for more details.** + +### Management + +Disable: + + $ leetcode plugin -d + +Enable: + + $ leetcode plugin -e + +Delete: -Check [leetcode-cli's configuration](https://skygragon.github.io/leetcode-cli/advanced#configuration) for more details. + $ leetcode plugin -D \ No newline at end of file From 5c81d9aa5273ede3aafa53a85ec4426812e0a38d Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 24 Dec 2017 11:00:30 +0800 Subject: [PATCH 16/48] [cookie.chrome] add doc. * refs https://github.com/skygragon/leetcode-cli/issues/71 Signed-off-by: Eric Wang --- docs/cookie.chrome.md | 42 ++++++++++++++++++++++++++++++++++++++++++ docs/github.md | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 docs/cookie.chrome.md diff --git a/docs/cookie.chrome.md b/docs/cookie.chrome.md new file mode 100644 index 0000000..a4f7593 --- /dev/null +++ b/docs/cookie.chrome.md @@ -0,0 +1,42 @@ +# cookie.chrome + +Leetcode.com only permits one live session for same account, which means if you login successfully via leetcode-cli, your existing session in browser will get expired, and vice versa. + +This plugin enables leetcode-cli to try to reuse the existing session in your chrome borwser on the same computer. + +If succeed, you can keep leetcode-cli and chrome both alive in the same time. + +If failed, it will fall back to normal login to leetcode.com as before. + + +## Requirement + +In short it's case by case since it varies on different platforms (Mac/Linux/Windows), different chrome versions, even different cookie encryption versions (v10/v11). + +### Linux + +Make sure `secret-tool` is available: + + $ sudo apt-get install libsecret-tools + +### Windows + +Make sure build environment is ready before installing plugin: + + $ npm install -g windows-build-tools + $ npm config set msvs_version 2015 -g + +## Usage + +If enabled, the login will try to reuse existing chrome cookies. You can verify it by printing debug output as below. + + $ leetcode user -l -v + login: + pass: + [DEBUG] running cookie.chrome.login + [DEBUG] running cookie.chrome.signin + [DEBUG] try to copy leetcode cookies from chrome ... + [DEBUG] Successfully copied leetcode cookies! + [DEBUG] running leetcode.getFavorites + Successfully login as + diff --git a/docs/github.md b/docs/github.md index 0b49a32..d756942 100644 --- a/docs/github.md +++ b/docs/github.md @@ -18,7 +18,7 @@ Auto commit the accepted code to your own (public) GitHub repo. *Unset Config* - $ leetcode config -f plugins:github + $ leetcode config -d plugins:github *Example* From c782c6d6a5e990f0d801ac7816da1973cb28f26a Mon Sep 17 00:00:00 2001 From: skygragon Date: Sun, 24 Dec 2017 11:41:14 +0800 Subject: [PATCH 17/48] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 85e507e..c5b4e89 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,16 @@ Take `gitHub` plugin for example: Set configs: - $ leetcode config plugins.github.token 12345678 + $ leetcode config plugins:github:token 12345678 Show configs: - $ leetcode config plugins.github + $ leetcode config plugins:github $ leetcode plugin -c github Delete configs: - $ leetcode config -d plugins.github + $ leetcode config -d plugins:github **NOTE: Check [leetcode-cli's configuration guide](https://skygragon.github.io/leetcode-cli/advanced#configuration) for more details.** @@ -60,4 +60,4 @@ Enable: Delete: - $ leetcode plugin -D \ No newline at end of file + $ leetcode plugin -D From cbf2c0961c237dd1a80dfeb6359ad2e7d22830fc Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 24 Dec 2017 22:30:52 +0800 Subject: [PATCH 18/48] Add logo image. Signed-off-by: Eric Wang --- README.md | 11 +++++++++-- docs/logo.png | Bin 0 -> 2181 bytes 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 docs/logo.png diff --git a/README.md b/README.md index c5b4e89..baf76fb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,15 @@ # leetcode-cli-plugins + + + 3rd party plugins for leetcode-cli. -|Plugin|Description|Enhanced Commands| -|------|-----------|-----------------| +See what [leetcode-cli](https://github.com/skygragon/leetcode-cli) is. + +## Plugins + +|Name|Description|Enhanced Commands| +|----|-----------|-----------------| |[company](/docs/company.md)|Filter questions by company or tags|`list`| |[cookie.chrome](/docs/cookie.chrome.md)|Don't expire Chrome's session on same computer|`login`| |[cpp.lint](/docs/cpp.lint.md)|C++ code syntax check|`test`| diff --git a/docs/logo.png b/docs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..cb69d3fbeabf7cb4939db4241de074ca6c4804dc GIT binary patch literal 2181 zcma)8i8s`1AD=N}nZX#chj5Xlm?;x)T(a-UZNey%ZOBfxp=2Ao$+cvOrkk=9g)mtr zeiNxTgBD9h%t)3RG*Mw(-06M)fcHJm`7WQ&`Fx*qo^!s>^L%s9oVF8(E5bn_khp`r z^&cP**p#0;iU{$&7Hm0!AB6mz?5siizt&$*>r40yEXp1i0|JR2_+?@AB~?2ImoowS1Yv&Z zX9sHwERnf-3s)d*BmW|W-QA)ja9KeREucceXcN`f*)}yq8}d!<0X?@wl&^?QwS-8rQxuiHVKkNaRlFls}1V0FP-B&ToXpWGxp1|$EMbr z8+n|y{fTWE5j7Ih@_#$^$?xmN3GgVhD8(o-l+?1s3V099OeF(CJ~}O@*JLa|T z)4B9xnRy<&HZHvA5Ikw|2Pc0vjU|_qH?srG0lvUNm3T6M7FD{S8x6AXIQ+ zBJ*?^CliT#hulhTs$Z2zV^#egURcfNRA zv-80w*hg|TAIH2!)jj(UvV*6+KR$uFin#s2(0UaXr!^+?TLBja2a?M zY(ByM{SfRzMx_mU!d-T+b(1IABEMAwA4*0?Q|J__fI5S+ zd;-g)Q8OVa0xZx)0lhR=RO4XYLLV_%d+@uu}Q@LUSPh{TP^b;Y-c$3UGWO)HPkM zwW(w^Wwl|U!UK|S1l=;u2r6kGK3dVc+py4WlD^zmJh3ZxOq!PdU#&NKuaZ*iPv;P- zmNS*$l*lj7j^MQyvY!<9?$3Ual{z;$S!PMi+oNBYAg@BVwLMZ$=vJC8#BcA zpA~QZ14A1IE-(hRY^Oi;$hX}}9g46-gc8X>8M5bjys8iKwS+O^0FI^@LRE5M}d(5-b6KryZ zmCwD#CQOOx`EE4y*L9GF5!u6Bk*{NyeAJ$2lw!%MV|i?u2dAP!f=j8=n5qhI9eds{+*U-HFwH+n+tlYf=M`>?Q*lDih zvnM1ErcI*mZY(kNC14b2vzB0FPXD8$+38CmHHAa1Y;m%$k-=iZYw;$5M~4Fdr}V@0 zp(-|pO}?7tlMYK~x{D zUNN31c2f}2AU=$L(b^ivE9gO|scGR3F$S9&@wqTrWTsO|gQQ0I?J-OP(DCj;?zoe< z!CIWRQ_GqYs`)9R>VOojc~W_4)Pg3BU9vQsTKrilM&pd{ z@jjBvzI@`$ym5+N?Yupr$%4*l$8^CYS$8C_bN1bW>1W%eVfeAfBS08u%BQNZ-bZUW z-XzS-@jWXvI#S?|aMk#6xzBpbu&8tI+N(CfjVOgg z??Z0`45%vOPj(tqppoe75A~=)+QdFb{@EpyTTVV}W5PZ-w0n1c4r%`96pc3Mh^cMXM$2fvbR~#bS``R5@ON-aMhzpdVW7RimA>^J zdvUa<8AVwd5&d= zsLIb-E%1}+loO3%gy8IC;rMBARV4aNv`Wj8ogcYg6?*unQ6f{nobABhW;6-M zCCfdSgQ?Lv4SeTtqDo~JtW5qRE}1_BD{Pa|#E!NZ%W@sLB;@$BGi){I72?G^S0s!v zwimDSRYh<&6Vk!d`#>UK&G>T@#bDb;Ixhtuth*h732faMz1;l&e5IBmMP~bu_W0t= UA7c08e@z1pHm9v0S^A{^10GiZp#T5? literal 0 HcmV?d00001 From b8368d2cb79e017768c7f263e3e1b76d6f647d1a Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Tue, 26 Dec 2017 20:42:02 +0800 Subject: [PATCH 19/48] [cookie.chrome] refactor to use queue. Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index 665d348..c318165 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -2,6 +2,7 @@ var path = require('path'); var log = require('../log'); var Plugin = require('../plugin'); +var Queue = require('../queue'); var session = require('../session'); // [Usage] @@ -110,37 +111,36 @@ Chrome.decodeCookie = function(cookie, cb) { }); }; -Chrome.decodeCookies = function(keys, cb) { - if (keys.length === 0) return cb(null, my.cookies); +function doDecode(key, queue, cb) { + var ctx = queue.ctx; + var cookie = ctx[key]; + if (!cookie) return cb('Not found cookie: ' + key); - var k = keys.pop(); - var v = my.cookies[k]; - if (!v) return cb('Not found cookie: ' + k); - - my.decodeCookie(v, function(e, cookie) { - my.cookies[k] = cookie; - my.decodeCookies(keys, cb); + my.decodeCookie(cookie, function(e, cookie) { + ctx[key] = cookie; + return cb(); }); -}; +} -var KEYS = ['csrftoken', 'LEETCODE_SESSION']; Chrome.getCookies = function(cb) { var sqlite3 = require('sqlite3'); var db = new sqlite3.Database(my.db); + var KEYS = ['csrftoken', 'LEETCODE_SESSION']; db.serialize(function() { - my.cookies = {}; + var cookies = {}; var sql = 'select name, encrypted_value from cookies where host_key like "%leetcode.com"'; db.each(sql, function(e, x) { if (e) return cb(e); if (KEYS.indexOf(x.name) < 0) return; - my.cookies[x.name] = x.encrypted_value; + cookies[x.name] = x.encrypted_value; }); db.close(function() { my.getPassword(function(password) { my.password = password; - my.decodeCookies(KEYS, cb); + var q = new Queue(KEYS, cookies, doDecode); + q.run(null, cb); }); }); }); From 37c6f81722cb6bbd54b34de5cb2a9cb763437fed Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 28 Dec 2017 12:22:46 +0800 Subject: [PATCH 20/48] Add cookie.firefox Signed-off-by: Eric Wang --- plugins/cookie.firefox.js | 80 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 plugins/cookie.firefox.js diff --git a/plugins/cookie.firefox.js b/plugins/cookie.firefox.js new file mode 100644 index 0000000..fe586ab --- /dev/null +++ b/plugins/cookie.firefox.js @@ -0,0 +1,80 @@ +var path = require('path'); + +var log = require('../log'); +var Plugin = require('../plugin'); +var session = require('../session'); + +// [Usage] +// +// TODO: still WIP +// +var plugin = new Plugin(13, 'cookie.firefox', '2017.12.28', + 'Plugin to reuse firefox\'s leetcode cookie.', + ['glob', 'sqlite3']); + +function getCookieFile(cb) { + var f; + switch (process.platform) { + case 'darwin': + f = process.env.HOME + '/Library/Application Support/Firefox/Profiles/*.default*/cookies.sqlite'; + break; + case 'linux': + f = process.env.HOME + '/.mozilla/firefox/*.default*/cookies.sqlite'; + break; + case 'win32': + f = path.resolve(process.env.APPDATA || '', '/Local/Mozilla/Firefox/Profiles/*.default*/cookies.sqlite'); + break; + } + require('glob')(f, {}, cb); +} + +function getCookies(cb) { + getCookieFile(function(e, files) { + if (e || files.length === 0) return cb('Not found cookie file!'); + + var sqlite3 = require('sqlite3'); + var db = new sqlite3.Database(files[0]); + var KEYS = ['csrftoken', 'LEETCODE_SESSION']; + + db.serialize(function() { + var cookies = {}; + var sql = 'select name, value from moz_cookies where host like "%leetcode.com"'; + db.each(sql, function(e, x) { + if (e) return cb(e); + if (KEYS.indexOf(x.name) < 0) return; + cookies[x.name] = x.value; + }); + + db.close(function() { + return cb(null, cookies); + }); + }); + }); +}; + +plugin.signin = function(user, cb) { + log.debug('running cookie.firefox.signin'); + log.debug('try to copy leetcode cookies from firefox ...'); + getCookies(function(e, cookies) { + if (e) { + log.error('failed to copy cookies: ' + e); + return plugin.next.signin(user, cb); + } + + log.debug('Successfully copied leetcode cookies!'); + user.sessionId = cookies.LEETCODE_SESSION; + user.sessionCSRF = cookies.csrftoken; + session.saveUser(user); + return cb(null, user); + }); +}; + +plugin.login = function(user, cb) { + log.debug('running cookie.firefox.login'); + plugin.signin(user, function(e, user) { + if (e) return cb(e); + plugin.getUser(user, cb); + }); +}; + +module.exports = plugin; From b7007f13504bfe17c5ac89489c4b82e0269b23df Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 28 Dec 2017 12:48:53 +0800 Subject: [PATCH 21/48] [cookie.firefox] fixes path on windows. Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 2 +- plugins/cookie.firefox.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index c318165..c5ac5b6 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -7,7 +7,7 @@ var session = require('../session'); // [Usage] // -// TODO: still WIP +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cookie.chrome.md // var plugin = new Plugin(13, 'cookie.chrome', '2017.12.23', 'Plugin to reuse Chrome\'s leetcode cookie.', diff --git a/plugins/cookie.firefox.js b/plugins/cookie.firefox.js index fe586ab..a2f9210 100644 --- a/plugins/cookie.firefox.js +++ b/plugins/cookie.firefox.js @@ -6,7 +6,7 @@ var session = require('../session'); // [Usage] // -// TODO: still WIP +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cookie.firefox.md // var plugin = new Plugin(13, 'cookie.firefox', '2017.12.28', 'Plugin to reuse firefox\'s leetcode cookie.', @@ -22,7 +22,7 @@ function getCookieFile(cb) { f = process.env.HOME + '/.mozilla/firefox/*.default*/cookies.sqlite'; break; case 'win32': - f = path.resolve(process.env.APPDATA || '', '/Local/Mozilla/Firefox/Profiles/*.default*/cookies.sqlite'); + f = path.resolve(process.env.APPDATA || '', '/Mozilla/Firefox/Profiles/*.default*/cookies.sqlite'); break; } require('glob')(f, {}, cb); From 05c7073ada88808ee6ad6e8902914e659077dd92 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 28 Dec 2017 12:54:38 +0800 Subject: [PATCH 22/48] [cookie.firefox] fixes path bug, 2nd Signed-off-by: Eric Wang --- plugins/cookie.firefox.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/cookie.firefox.js b/plugins/cookie.firefox.js index a2f9210..45d8645 100644 --- a/plugins/cookie.firefox.js +++ b/plugins/cookie.firefox.js @@ -1,5 +1,3 @@ -var path = require('path'); - var log = require('../log'); var Plugin = require('../plugin'); var session = require('../session'); @@ -22,7 +20,7 @@ function getCookieFile(cb) { f = process.env.HOME + '/.mozilla/firefox/*.default*/cookies.sqlite'; break; case 'win32': - f = path.resolve(process.env.APPDATA || '', '/Mozilla/Firefox/Profiles/*.default*/cookies.sqlite'); + f = (process.env.APPDATA || '') + '/Mozilla/Firefox/Profiles/*.default*/cookies.sqlite'; break; } require('glob')(f, {}, cb); From a86debbdbccbbff39ebc2222f0d2ac960b7580cd Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 28 Dec 2017 13:02:49 +0800 Subject: [PATCH 23/48] [cookie.firefox] update docs. Signed-off-by: Eric Wang --- README.md | 1 + docs/cookie.firefox.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docs/cookie.firefox.md diff --git a/README.md b/README.md index baf76fb..168aec7 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ See what [leetcode-cli](https://github.com/skygragon/leetcode-cli) is. |----|-----------|-----------------| |[company](/docs/company.md)|Filter questions by company or tags|`list`| |[cookie.chrome](/docs/cookie.chrome.md)|Don't expire Chrome's session on same computer|`login`| +|[cookie.firefox](/docs/cookie.firefox.md)|Don't expire Firefox's session on same computer|`login`| |[cpp.lint](/docs/cpp.lint.md)|C++ code syntax check|`test`| |[cpp.run](/docs/cpp.run.md)|Test C++ code locally|`test`| |[github](/docs/github.md)|Commit accpeted code to GitHub|`submit`| diff --git a/docs/cookie.firefox.md b/docs/cookie.firefox.md new file mode 100644 index 0000000..f3f413a --- /dev/null +++ b/docs/cookie.firefox.md @@ -0,0 +1,18 @@ +# cookie.firefox + +Same as [cookie.chrome](https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cookie.chrome.md), but works for Firefox. + +## Usage + +If enabled, the login will try to reuse existing Firefox cookies. You can verify it by printing debug output as below. + + $ leetcode user -l -v + login: + pass: + [DEBUG] running cookie.firefox.login + [DEBUG] running cookie.firefox.signin + [DEBUG] try to copy leetcode cookies from firefox ... + [DEBUG] Successfully copied leetcode cookies! + [DEBUG] running leetcode.getFavorites + Successfully login as + From 3565dbc0f838ef83cdff1650df4ad247f6b72081 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 6 Jan 2018 16:37:08 +0800 Subject: [PATCH 24/48] refs #4: fixes "Parameter url must be a string, not undefined" Signed-off-by: Eric Wang --- plugins/github.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/github.js b/plugins/github.js index 62f0500..f8a12e9 100644 --- a/plugins/github.js +++ b/plugins/github.js @@ -17,7 +17,7 @@ var plugin = new Plugin(100, 'github', '2017.08.10', var ctx = {}; plugin.submitProblem = function(problem, cb) { - var parts = url.parse(this.config.repo).pathname.split('/'); + var parts = url.parse(plugin.config.repo).pathname.split('/'); var filename = path.basename(problem.file); parts.push(filename); @@ -28,7 +28,7 @@ plugin.submitProblem = function(problem, cb) { var GitHubApi = require('github'); var github = new GitHubApi({host: 'api.github.com'}); - github.authenticate({type: 'token', token: this.config.token}); + github.authenticate({type: 'token', token: plugin.config.token}); plugin.next.submitProblem(problem, function(_e, results) { cb(_e, results); From 58660e94b252aa6f206b65e3cb509f93d5342146 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 6 Jan 2018 16:40:37 +0800 Subject: [PATCH 25/48] refs #4: update github plugin version. Signed-off-by: Eric Wang --- plugins/github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/github.js b/plugins/github.js index f8a12e9..80a8357 100644 --- a/plugins/github.js +++ b/plugins/github.js @@ -10,7 +10,7 @@ var Plugin = require('../plugin'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/github.md // -var plugin = new Plugin(100, 'github', '2017.08.10', +var plugin = new Plugin(100, 'github', '2018.01.06', 'Plugin to commit accepted code to your own github repo.', ['github']); From d671ec8bd1f087ef0998c945e04bdce591ce03e6 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 14 Jan 2018 09:53:12 +0800 Subject: [PATCH 26/48] Update README. Signed-off-by: Eric Wang --- README.md | 65 ++++++++++++++++--------------------------------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 168aec7..41fb9c1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ 3rd party plugins for leetcode-cli. -See what [leetcode-cli](https://github.com/skygragon/leetcode-cli) is. +* what is [leetcode-cli](https://github.com/skygragon/leetcode-cli) +* how to use [leetcode-cli plugins](https://skygragon.github.io/leetcode-cli/commands#plugin) +* how to use [leetcode-cli configs](https://skygragon.github.io/leetcode-cli/advanced#configuration) ## Plugins @@ -19,53 +21,24 @@ See what [leetcode-cli](https://github.com/skygragon/leetcode-cli) is. |[lintcode](/docs/lintcode.md)|Fight questions from lintcode.com|`list` `show` `test` `submit` `user`| |[solution.discuss](/docs/solution.discuss.md)|Fetch top voted solution|`show`| -## HOWTO +## Quick Start -### Install + $ leetcode plugin -i # install + $ leetcode plugin -d # disable + $ leetcode plugin -e # enable + $ leetcode plugin -D # delete -Install plugin from this GitHub repo: + $ leetcode plugin -c # show config + $ leetcode config plugins: # show config + $ leetcode config plugins:: # set config + $ leetcode config -d plugins: # delete config - $ leetcode plugin -i - -*Example* +**Example** - $ leetcode plugin -i company + $ leetcode plugin -i company # install compnay + $ leetcode plugin -D compnay # delete company -**NOTE: Check [leetcode-cli's plugin guide](https://skygragon.github.io/leetcode-cli/commands#plugin) for more details.** - -### Configuration - -Some plugins could be configured with your customized options. Please read plugin's doc to see the details. - -*Example* - -Take `gitHub` plugin for example: - -Set configs: - - $ leetcode config plugins:github:token 12345678 - -Show configs: - - $ leetcode config plugins:github - $ leetcode plugin -c github - -Delete configs: - - $ leetcode config -d plugins:github - -**NOTE: Check [leetcode-cli's configuration guide](https://skygragon.github.io/leetcode-cli/advanced#configuration) for more details.** - -### Management - -Disable: - - $ leetcode plugin -d - -Enable: - - $ leetcode plugin -e - -Delete: - - $ leetcode plugin -D + $ leetcode plugin -c github # show github plugin config + $ leetcode config plugins:github # show github plugin config + $ leetcode config plugins:github:token 12345678 # set github plugin config + $ leetcode config -d plugins:github # delete github plugin config From 7d8ccb8233bb06f209193a23a96f4fe82dd436fe Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 24 Mar 2018 18:31:51 +0800 Subject: [PATCH 27/48] refs #8: use old github lib for now. Signed-off-by: Eric Wang --- plugins/github.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/github.js b/plugins/github.js index 80a8357..cfbb3f2 100644 --- a/plugins/github.js +++ b/plugins/github.js @@ -10,9 +10,9 @@ var Plugin = require('../plugin'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/github.md // -var plugin = new Plugin(100, 'github', '2018.01.06', +var plugin = new Plugin(100, 'github', '2018.03.24', 'Plugin to commit accepted code to your own github repo.', - ['github']); + ['github@13']); var ctx = {}; From d276e3adffba1e8e8f6a16d4d51d915a4766e7e7 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 14 Apr 2018 11:15:01 +0800 Subject: [PATCH 28/48] [solution] update with latest leetcode.com change refs #9 refs #11 Signed-off-by: Eric Wang --- plugins/solution.discuss.js | 73 ++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/plugins/solution.discuss.js b/plugins/solution.discuss.js index fac9c1b..1289a13 100644 --- a/plugins/solution.discuss.js +++ b/plugins/solution.discuss.js @@ -12,33 +12,45 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/solution.discuss.md // -var plugin = new Plugin(200, 'solution.discuss', '2017.12.21', +var plugin = new Plugin(200, 'solution.discuss', '2018.04.14', 'Plugin to fetch most voted solution in discussions.'); -var URL_DISCUSSES = 'https://discuss.leetcode.com/api/category/'; -var URL_DISCUSS_TOPIC = 'https://discuss.leetcode.com/topic/'; -var URL_DISCUSS_TOPIC_API = 'https://discuss.leetcode.com/api/topic/'; - -function getSolutionDetail(solution, cb) { - if (!solution) return cb(); - - request(URL_DISCUSS_TOPIC_API + solution.slug, function(e, resp, body) { - if (e) return cb(e); - if (resp.statusCode !== 200) - return cb({msg: 'http error', statusCode: resp.statusCode}); - - var data = JSON.parse(body); - solution.title = data.titleRaw; - var $ = cheerio.load(data.posts[0].content); - solution.content = $.root().text(); - return cb(null, solution); - }); -} +var URL_DISCUSSES = 'https://leetcode.com/graphql'; +var URL_DISCUSS = 'https://leetcode.com/problems/$slug/discuss/$id'; function getSolution(problem, lang, cb) { if (!problem) return cb(); - request(URL_DISCUSSES + problem.discuss, function(e, resp, body) { + var opts = { + url: URL_DISCUSSES, + json: true, + qs: { + query: [ + 'query fetchTopics($questionId: Int!, $pageNo: Int!, $orderBy: String!) {', + ' questionTopics(questionId: $questionId, pageNo: $pageNo, orderBy: $orderBy) {', + ' data {', + ' id', + ' title', + ' post {', + ' content', + ' voteCount', + ' author {', + ' username', + ' }', + ' }', + ' }', + ' }', + '}' + ].join('\n'), + operationName: 'fetchTopics', + variables: JSON.stringify({ + pageNo: 1, + orderBy: 'most_votes', + questionId: problem.id + }) + } + }; + request(opts, function(e, resp, body) { if (e) return cb(e); if (resp.statusCode !== 200) return cb({msg: 'http error', statusCode: resp.statusCode}); @@ -51,16 +63,16 @@ function getSolution(problem, lang, cb) { if (lang === 'javascript') langs.push('js'); if (lang === 'python3') langs.push('python'); - var data = JSON.parse(body); - var solution = _.find(data.topics, function(x) { - var keys = x.title.toLowerCase().split(' '); + var solutions = body.data.questionTopics.data; + var solution = _.find(solutions, function(x) { + var keys = x.title.toLowerCase().split(/[^\w+]/); for (var i = 0; i < keys.length; ++i) { if (langs.indexOf(keys[i]) >= 0) return true; } return false; }); - return getSolutionDetail(solution, cb); + return cb(null, solution); }); } @@ -73,16 +85,19 @@ plugin.getProblem = function(problem, cb) { if (e) return cb(e); if (!solution) return log.error('Solution not found for ' + lang); + var link = URL_DISCUSS.replace('$slug', problem.slug).replace('$id', solution.id); + var content = solution.post.content.replace(/\\n/g, '\n').replace(/\\t/g, '\t'); + log.info(); log.info(solution.title); log.info(); - log.info(chalk.underline(URL_DISCUSS_TOPIC + solution.slug)); + log.info(chalk.underline(link)); log.info(); log.info('* Lang: ' + lang); - log.info('* Author: ' + solution.user.username); - log.info('* Votes: ' + solution.votes); + log.info('* Author: ' + solution.post.author.username); + log.info('* Votes: ' + solution.post.voteCount); log.info(); - log.info(solution.content); + log.info(content); }); }); }; From 36aa07cee70b826b248662aacfb70cab71bbcb20 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 14 May 2018 10:53:12 +0800 Subject: [PATCH 29/48] Report error if missing configurations. refs #13 Signed-off-by: Eric Wang --- plugins/cpp.lint.js | 4 ++++ plugins/github.js | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/plugins/cpp.lint.js b/plugins/cpp.lint.js index 5f12348..a892cd5 100644 --- a/plugins/cpp.lint.js +++ b/plugins/cpp.lint.js @@ -17,6 +17,10 @@ var DEFAULT_FLAGS = [ ]; plugin.testProblem = function(problem, cb) { + // TODO: unify error handling + if (!plugin.config.bin) + return log.error('cpplint.py not configured correctly! (plugins:cpp.lint:bin)'); + var flags = DEFAULT_FLAGS.concat(plugin.config.flags || []); var cmd = [ diff --git a/plugins/github.js b/plugins/github.js index cfbb3f2..4c00e75 100644 --- a/plugins/github.js +++ b/plugins/github.js @@ -17,6 +17,12 @@ var plugin = new Plugin(100, 'github', '2018.03.24', var ctx = {}; plugin.submitProblem = function(problem, cb) { + // TODO: unify error handling + if (!plugin.config.repo) + return log.error('GitHub repo not configured correctly! (plugins:github:repo)'); + if (!plugin.config.token) + return log.error('GitHub token not configured correctly! (plugins:github:token)'); + var parts = url.parse(plugin.config.repo).pathname.split('/'); var filename = path.basename(problem.file); parts.push(filename); From e2cb5ae877e37151197d95df190fd09ea5f61f9b Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Tue, 29 May 2018 14:13:03 +0800 Subject: [PATCH 30/48] [lintcode] update to latest API (WIP) refs #15 #14 Signed-off-by: Eric Wang --- plugins/lintcode.js | 237 +++++++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 126 deletions(-) diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 55e3aa4..657c0af 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -6,7 +6,7 @@ var util = require('util'); var h = require('../helper'); var log = require('../log'); var Plugin = require('../plugin'); -var queue = require('../queue'); +var Queue = require('../queue'); var session = require('../session'); // Still working in progress! @@ -18,36 +18,40 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/lintcode.md // -var plugin = new Plugin(15, 'lintcode', '2017.08.04', +const plugin = new Plugin(15, 'lintcode', '2018.05.29', 'Plugin to talk with lintcode APIs.'); -var config = { - URL_BASE: 'http://www.lintcode.com/en', - URL_PROBLEMS: 'http://www.lintcode.com/en/problem?page=$page', - URL_PROBLEM: 'http://www.lintcode.com/en/problem/$slug/', - URL_PROBLEM_CODE: 'http://www.lintcode.com/en/problem/api/code/?problem_id=$id&language=$lang', - URL_TEST: 'http://www.lintcode.com/submission/api/submit/', - URL_TEST_VERIFY: 'http://www.lintcode.com/submission/api/refresh/?id=$id&waiting_time=0&is_test_submission=true', - URL_SUBMIT_VERIFY: 'http://www.lintcode.com/submission/api/refresh/?id=$id&waiting_time=0', - URL_LOGIN: 'http://www.lintcode.com/en/accounts/signin/' +const config = { + URL_PROBLEMS: 'https://www.lintcode.com/api/problems/?page=$page', + URL_PROBLEM: 'https://www.lintcode.com/problem/$slug/description', + URL_PROBLEM_DETAIL: 'https://www.lintcode.com/api/problems/detail/?unique_name_or_alias=$slug&_format=detail', + URL_PROBLEM_CODE: 'https://www.lintcode.com/api/problems/$id/reset/?language=$lang', + URL_TEST: 'https://www.lintcode.com/api/submissions/', + URL_TEST_VERIFY: 'https://www.lintcode.com/api/submissions/refresh/?id=$id&is_test_submission=true', + URL_SUBMIT_VERIFY: 'https://www.lintcode.com/api/submissions/refresh/?id=$id', + URL_LOGIN: 'https://www.lintcode.com/api/accounts/signin/?next=%2F' }; -var LANGS = [ +// FIXME: add more langs +const LANGS = [ {value: 'cpp', text: 'C++'}, {value: 'java', text: 'Java'}, {value: 'python', text: 'Python'} ]; +var spin; + function signOpts(opts, user) { opts.headers.Cookie = 'sessionid=' + user.sessionId + ';csrftoken=' + user.sessionCSRF + ';'; + opts.headers['x-csrftoken'] = user.sessionCSRF; } function makeOpts(url) { - var opts = {}; - opts.url = url; - opts.headers = {}; - + const opts = { + url: url, + headers: {} + }; if (session.isLogin()) signOpts(opts, session.getUser()); return opts; @@ -55,7 +59,7 @@ function makeOpts(url) { function checkError(e, resp, expectedStatus) { if (!e && resp && resp.statusCode !== expectedStatus) { - var code = resp.statusCode; + const code = resp.statusCode; log.debug('http error: ' + code); if (code === 403 || code === 401) { @@ -84,126 +88,111 @@ plugin.getProblems = function(cb) { log.debug('running lintcode.getProblems'); var problems = []; - var doTask = function(page, taskDone) { - plugin.getPageProblems(page, function(e, _problems) { - if (!e) problems = problems.concat(_problems); - return taskDone(e); + const getPage = function(page, queue, cb) { + plugin.getPageProblems(page, function(e, _problems, ctx) { + if (!e) { + problems = problems.concat(_problems); + queue.tasks = _.reject(queue.tasks, x => ctx.pages > 0 && x > ctx.pages); + } + return cb(e); }); }; - // FIXME: remove this hardcoded range! - var pages = [0, 1, 2, 3, 4]; - queue.run(pages, doTask, function(e) { - problems = _.sortBy(problems, function(x) { - return -x.id; - }); + const pages = _.range(1, 100); + const q = new Queue(pages, {}, getPage); + spin = h.spin('Downloading problems'); + q.run(null, function(e, ctx) { + spin.stop(); + problems = _.sortBy(problems, x => -x.id); return cb(e, problems); }); }; plugin.getPageProblems = function(page, cb) { log.debug('running lintcode.getPageProblems: ' + page); - var opts = makeOpts(config.URL_PROBLEMS.replace('$page', page)); + const opts = makeOpts(config.URL_PROBLEMS.replace('$page', page)); + spin.text = 'Downloading page ' + page; request(opts, function(e, resp, body) { e = checkError(e, resp, 200); if (e) return cb(e); - var $ = cheerio.load(body); - var problems = $('div[id=problem_list_pagination] a').map(function(i, a) { - var problem = { - locked: false, + const ctx = {}; + const json = JSON.parse(body); + const problems = json.problems.map(function(p, a) { + const problem = { + id: p.id, + fid: p.id, + name: p.title, + slug: p.unique_name, category: 'lintcode', - state: 'None', - starred: false, - companies: [], + level: h.levelToName(p.level), + locked: false, + percent: p.accepted_rate, + starred: p.is_favorited, + companies: p.company_tags, tags: [] }; - problem.slug = $(a).attr('href').split('/').pop(); problem.link = config.URL_PROBLEM.replace('$slug', problem.slug); - - $(a).children('span').each(function(i, span) { - var text = $(span).text().trim(); - var type = _split($(span).attr('class'), ' '); - type = type.concat(_split($(span).find('i').attr('class'), ' ')); - - if (type.indexOf('title') >= 0) { - problem.id = Number(text.split('.')[0]); - problem.name = text.split('.')[1].trim(); - } else if (type.indexOf('difficulty') >= 0) problem.level = text; - else if (type.indexOf('rate') >= 0) problem.percent = parseInt(text, 10); - else if (type.indexOf('fa-star') >= 0) problem.starred = true; - else if (type.indexOf('fa-check') >= 0) problem.state = 'ac'; - else if (type.indexOf('fa-minus') >= 0) problem.state = 'notac'; - else if (type.indexOf('fa-briefcase') >= 0) problem.companies = _split($(span).attr('title'), ','); - }); - + switch (p.user_status) { + case 'Accepted': problem.state = 'ac'; break; + case 'Failed': problem.state = 'notac'; break; + default: problem.state = 'None'; + } return problem; - }).get(); + }); - return cb(null, problems); + ctx.count = json.count; + ctx.pages = json.maximum_page; + return cb(null, problems, ctx); }); }; plugin.getProblem = function(problem, cb) { log.debug('running lintcode.getProblem'); - var opts = makeOpts(problem.link); + const link = config.URL_PROBLEM_DETAIL.replace('$slug', problem.slug); + const opts = makeOpts(link); + const spin = h.spin('Downloading ' + problem.slug); request(opts, function(e, resp, body) { + spin.stop(); e = checkError(e, resp, 200); if (e) return cb(e); - var $ = cheerio.load(body); - problem.testcase = $('textarea[id=input-testcase]').text(); + const json = JSON.parse(body); + problem.testcase = json.testcase_sample; problem.testable = problem.testcase.length > 0; - - var lines = []; - $('div[id=description] > div').each(function(i, div) { - if (i === 0) { - div = $(div).find('div')[0]; - lines.push($(div).text().trim()); - return; - } - - var text = $(div).text().trim(); - var type = $(div).find('b').text().trim(); - - if (type === 'Tags') { - problem.tags = _split(text, '\n'); - problem.tags.shift(); - } else if (type === 'Related Problems') return; - else lines.push(text); - }); - problem.desc = lines.join('\n').replace(/\n{2,}/g, '\n'); - problem.totalAC = ''; - problem.totalSubmit = ''; + problem.tags = json.tags.map(x => x.name); + problem.desc = cheerio.load(json.description).root().text(); + problem.totalAC = json.total_accepted; + problem.totalSubmit = json.total_submissions; problem.templates = []; - var doTask = function(lang, taskDone) { + const getLang = function(lang, queue, cb) { plugin.getProblemCode(problem, lang, function(e, code) { - if (e) return taskDone(e); - - lang = _.clone(lang); - lang.defaultCode = code; - problem.templates.push(lang); - return taskDone(); + if (!e) { + lang = _.clone(lang); + lang.defaultCode = code; + problem.templates.push(lang); + } + return cb(e); }); }; - queue.run(LANGS, doTask, function(e) { - return cb(e, problem); - }); + const q = new Queue(LANGS, {}, getLang); + q.run(null, e => cb(e, problem)); }); }; plugin.getProblemCode = function(problem, lang, cb) { log.debug('running lintcode.getProblemCode:' + lang.value); - var url = config.URL_PROBLEM_CODE - .replace('$id', problem.id) - .replace('$lang', lang.text.replace(/\+/g, '%2b')); - var opts = makeOpts(url); + const url = config.URL_PROBLEM_CODE.replace('$id', problem.id) + .replace('$lang', lang.text.replace(/\+/g, '%2B')); + const opts = makeOpts(url); + const spin = h.spin('Downloading code for ' + lang.text); request(opts, function(e, resp, body) { + spin.stop(); e = checkError(e, resp, 200); if (e) return cb(e); @@ -213,29 +202,29 @@ plugin.getProblemCode = function(problem, lang, cb) { }; function runCode(problem, isTest, cb) { - var lang = _.find(LANGS, function(x) { - return x.value === h.extToLang(problem.file); - }); - - var opts = makeOpts(config.URL_TEST); + const lang = _.find(LANGS, x => x.value === h.extToLang(problem.file)); + const opts = makeOpts(config.URL_TEST); + opts.headers.referer = problem.link; opts.form = { problem_id: problem.id, code: h.getFileData(problem.file), - language: lang.text, - csrfmiddlewaretoken: session.getUser().sessionCSRF + language: lang.text }; if (isTest) { opts.form.input = problem.testcase; opts.form.is_test_submission = true; } + spin = h.spin('Sending code to judge'); request.post(opts, function(e, resp, body) { + spin.stop(); e = checkError(e, resp, 200); if (e) return cb(e); var json = JSON.parse(body); - if (!json.id || !json.success) return cb(json.message); + if (!json.id) return cb('Failed to start judge!'); + spin = h.spin('Waiting for judge result'); verifyResult(json.id, isTest, cb); }); } @@ -258,6 +247,7 @@ function verifyResult(id, isTest, cb) { } function formatResult(result) { + spin.stop(); var x = { ok: result.status === 'Accepted', type: 'Actual', @@ -290,7 +280,7 @@ plugin.testProblem = function(problem, cb) { runCode(problem, true, function(e, result) { if (e) return cb(e); - var expected = { + const expected = { ok: true, type: 'Expected', answer: result.expected_answer, @@ -322,33 +312,28 @@ plugin.starProblem = function(problem, starred, cb) { plugin.login = function(user, cb) { log.debug('running lintcode.login'); - request(config.URL_LOGIN, function(e, resp, body) { - e = checkError(e, resp, 200); - if (e) return cb(e); + const opts = { + url: config.URL_LOGIN, + headers: { + 'x-csrftoken': null + }, + form: { + username_or_email: user.login, + password: user.pass + } + }; - user.loginCSRF = h.getSetCookieValue(resp, 'csrftoken'); - - var opts = { - url: config.URL_LOGIN, - headers: { - Cookie: 'csrftoken=' + user.loginCSRF + ';' - }, - form: { - csrfmiddlewaretoken: user.loginCSRF, - username_or_email: user.login, - password: user.pass - } - }; - request.post(opts, function(e, resp, body) { - if (e) return cb(e); - if (resp.statusCode !== 302) return cb('invalid password?'); + const spin = h.spin('Signing in lintcode.com'); + request.post(opts, function(e, resp, body) { + spin.stop(); + if (e) return cb(e); + if (resp.statusCode !== 200) return cb('invalid password?'); - user.sessionCSRF = h.getSetCookieValue(resp, 'csrftoken'); - user.sessionId = h.getSetCookieValue(resp, 'sessionid'); - user.name = user.login; // FIXME + user.sessionCSRF = h.getSetCookieValue(resp, 'csrftoken'); + user.sessionId = h.getSetCookieValue(resp, 'sessionid'); + user.name = user.login; // FIXME - return cb(null, user); - }); + return cb(null, user); }); }; From a6b1a574fd65dd3001ecea1191d03f7529e385c2 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Tue, 29 May 2018 14:22:15 +0800 Subject: [PATCH 31/48] [lintcode] fixes missing level names Signed-off-by: Eric Wang --- plugins/lintcode.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 657c0af..449fbfb 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -39,6 +39,14 @@ const LANGS = [ {value: 'python', text: 'Python'} ]; +const LEVELS = { + 0: 'Naive', + 1: 'Easy', + 2: 'Medium', + 3: 'Hard', + 4: 'Super' +}; + var spin; function signOpts(opts, user) { @@ -126,7 +134,7 @@ plugin.getPageProblems = function(page, cb) { name: p.title, slug: p.unique_name, category: 'lintcode', - level: h.levelToName(p.level), + level: LEVELS[p.level], locked: false, percent: p.accepted_rate, starred: p.is_favorited, From 52b9353b0829bf91df75323376b2d8b5b898379c Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Tue, 29 May 2018 14:41:20 +0800 Subject: [PATCH 32/48] [WIP] talk to leetcode-cn.com Signed-off-by: Eric Wang --- plugins/leetcode.cn.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 plugins/leetcode.cn.js diff --git a/plugins/leetcode.cn.js b/plugins/leetcode.cn.js new file mode 100644 index 0000000..32686ac --- /dev/null +++ b/plugins/leetcode.cn.js @@ -0,0 +1,28 @@ +var Plugin = require('../plugin'); + +// +// [Usage] +// +// https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/leetcode.cn.md +// +var plugin = new Plugin(15, 'leetcode.cn', '2018.05.29', + 'Plugin to talk with leetcode-cn APIs.'); + +plugin.init = function() { + const config = require('../config'); + config.sys.urls.base = 'https://leetcode-cn.com'; + config.sys.urls.login = 'https://leetcode-cn.com/accounts/login/'; + config.sys.urls.problems = 'https://leetcode-cn.com/api/problems/$category/'; + config.sys.urls.problem = 'https://leetcode-cn.com/problems/$slug/description/'; + config.sys.urls.problem_detail = 'https://leetcode-cn.com/graphql'; + config.sys.urls.test = 'https://leetcode-cn.com/problems/$slug/interpret_solution/'; + config.sys.urls.session = 'https://leetcode-cn.com/session/'; + config.sys.urls.submit = 'https://leetcode-cn.com/problems/$slug/submit/'; + config.sys.urls.submissions = 'https://leetcode-cn.com/api/submissions/$slug'; + config.sys.urls.submission = 'https://leetcode-cn.com/submissions/detail/$id/'; + config.sys.urls.verify = 'https://leetcode-cn.com/submissions/detail/$id/check/'; + config.sys.urls.favorites = 'https://leetcode-cn.com/list/api/questions'; + config.sys.urls.favorite_delete = 'https://leetcode-cn.com/list/api/questions/$hash/$id'; +}; + +module.exports = plugin; From 18605dd77b1f49e8dbcb2f4f984226d2b8fca395 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Wed, 30 May 2018 12:00:28 +0800 Subject: [PATCH 33/48] Refactor to use consistent config.sys.urls Signed-off-by: Eric Wang --- plugins/leetcode.cn.js | 4 ++-- plugins/lintcode.js | 41 +++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/plugins/leetcode.cn.js b/plugins/leetcode.cn.js index 32686ac..30c7167 100644 --- a/plugins/leetcode.cn.js +++ b/plugins/leetcode.cn.js @@ -5,7 +5,7 @@ var Plugin = require('../plugin'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/leetcode.cn.md // -var plugin = new Plugin(15, 'leetcode.cn', '2018.05.29', +var plugin = new Plugin(15, 'leetcode.cn', '2018.05.30', 'Plugin to talk with leetcode-cn APIs.'); plugin.init = function() { @@ -14,7 +14,7 @@ plugin.init = function() { config.sys.urls.login = 'https://leetcode-cn.com/accounts/login/'; config.sys.urls.problems = 'https://leetcode-cn.com/api/problems/$category/'; config.sys.urls.problem = 'https://leetcode-cn.com/problems/$slug/description/'; - config.sys.urls.problem_detail = 'https://leetcode-cn.com/graphql'; + config.sys.urls.graphql = 'https://leetcode-cn.com/graphql'; config.sys.urls.test = 'https://leetcode-cn.com/problems/$slug/interpret_solution/'; config.sys.urls.session = 'https://leetcode-cn.com/session/'; config.sys.urls.submit = 'https://leetcode-cn.com/problems/$slug/submit/'; diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 449fbfb..7f0850d 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -4,6 +4,7 @@ var request = require('request'); var util = require('util'); var h = require('../helper'); +var config = require('../config'); var log = require('../log'); var Plugin = require('../plugin'); var Queue = require('../queue'); @@ -18,20 +19,9 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/lintcode.md // -const plugin = new Plugin(15, 'lintcode', '2018.05.29', +const plugin = new Plugin(15, 'lintcode', '2018.05.30', 'Plugin to talk with lintcode APIs.'); -const config = { - URL_PROBLEMS: 'https://www.lintcode.com/api/problems/?page=$page', - URL_PROBLEM: 'https://www.lintcode.com/problem/$slug/description', - URL_PROBLEM_DETAIL: 'https://www.lintcode.com/api/problems/detail/?unique_name_or_alias=$slug&_format=detail', - URL_PROBLEM_CODE: 'https://www.lintcode.com/api/problems/$id/reset/?language=$lang', - URL_TEST: 'https://www.lintcode.com/api/submissions/', - URL_TEST_VERIFY: 'https://www.lintcode.com/api/submissions/refresh/?id=$id&is_test_submission=true', - URL_SUBMIT_VERIFY: 'https://www.lintcode.com/api/submissions/refresh/?id=$id', - URL_LOGIN: 'https://www.lintcode.com/api/accounts/signin/?next=%2F' -}; - // FIXME: add more langs const LANGS = [ {value: 'cpp', text: 'C++'}, @@ -92,6 +82,17 @@ function _strip(s) { return util.inspect(s.trim()); } +plugin.init = function() { + config.sys.urls.problems = 'https://www.lintcode.com/api/problems/?page=$page'; + config.sys.urls.problem = 'https://www.lintcode.com/problem/$slug/description'; + config.sys.urls.problem_detail = 'https://www.lintcode.com/api/problems/detail/?unique_name_or_alias=$slug&_format=detail'; + config.sys.urls.problem_code = 'https://www.lintcode.com/api/problems/$id/reset/?language=$lang'; + config.sys.urls.test = 'https://www.lintcode.com/api/submissions/'; + config.sys.urls.test_verify = 'https://www.lintcode.com/api/submissions/refresh/?id=$id&is_test_submission=true'; + config.sys.urls.submit_verify = 'https://www.lintcode.com/api/submissions/refresh/?id=$id'; + config.sys.urls.login = 'https://www.lintcode.com/api/accounts/signin/?next=%2F'; +}; + plugin.getProblems = function(cb) { log.debug('running lintcode.getProblems'); @@ -118,7 +119,7 @@ plugin.getProblems = function(cb) { plugin.getPageProblems = function(page, cb) { log.debug('running lintcode.getPageProblems: ' + page); - const opts = makeOpts(config.URL_PROBLEMS.replace('$page', page)); + const opts = makeOpts(config.sys.urls.problems.replace('$page', page)); spin.text = 'Downloading page ' + page; request(opts, function(e, resp, body) { @@ -141,7 +142,7 @@ plugin.getPageProblems = function(page, cb) { companies: p.company_tags, tags: [] }; - problem.link = config.URL_PROBLEM.replace('$slug', problem.slug); + problem.link = config.sys.urls.problem.replace('$slug', problem.slug); switch (p.user_status) { case 'Accepted': problem.state = 'ac'; break; case 'Failed': problem.state = 'notac'; break; @@ -158,7 +159,7 @@ plugin.getPageProblems = function(page, cb) { plugin.getProblem = function(problem, cb) { log.debug('running lintcode.getProblem'); - const link = config.URL_PROBLEM_DETAIL.replace('$slug', problem.slug); + const link = config.sys.urls.problem_detail.replace('$slug', problem.slug); const opts = makeOpts(link); const spin = h.spin('Downloading ' + problem.slug); @@ -194,8 +195,8 @@ plugin.getProblem = function(problem, cb) { plugin.getProblemCode = function(problem, lang, cb) { log.debug('running lintcode.getProblemCode:' + lang.value); - const url = config.URL_PROBLEM_CODE.replace('$id', problem.id) - .replace('$lang', lang.text.replace(/\+/g, '%2B')); + const url = config.sys.urls.problem_code.replace('$id', problem.id) + .replace('$lang', lang.text.replace(/\+/g, '%2B')); const opts = makeOpts(url); const spin = h.spin('Downloading code for ' + lang.text); @@ -211,7 +212,7 @@ plugin.getProblemCode = function(problem, lang, cb) { function runCode(problem, isTest, cb) { const lang = _.find(LANGS, x => x.value === h.extToLang(problem.file)); - const opts = makeOpts(config.URL_TEST); + const opts = makeOpts(config.sys.urls.test); opts.headers.referer = problem.link; opts.form = { problem_id: problem.id, @@ -239,7 +240,7 @@ function runCode(problem, isTest, cb) { function verifyResult(id, isTest, cb) { log.debug('running verifyResult:' + id); - var url = isTest ? config.URL_TEST_VERIFY : config.URL_SUBMIT_VERIFY; + var url = isTest ? config.sys.urls.test_verify : config.sys.urls.submit_verify; var opts = makeOpts(url.replace('$id', id)); request(opts, function(e, resp, body) { @@ -321,7 +322,7 @@ plugin.starProblem = function(problem, starred, cb) { plugin.login = function(user, cb) { log.debug('running lintcode.login'); const opts = { - url: config.URL_LOGIN, + url: config.sys.urls.login, headers: { 'x-csrftoken': null }, From 78232d3af28e0374aca4db887ac5869e5503d9d6 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Wed, 30 May 2018 14:18:22 +0800 Subject: [PATCH 34/48] [cookie.chrome] support profile config. refs #7 Signed-off-by: Eric Wang --- docs/cookie.chrome.md | 22 ++++++++++++++++++++++ plugins/cookie.chrome.js | 21 +++++++++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/docs/cookie.chrome.md b/docs/cookie.chrome.md index a4f7593..c5a9dbc 100644 --- a/docs/cookie.chrome.md +++ b/docs/cookie.chrome.md @@ -26,6 +26,28 @@ Make sure build environment is ready before installing plugin: $ npm install -g windows-build-tools $ npm config set msvs_version 2015 -g +## Config + +* `profile`: chrome profile in use, default value is "Default". + +*Set Config* + + $ leetcode config plugins:cookie.chrome:profile "Your Profile" + +*Unset Config* + + $ leetcode config -d plugins:cookie.chrome + +*Example* + + { + "plugins": { + "cookie.chrome": { + "profile": "Profile 2" + } + } + } + ## Usage If enabled, the login will try to reuse existing chrome cookies. You can verify it by printing debug output as below. diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index c5ac5b6..13f28f4 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -9,7 +9,7 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cookie.chrome.md // -var plugin = new Plugin(13, 'cookie.chrome', '2017.12.23', +var plugin = new Plugin(13, 'cookie.chrome', '2018.05.30', 'Plugin to reuse Chrome\'s leetcode cookie.', ['ffi:win32', 'keytar:darwin', 'ref:win32', 'ref-struct:win32', 'sqlite3']); @@ -28,7 +28,9 @@ plugin.help = function() { var Chrome = {}; var ChromeMAC = { - db: process.env.HOME + '/Library/Application Support/Google/Chrome/Default/Cookies', + getDBPath: function() { + return `${process.env.HOME}/Library/Application Support/Google/Chrome/${this.profile}/Cookies`; + }, iterations: 1003, getPassword: function(cb) { var keytar = require('keytar'); @@ -37,7 +39,9 @@ var ChromeMAC = { }; var ChromeLinux = { - db: process.env.HOME + '/.config/google-chrome/Default/Cookies', + getDBPath: function() { + return `${process.env.HOME}/.config/google-chrome/${this.profile}/Cookies`; + }, iterations: 1, getPassword: function(cb) { // FIXME: keytar failed to read gnome-keyring on ubuntu?? @@ -48,7 +52,9 @@ var ChromeLinux = { }; var ChromeWindows = { - db: path.resolve(process.env.APPDATA || '', '../Local/Google/Chrome/User Data/Default/Cookies'), + getDBPath: function() { + return path.resolve(process.env.APPDATA || '', `../Local/Google/Chrome/User Data/${this.profile}/Cookies`); + }, getPassword: function(cb) { cb(); } }; @@ -124,7 +130,7 @@ function doDecode(key, queue, cb) { Chrome.getCookies = function(cb) { var sqlite3 = require('sqlite3'); - var db = new sqlite3.Database(my.db); + var db = new sqlite3.Database(my.getDBPath()); var KEYS = ['csrftoken', 'LEETCODE_SESSION']; db.serialize(function() { @@ -149,9 +155,12 @@ Chrome.getCookies = function(cb) { plugin.signin = function(user, cb) { log.debug('running cookie.chrome.signin'); log.debug('try to copy leetcode cookies from chrome ...'); + + my.profile = plugin.config.profile || 'Default'; my.getCookies(function(e, cookies) { if (e) { - log.error('failed to copy cookies: ' + e); + log.error(`Failed to copy cookies from profile "${my.profile}"`); + log.error(e); return plugin.next.signin(user, cb); } From 7456f72d0a7c2f3e815462e9be7d4d1c9e0108e4 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Wed, 30 May 2018 14:33:05 +0800 Subject: [PATCH 35/48] [leetcode.cn] update docs. Signed-off-by: Eric Wang --- README.md | 1 + docs/leetcode.cn.md | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 docs/leetcode.cn.md diff --git a/README.md b/README.md index 41fb9c1..ecda979 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ |[cpp.lint](/docs/cpp.lint.md)|C++ code syntax check|`test`| |[cpp.run](/docs/cpp.run.md)|Test C++ code locally|`test`| |[github](/docs/github.md)|Commit accpeted code to GitHub|`submit`| +|[leetcode.cn](/docs/leetcode.cn.md)|Fight questions from leetcode-cn.com|| |[lintcode](/docs/lintcode.md)|Fight questions from lintcode.com|`list` `show` `test` `submit` `user`| |[solution.discuss](/docs/solution.discuss.md)|Fetch top voted solution|`show`| diff --git a/docs/leetcode.cn.md b/docs/leetcode.cn.md new file mode 100644 index 0000000..3a65ddd --- /dev/null +++ b/docs/leetcode.cn.md @@ -0,0 +1,7 @@ +# leetcode.cn + +Run everything against "leetcode-cn.com" instead of "leetcode.com". + +## Requirement + +You need a valid account on leetcode-cn.com since it uses diffrent user database from leetcode.com. From 678ca1e60a9a201fa0aa46cf0441a188c8a22c45 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 31 May 2018 12:07:41 +0800 Subject: [PATCH 36/48] [lintcode] tiny fix of base url. Signed-off-by: Eric Wang --- plugins/lintcode.js | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 7f0850d..5e92278 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -83,6 +83,7 @@ function _strip(s) { } plugin.init = function() { + config.sys.urls.base = 'https://www.lintcode.com'; config.sys.urls.problems = 'https://www.lintcode.com/api/problems/?page=$page'; config.sys.urls.problem = 'https://www.lintcode.com/problem/$slug/description'; config.sys.urls.problem_detail = 'https://www.lintcode.com/api/problems/detail/?unique_name_or_alias=$slug&_format=detail'; From 80ac93367cd2030df0715125ef9f56f4b6d84d36 Mon Sep 17 00:00:00 2001 From: Eric Liang Date: Thu, 14 Jun 2018 11:46:18 -0700 Subject: [PATCH 37/48] Add binary-search-tree tag In Company plugin, binary search tree tag is missing. --- plugins/company.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/company.js b/plugins/company.js index 711d8a6..3884ba0 100644 --- a/plugins/company.js +++ b/plugins/company.js @@ -726,6 +726,7 @@ var TAGS = { '217': ['array', 'hash-table'], '218': ['binary-indexed-tree', 'divide-and-conquer', 'heap', 'segment-tree'], '219': ['array', 'hash-table'], + '220': ['binary-search-tree'], '221': ['dynamic-programming'], '222': ['binary-search', 'tree'], '223': ['math'], @@ -817,7 +818,7 @@ var TAGS = { '312': ['divide-and-conquer', 'dynamic-programming'], '313': ['heap', 'math'], '314': ['hash-table'], - '315': ['binary-indexed-tree', 'divide-and-conquer', 'segment-tree'], + '315': ['binary-indexed-tree', 'divide-and-conquer', 'segment-tree', 'binary-search-tree'], '316': ['greedy', 'stack'], '317': ['breadth-first-search'], '318': ['bit-manipulation'], @@ -829,7 +830,7 @@ var TAGS = { '324': ['sort'], '325': ['hash-table'], '326': ['math'], - '327': ['divide-and-conquer'], + '327': ['divide-and-conquer', 'binary-search-tree'], '328': ['linked-list'], '329': ['depth-first-search', 'topological-sort'], '330': ['greedy'], @@ -853,6 +854,7 @@ var TAGS = { '349': ['binary-search', 'hash-table', 'sort', 'two-pointers'], '350': ['binary-search', 'hash-table', 'sort', 'two-pointers'], '351': ['backtracking', 'dynamic-programming'], + '352': ['binary-search-tree'], '353': ['design', 'queue'], '354': ['binary-search', 'dynamic-programming'], '355': ['design', 'hash-table', 'heap'], @@ -963,7 +965,7 @@ var TAGS = { '488': ['depth-first-search'], '490': ['breadth-first-search', 'depth-first-search'], '491': ['depth-first-search'], - '493': ['binary-indexed-tree', 'divide-and-conquer', 'segment-tree'], + '493': ['binary-indexed-tree', 'divide-and-conquer', 'segment-tree', 'binary-search-tree'], '494': ['depth-first-search', 'dynamic-programming'], '495': ['array'], '496': ['stack'], @@ -989,6 +991,7 @@ var TAGS = { '526': ['backtracking'], '527': ['sort', 'string'], '529': ['breadth-first-search', 'depth-first-search'], + '530': ['array', 'depth-first-search', 'binary-search-tree'], '531': ['array', 'depth-first-search'], '532': ['array', 'two-pointers'], '533': ['array', 'depth-first-search'], @@ -1102,7 +1105,7 @@ var TAGS = { '680': ['string'], '681': ['string'], '682': ['stack'], - '683': ['array'], + '683': ['array', 'binary-search-tree'], '684': ['graph', 'tree', 'union-find'], '685': ['depth-first-search', 'graph', 'tree', 'union-find'], '686': ['string'], @@ -1118,12 +1121,12 @@ var TAGS = { '696': ['string'], '697': ['array'], '698': ['dynamic-programming'], - '699': ['segment-tree'], + '699': ['segment-tree', 'binary-search-tree'], '711': ['depth-first-search', 'hash-table'], '712': ['dynamic-programming'], '713': ['array', 'two-pointers'], '714': ['array', 'dynamic-programming', 'greedy'], - '715': ['array', 'segment-tree'], + '715': ['array', 'segment-tree', 'binary-search-tree'], '716': ['design'], '717': ['array'], '718': ['array', 'binary-search', 'dynamic-programming', 'hash-table'], @@ -1139,8 +1142,8 @@ var TAGS = { '728': ['math'], '729': ['array'], '730': ['dynamic-programming', 'string'], - '731': ['array'], - '732': ['segment-tree'], + '731': ['array', 'binary-search-tree'], + '732': ['segment-tree', 'binary-search-tree'], '733': ['depth-first-search'], '734': ['hash-table'], '735': ['stack'], From babbdf608450da7db38fcbaca1b6baf1a2555909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=A9=E5=AD=90?= Date: Thu, 9 Aug 2018 10:18:51 +0800 Subject: [PATCH 38/48] Fix leetcode-cn urls It seems the leetcode-cn plugin need one more url replaced for working well. That is config.sys.urls.problem_detail --- plugins/leetcode.cn.js | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/leetcode.cn.js b/plugins/leetcode.cn.js index 30c7167..8db8dfc 100644 --- a/plugins/leetcode.cn.js +++ b/plugins/leetcode.cn.js @@ -15,6 +15,7 @@ plugin.init = function() { config.sys.urls.problems = 'https://leetcode-cn.com/api/problems/$category/'; config.sys.urls.problem = 'https://leetcode-cn.com/problems/$slug/description/'; config.sys.urls.graphql = 'https://leetcode-cn.com/graphql'; + config.sys.urls.problem_detail = 'https://leetcode.com/graphql'; config.sys.urls.test = 'https://leetcode-cn.com/problems/$slug/interpret_solution/'; config.sys.urls.session = 'https://leetcode-cn.com/session/'; config.sys.urls.submit = 'https://leetcode-cn.com/problems/$slug/submit/'; From 6ef569dcf78d4eb1375a40b65bb4f14494d19954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=A9=E5=AD=90?= Date: Thu, 9 Aug 2018 10:22:04 +0800 Subject: [PATCH 39/48] Fix url Fix url for leetcode-cn --- plugins/leetcode.cn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/leetcode.cn.js b/plugins/leetcode.cn.js index 8db8dfc..53d79ce 100644 --- a/plugins/leetcode.cn.js +++ b/plugins/leetcode.cn.js @@ -15,7 +15,7 @@ plugin.init = function() { config.sys.urls.problems = 'https://leetcode-cn.com/api/problems/$category/'; config.sys.urls.problem = 'https://leetcode-cn.com/problems/$slug/description/'; config.sys.urls.graphql = 'https://leetcode-cn.com/graphql'; - config.sys.urls.problem_detail = 'https://leetcode.com/graphql'; + config.sys.urls.problem_detail = 'https://leetcode-cn.com/graphql'; config.sys.urls.test = 'https://leetcode-cn.com/problems/$slug/interpret_solution/'; config.sys.urls.session = 'https://leetcode-cn.com/session/'; config.sys.urls.submit = 'https://leetcode-cn.com/problems/$slug/submit/'; From 5ef609e75e3f19451d83ccd61e70b669d972e640 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 28 Oct 2018 11:38:09 +0800 Subject: [PATCH 40/48] move plugins' specific data into separate dirs. * see https://github.com/skygragon/leetcode-cli/commit/b72d4d69fe6b3279d3f40f00bb836696139a2fcc Signed-off-by: Eric Wang --- plugins/leetcode.cn.js | 3 ++- plugins/lintcode.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/leetcode.cn.js b/plugins/leetcode.cn.js index 53d79ce..9489d61 100644 --- a/plugins/leetcode.cn.js +++ b/plugins/leetcode.cn.js @@ -5,11 +5,12 @@ var Plugin = require('../plugin'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/leetcode.cn.md // -var plugin = new Plugin(15, 'leetcode.cn', '2018.05.30', +var plugin = new Plugin(15, 'leetcode.cn', '2018.10.28', 'Plugin to talk with leetcode-cn APIs.'); plugin.init = function() { const config = require('../config'); + config.app = 'leetcode.cn'; config.sys.urls.base = 'https://leetcode-cn.com'; config.sys.urls.login = 'https://leetcode-cn.com/accounts/login/'; config.sys.urls.problems = 'https://leetcode-cn.com/api/problems/$category/'; diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 5e92278..89be320 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -19,7 +19,7 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/lintcode.md // -const plugin = new Plugin(15, 'lintcode', '2018.05.30', +const plugin = new Plugin(15, 'lintcode', '2018.10.28', 'Plugin to talk with lintcode APIs.'); // FIXME: add more langs @@ -83,6 +83,7 @@ function _strip(s) { } plugin.init = function() { + config.app = 'lintcode'; config.sys.urls.base = 'https://www.lintcode.com'; config.sys.urls.problems = 'https://www.lintcode.com/api/problems/?page=$page'; config.sys.urls.problem = 'https://www.lintcode.com/problem/$slug/description'; From e8fda163ca9770ab0c7f0981dd634b7e5f10f20f Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 18 Nov 2018 10:51:26 +0800 Subject: [PATCH 41/48] [refactor] keep pace with leetcode-cli 2.5.4 Signed-off-by: Eric Wang --- plugins/github.js | 3 ++- plugins/lintcode.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/github.js b/plugins/github.js index 4c00e75..b0f8241 100644 --- a/plugins/github.js +++ b/plugins/github.js @@ -2,6 +2,7 @@ var path = require('path'); var url = require('url'); var h = require('../helper'); +var file = require('../file'); var log = require('../log'); var Plugin = require('../plugin'); @@ -47,7 +48,7 @@ plugin.submitProblem = function(problem, cb) { } ctx.message = 'update ' + filename; - ctx.content = new Buffer(h.getFileData(problem.file)).toString('base64'); + ctx.content = new Buffer(file.data(problem.file)).toString('base64'); var onFileDone = function(e, res) { if (e) diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 89be320..88c7e3c 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -4,6 +4,7 @@ var request = require('request'); var util = require('util'); var h = require('../helper'); +var file = require('../file'); var config = require('../config'); var log = require('../log'); var Plugin = require('../plugin'); @@ -218,7 +219,7 @@ function runCode(problem, isTest, cb) { opts.headers.referer = problem.link; opts.form = { problem_id: problem.id, - code: h.getFileData(problem.file), + code: file.data(problem.file), language: lang.text }; if (isTest) { From 23f7fdba0d37b1997a2ecef2c636968cb75c77fe Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 18 Nov 2018 23:41:14 +0800 Subject: [PATCH 42/48] tiny update. Signed-off-by: Eric Wang --- plugins/cookie.chrome.js | 5 +++-- plugins/github.js | 2 +- plugins/leetcode.cn.js | 4 ++-- plugins/lintcode.js | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index 13f28f4..0291144 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -9,7 +9,7 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cookie.chrome.md // -var plugin = new Plugin(13, 'cookie.chrome', '2018.05.30', +var plugin = new Plugin(13, 'cookie.chrome', '2018.11.18', 'Plugin to reuse Chrome\'s leetcode cookie.', ['ffi:win32', 'keytar:darwin', 'ref:win32', 'ref-struct:win32', 'sqlite3']); @@ -18,7 +18,7 @@ plugin.help = function() { case 'darwin': break; case 'linux': - log.info('To complete the install: sudo apt install libsecret-tools'); + log.warn('To complete the install: sudo apt install libsecret-tools'); break; case 'win32': break; @@ -131,6 +131,7 @@ function doDecode(key, queue, cb) { Chrome.getCookies = function(cb) { var sqlite3 = require('sqlite3'); var db = new sqlite3.Database(my.getDBPath()); + db.on('error', cb); var KEYS = ['csrftoken', 'LEETCODE_SESSION']; db.serialize(function() { diff --git a/plugins/github.js b/plugins/github.js index b0f8241..6c94e9e 100644 --- a/plugins/github.js +++ b/plugins/github.js @@ -11,7 +11,7 @@ var Plugin = require('../plugin'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/github.md // -var plugin = new Plugin(100, 'github', '2018.03.24', +var plugin = new Plugin(100, 'github', '2018.11.18', 'Plugin to commit accepted code to your own github repo.', ['github@13']); diff --git a/plugins/leetcode.cn.js b/plugins/leetcode.cn.js index 9489d61..c9b1aef 100644 --- a/plugins/leetcode.cn.js +++ b/plugins/leetcode.cn.js @@ -1,3 +1,4 @@ +var config = require('../config'); var Plugin = require('../plugin'); // @@ -5,11 +6,10 @@ var Plugin = require('../plugin'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/leetcode.cn.md // -var plugin = new Plugin(15, 'leetcode.cn', '2018.10.28', +var plugin = new Plugin(15, 'leetcode.cn', '2018.11.18', 'Plugin to talk with leetcode-cn APIs.'); plugin.init = function() { - const config = require('../config'); config.app = 'leetcode.cn'; config.sys.urls.base = 'https://leetcode-cn.com'; config.sys.urls.login = 'https://leetcode-cn.com/accounts/login/'; diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 88c7e3c..18b5c9d 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -20,7 +20,7 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/lintcode.md // -const plugin = new Plugin(15, 'lintcode', '2018.10.28', +const plugin = new Plugin(15, 'lintcode', '2018.11.18', 'Plugin to talk with lintcode APIs.'); // FIXME: add more langs From aeb680a7d89ce74a039ce89cbaa3f9ff2ee4fbb7 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 19 Nov 2018 14:00:28 +0800 Subject: [PATCH 43/48] [cookie.firefox] fail on invalid cookies. Signed-off-by: Eric Wang --- plugins/cookie.firefox.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/cookie.firefox.js b/plugins/cookie.firefox.js index 45d8645..de2db29 100644 --- a/plugins/cookie.firefox.js +++ b/plugins/cookie.firefox.js @@ -6,7 +6,7 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/cookie.firefox.md // -var plugin = new Plugin(13, 'cookie.firefox', '2017.12.28', +var plugin = new Plugin(13, 'cookie.firefox', '2018.11.19', 'Plugin to reuse firefox\'s leetcode cookie.', ['glob', 'sqlite3']); @@ -55,7 +55,12 @@ plugin.signin = function(user, cb) { log.debug('try to copy leetcode cookies from firefox ...'); getCookies(function(e, cookies) { if (e) { - log.error('failed to copy cookies: ' + e); + log.error('Failed to copy cookies: ' + e); + return plugin.next.signin(user, cb); + } + + if (!cookies.LEETCODE_SESSION || !cookies.csrftoken) { + log.error('Got invalid cookies: ' + JSON.stringify(cookies)); return plugin.next.signin(user, cb); } From 65cbe605aa704394dc52c385c166b6e7eadb1057 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 24 Nov 2018 22:27:40 +0800 Subject: [PATCH 44/48] fixes eslint errors. Signed-off-by: Eric Wang --- .eslintrc.js | 29 ++++++++++++++++++++++++----- package.json | 4 ++-- plugins/company.js | 4 ++++ plugins/cookie.chrome.js | 6 +++--- plugins/cookie.firefox.js | 2 +- plugins/lintcode.js | 10 +++++----- plugins/solution.discuss.js | 6 +++--- 7 files changed, 42 insertions(+), 19 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index f274110..0c40bef 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,17 +1,36 @@ module.exports = { "env": { "browser": false, - "node": true, - "es6": true + "es6": true, + "mocha": true, + "node": true }, - "extends": "google", + "extends": [ + "google", + "eslint:recommended" + ], "rules": { + "block-spacing": [2, "always"], + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "camelcase": [2, {properties: "never"}], "comma-dangle": 0, "curly": 0, "key-spacing": [2, {align: "value"}], - "max-len": [1, 120], + "max-len": [1, 150], + "no-console": 1, + "no-empty": [2, { "allowEmptyCatch": true }], + "no-eval": 1, // we use it on purpose + "no-loop-func": 1, + "no-multi-spaces": 0, + "no-proto": 1, + "no-unused-expressions": 1, + "no-unused-vars": 1, "no-var": 0, + "no-warning-comments": 0, + "prefer-rest-params": 0, + "prefer-spread": 0, + "quote-props": 1, "quotes": [2, "single", {avoidEscape: true}], - "require-jsdoc": 0 + "require-jsdoc": 0, } }; diff --git a/package.json b/package.json index 99fca68..4ea4b95 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/skygragon/leetcode-cli-plugins#readme", "devDependencies": { - "eslint": "^4.4.1", - "eslint-config-google": "^0.9.1" + "eslint": "5.9.0", + "eslint-config-google": "0.11.0" } } diff --git a/plugins/company.js b/plugins/company.js index 3884ba0..ac48974 100644 --- a/plugins/company.js +++ b/plugins/company.js @@ -21,6 +21,7 @@ var COMPONIES = { '5': ['amazon', 'bloomberg', 'microsoft'], '7': ['apple', 'bloomberg'], '8': ['amazon', 'bloomberg', 'microsoft', 'uber'], + '10': ['airbnb', 'facebook', 'google', 'twitter', 'uber'], '11': ['bloomberg'], '12': ['twitter'], @@ -84,6 +85,7 @@ var COMPONIES = { '94': ['microsoft'], '96': ['snapchat'], '98': ['amazon', 'bloomberg', 'facebook', 'microsoft'], + '100': ['bloomberg'], '101': ['bloomberg', 'linkedin', 'microsoft'], '102': ['amazon', 'apple', 'bloomberg', 'facebook', 'linkedin', 'microsoft'], @@ -532,6 +534,7 @@ var TAGS = { '7': ['math'], '8': ['math', 'string'], '9': ['math'], + '10': ['backtracking', 'dynamic-programming', 'string'], '11': ['array', 'two-pointers'], '12': ['math', 'string'], @@ -622,6 +625,7 @@ var TAGS = { '97': ['dynamic-programming', 'string'], '98': ['depth-first-search', 'tree'], '99': ['depth-first-search', 'tree'], + '100': ['depth-first-search', 'tree'], '101': ['breadth-first-search', 'depth-first-search', 'tree'], '102': ['breadth-first-search', 'tree'], diff --git a/plugins/cookie.chrome.js b/plugins/cookie.chrome.js index 0291144..e2d4278 100644 --- a/plugins/cookie.chrome.js +++ b/plugins/cookie.chrome.js @@ -28,7 +28,7 @@ plugin.help = function() { var Chrome = {}; var ChromeMAC = { - getDBPath: function() { + getDBPath: function() { return `${process.env.HOME}/Library/Application Support/Google/Chrome/${this.profile}/Cookies`; }, iterations: 1003, @@ -39,7 +39,7 @@ var ChromeMAC = { }; var ChromeLinux = { - getDBPath: function() { + getDBPath: function() { return `${process.env.HOME}/.config/google-chrome/${this.profile}/Cookies`; }, iterations: 1, @@ -52,7 +52,7 @@ var ChromeLinux = { }; var ChromeWindows = { - getDBPath: function() { + getDBPath: function() { return path.resolve(process.env.APPDATA || '', `../Local/Google/Chrome/User Data/${this.profile}/Cookies`); }, getPassword: function(cb) { cb(); } diff --git a/plugins/cookie.firefox.js b/plugins/cookie.firefox.js index de2db29..f69f869 100644 --- a/plugins/cookie.firefox.js +++ b/plugins/cookie.firefox.js @@ -48,7 +48,7 @@ function getCookies(cb) { }); }); }); -}; +} plugin.signin = function(user, cb) { log.debug('running cookie.firefox.signin'); diff --git a/plugins/lintcode.js b/plugins/lintcode.js index 18b5c9d..073d12d 100644 --- a/plugins/lintcode.js +++ b/plugins/lintcode.js @@ -218,9 +218,9 @@ function runCode(problem, isTest, cb) { const opts = makeOpts(config.sys.urls.test); opts.headers.referer = problem.link; opts.form = { - problem_id: problem.id, - code: file.data(problem.file), - language: lang.text + problem_id: problem.id, + code: file.data(problem.file), + language: lang.text }; if (isTest) { opts.form.input = problem.testcase; @@ -330,8 +330,8 @@ plugin.login = function(user, cb) { 'x-csrftoken': null }, form: { - username_or_email: user.login, - password: user.pass + username_or_email: user.login, + password: user.pass } }; diff --git a/plugins/solution.discuss.js b/plugins/solution.discuss.js index 1289a13..c155637 100644 --- a/plugins/solution.discuss.js +++ b/plugins/solution.discuss.js @@ -1,5 +1,4 @@ var _ = require('underscore'); -var cheerio = require('cheerio'); var request = require('request'); var log = require('../log'); @@ -24,7 +23,7 @@ function getSolution(problem, lang, cb) { var opts = { url: URL_DISCUSSES, json: true, - qs: { + qs: { query: [ 'query fetchTopics($questionId: Int!, $pageNo: Int!, $orderBy: String!) {', ' questionTopics(questionId: $questionId, pageNo: $pageNo, orderBy: $orderBy) {', @@ -42,8 +41,9 @@ function getSolution(problem, lang, cb) { ' }', '}' ].join('\n'), + operationName: 'fetchTopics', - variables: JSON.stringify({ + variables: JSON.stringify({ pageNo: 1, orderBy: 'most_votes', questionId: problem.id From 9de04127984e08d7d52dc0545c03291d2a69fc97 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 24 Nov 2018 22:33:01 +0800 Subject: [PATCH 45/48] enable travis Signed-off-by: Eric Wang --- .travis.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a6f5aa8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - 10 +os: + - linux +install: + - npm install +script: + - npm test From 6a33c98b09cc6a2332b42df3186cb1f80febb845 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 25 Nov 2018 22:19:05 +0800 Subject: [PATCH 46/48] refs #22: show chinese question name. Signed-off-by: Eric Wang --- plugins/leetcode.cn.js | 98 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/plugins/leetcode.cn.js b/plugins/leetcode.cn.js index c9b1aef..07d5d2d 100644 --- a/plugins/leetcode.cn.js +++ b/plugins/leetcode.cn.js @@ -1,12 +1,18 @@ +'use strict' +var request = require('request'); + var config = require('../config'); +var h = require('../helper'); +var log = require('../log'); var Plugin = require('../plugin'); +var session = require('../session'); // // [Usage] // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/leetcode.cn.md // -var plugin = new Plugin(15, 'leetcode.cn', '2018.11.18', +var plugin = new Plugin(15, 'leetcode.cn', '2018.11.25', 'Plugin to talk with leetcode-cn APIs.'); plugin.init = function() { @@ -27,4 +33,94 @@ plugin.init = function() { config.sys.urls.favorite_delete = 'https://leetcode-cn.com/list/api/questions/$hash/$id'; }; +// FIXME: refactor those +// update options with user credentials +function signOpts(opts, user) { + opts.headers.Cookie = 'LEETCODE_SESSION=' + user.sessionId + + ';csrftoken=' + user.sessionCSRF + ';'; + opts.headers['X-CSRFToken'] = user.sessionCSRF; + opts.headers['X-Requested-With'] = 'XMLHttpRequest'; +} + +function makeOpts(url) { + const opts = {}; + opts.url = url; + opts.headers = {}; + + if (session.isLogin()) + signOpts(opts, session.getUser()); + return opts; +} + +function checkError(e, resp, expectedStatus) { + if (!e && resp && resp.statusCode !== expectedStatus) { + const code = resp.statusCode; + log.debug('http error: ' + code); + + if (code === 403 || code === 401) { + e = session.errors.EXPIRED; + } else { + e = {msg: 'http error', statusCode: code}; + } + } + return e; +} + +plugin.getProblems = function(cb) { + plugin.next.getProblems(function(e, problems) { + if (e) return cb(e); + + plugin.getProblemsTitle(function(e, titles) { + if (e) return cb(e); + + problems.forEach(function(problem) { + const title = titles[problem.fid]; + if (title) + problem.name = title; + }); + + return cb(null, problems); + }); + }); +}; + +plugin.getProblemsTitle = function(cb) { + log.debug('running leetcode.cn.getProblemNames'); + + const opts = makeOpts(config.sys.urls.graphql); + opts.headers.Origin = config.sys.urls.base; + opts.headers.Referer = 'https://leetcode-cn.com/api/problems/algorithms/'; + + opts.json = true; + opts.body = { + query: [ + 'query getQuestionTranslation($lang: String) {', + ' translations: allAppliedQuestionTranslations(lang: $lang) {', + ' title', + ' question {', + ' questionId', + ' }', + ' }', + '}', + '' + ].join('\n'), + variables: {}, + operationName: 'getQuestionTranslation' + }; + + const spin = h.spin('Downloading questions titles'); + request.post(opts, function(e, resp, body) { + spin.stop(); + e = checkError(e, resp, 200); + if (e) return cb(e); + + const titles = []; + body.data.translations.forEach(function(x) { + titles[x.question.questionId] = x.title; + }); + + return cb(null, titles); + }); +}; + module.exports = plugin; From e0b4613c842f69a04bcf84e836d929f8ba774e5d Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 3 Feb 2019 12:27:53 +0800 Subject: [PATCH 47/48] fixes #28: [solution] fixes 400 error Signed-off-by: Eric Wang --- plugins/solution.discuss.js | 46 +++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/plugins/solution.discuss.js b/plugins/solution.discuss.js index c155637..b3a9a13 100644 --- a/plugins/solution.discuss.js +++ b/plugins/solution.discuss.js @@ -11,7 +11,7 @@ var session = require('../session'); // // https://github.com/skygragon/leetcode-cli-plugins/blob/master/docs/solution.discuss.md // -var plugin = new Plugin(200, 'solution.discuss', '2018.04.14', +var plugin = new Plugin(200, 'solution.discuss', '2019.02.03', 'Plugin to fetch most voted solution in discussions.'); var URL_DISCUSSES = 'https://leetcode.com/graphql'; @@ -20,14 +20,22 @@ var URL_DISCUSS = 'https://leetcode.com/problems/$slug/discuss/$id'; function getSolution(problem, lang, cb) { if (!problem) return cb(); + if (lang === 'python3') lang = 'python'; + var opts = { url: URL_DISCUSSES, json: true, - qs: { + body: { query: [ - 'query fetchTopics($questionId: Int!, $pageNo: Int!, $orderBy: String!) {', - ' questionTopics(questionId: $questionId, pageNo: $pageNo, orderBy: $orderBy) {', - ' data {', + 'query questionTopicsList($questionId: String!, $orderBy: TopicSortingOption, $skip: Int, $query: String, $first: Int!, $tags: [String!]) {', + ' questionTopicsList(questionId: $questionId, orderBy: $orderBy, skip: $skip, query: $query, first: $first, tags: $tags) {', + ' ...TopicsList', + ' }', + '}', + 'fragment TopicsList on TopicConnection {', + ' totalNum', + ' edges {', + ' node {', ' id', ' title', ' post {', @@ -42,11 +50,14 @@ function getSolution(problem, lang, cb) { '}' ].join('\n'), - operationName: 'fetchTopics', + operationName: 'questionTopicsList', variables: JSON.stringify({ - pageNo: 1, + query: '', + first: 1, + skip: 0, orderBy: 'most_votes', - questionId: problem.id + questionId: '' + problem.id, + tags: [lang] }) } }; @@ -55,23 +66,8 @@ function getSolution(problem, lang, cb) { if (resp.statusCode !== 200) return cb({msg: 'http error', statusCode: resp.statusCode}); - var langs = [lang]; - // try to find more compatible langs - if (lang === 'cpp') langs.push('c++'); - if (lang === 'csharp') langs.push('c#'); - if (lang === 'golang') langs.push('go'); - if (lang === 'javascript') langs.push('js'); - if (lang === 'python3') langs.push('python'); - - var solutions = body.data.questionTopics.data; - var solution = _.find(solutions, function(x) { - var keys = x.title.toLowerCase().split(/[^\w+]/); - for (var i = 0; i < keys.length; ++i) { - if (langs.indexOf(keys[i]) >= 0) return true; - } - return false; - }); - + const solutions = body.data.questionTopicsList.edges; + const solution = solutions.length > 0 ? solutions[0].node : null; return cb(null, solution); }); } From 752e94e8a755106106af65af9d9b831d9810c4cd Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 3 Feb 2019 12:39:39 +0800 Subject: [PATCH 48/48] fixes ut error Signed-off-by: Eric Wang --- plugins/solution.discuss.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/solution.discuss.js b/plugins/solution.discuss.js index b3a9a13..e78b90a 100644 --- a/plugins/solution.discuss.js +++ b/plugins/solution.discuss.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var request = require('request'); var log = require('../log'); @@ -25,7 +24,7 @@ function getSolution(problem, lang, cb) { var opts = { url: URL_DISCUSSES, json: true, - body: { + body: { query: [ 'query questionTopicsList($questionId: String!, $orderBy: TopicSortingOption, $skip: Int, $query: String, $first: Int!, $tags: [String!]) {', ' questionTopicsList(questionId: $questionId, orderBy: $orderBy, skip: $skip, query: $query, first: $first, tags: $tags) {',