Change lodash stuff so that it can be tree-shaken out of build (#233)
* Set common package.json sideEffects: false * Configure SWC to modularize lodash imports * Import specific lodash functions instead of _ * Add an eslint rule to avoid full lodash import
This commit is contained in:
parent
0803a15902
commit
47f10301c8
|
@ -1,4 +1,5 @@
|
|||
module.exports = {
|
||||
plugins: ['lodash'],
|
||||
extends: ['eslint:recommended'],
|
||||
env: {
|
||||
browser: true,
|
||||
|
@ -14,5 +15,6 @@ module.exports = {
|
|||
rules: {
|
||||
'no-unused-vars': 'off',
|
||||
'no-constant-condition': ['error', { checkLoops: false }],
|
||||
'lodash/import-scope': [2, 'member'],
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { range } from 'lodash'
|
||||
import { Bet, NumericBet } from './bet'
|
||||
import { getDpmProbability, getValueFromBucket } from './calculate-dpm'
|
||||
import {
|
||||
|
@ -11,7 +12,6 @@ import {
|
|||
import { User } from './user'
|
||||
import { LiquidityProvision } from './liquidity-provision'
|
||||
import { noFees } from './fees'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
export const FIXED_ANTE = 100
|
||||
|
||||
|
@ -127,11 +127,11 @@ export function getNumericAnte(
|
|||
const betShares = Math.sqrt(ante ** 2 / bucketCount)
|
||||
|
||||
const allOutcomeShares = Object.fromEntries(
|
||||
_.range(0, bucketCount).map((_, i) => [i, betShares])
|
||||
range(0, bucketCount).map((_, i) => [i, betShares])
|
||||
)
|
||||
|
||||
const allBetAmounts = Object.fromEntries(
|
||||
_.range(0, bucketCount).map((_, i) => [i, betAnte])
|
||||
range(0, bucketCount).map((_, i) => [i, betAnte])
|
||||
)
|
||||
|
||||
const anteBet: NumericBet = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { sum, groupBy, mapValues, sumBy } from 'lodash'
|
||||
|
||||
import { Binary, CPMM, FullContract } from './contract'
|
||||
import { CREATOR_FEE, Fees, LIQUIDITY_FEE, noFees, PLATFORM_FEE } from './fees'
|
||||
|
@ -278,16 +278,16 @@ export function getCpmmLiquidityPoolWeights(
|
|||
return liquidity
|
||||
})
|
||||
|
||||
const shareSum = _.sum(liquidityShares)
|
||||
const shareSum = sum(liquidityShares)
|
||||
|
||||
const weights = liquidityShares.map((s, i) => ({
|
||||
weight: s / shareSum,
|
||||
providerId: liquidities[i].userId,
|
||||
}))
|
||||
|
||||
const userWeights = _.groupBy(weights, (w) => w.providerId)
|
||||
const totalUserWeights = _.mapValues(userWeights, (userWeight) =>
|
||||
_.sumBy(userWeight, (w) => w.weight)
|
||||
const userWeights = groupBy(weights, (w) => w.providerId)
|
||||
const totalUserWeights = mapValues(userWeights, (userWeight) =>
|
||||
sumBy(userWeight, (w) => w.weight)
|
||||
)
|
||||
return totalUserWeights
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
|
||||
import { cloneDeep, range, sum, sumBy, sortBy, mapValues } from 'lodash'
|
||||
import { Bet, NumericBet } from './bet'
|
||||
import {
|
||||
Binary,
|
||||
|
@ -24,7 +23,7 @@ export function getDpmOutcomeProbability(
|
|||
},
|
||||
outcome: string
|
||||
) {
|
||||
const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
const squareSum = sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
const shares = totalShares[outcome] ?? 0
|
||||
return shares ** 2 / squareSum
|
||||
}
|
||||
|
@ -32,8 +31,8 @@ export function getDpmOutcomeProbability(
|
|||
export function getDpmOutcomeProbabilities(totalShares: {
|
||||
[outcome: string]: number
|
||||
}) {
|
||||
const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
return _.mapValues(totalShares, (shares) => shares ** 2 / squareSum)
|
||||
const squareSum = sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
return mapValues(totalShares, (shares) => shares ** 2 / squareSum)
|
||||
}
|
||||
|
||||
export function getNumericBets(
|
||||
|
@ -44,20 +43,20 @@ export function getNumericBets(
|
|||
) {
|
||||
const { bucketCount } = contract
|
||||
const bucketNumber = parseInt(bucket)
|
||||
const buckets = _.range(0, bucketCount)
|
||||
const buckets = range(0, bucketCount)
|
||||
|
||||
const mean = bucketNumber / bucketCount
|
||||
|
||||
const allDensities = buckets.map((i) =>
|
||||
normpdf(i / bucketCount, mean, variance)
|
||||
)
|
||||
const densitySum = _.sum(allDensities)
|
||||
const densitySum = sum(allDensities)
|
||||
|
||||
const rawBetAmounts = allDensities
|
||||
.map((d) => (d / densitySum) * betAmount)
|
||||
.map((x) => (x >= 1 / bucketCount ? x : 0))
|
||||
|
||||
const rawSum = _.sum(rawBetAmounts)
|
||||
const rawSum = sum(rawBetAmounts)
|
||||
const scaledBetAmounts = rawBetAmounts.map((x) => (x / rawSum) * betAmount)
|
||||
|
||||
const bets = scaledBetAmounts
|
||||
|
@ -90,26 +89,24 @@ export const getValueFromBucket = (
|
|||
export const getExpectedValue = (contract: NumericContract) => {
|
||||
const { bucketCount, min, max, totalShares } = contract
|
||||
|
||||
const totalShareSum = _.sumBy(
|
||||
const totalShareSum = sumBy(
|
||||
Object.values(totalShares),
|
||||
(shares) => shares ** 2
|
||||
)
|
||||
const probs = _.range(0, bucketCount).map(
|
||||
const probs = range(0, bucketCount).map(
|
||||
(i) => totalShares[i] ** 2 / totalShareSum
|
||||
)
|
||||
|
||||
const values = _.range(0, bucketCount).map(
|
||||
const values = range(0, bucketCount).map(
|
||||
(i) =>
|
||||
// use mid point within bucket
|
||||
0.5 * (min + (i / bucketCount) * (max - min)) +
|
||||
0.5 * (min + ((i + 1) / bucketCount) * (max - min))
|
||||
)
|
||||
|
||||
const weightedValues = _.range(0, bucketCount).map(
|
||||
(i) => probs[i] * values[i]
|
||||
)
|
||||
const weightedValues = range(0, bucketCount).map((i) => probs[i] * values[i])
|
||||
|
||||
const expectation = _.sum(weightedValues)
|
||||
const expectation = sum(weightedValues)
|
||||
const rounded = Math.round(expectation * 1e2) / 1e2
|
||||
return rounded
|
||||
}
|
||||
|
@ -150,7 +147,7 @@ export function calculateDpmShares(
|
|||
bet: number,
|
||||
betChoice: string
|
||||
) {
|
||||
const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
const squareSum = sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
const shares = totalShares[betChoice] ?? 0
|
||||
|
||||
const c = 2 * bet * Math.sqrt(squareSum)
|
||||
|
@ -166,9 +163,9 @@ export function calculateNumericDpmShares(
|
|||
) {
|
||||
const shares: number[] = []
|
||||
|
||||
totalShares = _.cloneDeep(totalShares)
|
||||
totalShares = cloneDeep(totalShares)
|
||||
|
||||
const order = _.sortBy(
|
||||
const order = sortBy(
|
||||
bets.map(([, amount], i) => [amount, i]),
|
||||
([amount]) => amount
|
||||
).map(([, i]) => i)
|
||||
|
@ -190,11 +187,11 @@ export function calculateDpmRawShareValue(
|
|||
betChoice: string
|
||||
) {
|
||||
const currentValue = Math.sqrt(
|
||||
_.sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||
)
|
||||
|
||||
const postSaleValue = Math.sqrt(
|
||||
_.sumBy(Object.keys(totalShares), (outcome) =>
|
||||
sumBy(Object.keys(totalShares), (outcome) =>
|
||||
outcome === betChoice
|
||||
? Math.max(0, totalShares[outcome] - shares) ** 2
|
||||
: totalShares[outcome] ** 2
|
||||
|
@ -214,12 +211,12 @@ export function calculateDpmMoneyRatio(
|
|||
|
||||
const p = getDpmOutcomeProbability(totalShares, outcome)
|
||||
|
||||
const actual = _.sum(Object.values(pool)) - shareValue
|
||||
const actual = sum(Object.values(pool)) - shareValue
|
||||
|
||||
const betAmount = p * amount
|
||||
|
||||
const expected =
|
||||
_.sumBy(
|
||||
sumBy(
|
||||
Object.keys(totalBets),
|
||||
(outcome) =>
|
||||
getDpmOutcomeProbability(totalShares, outcome) *
|
||||
|
@ -271,8 +268,8 @@ export function calculateDpmCancelPayout(
|
|||
bet: Bet
|
||||
) {
|
||||
const { totalBets, pool } = contract
|
||||
const betTotal = _.sum(Object.values(totalBets))
|
||||
const poolTotal = _.sum(Object.values(pool))
|
||||
const betTotal = sum(Object.values(totalBets))
|
||||
const poolTotal = sum(Object.values(pool))
|
||||
|
||||
return (bet.amount / betTotal) * poolTotal
|
||||
}
|
||||
|
@ -295,7 +292,7 @@ export function calculateStandardDpmPayout(
|
|||
const { totalShares, phantomShares, pool } = contract
|
||||
if (!totalShares[outcome]) return 0
|
||||
|
||||
const poolTotal = _.sum(Object.values(pool))
|
||||
const poolTotal = sum(Object.values(pool))
|
||||
|
||||
const total =
|
||||
totalShares[outcome] - (phantomShares ? phantomShares[outcome] : 0)
|
||||
|
@ -356,19 +353,19 @@ function calculateMktDpmPayout(
|
|||
let probs: { [outcome: string]: number }
|
||||
|
||||
if (resolutions) {
|
||||
const probTotal = _.sum(Object.values(resolutions))
|
||||
probs = _.mapValues(
|
||||
const probTotal = sum(Object.values(resolutions))
|
||||
probs = mapValues(
|
||||
totalShares,
|
||||
(_, outcome) => (resolutions[outcome] ?? 0) / probTotal
|
||||
)
|
||||
} else {
|
||||
const squareSum = _.sum(
|
||||
const squareSum = sum(
|
||||
Object.values(totalShares).map((shares) => shares ** 2)
|
||||
)
|
||||
probs = _.mapValues(totalShares, (shares) => shares ** 2 / squareSum)
|
||||
probs = mapValues(totalShares, (shares) => shares ** 2 / squareSum)
|
||||
}
|
||||
|
||||
const weightedShareTotal = _.sumBy(Object.keys(totalShares), (outcome) => {
|
||||
const weightedShareTotal = sumBy(Object.keys(totalShares), (outcome) => {
|
||||
return probs[outcome] * totalShares[outcome]
|
||||
})
|
||||
|
||||
|
@ -376,7 +373,7 @@ function calculateMktDpmPayout(
|
|||
|
||||
const poolFrac =
|
||||
outcomeType === 'NUMERIC'
|
||||
? _.sumBy(
|
||||
? sumBy(
|
||||
Object.keys((bet as NumericBet).allOutcomeShares ?? {}),
|
||||
(outcome) => {
|
||||
return (
|
||||
|
@ -387,7 +384,7 @@ function calculateMktDpmPayout(
|
|||
)
|
||||
: (probs[outcome] * shares) / weightedShareTotal
|
||||
|
||||
const totalPool = _.sum(Object.values(pool))
|
||||
const totalPool = sum(Object.values(pool))
|
||||
const winnings = poolFrac * totalPool
|
||||
return deductDpmFees(amount, winnings)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { maxBy } from 'lodash'
|
||||
import { Bet } from './bet'
|
||||
import {
|
||||
calculateCpmmSale,
|
||||
|
@ -180,7 +180,7 @@ export function getContractBetNullMetrics() {
|
|||
|
||||
export function getTopAnswer(contract: FreeResponseContract) {
|
||||
const { answers } = contract
|
||||
const top = _.maxBy(
|
||||
const top = maxBy(
|
||||
answers?.map((answer) => ({
|
||||
answer,
|
||||
prob: getOutcomeProbability(contract, answer.id),
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import * as _ from 'lodash'
|
||||
import { Answer } from './answer'
|
||||
import { Fees } from './fees'
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { sumBy } from 'lodash'
|
||||
|
||||
import { Bet, MAX_LOAN_PER_CONTRACT, NumericBet } from './bet'
|
||||
import {
|
||||
|
@ -210,7 +210,7 @@ export const getNumericBetsInfo = (
|
|||
|
||||
export const getLoanAmount = (yourBets: Bet[], newBetAmount: number) => {
|
||||
const openBets = yourBets.filter((bet) => !bet.isSold && !bet.sale)
|
||||
const prevLoanAmount = _.sumBy(openBets, (bet) => bet.loanAmount ?? 0)
|
||||
const prevLoanAmount = sumBy(openBets, (bet) => bet.loanAmount ?? 0)
|
||||
const loanAmount = Math.min(
|
||||
newBetAmount,
|
||||
MAX_LOAN_PER_CONTRACT - prevLoanAmount
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
|
||||
import { range } from 'lodash'
|
||||
import { PHANTOM_ANTE } from './antes'
|
||||
import {
|
||||
Binary,
|
||||
|
@ -131,7 +130,7 @@ const getNumericProps = (
|
|||
min: number,
|
||||
max: number
|
||||
) => {
|
||||
const buckets = _.range(0, bucketCount).map((i) => i.toString())
|
||||
const buckets = range(0, bucketCount).map((i) => i.toString())
|
||||
|
||||
const betAnte = ante / bucketCount
|
||||
const pool = Object.fromEntries(buckets.map((answer) => [answer, betAnte]))
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {},
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"lodash": "4.17.21"
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { sum, groupBy, sumBy, mapValues } from 'lodash'
|
||||
|
||||
import { Bet, NumericBet } from './bet'
|
||||
import { deductDpmFees, getDpmProbability } from './calculate-dpm'
|
||||
|
@ -17,10 +17,10 @@ export const getDpmCancelPayouts = (
|
|||
bets: Bet[]
|
||||
) => {
|
||||
const { pool } = contract
|
||||
const poolTotal = _.sum(Object.values(pool))
|
||||
const poolTotal = sum(Object.values(pool))
|
||||
console.log('resolved N/A, pool M$', poolTotal)
|
||||
|
||||
const betSum = _.sumBy(bets, (b) => b.amount)
|
||||
const betSum = sumBy(bets, (b) => b.amount)
|
||||
|
||||
const payouts = bets.map((bet) => ({
|
||||
userId: bet.userId,
|
||||
|
@ -42,8 +42,8 @@ export const getDpmStandardPayouts = (
|
|||
) => {
|
||||
const winningBets = bets.filter((bet) => bet.outcome === outcome)
|
||||
|
||||
const poolTotal = _.sum(Object.values(contract.pool))
|
||||
const totalShares = _.sumBy(winningBets, (b) => b.shares)
|
||||
const poolTotal = sum(Object.values(contract.pool))
|
||||
const totalShares = sumBy(winningBets, (b) => b.shares)
|
||||
|
||||
const payouts = winningBets.map(({ userId, amount, shares }) => {
|
||||
const winnings = (shares / totalShares) * poolTotal
|
||||
|
@ -54,7 +54,7 @@ export const getDpmStandardPayouts = (
|
|||
return { userId, profit, payout }
|
||||
})
|
||||
|
||||
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||
const profits = sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||
const creatorFee = DPM_CREATOR_FEE * profits
|
||||
const platformFee = DPM_PLATFORM_FEE * profits
|
||||
|
||||
|
@ -93,10 +93,10 @@ export const getNumericDpmPayouts = (
|
|||
contract: FullContract<DPM, any>,
|
||||
bets: NumericBet[]
|
||||
) => {
|
||||
const totalShares = _.sumBy(bets, (bet) => bet.allOutcomeShares[outcome] ?? 0)
|
||||
const totalShares = sumBy(bets, (bet) => bet.allOutcomeShares[outcome] ?? 0)
|
||||
const winningBets = bets.filter((bet) => !!bet.allOutcomeShares[outcome])
|
||||
|
||||
const poolTotal = _.sum(Object.values(contract.pool))
|
||||
const poolTotal = sum(Object.values(contract.pool))
|
||||
|
||||
const payouts = winningBets.map(
|
||||
({ userId, allBetAmounts, allOutcomeShares }) => {
|
||||
|
@ -112,7 +112,7 @@ export const getNumericDpmPayouts = (
|
|||
}
|
||||
)
|
||||
|
||||
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||
const profits = sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||
const creatorFee = DPM_CREATOR_FEE * profits
|
||||
const platformFee = DPM_PLATFORM_FEE * profits
|
||||
|
||||
|
@ -156,7 +156,7 @@ export const getDpmMktPayouts = (
|
|||
? getDpmProbability(contract.totalShares)
|
||||
: resolutionProbability
|
||||
|
||||
const weightedShareTotal = _.sumBy(bets, (b) =>
|
||||
const weightedShareTotal = sumBy(bets, (b) =>
|
||||
b.outcome === 'YES' ? p * b.shares : (1 - p) * b.shares
|
||||
)
|
||||
|
||||
|
@ -170,7 +170,7 @@ export const getDpmMktPayouts = (
|
|||
return { userId, profit, payout }
|
||||
})
|
||||
|
||||
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||
const profits = sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||
|
||||
const creatorFee = DPM_CREATOR_FEE * profits
|
||||
const platformFee = DPM_PLATFORM_FEE * profits
|
||||
|
@ -210,15 +210,15 @@ export const getPayoutsMultiOutcome = (
|
|||
contract: FullContract<DPM, Multi | FreeResponse>,
|
||||
bets: Bet[]
|
||||
) => {
|
||||
const poolTotal = _.sum(Object.values(contract.pool))
|
||||
const poolTotal = sum(Object.values(contract.pool))
|
||||
const winningBets = bets.filter((bet) => resolutions[bet.outcome])
|
||||
|
||||
const betsByOutcome = _.groupBy(winningBets, (bet) => bet.outcome)
|
||||
const sharesByOutcome = _.mapValues(betsByOutcome, (bets) =>
|
||||
_.sumBy(bets, (bet) => bet.shares)
|
||||
const betsByOutcome = groupBy(winningBets, (bet) => bet.outcome)
|
||||
const sharesByOutcome = mapValues(betsByOutcome, (bets) =>
|
||||
sumBy(bets, (bet) => bet.shares)
|
||||
)
|
||||
|
||||
const probTotal = _.sum(Object.values(resolutions))
|
||||
const probTotal = sum(Object.values(resolutions))
|
||||
|
||||
const payouts = winningBets.map(({ userId, outcome, amount, shares }) => {
|
||||
const prob = resolutions[outcome] / probTotal
|
||||
|
@ -229,7 +229,7 @@ export const getPayoutsMultiOutcome = (
|
|||
return { userId, profit, payout }
|
||||
})
|
||||
|
||||
const profits = _.sumBy(payouts, (po) => po.profit)
|
||||
const profits = sumBy(payouts, (po) => po.profit)
|
||||
|
||||
const creatorFee = DPM_CREATOR_FEE * profits
|
||||
const platformFee = DPM_PLATFORM_FEE * profits
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { sum } from 'lodash'
|
||||
|
||||
import { Bet } from './bet'
|
||||
import { getProbability } from './calculate'
|
||||
|
@ -50,7 +50,7 @@ export const getStandardFixedPayouts = (
|
|||
'pool',
|
||||
contract.pool[outcome],
|
||||
'payouts',
|
||||
_.sum(payouts),
|
||||
sum(payouts),
|
||||
'creator fee',
|
||||
creatorPayout
|
||||
)
|
||||
|
@ -105,7 +105,7 @@ export const getMktFixedPayouts = (
|
|||
'pool',
|
||||
p * contract.pool.YES + (1 - p) * contract.pool.NO,
|
||||
'payouts',
|
||||
_.sum(payouts),
|
||||
sum(payouts),
|
||||
'creator fee',
|
||||
creatorPayout
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { sumBy, groupBy, mapValues } from 'lodash'
|
||||
|
||||
import { Bet, NumericBet } from './bet'
|
||||
import {
|
||||
|
@ -32,16 +32,19 @@ export type Payout = {
|
|||
|
||||
export const getLoanPayouts = (bets: Bet[]): Payout[] => {
|
||||
const betsWithLoans = bets.filter((bet) => bet.loanAmount)
|
||||
const betsByUser = _.groupBy(betsWithLoans, (bet) => bet.userId)
|
||||
const loansByUser = _.mapValues(betsByUser, (bets) =>
|
||||
_.sumBy(bets, (bet) => -(bet.loanAmount ?? 0))
|
||||
const betsByUser = groupBy(betsWithLoans, (bet) => bet.userId)
|
||||
const loansByUser = mapValues(betsByUser, (bets) =>
|
||||
sumBy(bets, (bet) => -(bet.loanAmount ?? 0))
|
||||
)
|
||||
return _.toPairs(loansByUser).map(([userId, payout]) => ({ userId, payout }))
|
||||
return Object.entries(loansByUser).map(([userId, payout]) => ({
|
||||
userId,
|
||||
payout,
|
||||
}))
|
||||
}
|
||||
|
||||
export const groupPayoutsByUser = (payouts: Payout[]) => {
|
||||
const groups = _.groupBy(payouts, (payout) => payout.userId)
|
||||
return _.mapValues(groups, (group) => _.sumBy(group, (g) => g.payout))
|
||||
const groups = groupBy(payouts, (payout) => payout.userId)
|
||||
return mapValues(groups, (group) => sumBy(group, (g) => g.payout))
|
||||
}
|
||||
|
||||
export type PayoutInfo = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { union, sum, sumBy, sortBy, groupBy, mapValues } from 'lodash'
|
||||
import { Bet } from './bet'
|
||||
import { Contract } from './contract'
|
||||
import { ClickEvent } from './tracking'
|
||||
|
@ -21,13 +21,13 @@ export const getRecommendedContracts = (
|
|||
|
||||
const yourWordFrequency = contractsToWordFrequency(yourContracts)
|
||||
const otherWordFrequency = contractsToWordFrequency(notYourContracts)
|
||||
const words = _.union(
|
||||
const words = union(
|
||||
Object.keys(yourWordFrequency),
|
||||
Object.keys(otherWordFrequency)
|
||||
)
|
||||
|
||||
const yourWeightedFrequency = _.fromPairs(
|
||||
_.map(words, (word) => {
|
||||
const yourWeightedFrequency = Object.fromEntries(
|
||||
words.map((word) => {
|
||||
const [yourFreq, otherFreq] = [
|
||||
yourWordFrequency[word] ?? 0,
|
||||
otherWordFrequency[word] ?? 0,
|
||||
|
@ -47,7 +47,7 @@ export const getRecommendedContracts = (
|
|||
const scoredContracts = contracts.map((contract) => {
|
||||
const wordFrequency = contractToWordFrequency(contract)
|
||||
|
||||
const score = _.sumBy(Object.keys(wordFrequency), (word) => {
|
||||
const score = sumBy(Object.keys(wordFrequency), (word) => {
|
||||
const wordFreq = wordFrequency[word] ?? 0
|
||||
const weight = yourWeightedFrequency[word] ?? 0
|
||||
return wordFreq * weight
|
||||
|
@ -59,7 +59,7 @@ export const getRecommendedContracts = (
|
|||
}
|
||||
})
|
||||
|
||||
return _.sortBy(scoredContracts, (scored) => -scored.score).map(
|
||||
return sortBy(scoredContracts, (scored) => -scored.score).map(
|
||||
(scored) => scored.contract
|
||||
)
|
||||
}
|
||||
|
@ -87,8 +87,8 @@ const getWordsCount = (text: string) => {
|
|||
}
|
||||
|
||||
const toFrequency = (counts: { [word: string]: number }) => {
|
||||
const total = _.sum(Object.values(counts))
|
||||
return _.mapValues(counts, (count) => count / total)
|
||||
const total = sum(Object.values(counts))
|
||||
return mapValues(counts, (count) => count / total)
|
||||
}
|
||||
|
||||
const contractToWordFrequency = (contract: Contract) =>
|
||||
|
@ -108,8 +108,8 @@ export const getWordScores = (
|
|||
clicks: ClickEvent[],
|
||||
bets: Bet[]
|
||||
) => {
|
||||
const contractClicks = _.groupBy(clicks, (click) => click.contractId)
|
||||
const contractBets = _.groupBy(bets, (bet) => bet.contractId)
|
||||
const contractClicks = groupBy(clicks, (click) => click.contractId)
|
||||
const contractBets = groupBy(bets, (bet) => bet.contractId)
|
||||
|
||||
const yourContracts = contracts.filter(
|
||||
(c) =>
|
||||
|
@ -117,25 +117,22 @@ export const getWordScores = (
|
|||
)
|
||||
const yourTfIdf = calculateContractTfIdf(yourContracts)
|
||||
|
||||
const contractWordScores = _.mapValues(
|
||||
yourTfIdf,
|
||||
(wordsTfIdf, contractId) => {
|
||||
const viewCount = contractViewCounts[contractId] ?? 0
|
||||
const clickCount = contractClicks[contractId]?.length ?? 0
|
||||
const betCount = contractBets[contractId]?.length ?? 0
|
||||
const contractWordScores = mapValues(yourTfIdf, (wordsTfIdf, contractId) => {
|
||||
const viewCount = contractViewCounts[contractId] ?? 0
|
||||
const clickCount = contractClicks[contractId]?.length ?? 0
|
||||
const betCount = contractBets[contractId]?.length ?? 0
|
||||
|
||||
const factor =
|
||||
-1 * Math.log(viewCount + 1) +
|
||||
10 * Math.log(betCount + clickCount / 4 + 1)
|
||||
const factor =
|
||||
-1 * Math.log(viewCount + 1) +
|
||||
10 * Math.log(betCount + clickCount / 4 + 1)
|
||||
|
||||
return _.mapValues(wordsTfIdf, (tfIdf) => tfIdf * factor)
|
||||
}
|
||||
)
|
||||
return mapValues(wordsTfIdf, (tfIdf) => tfIdf * factor)
|
||||
})
|
||||
|
||||
const wordScores = Object.values(contractWordScores).reduce(addObjects, {})
|
||||
const minScore = Math.min(...Object.values(wordScores))
|
||||
const maxScore = Math.max(...Object.values(wordScores))
|
||||
const normalizedWordScores = _.mapValues(
|
||||
const normalizedWordScores = mapValues(
|
||||
wordScores,
|
||||
(score) => (score - minScore) / (maxScore - minScore)
|
||||
)
|
||||
|
@ -156,7 +153,7 @@ export function getContractScore(
|
|||
if (Object.keys(wordScores).length === 0) return 1
|
||||
|
||||
const wordFrequency = contractToWordFrequency(contract)
|
||||
const score = _.sumBy(Object.keys(wordFrequency), (word) => {
|
||||
const score = sumBy(Object.keys(wordFrequency), (word) => {
|
||||
const wordFreq = wordFrequency[word] ?? 0
|
||||
const weight = wordScores[word] ?? 0
|
||||
return wordFreq * weight
|
||||
|
@ -178,11 +175,13 @@ function calculateContractTfIdf(contracts: Contract[]) {
|
|||
}
|
||||
}
|
||||
|
||||
const wordIdf = _.mapValues(wordsCount, (count) =>
|
||||
const wordIdf = mapValues(wordsCount, (count) =>
|
||||
Math.log(contracts.length / count)
|
||||
)
|
||||
const contractWordsTfIdf = _.map(contractFreq, (wordFreq) =>
|
||||
_.mapValues(wordFreq, (freq, word) => freq * wordIdf[word])
|
||||
const contractWordsTfIdf = contractFreq.map((wordFreq) =>
|
||||
mapValues(wordFreq, (freq, word) => freq * wordIdf[word])
|
||||
)
|
||||
return Object.fromEntries(
|
||||
contracts.map((c, i) => [c.id, contractWordsTfIdf[i]])
|
||||
)
|
||||
return _.fromPairs(contracts.map((c, i) => [c.id, contractWordsTfIdf[i]]))
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import * as _ from 'lodash'
|
||||
import { groupBy, sumBy, mapValues, partition } from 'lodash'
|
||||
|
||||
import { Bet } from './bet'
|
||||
import { Binary, Contract, FullContract } from './contract'
|
||||
import { getPayouts } from './payouts'
|
||||
|
||||
export function scoreCreators(contracts: Contract[], bets: Bet[][]) {
|
||||
const creatorScore = _.mapValues(
|
||||
_.groupBy(contracts, ({ creatorId }) => creatorId),
|
||||
(contracts) => _.sumBy(contracts, ({ pool }) => pool.YES + pool.NO)
|
||||
const creatorScore = mapValues(
|
||||
groupBy(contracts, ({ creatorId }) => creatorId),
|
||||
(contracts) => sumBy(contracts, ({ pool }) => pool.YES + pool.NO)
|
||||
)
|
||||
|
||||
return creatorScore
|
||||
|
@ -30,7 +30,7 @@ export function scoreUsersByContract(
|
|||
) {
|
||||
const { resolution, resolutionProbability } = contract
|
||||
|
||||
const [closedBets, openBets] = _.partition(
|
||||
const [closedBets, openBets] = partition(
|
||||
bets,
|
||||
(bet) => bet.isSold || bet.sale
|
||||
)
|
||||
|
@ -58,9 +58,9 @@ export function scoreUsersByContract(
|
|||
|
||||
const netPayouts = [...resolvePayouts, ...salePayouts, ...investments]
|
||||
|
||||
const userScore = _.mapValues(
|
||||
_.groupBy(netPayouts, (payout) => payout.userId),
|
||||
(payouts) => _.sumBy(payouts, ({ payout }) => payout)
|
||||
const userScore = mapValues(
|
||||
groupBy(netPayouts, (payout) => payout.userId),
|
||||
(payouts) => sumBy(payouts, ({ payout }) => payout)
|
||||
)
|
||||
|
||||
return userScore
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { union } from 'lodash'
|
||||
|
||||
export const removeUndefinedProps = <T>(obj: T): T => {
|
||||
let newObj: any = {}
|
||||
|
@ -14,7 +14,7 @@ export const addObjects = <T extends { [key: string]: number }>(
|
|||
obj1: T,
|
||||
obj2: T
|
||||
) => {
|
||||
const keys = _.union(Object.keys(obj1), Object.keys(obj2))
|
||||
const keys = union(Object.keys(obj1), Object.keys(obj2))
|
||||
const newObj = {} as any
|
||||
|
||||
for (let key of keys) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
module.exports = {
|
||||
plugins: ['lodash'],
|
||||
extends: ['eslint:recommended'],
|
||||
ignorePatterns: ['lib'],
|
||||
env: {
|
||||
|
@ -17,5 +18,6 @@ module.exports = {
|
|||
rules: {
|
||||
'no-unused-vars': 'off',
|
||||
'no-constant-condition': ['error', { checkLoops: false }],
|
||||
'lodash/import-scope': [2, 'member'],
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import * as functions from 'firebase-functions'
|
||||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { getUser } from './utils'
|
||||
import { Contract } from '../../common/contract'
|
||||
|
@ -34,7 +33,7 @@ export const createFold = functions.runWith({ minInstances: 1 }).https.onCall(
|
|||
return { status: 'error', message: 'About must be a string' }
|
||||
about = about.trim().slice(0, 140)
|
||||
|
||||
if (!_.isArray(tags))
|
||||
if (!Array.isArray(tags))
|
||||
return { status: 'error', message: 'Tags must be an array of strings' }
|
||||
|
||||
console.log(
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import * as _ from 'lodash'
|
||||
|
||||
import { DOMAIN, PROJECT_ID } from '../../common/envs/constants'
|
||||
import { Answer } from '../../common/answer'
|
||||
import { Bet } from '../../common/bet'
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import * as functions from 'firebase-functions'
|
||||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { getContract } from './utils'
|
||||
import { Bet } from '../../common/bet'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as functions from 'firebase-functions'
|
||||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { uniq } from 'lodash'
|
||||
|
||||
import { getContract, getUser, getValues } from './utils'
|
||||
import { Comment } from '../../common/comment'
|
||||
|
@ -60,7 +60,7 @@ export const onCreateComment = functions.firestore
|
|||
firestore.collection('contracts').doc(contractId).collection('comments')
|
||||
)
|
||||
|
||||
const recipientUserIds = _.uniq([
|
||||
const recipientUserIds = uniq([
|
||||
contract.creatorId,
|
||||
...comments.map((comment) => comment.userId),
|
||||
]).filter((id) => id !== comment.userId)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { partition, sumBy } from 'lodash'
|
||||
|
||||
import { Bet } from '../../common/bet'
|
||||
import { getProbability } from '../../common/calculate'
|
||||
|
@ -25,14 +25,14 @@ export const redeemShares = async (userId: string, contractId: string) => {
|
|||
.where('userId', '==', userId)
|
||||
)
|
||||
const bets = betsSnap.docs.map((doc) => doc.data() as Bet)
|
||||
const [yesBets, noBets] = _.partition(bets, (b) => b.outcome === 'YES')
|
||||
const yesShares = _.sumBy(yesBets, (b) => b.shares)
|
||||
const noShares = _.sumBy(noBets, (b) => b.shares)
|
||||
const [yesBets, noBets] = partition(bets, (b) => b.outcome === 'YES')
|
||||
const yesShares = sumBy(yesBets, (b) => b.shares)
|
||||
const noShares = sumBy(noBets, (b) => b.shares)
|
||||
|
||||
const amount = Math.min(yesShares, noShares)
|
||||
if (amount <= 0) return
|
||||
|
||||
const prevLoanAmount = _.sumBy(bets, (bet) => bet.loanAmount ?? 0)
|
||||
const prevLoanAmount = sumBy(bets, (bet) => bet.loanAmount ?? 0)
|
||||
const loanPaid = Math.min(prevLoanAmount, amount)
|
||||
const netAmount = amount - loanPaid
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as functions from 'firebase-functions'
|
||||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { difference, uniq, mapValues, groupBy, sumBy } from 'lodash'
|
||||
|
||||
import { Contract } from '../../common/contract'
|
||||
import { User } from '../../common/user'
|
||||
|
@ -187,13 +187,13 @@ const sendResolutionEmails = async (
|
|||
resolutionProbability?: number,
|
||||
resolutions?: { [outcome: string]: number }
|
||||
) => {
|
||||
const nonWinners = _.difference(
|
||||
_.uniq(openBets.map(({ userId }) => userId)),
|
||||
const nonWinners = difference(
|
||||
uniq(openBets.map(({ userId }) => userId)),
|
||||
Object.keys(userPayouts)
|
||||
)
|
||||
const investedByUser = _.mapValues(
|
||||
_.groupBy(openBets, (bet) => bet.userId),
|
||||
(bets) => _.sumBy(bets, (bet) => bet.amount)
|
||||
const investedByUser = mapValues(
|
||||
groupBy(openBets, (bet) => bet.userId),
|
||||
(bets) => sumBy(bets, (bet) => bet.amount)
|
||||
)
|
||||
const emailPayouts = [
|
||||
...Object.entries(userPayouts),
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { sortBy } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -20,7 +20,7 @@ async function migrateContract(
|
|||
.get()
|
||||
.then((snap) => snap.docs.map((bet) => bet.data() as Bet))
|
||||
|
||||
const lastBet = _.sortBy(bets, (bet) => -bet.createdTime)[0]
|
||||
const lastBet = sortBy(bets, (bet) => -bet.createdTime)[0]
|
||||
if (lastBet) {
|
||||
const probAfter = getDpmProbability(contract.totalShares)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import * as fs from 'fs'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { uniq } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -19,7 +19,7 @@ async function lowercaseFoldTags() {
|
|||
const foldRef = firestore.doc(`folds/${fold.id}`)
|
||||
|
||||
const { tags } = fold
|
||||
const lowercaseTags = _.uniq(tags.map((tag) => tag.toLowerCase()))
|
||||
const lowercaseTags = uniq(tags.map((tag) => tag.toLowerCase()))
|
||||
|
||||
console.log('Adding lowercase tags', fold.slug, lowercaseTags)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { sumBy } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -25,8 +25,8 @@ async function migrateContract(contractRef: DocRef, contract: Contract) {
|
|||
.then((snap) => snap.docs.map((bet) => bet.data() as Bet))
|
||||
|
||||
const totalShares = {
|
||||
YES: _.sumBy(bets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
|
||||
NO: _.sumBy(bets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
|
||||
YES: sumBy(bets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
|
||||
NO: sumBy(bets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
|
||||
}
|
||||
|
||||
await contractRef.update({ totalShares })
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { sortBy } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -48,7 +48,7 @@ async function recalculateContract(contractRef: DocRef, isCommit = false) {
|
|||
|
||||
const betsRef = contractRef.collection('bets')
|
||||
const betDocs = await transaction.get(betsRef)
|
||||
const bets = _.sortBy(
|
||||
const bets = sortBy(
|
||||
betDocs.docs.map((d) => d.data() as Bet),
|
||||
(b) => b.createdTime
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { sortBy, sumBy } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -35,7 +35,7 @@ async function recalculateContract(
|
|||
const contract = contractDoc.data() as FullContract<DPM, Binary>
|
||||
|
||||
const betDocs = await transaction.get(contractRef.collection('bets'))
|
||||
const bets = _.sortBy(
|
||||
const bets = sortBy(
|
||||
betDocs.docs.map((d) => d.data() as Bet),
|
||||
(b) => b.createdTime
|
||||
)
|
||||
|
@ -43,8 +43,8 @@ async function recalculateContract(
|
|||
const phantomAnte = startPool.YES + startPool.NO
|
||||
|
||||
const leftovers =
|
||||
_.sumBy(bets, (b) => b.amount) -
|
||||
_.sumBy(bets, (b) => {
|
||||
sumBy(bets, (b) => b.amount) -
|
||||
sumBy(bets, (b) => {
|
||||
if (!b.sale) return b.amount
|
||||
const soldBet = bets.find((bet) => bet.id === b.sale?.betId)
|
||||
return soldBet?.amount || 0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { flatten, groupBy, sumBy, mapValues } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -35,12 +35,12 @@ async function checkIfPayOutAgain(contractRef: DocRef, contract: Contract) {
|
|||
)
|
||||
|
||||
const loanPayouts = getLoanPayouts(openBets)
|
||||
const groups = _.groupBy(
|
||||
const groups = groupBy(
|
||||
[...payouts, ...loanPayouts],
|
||||
(payout) => payout.userId
|
||||
)
|
||||
const userPayouts = _.mapValues(groups, (group) =>
|
||||
_.sumBy(group, (g) => g.payout)
|
||||
const userPayouts = mapValues(groups, (group) =>
|
||||
sumBy(group, (g) => g.payout)
|
||||
)
|
||||
|
||||
const entries = Object.entries(userPayouts)
|
||||
|
@ -93,7 +93,7 @@ async function payOutContractAgain() {
|
|||
)
|
||||
)
|
||||
|
||||
const flattened = _.flatten(toPayOutAgain.map((d) => d.toBePaidOut))
|
||||
const flattened = flatten(toPayOutAgain.map((d) => d.toBePaidOut))
|
||||
|
||||
for (const [userId, payout] of flattened) {
|
||||
console.log('Paying out', userId, payout)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { sumBy } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -20,13 +20,13 @@ async function recalculateContract(contractRef: DocRef, contract: Contract) {
|
|||
const openBets = bets.filter((b) => !b.isSold && !b.sale)
|
||||
|
||||
const totalShares = {
|
||||
YES: _.sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
|
||||
NO: _.sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
|
||||
YES: sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
|
||||
NO: sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
|
||||
}
|
||||
|
||||
const totalBets = {
|
||||
YES: _.sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.amount : 0)),
|
||||
NO: _.sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.amount : 0)),
|
||||
YES: sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.amount : 0)),
|
||||
NO: sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.amount : 0)),
|
||||
}
|
||||
|
||||
await contractRef.update({ totalShares, totalBets })
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
import { uniq } from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
@ -19,7 +19,7 @@ async function updateContractTags() {
|
|||
for (const contract of contracts) {
|
||||
const contractRef = firestore.doc(`contracts/${contract.id}`)
|
||||
|
||||
const tags = _.uniq([
|
||||
const tags = uniq([
|
||||
...parseTags(contract.question + contract.description),
|
||||
...(contract.tags ?? []),
|
||||
])
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import { initAdmin } from './script-init'
|
||||
initAdmin()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as _ from 'lodash'
|
||||
import { partition, sumBy } from 'lodash'
|
||||
import * as admin from 'firebase-admin'
|
||||
import * as functions from 'firebase-functions'
|
||||