import type { FinancialStatementKind, FinancialUnit } from '@/lib/types'; export type TemplateSelectionPolicy = | 'single_best_period_match' | 'prefer_exact_local_name' | 'prefer_primary_statement_concept' | 'formula_only' | 'aggregate_multiple_components' | 'direct_or_formula_fallback'; export type TemplateFormula = | { kind: 'sum'; sourceKeys: readonly string[]; treatNullAsZero?: boolean; } | { kind: 'subtract'; left: string; right: string; } | { kind: 'divide'; numerator: string; denominator: string; }; export type StandardTemplateRowDefinition = { key: string; label: string; category: string; includeInOutput?: boolean; order: number; statement: Extract; unit: FinancialUnit; selectionPolicy: TemplateSelectionPolicy; matchers: { exactLocalNames?: readonly string[]; secondaryLocalNames?: readonly string[]; allowedLabelPhrases?: readonly string[]; excludeLabelPhrases?: readonly string[]; excludeLocalNames?: readonly string[]; }; fallbackFormula?: TemplateFormula; signTransform?: 'invert' | 'absolute'; }; const income = ( definition: Omit & { category?: string } ) => ({ statement: 'income' as const, category: definition.category ?? 'statement', ...definition }); const balance = ( definition: Omit ) => ({ statement: 'balance' as const, ...definition }); const cashFlow = ( definition: Omit ) => ({ statement: 'cash_flow' as const, ...definition }); export const STANDARD_FINANCIAL_TEMPLATES: Record< Extract, StandardTemplateRowDefinition[] > = { income: [ income({ key: 'revenue', label: 'Total Revenues', order: 10, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'Revenues', 'RevenueFromContractWithCustomerExcludingAssessedTax', 'SalesRevenueNet', 'TotalRevenuesAndOtherIncome' ], secondaryLocalNames: ['RevenueFromContractWithCustomerIncludingAssessedTax'], allowedLabelPhrases: ['total revenues', 'total revenue', 'revenue', 'net sales'], excludeLabelPhrases: ['pro forma', 'acquiree'], excludeLocalNames: [ 'BusinessAcquisitionsProFormaRevenue', 'BusinessCombinationProFormaInformationRevenueOfAcquireeSinceAcquisitionDateActual' ] } }), income({ key: 'cost_of_revenue', label: 'Cost of Sales', order: 20, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'CostOfGoodsSoldExcludingEmployeeStockOptionPlanSpecialDividendCompensation', 'CostOfRevenue', 'CostOfGoodsSold', 'CostOfSales', 'CostOfGoodsAndServicesSold', 'CostOfGoodsAndServiceExcludingDepreciationDepletionAndAmortization', 'CostOfProductsSold', 'CostOfServices' ], allowedLabelPhrases: ['cost of sales', 'cost of revenue', 'cost of goods sold'], excludeLocalNames: ['CostOfGoodsAndServicesSoldDepreciationAndAmortization'] } }), income({ key: 'gross_profit', label: 'Gross Profit', order: 30, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: ['GrossProfit'], allowedLabelPhrases: ['gross profit'] }, fallbackFormula: { kind: 'subtract', left: 'revenue', right: 'cost_of_revenue' } }), income({ key: 'gross_margin', label: 'Gross Profit Margin', order: 40, unit: 'percent', selectionPolicy: 'formula_only', matchers: {}, fallbackFormula: { kind: 'divide', numerator: 'gross_profit', denominator: 'revenue' } }), income({ key: 'selling_general_and_administrative', label: 'Selling, General & Administrative Expenses', order: 50, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: [ 'SellingGeneralAndAdministrativeExpenseExcludingEmployeeStockOptionPlanSpecialDividendCompensation', 'SellingGeneralAndAdministrativeExpense' ], secondaryLocalNames: ['OperatingExpenses'], allowedLabelPhrases: ['selling general administrative', 'selling general and administrative'], excludeLocalNames: ['SellingGeneralAndAdministrativeExpenseEmployeeStockOptionPlanSpecialDividendCompensation'] }, fallbackFormula: { kind: 'sum', sourceKeys: ['sales_and_marketing', 'general_and_administrative'] } }), income({ key: 'research_and_development', label: 'Research & Development Expenses', order: 60, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ResearchAndDevelopmentExpense'], allowedLabelPhrases: ['research development', 'research and development'] } }), income({ key: 'sales_and_marketing', label: 'Sales & Marketing', includeInOutput: false, order: 61, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['SalesAndMarketingExpense', 'SellingAndMarketingExpense'], allowedLabelPhrases: ['sales and marketing', 'selling and marketing'] } }), income({ key: 'general_and_administrative', label: 'General & Administrative', includeInOutput: false, order: 62, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['GeneralAndAdministrativeExpense'], allowedLabelPhrases: ['general and administrative'] } }), income({ key: 'operating_income', label: 'Operating Profit', order: 70, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: ['OperatingIncomeLoss', 'IncomeLossFromOperations'], allowedLabelPhrases: ['operating profit', 'operating income', 'income from operations'], excludeLocalNames: ['NonoperatingIncomeExpense', 'OtherNonoperatingIncomeExpense'] } }), income({ key: 'operating_margin', label: 'Operating Margin', order: 80, unit: 'percent', selectionPolicy: 'formula_only', matchers: {}, fallbackFormula: { kind: 'divide', numerator: 'operating_income', denominator: 'revenue' } }), income({ key: 'pretax_income', label: 'Pretax Income', order: 90, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: [ 'IncomeLossFromContinuingOperationsBeforeIncomeTaxesExtraordinaryItemsNoncontrollingInterest', 'IncomeBeforeTaxExpenseBenefit', 'PretaxIncome' ], allowedLabelPhrases: ['pretax income', 'income before taxes', 'income before tax'] }, fallbackFormula: { kind: 'sum', sourceKeys: ['net_income', 'income_tax_expense'] } }), income({ key: 'income_before_provision_for_income_taxes', label: 'Income Before Provision for Income Taxes', order: 95, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: [ 'IncomeLossFromContinuingOperationsBeforeIncomeTaxesExtraordinaryItemsNoncontrollingInterest', 'IncomeBeforeTaxExpenseBenefit', 'PretaxIncome' ], allowedLabelPhrases: ['income before provision for income taxes', 'income before taxes', 'pretax income'] }, fallbackFormula: { kind: 'sum', sourceKeys: ['net_income', 'income_tax_expense'] } }), income({ key: 'income_tax_expense', label: 'Income Tax Expense', order: 100, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncomeTaxExpenseBenefit'], secondaryLocalNames: ['IncomeTaxes'], allowedLabelPhrases: ['income tax expense', 'income tax provision'], excludeLocalNames: [ 'CurrentIncomeTaxExpenseBenefit', 'DeferredIncomeTaxExpenseBenefit', 'DeferredFederalIncomeTaxExpenseBenefit', 'DeferredForeignIncomeTaxExpenseBenefit', 'DeferredStateAndLocalIncomeTaxExpenseBenefit' ], excludeLabelPhrases: ['current income tax', 'deferred income tax'] } }), income({ key: 'provision_for_income_taxes', label: 'Provision for Income Taxes', order: 105, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncomeTaxExpenseBenefit'], secondaryLocalNames: ['IncomeTaxes'], allowedLabelPhrases: ['provision for income taxes', 'income tax provision'] } }), income({ key: 'net_income', label: 'Net Income', order: 110, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['NetIncomeLossAvailableToCommonStockholdersBasic', 'NetIncomeLoss', 'ProfitLoss'], allowedLabelPhrases: ['net income', 'net earnings'], excludeLocalNames: ['BusinessAcquisitionsProFormaNetIncomeLoss'], excludeLabelPhrases: ['pro forma'] } }), income({ key: 'consolidated_net_income', label: 'Consolidated Net Income', order: 112, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['NetIncomeLoss', 'ProfitLoss'], allowedLabelPhrases: ['consolidated net income', 'net income'] } }), income({ key: 'net_income_attributable_to_common_shareholders', label: 'Net Income Attributable to Common Shareholders', order: 114, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['NetIncomeLossAvailableToCommonStockholdersBasic'], allowedLabelPhrases: ['net income attributable to common shareholders', 'net income available to common stockholders'] } }), income({ key: 'depreciation_and_amortization', label: 'Depreciation & Amortization', order: 200, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'DepreciationDepletionAndAmortization', 'DepreciationAmortizationAndAccretionNet', 'DepreciationAndAmortization', 'DepreciationAmortizationAndOther', 'CostOfGoodsAndServicesSoldDepreciationAndAmortization' ], secondaryLocalNames: ['AmortizationOfIntangibleAssets'], allowedLabelPhrases: ['depreciation amortization', 'depreciation and amortization'] } }), income({ key: 'depreciation_and_amortization_expenses', label: 'Depreciation & Amortization Expense', order: 205, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['CostOfGoodsAndServicesSoldDepreciationAndAmortization'], allowedLabelPhrases: ['depreciation amortization expense', 'depreciation and amortization expense'] } }), income({ key: 'interest_income', label: 'Interest Income', order: 210, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['InterestIncomeOther', 'InvestmentIncomeInterest'], secondaryLocalNames: ['InvestmentIncomeNet'], allowedLabelPhrases: ['interest income'], excludeLabelPhrases: ['effective income tax rate reconciliation', 'reconciliation'], excludeLocalNames: ['InterestIncomeExpenseNet'] } }), income({ key: 'interest_expense', label: 'Interest Expense', order: 220, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['InterestIncomeExpenseNonoperatingNet', 'InterestExpense', 'InterestAndDebtExpense'], allowedLabelPhrases: ['interest expense'] }, signTransform: 'absolute' }), income({ key: 'other_non_operating_income', label: 'Other Non-Operating Income', order: 230, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['OtherNonoperatingIncomeExpense', 'NonoperatingIncomeExpense'], allowedLabelPhrases: ['other non operating', 'other non-operating'] } }), income({ key: 'stock_based_compensation', label: 'Share-Based Compensation Expense', order: 240, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ShareBasedCompensation', 'AllocatedShareBasedCompensationExpense'], allowedLabelPhrases: ['share based compensation', 'stock based compensation'] } }), income({ key: 'ebitda', label: 'EBITDA', order: 250, unit: 'currency', selectionPolicy: 'formula_only', matchers: {}, fallbackFormula: { kind: 'sum', sourceKeys: ['operating_income', 'depreciation_and_amortization'] } }), income({ key: 'effective_tax_rate', label: 'Effective Tax Rate', order: 260, unit: 'percent', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: ['EffectiveIncomeTaxRateContinuingOperations'], allowedLabelPhrases: ['effective tax rate'] }, fallbackFormula: { kind: 'divide', numerator: 'income_tax_expense', denominator: 'pretax_income' } }), income({ key: 'diluted_eps', label: 'Diluted EPS', order: 300, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['EarningsPerShareDiluted', 'DilutedEarningsPerShare'], allowedLabelPhrases: ['diluted eps', 'diluted earnings per share'] } }), income({ key: 'basic_eps', label: 'Basic EPS', order: 310, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['EarningsPerShareBasic', 'BasicEarningsPerShare'], allowedLabelPhrases: ['basic eps', 'basic earnings per share'] } }), income({ key: 'diluted_shares', label: 'Diluted Shares', order: 320, unit: 'shares', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'WeightedAverageNumberOfDilutedSharesOutstanding', 'WeightedAverageNumberOfShareOutstandingDiluted' ], allowedLabelPhrases: ['diluted shares', 'weighted average diluted'] } }), income({ key: 'basic_shares', label: 'Basic Shares', order: 330, unit: 'shares', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'WeightedAverageNumberOfSharesOutstandingBasic', 'WeightedAverageNumberOfShareOutstandingBasicAndDiluted' ], allowedLabelPhrases: ['basic shares', 'weighted average basic'] } }) ], balance: [ balance({ key: 'cash_and_equivalents', label: 'Cash and Cash Equivalents', category: 'assets', order: 10, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['CashAndCashEquivalentsAtCarryingValue'], secondaryLocalNames: ['Cash', 'CashCashEquivalentsAndFederalFundsSold'], allowedLabelPhrases: ['cash and cash equivalents'] } }), balance({ key: 'short_term_investments', label: 'Short-Term Investments', category: 'assets', order: 20, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['AvailableForSaleSecuritiesCurrent', 'ShortTermInvestments', 'MarketableSecuritiesCurrent'], allowedLabelPhrases: ['short term investments', 'marketable securities'] } }), balance({ key: 'total_cash_and_equivalents', label: 'Total Cash and Cash Equivalents', category: 'assets', order: 30, unit: 'currency', selectionPolicy: 'aggregate_multiple_components', matchers: { exactLocalNames: ['CashCashEquivalentsAndShortTermInvestments', 'CashAndShortTermInvestments'], allowedLabelPhrases: ['total cash and cash equivalents'] }, fallbackFormula: { kind: 'sum', sourceKeys: ['cash_and_equivalents', 'short_term_investments'], treatNullAsZero: true } }), balance({ key: 'accounts_receivable', label: 'Accounts Receivable', category: 'assets', order: 40, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['AccountsReceivableNetCurrent', 'ReceivablesNetCurrent'], allowedLabelPhrases: ['accounts receivable'] } }), balance({ key: 'inventory', label: 'Inventories', category: 'assets', order: 50, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['InventoryNet'], allowedLabelPhrases: ['inventories', 'inventory'] } }), balance({ key: 'other_current_assets', label: 'Other Current Assets', category: 'assets', order: 60, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['OtherAssetsCurrent'], allowedLabelPhrases: ['other current assets'] } }), balance({ key: 'deferred_income_taxes_asset', label: 'Deferred Income Taxes', category: 'assets', order: 70, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['DeferredIncomeTaxAssetsNet', 'DeferredTaxAssetsNet'], allowedLabelPhrases: ['deferred income taxes', 'deferred tax assets'], excludeLocalNames: ['DeferredIncomeTaxLiabilities', 'DeferredIncomeTaxLiabilitiesNet'] } }), balance({ key: 'current_assets', label: 'Total Current Assets', category: 'assets', order: 80, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['AssetsCurrent'], allowedLabelPhrases: ['total current assets', 'current assets'] } }), balance({ key: 'property_plant_equipment', label: 'Net Property, Plant & Equipment', category: 'assets', order: 90, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['PropertyPlantAndEquipmentNet'], secondaryLocalNames: ['PropertyPlantAndEquipmentAndFinanceLeaseRightOfUseAssetAfterAccumulatedDepreciationAndAmortization'], allowedLabelPhrases: ['property plant equipment', 'property and equipment net'] } }), balance({ key: 'operating_lease_right_of_use_assets', label: 'Operating Lease Right-of-Use Assets', category: 'assets', order: 100, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['OperatingLeaseRightOfUseAsset'], allowedLabelPhrases: ['operating lease right of use assets', 'operating lease right of use asset'] } }), balance({ key: 'intangible_assets', label: 'Net Intangible Assets', category: 'assets', order: 110, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'FiniteLivedIntangibleAssetsNet', 'IntangibleAssetsNetExcludingGoodwill', 'FiniteLivedIntangibleAssetsNetExcludingGoodwill' ], allowedLabelPhrases: ['net intangible assets', 'intangible assets net'] } }), balance({ key: 'goodwill', label: 'Goodwill', category: 'assets', order: 120, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['Goodwill'], allowedLabelPhrases: ['goodwill'], excludeLabelPhrases: ['excluding goodwill'] } }), balance({ key: 'long_term_investments', label: 'Long-Term Investments', category: 'assets', order: 130, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'AvailableForSaleSecuritiesDebtMaturitiesSingleMaturityDate', 'AvailableForSaleSecuritiesNoncurrent', 'LongTermInvestments' ], secondaryLocalNames: ['AvailableForSaleSecuritiesDebtSecurities'], allowedLabelPhrases: ['long term investments'] } }), balance({ key: 'other_long_term_assets', label: 'Other Long-Term Assets', category: 'assets', order: 140, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['OtherAssetsNoncurrent'], allowedLabelPhrases: ['other long term assets', 'other noncurrent assets'], excludeLocalNames: ['NoncurrentAssets'] } }), balance({ key: 'total_assets', label: 'Total Assets', category: 'assets', order: 150, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['Assets'], allowedLabelPhrases: ['total assets'] } }), balance({ key: 'accounts_payable', label: 'Accounts Payable', category: 'liabilities', order: 160, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['AccountsPayableCurrent'], allowedLabelPhrases: ['accounts payable'], excludeLabelPhrases: ['business combination', 'liabilities assumed'] } }), balance({ key: 'accrued_liabilities', label: 'Accrued Expenses', category: 'liabilities', order: 170, unit: 'currency', selectionPolicy: 'aggregate_multiple_components', matchers: { exactLocalNames: [ 'AccruedLiabilitiesCurrent', 'OtherAccruedLiabilitiesCurrent', 'AccruedCompensationCurrent', 'EmployeeRelatedLiabilitiesCurrent', 'OtherLiabilitiesCurrent', 'AccruedPropertyTaxes' ], allowedLabelPhrases: ['accrued expenses', 'accrued liabilities', 'accrued compensation', 'accrued property taxes'] } }), balance({ key: 'short_term_debt', label: 'Short-Term Debt', category: 'liabilities', order: 180, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ShortTermBorrowings', 'DebtCurrent', 'CommercialPaper'], allowedLabelPhrases: ['short term debt', 'short-term debt'] } }), balance({ key: 'current_debt', label: 'Current Portion of Long-Term Debt', category: 'liabilities', order: 190, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['LongTermDebtCurrent', 'CurrentPortionOfLongTermDebt', 'LongTermDebtAndCapitalLeaseObligationsCurrent'], allowedLabelPhrases: ['current portion of long term debt', 'current portion of long-term debt'] } }), balance({ key: 'long_term_debt', label: 'Long-Term Debt', category: 'liabilities', order: 200, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['LongTermDebtNoncurrent', 'DebtNoncurrent', 'LongTermDebtAndCapitalLeaseObligations'], secondaryLocalNames: ['LongTermDebt', 'DebtInstrumentCarryingAmount'], allowedLabelPhrases: ['long term debt', 'long-term debt'] } }), balance({ key: 'unearned_revenue', label: 'Unearned Revenue', category: 'liabilities', order: 210, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: ['ContractWithCustomerLiabilityCurrent', 'DeferredRevenueCurrent'], secondaryLocalNames: ['ContractWithCustomerLiability', 'DeferredRevenue'], allowedLabelPhrases: ['unearned revenue', 'deferred revenue'] }, fallbackFormula: { kind: 'sum', sourceKeys: ['deferred_revenue_current', 'deferred_revenue_noncurrent'], treatNullAsZero: true } }), balance({ key: 'deferred_revenue_current', label: 'Deferred Revenue, Current', includeInOutput: false, category: 'liabilities', order: 211, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ContractWithCustomerLiabilityCurrent', 'DeferredRevenueCurrent'], allowedLabelPhrases: ['deferred revenue current', 'current deferred revenue'] } }), balance({ key: 'deferred_revenue_noncurrent', label: 'Deferred Revenue, Noncurrent', includeInOutput: false, category: 'liabilities', order: 212, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ContractWithCustomerLiabilityNoncurrent', 'DeferredRevenueNoncurrent'], allowedLabelPhrases: ['deferred revenue noncurrent', 'noncurrent deferred revenue'] } }), balance({ key: 'deferred_income_taxes_liability', label: 'Deferred Income Taxes', category: 'liabilities', order: 220, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['DeferredIncomeTaxLiabilitiesNet', 'DeferredIncomeTaxLiabilities'], allowedLabelPhrases: ['deferred income taxes', 'deferred tax liabilities'], excludeLocalNames: ['DeferredIncomeTaxAssetsNet', 'DeferredTaxAssetsNet'] } }), balance({ key: 'other_long_term_liabilities', label: 'Other Long-Term Liabilities', category: 'liabilities', order: 230, unit: 'currency', selectionPolicy: 'aggregate_multiple_components', matchers: { exactLocalNames: [ 'DeferredIncomeTaxLiabilitiesNet', 'DeferredIncomeTaxLiabilities', 'AssetRetirementObligationsNoncurrent', 'OtherLiabilitiesNoncurrent' ], allowedLabelPhrases: ['other long term liabilities', 'other noncurrent liabilities'], excludeLocalNames: [ 'DeferredIncomeTaxLiabilitiesNet', 'DeferredIncomeTaxLiabilities', 'OperatingLeaseLiability', 'OperatingLeaseLiabilityCurrent', 'OperatingLeaseLiabilityNoncurrent', 'FinanceLeaseLiability', 'FinanceLeaseLiabilityCurrent', 'FinanceLeaseLiabilityNoncurrent', 'LesseeOperatingLeaseLiability' ] } }), balance({ key: 'current_liabilities', label: 'Current Liabilities', category: 'liabilities', order: 240, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['LiabilitiesCurrent'], allowedLabelPhrases: ['current liabilities'] } }), balance({ key: 'total_current_liabilities', label: 'Total Current Liabilities', category: 'liabilities', order: 241, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['LiabilitiesCurrent'], allowedLabelPhrases: ['total current liabilities'] } }), balance({ key: 'lease_liabilities', label: 'Lease Liabilities', category: 'liabilities', order: 250, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'OperatingLeaseLiabilityNoncurrent', 'OperatingLeaseLiability', 'FinanceLeaseLiability', 'FinanceLeaseLiabilityNoncurrent', 'LesseeOperatingLeaseLiability' ], allowedLabelPhrases: ['lease liabilities'] } }), balance({ key: 'leases', label: 'Leases', category: 'liabilities', order: 255, unit: 'currency', selectionPolicy: 'aggregate_multiple_components', matchers: { exactLocalNames: [ 'OperatingLeaseLiability', 'OperatingLeaseLiabilityCurrent', 'OperatingLeaseLiabilityNoncurrent', 'FinanceLeaseLiability', 'FinanceLeaseLiabilityCurrent', 'FinanceLeaseLiabilityNoncurrent', 'LesseeOperatingLeaseLiability' ], allowedLabelPhrases: ['leases'] } }), balance({ key: 'total_liabilities', label: 'Total Liabilities', category: 'liabilities', order: 260, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['Liabilities'], allowedLabelPhrases: ['total liabilities'] } }), balance({ key: 'common_stock', label: 'Common Stock', category: 'equity', order: 270, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['CommonStocksIncludingAdditionalPaidInCapital', 'CommonStockValue'], secondaryLocalNames: ['AdditionalPaidInCapitalCommonStock', 'AdditionalPaidInCapital'], allowedLabelPhrases: ['common stock'] } }), balance({ key: 'accumulated_other_comprehensive_income', label: 'Accumulated Other Comprehensive Income', category: 'equity', order: 280, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['AccumulatedOtherComprehensiveIncomeLossNetOfTax'], allowedLabelPhrases: ['accumulated other comprehensive income'] } }), balance({ key: 'retained_earnings', label: 'Retained Earnings', category: 'equity', order: 290, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['RetainedEarningsAccumulatedDeficit'], allowedLabelPhrases: ['retained earnings', 'accumulated deficit'] } }), balance({ key: 'total_equity', label: "Total Shareholders' Equity", category: 'equity', order: 300, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: ['StockholdersEquity', 'StockholdersEquityIncludingPortionAttributableToNoncontrollingInterest', 'PartnersCapital'], allowedLabelPhrases: ['total shareholders equity', 'total stockholders equity', 'total equity'] }, fallbackFormula: { kind: 'subtract', left: 'total_assets', right: 'total_liabilities' } }), balance({ key: 'total_common_shareholders_equity', label: "Total Common Shareholders' Equity", category: 'equity', order: 301, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['StockholdersEquity'], allowedLabelPhrases: ['total common shareholders equity', 'total stockholders equity'] } }), balance({ key: 'total_liabilities_and_equity', label: "Total Liabilities and Shareholders' Equity", category: 'equity', order: 310, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: ['LiabilitiesAndStockholdersEquity'], allowedLabelPhrases: ['total liabilities and shareholders equity', 'total liabilities and stockholders equity'] }, fallbackFormula: { kind: 'sum', sourceKeys: ['total_liabilities', 'total_equity'] } }), balance({ key: 'total_debt', label: 'Total Debt', category: 'liabilities', order: 320, unit: 'currency', selectionPolicy: 'formula_only', matchers: {}, fallbackFormula: { kind: 'sum', sourceKeys: ['short_term_debt', 'current_debt', 'long_term_debt', 'lease_liabilities'], treatNullAsZero: true } }), balance({ key: 'net_cash_position', label: 'Net Cash Position', category: 'assets', order: 330, unit: 'currency', selectionPolicy: 'formula_only', matchers: {}, fallbackFormula: { kind: 'subtract', left: 'total_cash_and_equivalents', right: 'total_debt' } }) ], cash_flow: [ cashFlow({ key: 'net_income', label: 'Net Income', category: 'operating', order: 10, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['NetIncomeLossAvailableToCommonStockholdersBasic', 'NetIncomeLoss', 'ProfitLoss'], allowedLabelPhrases: ['net income'] } }), cashFlow({ key: 'depreciation_and_amortization', label: 'Depreciation & Amortization', category: 'operating', order: 20, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'DepreciationDepletionAndAmortization', 'DepreciationAmortizationAndAccretionNet', 'DepreciationAndAmortization', 'DepreciationAmortizationAndOther' ], secondaryLocalNames: ['AmortizationOfIntangibleAssets'], allowedLabelPhrases: ['depreciation amortization', 'depreciation and amortization'] } }), cashFlow({ key: 'stock_based_compensation', label: 'Share-Based Compensation Expense', category: 'operating', order: 30, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ShareBasedCompensation', 'AllocatedShareBasedCompensationExpense'], allowedLabelPhrases: ['share based compensation', 'stock based compensation'] } }), cashFlow({ key: 'other_adjustments', label: 'Other Adjustments', category: 'operating', order: 40, unit: 'currency', selectionPolicy: 'aggregate_multiple_components', matchers: { exactLocalNames: [ 'OtherAdjustmentsToReconcileNetIncomeLossToCashProvidedByUsedInOperatingActivities', 'IncreaseDecreaseInDeferredIncomeTaxes', 'OtherNoncashIncomeExpense' ], allowedLabelPhrases: ['other adjustments'] }, signTransform: 'invert' }), cashFlow({ key: 'changes_trade_receivables', label: 'Changes in Trade Receivables', category: 'operating', order: 50, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInAccountsReceivable', 'IncreaseDecreaseInReceivables'], allowedLabelPhrases: ['changes in trade receivables', 'accounts receivable'] }, signTransform: 'invert' }), cashFlow({ key: 'changes_inventories', label: 'Changes in Inventories', category: 'operating', order: 60, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInInventories'], allowedLabelPhrases: ['changes in inventories', 'inventories'] }, signTransform: 'invert' }), cashFlow({ key: 'changes_accounts_payable', label: 'Changes in Accounts Payable', category: 'operating', order: 70, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInAccountsPayable'], allowedLabelPhrases: ['changes in accounts payable', 'accounts payable'] } }), cashFlow({ key: 'changes_accrued_expenses', label: 'Changes in Accrued Expenses', category: 'operating', order: 75, unit: 'currency', selectionPolicy: 'aggregate_multiple_components', matchers: { exactLocalNames: [ 'IncreaseDecreaseInAccruedLiabilities', 'IncreaseDecreaseInEmployeeRelatedLiabilitiesCurrent', 'IncreaseDecreaseInOtherLiabilitiesCurrent' ], allowedLabelPhrases: ['changes in accrued expenses', 'increase decrease in accrued liabilities'] } }), cashFlow({ key: 'changes_income_taxes_payable', label: 'Changes in Income Taxes Payable', category: 'operating', order: 80, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInAccruedIncomeTaxesPayable', 'IncreaseDecreaseInIncomeTaxes'], allowedLabelPhrases: ['changes in income taxes payable', 'income taxes'], excludeLocalNames: ['IncreaseDecreaseInIncomeTaxesReceivable'] } }), cashFlow({ key: 'changes_unearned_revenue', label: 'Changes in Unearned Revenue', category: 'operating', order: 90, unit: 'currency', selectionPolicy: 'direct_or_formula_fallback', matchers: { exactLocalNames: ['IncreaseDecreaseInDeferredRevenue'], allowedLabelPhrases: ['changes in unearned revenue', 'deferred revenue'] }, fallbackFormula: { kind: 'subtract', left: 'contract_liability_incurred', right: 'contract_liability_recognized' } }), cashFlow({ key: 'contract_liability_incurred', label: 'Unearned Revenue Incurred', includeInOutput: false, category: 'operating', order: 91, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ContractWithCustomerLiabilityIncurred'], allowedLabelPhrases: ['deferral of unearned revenue'] } }), cashFlow({ key: 'contract_liability_recognized', label: 'Unearned Revenue Recognized', includeInOutput: false, category: 'operating', order: 92, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ContractWithCustomerLiabilityRevenueRecognized'], allowedLabelPhrases: ['recognition of unearned revenue'] } }), cashFlow({ key: 'changes_other_operating_activities', label: 'Changes in Other Operating Activities', category: 'operating', order: 100, unit: 'currency', selectionPolicy: 'aggregate_multiple_components', matchers: { exactLocalNames: [ 'IncreaseDecreaseInOtherOperatingAssets', 'IncreaseDecreaseInOtherOperatingLiabilities', 'IncreaseDecreaseInDeferredIncomeTaxes', 'IncreaseDecreaseInPrepaidExpense' ], allowedLabelPhrases: ['changes in other operating activities'] }, fallbackFormula: { kind: 'sum', sourceKeys: [ 'changes_other_current_assets', 'changes_other_current_liabilities', 'changes_other_noncurrent_assets', 'changes_other_noncurrent_liabilities' ], treatNullAsZero: true }, signTransform: 'invert' }), cashFlow({ key: 'changes_other_current_assets', label: 'Other Current Assets', includeInOutput: false, category: 'operating', order: 101, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInOtherCurrentAssets'] } }), cashFlow({ key: 'changes_other_current_liabilities', label: 'Other Current Liabilities', includeInOutput: false, category: 'operating', order: 102, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInOtherCurrentLiabilities'] } }), cashFlow({ key: 'changes_other_noncurrent_assets', label: 'Other Long-Term Assets', includeInOutput: false, category: 'operating', order: 103, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInOtherNoncurrentAssets'] } }), cashFlow({ key: 'changes_other_noncurrent_liabilities', label: 'Other Long-Term Liabilities', includeInOutput: false, category: 'operating', order: 104, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['IncreaseDecreaseInOtherNoncurrentLiabilities'] } }), cashFlow({ key: 'operating_cash_flow', label: 'Cash from Operating Activities', category: 'operating', order: 110, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: [ 'NetCashProvidedByUsedInOperatingActivities', 'NetCashProvidedByUsedInOperatingActivitiesContinuingOperations' ], allowedLabelPhrases: ['cash from operating activities', 'net cash from operations'] } }), cashFlow({ key: 'capital_expenditures', label: 'Capital Expenditures', category: 'investing', order: 120, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['PaymentsToAcquirePropertyPlantAndEquipment'], secondaryLocalNames: ['CapitalExpendituresIncurredButNotYetPaid'], allowedLabelPhrases: ['capital expenditures', 'capital expenditure'] }, signTransform: 'invert' }), cashFlow({ key: 'acquisitions', label: 'Acquisitions', category: 'investing', order: 130, unit: 'currency', selectionPolicy: 'prefer_primary_statement_concept', matchers: { exactLocalNames: [ 'PaymentsToAcquireBusinessesNetOfCashAcquired', 'AcquisitionsNetOfCashAcquiredAndPurchasesOfIntangibleAndOtherAssets' ], allowedLabelPhrases: ['acquisitions'] }, signTransform: 'invert' }), cashFlow({ key: 'investments', label: 'Investments', category: 'investing', order: 140, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['PaymentsForProceedsFromOtherInvestingActivities'], allowedLabelPhrases: ['investments'] } }), cashFlow({ key: 'proceeds_from_sale_of_property_plant_and_equipment', label: 'Proceeds from Sale of Property, Plant & Equipment', category: 'investing', order: 145, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ProceedsFromSaleOfPropertyPlantAndEquipment'], allowedLabelPhrases: ['proceeds from sale of property plant equipment'] } }), cashFlow({ key: 'other_investing_activities', label: 'Other Investing Activities', category: 'investing', order: 150, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['OtherInvestingActivitiesNet', 'OtherCashFlowFromInvestingActivities'], allowedLabelPhrases: ['other investing activities'] }, signTransform: 'invert' }), cashFlow({ key: 'investing_cash_flow', label: 'Cash from Investing Activities', category: 'investing', order: 160, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['NetCashProvidedByUsedInInvestingActivities'], allowedLabelPhrases: ['cash from investing activities'] } }), cashFlow({ key: 'short_term_debt_issued', label: 'Short-Term Debt Issued', category: 'financing', order: 170, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ProceedsFromShortTermDebt'], allowedLabelPhrases: ['short term debt issued'] } }), cashFlow({ key: 'long_term_debt_issued', label: 'Long-Term Debt Issued', category: 'financing', order: 180, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ProceedsFromIssuanceOfLongTermDebt'], allowedLabelPhrases: ['long term debt issued'] } }), cashFlow({ key: 'debt_repaid', label: 'Debt Repaid', category: 'financing', order: 190, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['RepaymentsOfDebt', 'RepaymentsOfLongTermDebt'], allowedLabelPhrases: ['debt repaid'] }, signTransform: 'invert' }), cashFlow({ key: 'share_repurchases', label: 'Repurchases of Common Shares', category: 'financing', order: 200, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['PaymentsForRepurchaseOfCommonStock', 'PaymentsForRepurchaseOfEquity'], allowedLabelPhrases: ['repurchases of common shares', 'share repurchases'] }, signTransform: 'invert' }), cashFlow({ key: 'dividends_paid', label: 'Common Share Dividends Paid', category: 'financing', order: 210, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['DividendsCommonStockCash', 'PaymentsOfDividendsCommonStock', 'PaymentsOfDividends'], allowedLabelPhrases: ['common share dividends paid', 'dividends paid'] }, signTransform: 'invert' }), cashFlow({ key: 'other_financing_activities', label: 'Other Financing Activities', category: 'financing', order: 220, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['ProceedsFromPaymentsForOtherFinancingActivities'], allowedLabelPhrases: ['other financing activities'] } }), cashFlow({ key: 'financing_cash_flow', label: 'Cash from Financing Activities', category: 'financing', order: 230, unit: 'currency', selectionPolicy: 'prefer_exact_local_name', matchers: { exactLocalNames: ['NetCashProvidedByUsedInFinancingActivities'], allowedLabelPhrases: ['cash from financing activities'] } }), cashFlow({ key: 'free_cash_flow', label: 'Free Cash Flow', category: 'free_cash_flow', order: 240, unit: 'currency', selectionPolicy: 'formula_only', matchers: {}, fallbackFormula: { kind: 'sum', sourceKeys: ['operating_cash_flow', 'capital_expenditures'] } }) ] };