├── assets ├── css │ └── main.min.css ├── fonts │ ├── inter-v12-latin-500.woff2 │ ├── inter-v12-latin-600.woff2 │ ├── inter-v12-latin-800.woff2 │ └── inter-v12-latin-regular.woff2 ├── images │ ├── apple-touch-icon.png │ ├── banner-1280x640.png │ ├── banner-1544x500.png │ ├── banner-772x250.png │ ├── binary-calculator-001.png │ ├── binary-calculator-002.png │ ├── binary-calculator-003.png │ ├── binary-calculator-004.png │ ├── favicon.ico │ ├── icon-128.png │ ├── icon-128x128.png │ ├── icon-192.png │ ├── icon-196.png │ ├── icon-256.png │ ├── icon-256x256.png │ ├── icon-32.png │ ├── icon-96.png │ ├── icon-og.png │ ├── icon-rounded.png │ ├── icon-square.png │ ├── illustration-1.png │ ├── illustration-1.svg │ ├── illustration-and.png │ ├── illustration-and.svg │ ├── illustration-els.png │ ├── illustration-els.svg │ ├── illustration-og.png │ ├── screenshot-1.png │ └── screenshot-2.png └── js │ ├── all-calculators.js │ ├── app.js │ ├── calculator.js │ ├── chart.js │ ├── datepicker.js │ ├── dialog-table.js │ ├── dropdown-icon.js │ ├── fractions.js │ ├── functions.js │ ├── hourpicker.js │ ├── lib │ ├── air-datepicker.js │ ├── chartjs │ │ ├── chart.js │ │ ├── chart.js.map │ │ ├── chart.min.js │ │ ├── chart.umd.js │ │ ├── chart.umd.js.map │ │ ├── chunks │ │ │ ├── helpers.core.d.ts │ │ │ ├── helpers.segment.js │ │ │ └── helpers.segment.js.map │ │ ├── helpers.d.ts │ │ ├── helpers.js │ │ ├── helpers.js.map │ │ └── types.d.ts │ ├── input-mask.min.js │ ├── katex │ │ ├── auto-render.min.js │ │ ├── fonts │ │ │ ├── KaTeX_AMS-Regular.ttf │ │ │ ├── KaTeX_AMS-Regular.woff │ │ │ ├── KaTeX_AMS-Regular.woff2 │ │ │ ├── KaTeX_Caligraphic-Bold.ttf │ │ │ ├── KaTeX_Caligraphic-Bold.woff │ │ │ ├── KaTeX_Caligraphic-Bold.woff2 │ │ │ ├── KaTeX_Caligraphic-Regular.ttf │ │ │ ├── KaTeX_Caligraphic-Regular.woff │ │ │ ├── KaTeX_Caligraphic-Regular.woff2 │ │ │ ├── KaTeX_Fraktur-Bold.ttf │ │ │ ├── KaTeX_Fraktur-Bold.woff │ │ │ ├── KaTeX_Fraktur-Bold.woff2 │ │ │ ├── KaTeX_Fraktur-Regular.ttf │ │ │ ├── KaTeX_Fraktur-Regular.woff │ │ │ ├── KaTeX_Fraktur-Regular.woff2 │ │ │ ├── KaTeX_Main-Bold.ttf │ │ │ ├── KaTeX_Main-Bold.woff │ │ │ ├── KaTeX_Main-Bold.woff2 │ │ │ ├── KaTeX_Main-BoldItalic.ttf │ │ │ ├── KaTeX_Main-BoldItalic.woff │ │ │ ├── KaTeX_Main-BoldItalic.woff2 │ │ │ ├── KaTeX_Main-Italic.ttf │ │ │ ├── KaTeX_Main-Italic.woff │ │ │ ├── KaTeX_Main-Italic.woff2 │ │ │ ├── KaTeX_Main-Regular.ttf │ │ │ ├── KaTeX_Main-Regular.woff │ │ │ ├── KaTeX_Main-Regular.woff2 │ │ │ ├── KaTeX_Math-BoldItalic.ttf │ │ │ ├── KaTeX_Math-BoldItalic.woff │ │ │ ├── KaTeX_Math-BoldItalic.woff2 │ │ │ ├── KaTeX_Math-Italic.ttf │ │ │ ├── KaTeX_Math-Italic.woff │ │ │ ├── KaTeX_Math-Italic.woff2 │ │ │ ├── KaTeX_SansSerif-Bold.ttf │ │ │ ├── KaTeX_SansSerif-Bold.woff │ │ │ ├── KaTeX_SansSerif-Bold.woff2 │ │ │ ├── KaTeX_SansSerif-Italic.ttf │ │ │ ├── KaTeX_SansSerif-Italic.woff │ │ │ ├── KaTeX_SansSerif-Italic.woff2 │ │ │ ├── KaTeX_SansSerif-Regular.ttf │ │ │ ├── KaTeX_SansSerif-Regular.woff │ │ │ ├── KaTeX_SansSerif-Regular.woff2 │ │ │ ├── KaTeX_Script-Regular.ttf │ │ │ ├── KaTeX_Script-Regular.woff │ │ │ ├── KaTeX_Script-Regular.woff2 │ │ │ ├── KaTeX_Size1-Regular.ttf │ │ │ ├── KaTeX_Size1-Regular.woff │ │ │ ├── KaTeX_Size1-Regular.woff2 │ │ │ ├── KaTeX_Size2-Regular.ttf │ │ │ ├── KaTeX_Size2-Regular.woff │ │ │ ├── KaTeX_Size2-Regular.woff2 │ │ │ ├── KaTeX_Size3-Regular.ttf │ │ │ ├── KaTeX_Size3-Regular.woff │ │ │ ├── KaTeX_Size3-Regular.woff2 │ │ │ ├── KaTeX_Size4-Regular.ttf │ │ │ ├── KaTeX_Size4-Regular.woff │ │ │ ├── KaTeX_Size4-Regular.woff2 │ │ │ ├── KaTeX_Typewriter-Regular.ttf │ │ │ ├── KaTeX_Typewriter-Regular.woff │ │ │ └── KaTeX_Typewriter-Regular.woff2 │ │ ├── katex.min.css │ │ └── katex.min.js │ ├── lazysizes.min.js │ └── math.min.js │ ├── mask.js │ ├── module.js │ ├── options.js │ ├── themes.js │ └── timepicker.js ├── ci_binary_calculator.php ├── index.html ├── plugin.php ├── readme.md └── readme.txt /assets/fonts/inter-v12-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/fonts/inter-v12-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter-v12-latin-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/fonts/inter-v12-latin-600.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter-v12-latin-800.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/fonts/inter-v12-latin-800.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter-v12-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/fonts/inter-v12-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/images/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/apple-touch-icon.png -------------------------------------------------------------------------------- /assets/images/banner-1280x640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/banner-1280x640.png -------------------------------------------------------------------------------- /assets/images/banner-1544x500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/banner-1544x500.png -------------------------------------------------------------------------------- /assets/images/banner-772x250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/banner-772x250.png -------------------------------------------------------------------------------- /assets/images/binary-calculator-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/binary-calculator-001.png -------------------------------------------------------------------------------- /assets/images/binary-calculator-002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/binary-calculator-002.png -------------------------------------------------------------------------------- /assets/images/binary-calculator-003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/binary-calculator-003.png -------------------------------------------------------------------------------- /assets/images/binary-calculator-004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/binary-calculator-004.png -------------------------------------------------------------------------------- /assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/favicon.ico -------------------------------------------------------------------------------- /assets/images/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-128.png -------------------------------------------------------------------------------- /assets/images/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-128x128.png -------------------------------------------------------------------------------- /assets/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-192.png -------------------------------------------------------------------------------- /assets/images/icon-196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-196.png -------------------------------------------------------------------------------- /assets/images/icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-256.png -------------------------------------------------------------------------------- /assets/images/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-256x256.png -------------------------------------------------------------------------------- /assets/images/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-32.png -------------------------------------------------------------------------------- /assets/images/icon-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-96.png -------------------------------------------------------------------------------- /assets/images/icon-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-og.png -------------------------------------------------------------------------------- /assets/images/icon-rounded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-rounded.png -------------------------------------------------------------------------------- /assets/images/icon-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/icon-square.png -------------------------------------------------------------------------------- /assets/images/illustration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/illustration-1.png -------------------------------------------------------------------------------- /assets/images/illustration-and.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/illustration-and.png -------------------------------------------------------------------------------- /assets/images/illustration-els.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/illustration-els.png -------------------------------------------------------------------------------- /assets/images/illustration-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/illustration-og.png -------------------------------------------------------------------------------- /assets/images/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/screenshot-1.png -------------------------------------------------------------------------------- /assets/images/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pub-calculator-io/binary-calculator/05be5554972edd68ee93b41a7eca55a908a9baa8/assets/images/screenshot-2.png -------------------------------------------------------------------------------- /assets/js/all-calculators.js: -------------------------------------------------------------------------------- 1 | const JSON_CALCULATORS = [ { "title": "Age Calculator", "description": "An online age calculator calculates age and date of birth by adding and subtracting time, including years, days, hours, minutes, and seconds.", "uri": "/age-calculator/", "image": "../images/icon-96.png" }, { "title": "BMI Calculator", "description": "The free Body Mass Index calculator, also known as BMI, computes and classifies BMI for children and adults using data obtained from WHO and CDC.", "uri": "/bmi-calculator/", "image": "../images/icon-96.png" }, { "title": "Calorie Calculator", "description": "This calorie calculator computes how many calories are required daily to maintain, decrease, or gain weight. Learn about the different types of calories and how they affect you.", "uri": "/calorie-calculator/", "image": "../images/icon-96.png" }, { "title": "Time Calculator", "description": "This free time calculator allows you to add and subtract time values using days, hours, minutes, and seconds. Learn about the different concepts of time here as well.", "uri": "/time-calculator/", "image": "../images/icon-96.png" }, { "title": "Auto Loan Calculator", "description": "This free loan calculator computes the monthly payment and overall cost of an auto loan while taking into consideration sales tax, costs, trade-in value, and other factors.", "uri": "/auto-loan-calculator/", "image": "../images/icon-96.png" }, { "title": "Loan Calculator", "description": "Free loan calculator helps determine repayment plans, the interest cost, the amortization schedule of conventional amortized loans, deferred payment loans, and bonds.", "uri": "/loan-calculator/", "image": "../images/icon-96.png" }, { "title": "Dice Roller", "description": "This online dice roller uses random number generation to create a digital dice rolling experience with all sorts of beneficial uses.", "uri": "/dice-roller/", "image": "../images/icon-96.png" }, { "title": "Hours Calculator", "description": "This online hour calculator is ideal for determining hours worked so that employers can determine pay accurately.", "uri": "/hours-calculator/", "image": "../images/icon-96.png" }, { "title": "Grade Calculator", "description": "Our weighted grade calculator shows your average and what to earn for the final grade you want. A timesaver if you don't know how to calculate grades!", "uri": "/grade-calculator/", "image": "../images/icon-96.png" }, { "title": "Basic Calculator", "description": "This online calculator performs basic mathematical operations like addition, subtraction, division, and multiplication. You can use the calculator to find percentages and taxes.", "uri": "/basic-calculator/", "image": "../images/icon-96.png" }, { "title": "Fraction Calculator", "description": "Check out this free online fraction calculator. It can solve mathematical problems such as addition, subtraction, multiplication, and division of fractions.", "uri": "/fraction-calculator/", "image": "../images/icon-96.png" }, { "title": "BMR Calculator", "description": "Free BMR calculator uses well-known algorithms to calculate the basal metabolic rate. Also, find out more about the factors that influence BMR.", "uri": "/bmr-calculator/", "image": "../images/icon-96.png" }, { "title": "Percentage Calculator", "description": "This percentage calculator computes the percent of a number, the percentage change, and the quantity of a number whose percentage is provided.", "uri": "/percentage-calculator/", "image": "../images/icon-96.png" }, { "title": "Random Number Generator", "description": "Random number generators have a variety of uses beyond picking a number to determine a prize winner. Find out what situations are ideal for them and how they solve problems.", "uri": "/random-number-generator/", "image": "../images/icon-96.png" }, { "title": "Subnet Calculator", "description": "This IP subnet calculator makes subnetting easy, providing full subnet information like IP ranges, subnet masks and more from just basic network information.", "uri": "/subnet-calculator/", "image": "../images/icon-96.png" }, { "title": "Body Fat Percentage Calculator", "description": "This free body fat calculator uses the US Navy and BMI methods to approximate body fat percentage. It provides weight loss information to help you achieve your ideal body fat.", "uri": "/body-fat-percentage-calculator/", "image": "../images/icon-96.png" }, { "title": "Square Footage Calculator", "description": "Square footage calculator finds the surface area (square footage) of various shapes and calculates associated construction costs. It can be used as a room area calculator.", "uri": "/square-footage-calculator/", "image": "../images/icon-96.png" }, { "title": "Percentage Calculator Online", "description": "Percent calculator to calculate percentage of a number online. The calculator can find percentages and calculate discounts, taxes, and tips.", "uri": "/percentage-calculator-online/", "image": "../images/icon-96.png" }, { "title": "GPA Calculator", "description": "This GPA calculator computes your GPA and creates a report based on your course credits and grade. Both numerical and letter grades are accepted.", "uri": "/gpa-calculator/", "image": "../images/icon-96.png" }, { "title": "Standard Deviation Calculator", "description": "Given a discrete data set, the calculator calculates the mean, variance, and standard deviation of a sample or a population and shows all the intermediate steps of calculations.", "uri": "/standard-deviation-calculator/", "image": "../images/icon-96.png" }, { "title": "Mean, Median, Mode Calculator", "description": "Calculator for mean, median, and mode in statistics. Use this calculator to get the mean, median, mode, range, and the average for any data set.", "uri": "/mean-median-mode-calculator/", "image": "../images/icon-96.png" }, { "title": "Quadratic Formula Calculator", "description": "Quadratic formula calculator solves quadratic equations using the quadratic formula. Quadratic equations are solved for real roots and complex roots.", "uri": "/quadratic-formula-calculator/", "image": "../images/icon-96.png" }, { "title": "Numbers to Words Converter", "description": "Convert numbers to words with our calculator. It accepts decimals and scientific notation and can display any U.S. dollar amount in words.", "uri": "/numbers-to-words-converter/", "image": "../images/icon-96.png" }, { "title": "Number Generator", "description": "The random number generator provides a set of random numbers according to user-specified options such as range, repeat, and sort.", "uri": "/number-generator/", "image": "../images/icon-96.png" }, { "title": "Ideal Weight Calculator", "description": "Based on many famous equations, this free ideal weight calculator determines an optimal healthy body weight based on age, gender, and height.", "uri": "/ideal-weight-calculator/", "image": "../images/icon-96.png" }, { "title": "Height Calculator", "description": "Based on a linear regression study, this free growth calculator estimates a child's growth as an adult in the future. It can also be converted between several height units.", "uri": "/height-calculator/", "image": "../images/icon-96.png" }, { "title": "Salary Calculator", "description": "This free salary calculator easily switches between hourly, bi-weekly, monthly, and yearly pay. Holidays and vacation days need special consideration and adjustments.", "uri": "/salary-calculator/", "image": "../images/icon-96.png" }, { "title": "Rounding Calculator", "description": "This rounding calculator rounds off numbers to the nearest whole number, significant digit, or decimal place. You can round the decimal numbers to the nearest tenths, hundredths, or thousandths.", "uri": "/rounding-calculator/", "image": "../images/icon-96.png" }, { "title": "Time Duration Calculator", "description": "Use our time duration calculator to determine how much time has passed between two events. It is perfect for tracking work time for your business.", "uri": "/time-duration-calculator/", "image": "../images/icon-96.png" }, { "title": "Scientific Calculator", "description": "This scientific calculator is a free tool that solves complex mathematical expressions by supporting several built-in functions.", "uri": "/scientific-calculator/", "image": "../images/icon-96.png" }, { "title": "Amortization Calculator", "description": "This amortization calculator will show you how much your monthly payments will be and the breakdown of your payments. You can also see a graph and a pie chart of your loan’s amortization.", "uri": "/amortization-calculator/", "image": "../images/icon-96.png" }, { "title": "Pregnancy Calculator", "description": "Using the due date, last period date, ultrasound date, conception date, or IVF transfer date, this calculator generates an expected pregnancy timeline.", "uri": "/pregnancy-calculator/", "image": "../images/icon-96.png" }, { "title": "Bra Size Calculator", "description": "To get a bra that fits properly, it is vital to measure your bra size. This free calculator will tell you how to measure your breast size.", "uri": "/bra-size-calculator/", "image": "../images/icon-96.png" }, { "title": "TDEE Calculator", "description": "The TDEE calculator provides an accurate estimate of your daily caloric expenditure using your BMR and several other personal characteristics. ", "uri": "/tdee-calculator/", "image": "../images/icon-96.png" }, { "title": "Unit Converter", "description": "This free online tool converts common length, temperature, area, volume, weight, and time units.", "uri": "/unit-converter/", "image": "../images/icon-96.png" }, { "title": "Mixed Number Calculator", "description": "Mixed number calculator is designed to help you add, subtract, multiply, and divide mixed numbers. Mixed Fractions Calculator is created for performing mathematical operations on mixed numbers.", "uri": "/mixed-number-calculator/", "image": "../images/icon-96.png" }, { "title": "Decimal to Fraction Calculator", "description": "Decimal to Fraction Calculator converts decimals to fractions or mixed numbers. The Fraction converter works for terminating and for recurring decimals.", "uri": "/decimal-to-fraction-calculator/", "image": "../images/icon-96.png" }, { "title": "Simplifying Fractions Calculator", "description": "Simplifying fractions calculator to reduce fractions. Simplify proper and improper fractions and convert improper fractions to mixed numbers.", "uri": "/simplifying-fractions-calculator/", "image": "../images/icon-96.png" }, { "title": "Investment Calculator", "description": "This free investment calculator considers the initial and ending balances, return rate, and investment time when evaluating various investment circumstances.", "uri": "/investment-calculator/", "image": "../images/icon-96.png" }, { "title": "Simple Interest Calculator", "description": "The simple interest calculator can be used to provide a quick and accurate calculation of interest assessed on a loan or investment.", "uri": "/simple-interest-calculator/", "image": "../images/icon-96.png" }, { "title": "Standard Deviation", "description": "Given a discrete data set, the calculator calculates the mean, variance, and standard deviation of a sample or a population and shows all the intermediate steps of calculations.", "uri": "/standard-deviation/", "image": "../images/icon-96.png" }, { "title": "Compound Interest Calculator", "description": "Compound interest calculator that uses the interest formula (A = P(1 + r/n)ⁿᵗ) to help users understand the impacts of compound interest and money growth over time.", "uri": "/compound-interest-calculator/", "image": "../images/icon-96.png" }, { "title": "Slope Calculator", "description": "The slope calculator finds the slope of a line using the slope formula. It can also find point coordinates, incline angle, and length if the slope and one point are known.", "uri": "/slope-calculator/", "image": "../images/icon-96.png" }, { "title": "Variance Calculator", "description": "Given a discrete data set representing a sample or a population, the calculator calculates the mean, variance, and standard deviation and displays the workflow involved in the calculation.", "uri": "/variance-calculator/", "image": "../images/icon-96.png" }, { "title": "LCM Calculator", "description": "LCM calculator to find the LCM of two or more numbers. Shows solutions by prime factorization, common multiples, cake/ladder, GCF, division, and Venn diagram.", "uri": "/lcm-calculator/", "image": "../images/icon-96.png" }, { "title": "Ratio Calculator", "description": "The ratio calculator simplifies ratios by bringing ratios to the lowest terms. Finds missing values in proportions and compares two given ratios finding if they are equal.", "uri": "/ratio-calculator/", "image": "../images/icon-96.png" }, { "title": "Percentage Increase Calculator", "description": "Percentage increase calculator to find an increase from one number to another, calculate growth rate and calculate price increase in percentages.", "uri": "/percentage-increase-calculator/", "image": "../images/icon-96.png" }, { "title": "Long Division Calculator", "description": "Long division calculator performs long division with remainders. Demonstrates solution with steps, and answer as quotient and remainder and as mixed number.", "uri": "/long-division-calculator/", "image": "../images/icon-96.png" }, { "title": "Triangle Calculator", "description": "The triangle calculator finds all triangle measurements – side lengths, triangle angles, area, perimeter, semiperimeter, heights, medians, inradius, and circumradius.", "uri": "/triangle-calculator/", "image": "../images/icon-96.png" }, { "title": "BAC Calculator", "description": "The Blood Alcohol Concentration Calculator provides an accurate estimate of your current blood alcohol concentration based on several key inputs and personal characteristics. ", "uri": "/bac-calculator/", "image": "../images/icon-96.png" }, { "title": "Combinations Calculator", "description": "Combinations Calculator calculates the number of ways of selecting r outcomes from n possibilities when the order of the items chosen in the subset does not matter.", "uri": "/combinations-calculator/", "image": "../images/icon-96.png" }, { "title": "Percentage Change Calculator", "description": "Percentage change calculator to find percentage increase or decrease, calculate the rate of change and calculate price change over a period of time.", "uri": "/percentage-change-calculator/", "image": "../images/icon-96.png" }, { "title": "Volume Calculator", "description": "The online volume calculator performs calculations for 11 different geometric shapes. The tool supports different units of measurement and demonstrates the solution steps.", "uri": "/volume-calculator/", "image": "../images/icon-96.png" }, { "title": "Scientific Notation Converter", "description": "Scientific notation calculator converts numbers to scientific notation, standard form, engineering notation, scientific e-notation, and word form and finds the order of magnitude.", "uri": "/scientific-notation-converter/", "image": "../images/icon-96.png" }, { "title": "Date Calculator", "description": "Free calculator to effortlessly evaluate the difference between dates. Easily add or subtract days from any date, with or without holidays and weekends.", "uri": "/date-calculator/", "image": "../images/icon-96.png" }, { "title": "Speed Calculator", "description": "The speed calculator helps find speed, distance, time using the formulas d=st, s=d/t, t=d/s. Easy to use and intuitive speed calculator.", "uri": "/speed-calculator/", "image": "../images/icon-96.png" }, { "title": "GCF Calculator", "description": "Greatest common factor calculator finds the GCF of a set of numbers and all factors of these numbers. Solutions with steps for finding the GCF are also demonstrated.", "uri": "/gcf-calculator/", "image": "../images/icon-96.png" }, { "title": "Financial Calculator", "description": "You can use free financial calculators online to estimate your investments’ future value (FV), compounding periods (N), interest rate (I/Y), periodic payment (PMT), and present value (PV).", "uri": "/financial-calculator/", "image": "../images/icon-96.png" }, { "title": "Payment Calculator", "description": "Define the monthly payment amount or time period to pay off a loan with a set term or fixed payment with our free payment calculator.", "uri": "/payment-calculator/", "image": "../images/icon-96.png" }, { "title": "Fraction to Decimal Calculator", "description": "The fraction to decimal calculator allows the user to convert fractions to decimal points while specifying the rounding options.", "uri": "/fraction-to-decimal-calculator/", "image": "../images/icon-96.png" }, { "title": "Conception Date Calculator", "description": "This conception calculator calculates your conception date based on the date of your last period, your ultrasound date, or your due date.", "uri": "/conception-date-calculator/", "image": "../images/icon-96.png" }, { "title": "Binary Calculator", "description": "Binary calculator for binary to decimal conversion, decimal to binary conversion, binary operations – addition, subtraction, multiplication, division.", "uri": "/binary-calculator/", "image": "../images/icon-96.png" }, { "title": "Macro Calculator", "description": "This macronutrient calculator computes macronutrient requirements relative to age, physical attributes, exercise level, and body weight objectives.", "uri": "/macro-calculator/", "image": "../images/icon-96.png" }, { "title": "Sales Tax Calculator", "description": "You can use our free sales tax calculator to determine the total cost of a product, including all fees and taxes. Also, be sure to check out the sales tax rates in various U.S. states.", "uri": "/sales-tax-calculator/", "image": "../images/icon-96.png" }, { "title": "Hours and Minutes Calculator", "description": "This online hours calculator is an easy way to count hours and minutes at the touch of a button.", "uri": "/hours-and-minutes-calculator/", "image": "../images/icon-96.png" }, { "title": "Area Calculator", "description": "Area calculator to find the surface area of the following shapes - rectangle, triangle, circle, sector, ellipse, trapezoid, and parallelogram.", "uri": "/area-calculator/", "image": "../images/icon-96.png" }, { "title": "Interest Calculator", "description": "With this free interest calculator you can compute accumulation schedules, final balances, and accrued interest.", "uri": "/interest-calculator/", "image": "../images/icon-96.png" }, { "title": "Average Calculator", "description": "The average calculator helps find a data set's average or arithmetic mean. It also shows the calculation steps and other important statistics.", "uri": "/average-calculator/", "image": "../images/icon-96.png" }, { "title": "Concrete Calculator", "description": "Estimate the right amount of concrete for home improvement projects. Concrete calculators do the math to figure out how many bags of mix to buy for driveway slabs, deck footings, stairs, and DIY projects.", "uri": "/concrete-calculator/", "image": "../images/icon-96.png" }, { "title": "Roman Numeral Converter", "description": "Roman numeral converter produces Roman numerals from Arabic numbers or converts Arabic numbers to Roman numerals, with values between 1 and 3,999,999.", "uri": "/roman-numeral-converter/", "image": "../images/icon-96.png" }, { "title": "Gas Cost Calculator", "description": "This free gasoline cost calculator evaluates the fuel cost of a journey using several units of measurement depending on fuel efficiency, distance, and gas price.", "uri": "/gas-cost-calculator/", "image": "../images/icon-96.png" }, { "title": "Factoring Calculator", "description": "The factoring calculator finds all factors and factor pairs of positive and negative numbers. Factor calculator finds divisors of non-zero integers.", "uri": "/factoring-calculator/", "image": "../images/icon-96.png" }, { "title": "Sig Fig Calculator", "description": "Significant figures are essential in various situations. Here, we determine the rules of sig figs and how we can apply them in the real world.", "uri": "/sig-fig-calculator/", "image": "../images/icon-96.png" }, { "title": "Mean, Median, Mode, Range Calculator", "description": "The Mean, Median, Mode, and Range calculator helps you find these statistics quickly and conveniently. Learn how to use this calculator's output by reading this article.", "uri": "/mean-median-mode-range-calculator/", "image": "../images/icon-96.png" }, { "title": "Z-Score Calculator", "description": "The Z-Score Calculator helps to get the z-score of a normal distribution, convert between z-score and probability, and get the probability between 2 z-scores.", "uri": "/z-score-calculator/", "image": "../images/icon-96.png" }, { "title": "Permutation Calculator", "description": "Permutations calculator will help determine the number of ways to obtain an ordered subset of r elements from a set of n elements.", "uri": "/permutation-calculator/", "image": "../images/icon-96.png" }, { "title": "Percentage Difference Calculator", "description": "Percentage difference calculator to find percent difference between two numbers. The calculator is used to compare two positive values.", "uri": "/percentage-difference-calculator/", "image": "../images/icon-96.png" }, { "title": "Body Type Calculator", "description": "Discover your body shape with our easy and accurate body type calculator. Learn how to flatter your unique proportions with our helpful guide.", "uri": "/body-type-calculator/", "image": "../images/icon-96.png" }, { "title": "Probability Calculator", "description": "The probability calculator can find two events' probability and the normal distribution probability. Learn more about probability's laws and calculations.", "uri": "/probability-calculator/", "image": "../images/icon-96.png" }, { "title": "Quartile Calculator", "description": "The quartile calculator helps to find the first(Q1), second(Q2), and third(Q3) quartiles, interquartile range, minimum and maximum values, and range of a data set.", "uri": "/quartile-calculator/", "image": "../images/icon-96.png" }, { "title": "Right Triangle Calculator", "description": "Right triangle calculator finds missing triangle measurements. It calculates side lengths, angles, perimeter, area, altitude-to-hypotenuse, inradius, and circumradius.", "uri": "/right-triangle-calculator/", "image": "../images/icon-96.png" }, { "title": "Tip Calculator", "description": "Free tip calculator that helps people know how much to tip when receiving services from various businesses and workers. This tool also calculates how to split a bill and tip between a group of people.", "uri": "/tip-calculator/", "image": "../images/icon-96.png" }, { "title": "Interest Rate Calculator", "description": "Free online calculator to estimate the interest rate and total interest cost of an amortized loan with a fixed monthly repayment amount.", "uri": "/interest-rate-calculator/", "image": "../images/icon-96.png" }, { "title": "Calories Burned Calculator", "description": "Track your calorie burn with our free calorie calculator. Quickly estimate your calories burned based on activity and duration.", "uri": "/calories-burned-calculator/", "image": "../images/icon-96.png" }, { "title": "Mixed Fraction Calculator", "description": "Mixed number to improper fraction calculator to convert mixed numbers, consisting of a whole number and a proper fraction, to improper fractions.", "uri": "/mixed-fraction-calculator/", "image": "../images/icon-96.png" }, { "title": "Height Converter", "description": "With the height converter tool, you can easily convert height to cm. Convert between US units and metric units.", "uri": "/height-converter/", "image": "../images/icon-96.png" }, { "title": "Work Hours Calculator", "description": "Work hours calculator helps employees accurately calculate the number of hours worked each week with settings to account for breaks, hourly rounding, and military time.", "uri": "/work-hours-calculator/", "image": "../images/icon-96.png" }, { "title": "Sample Size Calculator", "description": "This sample size calculator enables you to calculate the minimum sample size and the margin of error. Learn about sample size, the margin of error, & confidence interval.", "uri": "/sample-size-calculator/", "image": "../images/icon-96.png" }, { "title": "Fraction to Percent Calculator", "description": "Fraction to percent calculator converts proper and improper fractions to percentages. Calculator is using fraction-decimal-percent algorithm.", "uri": "/fraction-to-percent-calculator/", "image": "../images/icon-96.png" }, { "title": "Least Common Denominator Calculator", "description": "Least common denominator calculator, or LCD calculator, determines the lowest common denominator of integers, mixed numbers, and fractions.", "uri": "/lcd-calculator/", "image": "../images/icon-96.png" }, { "title": "Protein Calculator", "description": "Relying on certain statistics and recommendations, this free protein calculator predicts how much protein a person needs each day to be healthy.", "uri": "/protein-calculator/", "image": "../images/icon-96.png" }, { "title": "Modulo Calculator", "description": "The modulo calculator finds the remainder of the division of two rational/irrational positive/negative numbers. You can also find out how to find modulus manually.", "uri": "/modulo-calculator/", "image": "../images/icon-96.png" }, { "title": "Density Calculator", "description": "This volume calculator uses a density formula ρ = m/V to find densities of different substances and objects. It calculates the third one for two given values - density, mass, or volume of a substance.", "uri": "/density-calculator/", "image": "../images/icon-96.png" }, { "title": "Mean Calculator", "description": "The mean calculator or the average calculator helps you to get the average value of a data set. It divides the data values sum by the data values count to get the average (mean).", "uri": "/mean-calculator/", "image": "../images/icon-96.png" }, { "title": "Circle Calculator", "description": "Circle calculator finds missing characteristics of a circle. It includes a radius calculator, circumference calculator, diameter calculator, and circle area calculator.", "uri": "/circle-calculator/", "image": "../images/icon-96.png" }, { "title": "Mortgage Calculator", "description": "Calculate your monthly payment, total property ownership costs, and amortization timeline with options for taxes, PMI, HOA, and early payments with our free mortgage calculator.", "uri": "/mortgage-calculator/", "image": "../images/icon-96.png" }, { "title": "Personal Loan Calculator", "description": "After factoring the fees, insurance, and interest of a personal loan, this free personal loan calculator computes the monthly payment, true loan cost, and Annual percentage rate (APR).", "uri": "/personal-loan-calculator/", "image": "../images/icon-96.png" }, { "title": "Equivalent Fractions Calculator", "description": "Equivalent fractions calculator to find equivalent fractions of positive and negative mixed numbers, integers, proper and improper fractions.", "uri": "/equivalent-fractions-calculator/", "image": "../images/icon-96.png" }, { "title": "Scientific Notation Calculator", "description": "Scientific notation calculator converts numbers to scientific notation, e-notation, engineering notation, and adds, subtracts, multiplies or divides them.", "uri": "/scientific-notation-calculator/", "image": "../images/icon-96.png" }, { "title": "Future Value Calculator", "description": "Free future value calculator that uses the formula FV = PV (1 + I/Y)ⁿ to find the future value of an investment with periodic deposits.", "uri": "/future-value-calculator/", "image": "../images/icon-96.png" }, { "title": "Adding Fractions Calculator", "description": "Adding fractions calculator to add and subtract proper and improper fractions. The calculator performs operations with up to nine given fractions.", "uri": "/adding-fractions-calculator/", "image": "../images/icon-96.png" }, { "title": "Decimal to Percent Calculator", "description": "Decimal to percent calculator converts decimals to percentages and whole numbers to percentages by multiplying by 100% or shifting the decimal point.", "uri": "/decimal-to-percent-calculator/", "image": "../images/icon-96.png" }, { "title": "Period Calculator", "description": "With our free period calculator, you can find out more about your menstrual cycle and accurately predict when your next period will be.", "uri": "/period-calculator/", "image": "../images/icon-96.png" }, { "title": "Meters to Feet Converter", "description": "Convert meters to feet & inches using a meters to feet calculator. Choose decimal places or fractions of an inch for rounding and calculation.", "uri": "/meters-to-feet-converter/", "image": "../images/icon-96.png" }, { "title": "Mortgage Payment Calculator", "description": "Free mortgage payment calculator helps assess possibilities for paying off a mortgage sooner, such as additional payments, bi-weekly payments, or paying off the loan entirely.", "uri": "/mortgage-payment-calculator/", "image": "../images/icon-96.png" }, { "title": "Hex Calculator", "description": "Online hex calculator performs hex math operations and conversions. Hex addition, hex subtraction, hex multiplication, hex division became fast & easy", "uri": "/hex-calculator/", "image": "../images/icon-96.png" }, { "title": "Tank Volume Calculator", "description": "The tank volume calculator finds the total volume of various tank shapes in gallons, liters, and cubic meters. It calculates the liquid volume of partially filled tanks.", "uri": "/tank-volume-calculator/", "image": "../images/icon-96.png" }, { "title": "Standard Form Calculator", "description": "Standard form calculator converts any number to standard form or scientific notation. It accepts number notation, e-notation, and scientific notation.", "uri": "/standard-form-calculator/", "image": "../images/icon-96.png" }, { "title": "Math Equation Solver", "description": "PEMDAS calculator solves mathematical expressions with the order of operations - brackets, exponents, multiplication, division, addition, and subtraction.", "uri": "/math-equation-solver/", "image": "../images/icon-96.png" }, { "title": "APR Calculator", "description": "APR calculator that uses the formula APR = ((I + F) / P) / N can help borrowers understand the true cost of loans and how to calculate APR on a loan.", "uri": "/apr-calculator/", "image": "../images/icon-96.png" }, { "title": "Kinetic Energy Calculator", "description": "Kinetic energy calculator easily finds kinetic energy, mass or velocity with the kinetic energy formula KE = 1/2 mv². Easy to use KE calculator.", "uri": "/kinetic-energy-calculator/", "image": "../images/icon-96.png" }, { "title": "Cube Root Calculator", "description": "Cube root calculator finds the principal (real) cube root of positive and negative numbers and the imaginary cube roots of the given number.", "uri": "/cube-root-calculator/", "image": "../images/icon-96.png" }, { "title": "Return on Investment (ROI) Calculator", "description": "Free return on investment (ROI) calculator that helps investors calculate return on investment, investment gain, and annualized ROI rates. ", "uri": "/roi-calculator/", "image": "../images/icon-96.png" }, { "title": "Cubic Yards Calculator", "description": "Cubic yard calculator calculates cubic yards, feet, meters for landscape materials. Enter measurements in yards and feet and get volume conversions.", "uri": "/cubic-yards-calculator/", "image": "../images/icon-96.png" }, { "title": "Arithmetic and Geometric Sequence Calculator", "description": "Number sequence calculator to find the nth term of arithmetic, geometric, and Fibonacci sequences. The calculator also finds the sum of the terms of a sequence.", "uri": "/arithmetic-geometric-sequence-calculator/", "image": "../images/icon-96.png" }, { "title": "Square Root Calculator", "description": "Square root calculator finds square roots of positive and negative numbers, identifies the principal root, and determines if the number is a perfect square.", "uri": "/square-root-calculator/", "image": "../images/icon-96.png" }, { "title": "Distance Formula Calculator", "description": "Distance formula calculator finds the distance between two points on a plane based on their coordinates. The calculator uses the Euclidean distance formula. ", "uri": "/distance-formula-calculator/", "image": "../images/icon-96.png" }, { "title": "Prime Factorization Calculator", "description": "The prime factorization calculator finds a number's prime factors. The calculator demonstrates the prime factors tree and all factors of the number. ", "uri": "/prime-factorization-calculator/", "image": "../images/icon-96.png" }, { "title": "Business Loan Calculator", "description": "Free business loan calculator that lets entrepreneurs estimate monthly payments, calculate interest on loans, and understand the total cost of the business loan.", "uri": "/business-loan-calculator/", "image": "../images/icon-96.png" }, { "title": "Odds Calculator", "description": "The odds probability calculator can convert the odds of winning and losing to the probability of winning and losing. Learn the differences between odds and probability.", "uri": "/odds-calculator/", "image": "../images/icon-96.png" }, { "title": "Margin Calculator", "description": "Free margin calculator using the margin formula ((R - C) / R) × 100 to help businesses quickly calculate both margin and markup percentages based on cost and sale price.", "uri": "/margin-calculator/", "image": "../images/icon-96.png" }, { "title": "Pace Calculator", "description": "This free pace calculator computes pace, distance and time by setting values of two variables. You can use it for training purposes.", "uri": "/pace-calculator/", "image": "../images/icon-96.png" }, { "title": "Ovulation Calculator", "description": "Not sure when you’re ovulating? Use this free ovulation calculator to estimate your most fertile days and know when you are most likely to conceive.", "uri": "/ovulation-calculator/", "image": "../images/icon-96.png" }, { "title": "Integer Calculator", "description": "Adding and subtracting integers calculator allows adding and subtracting positive and negative integers and decimals, demonstrating the solution algorithm.", "uri": "/integer-calculator/", "image": "../images/icon-96.png" }, { "title": "Army Body Fat Calculator", "description": "The Army Body Fat Calculator provides users with an accurate estimate of their body fat percentage using the standards of the U.S. Army.", "uri": "/army-body-fat-calculator/", "image": "../images/icon-96.png" }, { "title": "401K Calculator", "description": "Free 401k retirement calculator that uses the 401k Growth Formula can help users plan for retirement and calculate 401k growth. ", "uri": "/401k-calculator/", "image": "../images/icon-96.png" }, { "title": "Car Loan Calculator", "description": "Free car loan calculator uses the formula PMT = (R × A) / (1 - (1+R)⁻ⁿ) to help buyers calculate a car payment, analyze interest rates, and understand the total cost of an auto loan.", "uri": "/car-loan-calculator/", "image": "../images/icon-96.png" }, { "title": "Roman Numeral Date Converter", "description": "The Roman Numerals Date Converter can convert dates from Arabic numerals to Roman numerals and back. Get any date in Roman or Arabic numerals.", "uri": "/roman-numeral-date-converter/", "image": "../images/icon-96.png" }, { "title": "Rental Property Calculator", "description": "Free rental property calculator that uses the formula NPV = [CF¹ / (1 + R¹)] - PC. A rental ROI calculator that helps analyze and compare investment rental properties.", "uri": "/rental-property-calculator/", "image": "../images/icon-96.png" }, { "title": "Time to Decimal Calculator", "description": "Time to decimal calculator can convert the time format from hh:mm:ss to decimal hours, minutes, and seconds. Learn to convert hours to decimal form.", "uri": "/time-to-decimal-calculator/", "image": "../images/icon-96.png" }, { "title": "Significant Figures Calculator", "description": "The significant figure rounder rounds numbers to the required quantity of significant figures. It works with a standard number format, e-notation, and scientific notation.", "uri": "/significant-figures-calculator/", "image": "../images/icon-96.png" }, { "title": "Pregnancy Weight Gain Calculator", "description": "This pregnancy weight gain calculator gives a recommended weight increase plan every week based on the user’s body weight before pregnancy and the parameters provided by the IOM (the Institute of Medicine).", "uri": "/pregnancy-weight-gain-calculator/", "image": "../images/icon-96.png" }, { "title": "Feet and Inches Calculator", "description": "A feet and inches calculator helps with math problems. Add feet and inches, subtract, multiply, or divide them with ease.", "uri": "/feet-and-inches-calculator/", "image": "../images/icon-96.png" }, { "title": "Velocity Calculator", "description": "Free online velocity calculator solves for v, u, a or t using velocity formula. Calculate the final velocity (v) using the equation v = u + at.", "uri": "/velocity-calculator/", "image": "../images/icon-96.png" }, { "title": "Force Calculator", "description": "Easy to use force calculator helps determine the unknown variable in the force equation (F = ma). Force = mass × acceleration.", "uri": "/force-calculator/", "image": "../images/icon-96.png" }, { "title": "Percentile Calculator", "description": "The percentile calculator helps to find percentile values for a data set. Use this percentile calculator to create a table listing each 5th percentile", "uri": "/percentile-calculator/", "image": "../images/icon-96.png" }, { "title": "Distance Calculator", "description": "These calculators find the distance between two points on a 2D plane, in a 3D space, as well as along the surface of the Earth with Lambert’s formulas.", "uri": "/distance-calculator/", "image": "../images/icon-96.png" }, { "title": "Days Calculator", "description": "The free days calculator makes it easy to figure out how many days between two dates. This day tracker can include or exclude weekends and holidays.", "uri": "/days-calculator/", "image": "../images/icon-96.png" }, { "title": "Percent to Fraction Calculator", "description": "The percent to fraction calculator converts the given percentages into fractions. If the percent value exceeds 100, the calculator performs percent to mixed number conversion.", "uri": "/percent-to-fraction-calculator/", "image": "../images/icon-96.png" }, { "title": "Pythagorean Theorem Calculator", "description": "Pythagorean theorem calculator finds the unknown side length of a right triangle. It also calculates angles, area, perimeter, and altitude to hypotenuse.", "uri": "/pythagorean-theorem-calculator/", "image": "../images/icon-96.png" }, { "title": "Retirement Calculator", "description": "Retirement savings calculator that uses the formula FV = PV (1 + R)ⁿ to help users plan for retirement and calculate retirement income.", "uri": "/retirement-calculator/", "image": "../images/icon-96.png" }, { "title": "Percentage Decrease Calculator", "description": "The percentage decrease calculator finds a percentage decrease from the starting value to the final value and identifies whether the change is an increase or a decrease.", "uri": "/percentage-decrease-calculator/", "image": "../images/icon-96.png" }, { "title": "Present Value Calculator", "description": "Unlock the true value of your investments with our easy-to-use present value calculator. Make smarter financial decisions now!", "uri": "/present-value-calculator/", "image": "../images/icon-96.png" }, { "title": "Cylinder Volume Calculator", "description": "This calculator can be used as a cylinder volume calculator and surface area calculator. It also finds the lateral, base, and top surface areas.", "uri": "/cylinder-volume-calculator/", "image": "../images/icon-96.png" }, { "title": "Proportion Calculator ", "description": "The ratio calculator finds a missing ratio number based on the given proportion. The calculator can also scale ratios, enlarging or shrinking them.", "uri": "/proportion-calculator/", "image": "../images/icon-96.png" }, { "title": "Quadratic Equation Calculator", "description": "Quadratic Equation Calculator is a free tool that provides a detailed solution to quadratic equations by supplying the values of a, b and c.", "uri": "/quadratic-equation-calculator/", "image": "../images/icon-96.png" }, { "title": "Refinance Calculator", "description": "This free and comprehensive refinance calculator can help you calculate monthly payments, amortization, total purchase price, and more.", "uri": "/refinance-calculator/", "image": "../images/icon-96.png" }, { "title": "Roofing Calculator", "description": "Use a free roofing square footage calculator to determine your roof size and get the right amount of roofing shingles for your job. Estimate cost, time, and labor for DIY or contractors.", "uri": "/roofing-calculator/", "image": "../images/icon-96.png" }, { "title": "FHA Loan Calculator", "description": "The FHA loan calculator lets you plug in the numbers and calculate the monthly payments, interest, and total amount paid over time.", "uri": "/fha-loan-calculator/", "image": "../images/icon-96.png" }, { "title": "Annuity Calculator", "description": "Annuity calculator that uses the formula FV = PV (1 + R)ⁿ to help investors calculate annuity growth over time and make retirement decisions.", "uri": "/annuity-calculator/", "image": "../images/icon-96.png" }, { "title": "Simple Investment Calculator", "description": "Free investment calculator that uses the formula PV (1 + R)ⁿ to help investors understand how to calculate investment returns and analyze investments.", "uri": "/simple-investment-calculator/", "image": "../images/icon-96.png" }, { "title": "Credit Card Payoff Calculator", "description": "Free online credit card calculator that provides valuable information to users, including how to minimize debt and a credit payment calculator with recommended payment amounts.", "uri": "/credit-card-payoff-calculator/", "image": "../images/icon-96.png" }, { "title": "Due Date Calculator", "description": "This online due date calculator helps moms-to-be calculate their due date based on their last menstrual period or the date of conception.", "uri": "/due-date-calculator/", "image": "../images/icon-96.png" }, { "title": "Home Loan Calculator", "description": "This easy home loan calculator will help you calculate monthly mortgage payments. The mortgage calculator is perfect for both fixed-rate or adjustable-rate home loans.", "uri": "/home-loan-calculator/", "image": "../images/icon-96.png" }, { "title": "EMI Calculator", "description": "Manage loans effectively with an EMI calculator. Calculate EMIs, total interest, and assess affordability. Make informed decisions and save money.", "uri": "/emi-calculator/", "image": "../images/icon-96.png" }, { "title": "SIP Сalculator", "description": "Calculate SIP returns, growth & wealth accumulation with confidence using our SIP calculator. Make informed investment decisions.", "uri": "/sip-calculator/", "image": "../images/icon-96.png" } ]; -------------------------------------------------------------------------------- /assets/js/app.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | window._ = document.getElementById.bind(document); 4 | window.$ = document.querySelector.bind(document); 5 | window.$$ = document.querySelectorAll.bind(document); 6 | 7 | console.log('Script is OK! ༼ つ ◕_◕ ༽つ') 8 | // IS MAIN PAGE 9 | // if(window.location.pathname === '/') document.body.classList.add('isMainPage') 10 | 11 | // DIALOG TABLE 12 | if(document.querySelector('.result-table__dialog')) { 13 | import('./dialog-table.js').then(e => { 14 | console.log("Dialog table loaded (づ ◕‿◕ )づ") 15 | }).catch(e => { 16 | console.log("Sorry, dialog tables not loaded (ಥ﹏ಥ)", e) 17 | }) 18 | } 19 | // MASK 20 | if(document.querySelector('[data-inputmask]')) { 21 | import('./mask.js').then(e => { 22 | console.log("Mask loaded (づ ◕‿◕ )づ") 23 | }).catch(e => { 24 | console.log("Sorry, masks not loaded (ಥ﹏ಥ)", e) 25 | }) 26 | } 27 | // DATEPICKER 28 | if(document.querySelector('.datepicker')) { 29 | import('./datepicker.js').then(e => { 30 | console.log("Datepicker loaded (づ ◕‿◕ )づ") 31 | }).catch(e => { 32 | console.log("Sorry, datepicker not loaded (ಥ﹏ಥ)", e) 33 | }) 34 | } 35 | // TIMEPICKER 36 | if(document.querySelector('.timepicker-input')) { 37 | import('./timepicker.js').then(e => { 38 | console.log("Timepicker loaded (づ ◕‿◕ )づ") 39 | }).catch(e => { 40 | console.log("Sorry, timepicker not loaded (ಥ﹏ಥ)", e) 41 | }) 42 | } 43 | // HOURPICKER 44 | if(document.querySelector('.hourpicker-input')) { 45 | import('./hourpicker.js').then(e => { 46 | console.log("Hourpicker loaded (づ ◕‿◕ )づ") 47 | }).catch(e => { 48 | console.log("Sorry, Hourpicker not loaded (ಥ﹏ಥ)", e) 49 | }) 50 | } 51 | // OPTIONS 52 | if(document.querySelector('.calculator-content--options')) { 53 | import('./options.js').then(e => { 54 | console.log("Options loaded (づ ◕‿◕ )づ") 55 | }).catch(e => { 56 | console.log("Sorry, options not loaded (ಥ﹏ಥ)", e) 57 | }) 58 | } 59 | // ICON DROPDOWN 60 | if(document.querySelector('.dropdown-icon')) { 61 | import('./dropdown-icon.js').then(e => { 62 | console.log("Dropdown-icon loaded (づ ◕‿◕ )づ") 63 | }).catch(e => { 64 | console.log("Sorry, dropdown-icon not loaded (ಥ﹏ಥ)", e) 65 | }) 66 | } 67 | 68 | // MODAL 69 | const MODAL_OPENERS = document.querySelectorAll('.js-modal-open') 70 | const MODAL_CLOSERS = document.querySelectorAll('.js-modal-close') 71 | const MODAL_WINDOW = document.querySelector('.modal-window') 72 | 73 | let currentShare = 0 74 | let isOpenPopupHeader = false; 75 | let focusedElement = 0; 76 | 77 | const closeAll = () => { 78 | MODAL_SEARCH.value = '' 79 | MODAL_SEARCH_LIST.classList.remove('modal-search__list--error') 80 | MODAL_SEARCH_LIST.classList.remove('modal-search__list--active') 81 | MODAL_OPENERS.forEach(MODAL_OPENER => { 82 | const MODAL_ID = MODAL_OPENER.getAttribute('data-modal') 83 | const MODAL = document.querySelector(`.modal-${MODAL_ID}`) 84 | MODAL.classList.remove(`modal-${MODAL_ID}--active`) 85 | }) 86 | } 87 | 88 | window.addEventListener('click', (e) => { 89 | let controllerTheme = document.querySelector('#popup-theme') 90 | let controllerLang = document.querySelector('#popup-lang') 91 | if(isOpenPopupHeader && !(e.composedPath().includes(controllerLang) || e.composedPath().includes(controllerTheme))) { 92 | isOpenPopupHeader = false 93 | document.querySelector('.modal-lang--active')?.classList.remove(`modal-lang--active`) 94 | document.querySelector('.modal-theme--active')?.classList.remove(`modal-theme--active`) 95 | } 96 | }) 97 | 98 | window.addEventListener('keydown', (e) => { 99 | if(e.key === 'Escape') { 100 | MODAL_WINDOW.classList.remove('modal-window--active') 101 | closeAll() 102 | } 103 | 104 | if((e.metaKey && e.key === 'k') || (e.ctrlKey && e.key === 'k')) { 105 | closeAll(); 106 | $('.modal-search__input').focus(); 107 | MODAL_WINDOW.classList.add(`modal-window--active`) 108 | $('.modal-search').classList.toggle(`modal-search--active`); 109 | } 110 | 111 | if(!MODAL_WINDOW) return; 112 | 113 | if(e.key === 'ArrowUp') { 114 | let listItem = [...MODAL_SEARCH_LIST_CONTENT.children] 115 | if(focusedElement - 1 < 0) { 116 | focusedElement = listItem.length - 1 117 | } else { 118 | focusedElement-- 119 | } 120 | listItem[focusedElement]?.focus() 121 | // listItem[focusedElement].scrollIntoView(true) 122 | } 123 | 124 | if(e.key === 'ArrowDown') { 125 | let listItem = [...MODAL_SEARCH_LIST_CONTENT.children] 126 | listItem[focusedElement]?.focus() 127 | if(focusedElement + 1 > listItem.length - 1) { 128 | focusedElement = 0 129 | } else { 130 | focusedElement++ 131 | } 132 | } 133 | }) 134 | 135 | if(MODAL_WINDOW) { 136 | MODAL_WINDOW.addEventListener('click', (e) => { 137 | if(e.target.classList.contains('modal-window')) { 138 | MODAL_WINDOW.classList.remove(`modal-window--active`) 139 | MODAL_WINDOW.classList.remove(`modal-window--active-mini`) 140 | closeAll() 141 | } 142 | }) 143 | } 144 | if(MODAL_OPENERS.length > 0) { 145 | MODAL_OPENERS.forEach(MODAL_OPENER => { 146 | MODAL_OPENER.addEventListener('click', () => { 147 | const MODAL_ID = MODAL_OPENER.getAttribute('data-modal') 148 | const MODAL = document.querySelector(`.modal-${MODAL_ID}`) 149 | 150 | closeAll(); 151 | 152 | if(MODAL_ID !== 'lang' && MODAL_ID !== 'theme') MODAL_WINDOW.classList.toggle(`modal-window--active`) 153 | else isOpenPopupHeader = true 154 | 155 | if(MODAL_ID === 'search') document.querySelector('.modal-search__input').focus() 156 | if(MODAL_ID === 'share') { 157 | console.log($('.modal-share__textarea').value) 158 | $$('.modal-share__textarea')[currentShare].focus() 159 | $$('.modal-share__textarea')[currentShare].setSelectionRange(0, $$('.modal-share__textarea')[currentShare].value.length) 160 | } 161 | 162 | MODAL.classList.toggle(`modal-${MODAL_ID}--active`) 163 | }) 164 | }) 165 | } 166 | if(MODAL_CLOSERS.length > 0) { 167 | MODAL_CLOSERS.forEach(MODAL_CLOSER => { 168 | MODAL_CLOSER.addEventListener('click', () => { 169 | const MODAL_ID = MODAL_CLOSER.getAttribute('data-modal') 170 | const MODAL = document.querySelector(`.modal-${MODAL_ID}`) 171 | 172 | closeAll(); 173 | 174 | if(MODAL_ID !== 'lang' && MODAL_ID !== 'theme') MODAL_WINDOW.classList.toggle(`modal-window--active`) 175 | else isOpenPopupHeader = true 176 | 177 | MODAL.classList.remove(`modal-${MODAL_ID}--active`) 178 | }) 179 | }) 180 | } 181 | 182 | // THEME 183 | const light = document.querySelectorAll('.light-theme'); 184 | const dark = document.querySelectorAll('.dark-theme'); 185 | const system = document.querySelectorAll('.system-theme'); 186 | 187 | light.forEach((i) => 188 | i.addEventListener('click', () => { 189 | document.documentElement.classList = ''; 190 | localStorage.setItem('theme', 'light'); 191 | setActiveThemeButton('light') 192 | if(switchTheme !== null) { 193 | if(typeof switchTheme === 'object') { 194 | switchTheme.forEach(element => element('light')) 195 | } else { 196 | switchTheme('light') 197 | } 198 | } 199 | }), 200 | ); 201 | dark.forEach((i) => 202 | i.addEventListener('click', () => { 203 | document.documentElement.classList = 'dark'; 204 | localStorage.setItem('theme', 'dark'); 205 | setActiveThemeButton('dark') 206 | if(switchTheme !== null) { 207 | if(typeof switchTheme === 'object') { 208 | switchTheme.forEach(element => element('dark')) 209 | } else { 210 | switchTheme('dark') 211 | } 212 | } 213 | }), 214 | ); 215 | system.forEach((i) => 216 | i.addEventListener('click', () => { 217 | document.documentElement.classList = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : ''; 218 | localStorage.setItem('theme', 'system'); 219 | setActiveThemeButton('system') 220 | if(switchTheme !== null) { 221 | if(typeof switchTheme === 'object') { 222 | switchTheme.forEach(element => element(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) 223 | } else { 224 | switchTheme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') 225 | } 226 | } 227 | }), 228 | ); 229 | 230 | // SEARCH 231 | const MODAL_SEARCH = document.querySelector('.modal-search__input') 232 | const MODAL_SEARCH_LIST = document.querySelector('.modal-search__list') 233 | const MODAL_SEARCH_LIST_CONTENT = document.querySelector('.modal-search__list-content') 234 | 235 | if(MODAL_SEARCH) MODAL_SEARCH.addEventListener('input', (e) => { 236 | focusedElement = 0 237 | if(e.target.value.length > 0) { 238 | const FILTERED_JSON = JSON_CALCULATORS.filter(CALCULATOR => { 239 | return (CALCULATOR.description.toLowerCase().match(e.target.value.toLowerCase()) !== null) || 240 | CALCULATOR.title.toLowerCase().match(e.target.value.toLowerCase()) !== null; 241 | }) 242 | if(FILTERED_JSON.length > 0) { 243 | MODAL_SEARCH_LIST.classList.remove('modal-search__list--error') 244 | MODAL_SEARCH_LIST.classList.add('modal-search__list--active') 245 | MODAL_SEARCH_LIST_CONTENT.innerHTML = '' 246 | FILTERED_JSON.forEach(CALCULATOR => { 247 | let calculatorWrapper = document.createElement('a') 248 | calculatorWrapper.classList.add('modal-search-item') 249 | calculatorWrapper.href = CALCULATOR.uri 250 | 251 | let calculatorImg = document.createElement('img') 252 | calculatorImg.classList.add('modal-search-item__img') 253 | calculatorImg.src = CALCULATOR.image 254 | 255 | let calculatorTitle = document.createElement('span') 256 | calculatorTitle.classList.add('modal-search-item__text') 257 | calculatorTitle.innerText = CALCULATOR.title 258 | 259 | calculatorWrapper.append(calculatorImg, calculatorTitle) 260 | MODAL_SEARCH_LIST_CONTENT.append(calculatorWrapper) 261 | }) 262 | } else { 263 | MODAL_SEARCH_LIST_CONTENT.innerHTML = '' 264 | MODAL_SEARCH_LIST.classList.remove('modal-search__list--active') 265 | MODAL_SEARCH_LIST.classList.add('modal-search__list--error') 266 | } 267 | } else { 268 | MODAL_SEARCH_LIST_CONTENT.innerHTML = '' 269 | MODAL_SEARCH_LIST.classList.remove('modal-search__list--active') 270 | MODAL_SEARCH_LIST.classList.remove('modal-search__list--error') 271 | } 272 | }) 273 | 274 | // LANG 275 | const LANG_SELECTS = document.querySelectorAll('.header-lang__select') 276 | 277 | if (LANG_SELECTS){ 278 | let langIsEng = true 279 | 280 | for (const LANG_SELECT of LANG_SELECTS) { 281 | if(LANG_SELECT.innerText !== 'ENG' && window.location.href.match(LANG_SELECT.href) !== null) { 282 | LANG_SELECT.classList.add('header-lang__select--active') 283 | langIsEng = false 284 | } 285 | } 286 | 287 | if(langIsEng) LANG_SELECTS[0]?.classList?.add('header-lang__select--active') 288 | } 289 | 290 | // SHARE 291 | $$('.modal-share__button').forEach((button,index) => { 292 | button.addEventListener('click', () => { 293 | $$('.modal-share__button').forEach(i => i.classList.remove('modal-share__button--active')) 294 | $$('.modal-share__content').forEach(i => i.classList.remove('modal-share__content--active')) 295 | button.classList.add('modal-share__button--active') 296 | $$('.modal-share__content')[index].classList.add('modal-share__content--active') 297 | $$('.modal-share__textarea')[index].setSelectionRange(0, $$('.modal-share__textarea')[index].value.length) 298 | currentShare = index 299 | }) 300 | }) 301 | 302 | window.copyWidget = function (button) { 303 | button.classList.add('button--copy-active') 304 | navigator.clipboard.writeText($$('.modal-share__textarea')[currentShare].value) 305 | setTimeout(() => { 306 | button.classList.remove('button--copy-active') 307 | }, 1000) 308 | } 309 | 310 | window.now = function (suffix = 0){ 311 | let date = new Date(); 312 | date.setDate(date.getDate() + suffix); 313 | return ("0" + date.getHours()).slice(-2) + ':' + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2) 314 | } 315 | 316 | if(window.innerWidth < 1024){ 317 | $$('.calculator-content .button--primary').forEach((button) => { 318 | button.addEventListener('click', () => { 319 | let scrollValue = _('result-container').offsetTop; 320 | window.scrollTo({ top: scrollValue, behavior: 'smooth'}); 321 | }) 322 | }); 323 | } 324 | -------------------------------------------------------------------------------- /assets/js/calculator.js: -------------------------------------------------------------------------------- 1 | function calculate(){ 2 | const inputBinary = (elementId, optional) => { 3 | let value = input.get(elementId).raw(); 4 | if(optional && !value) return ''; 5 | if(!/^[01]+$/.test(value)) { 6 | input.error(elementId, `"${elementId}" must be a natural binary number.`); 7 | } 8 | return value; 9 | }; 10 | switch($('[data-tab].tab--active').dataset.tab){ 11 | case '0': 12 | // 1. init & validate 13 | const a = inputBinary('value_1'); 14 | const b = inputBinary('value_2'); 15 | const operation = input.get('operation').raw(); 16 | if(b == 0 && operation == 'divide') input.error('value_2', 'Division by zero in value_2'); 17 | if(!input.valid()) return; 18 | 19 | // 2. calculate 20 | const result = math.bin(math[operation]('0b'+a,'0b'+b)).replace('0b',''); 21 | 22 | // 3. output 23 | _('result').innerHTML = result; 24 | break; 25 | case '1': 26 | // 1. init & validate 27 | const binary = inputBinary('binary', true); 28 | const decimal = input.get('decimal').optional().natural().raw(); 29 | input.silent = false; 30 | if(!binary && !decimal){ 31 | input.error('binary'); 32 | input.error('decimal'); 33 | } 34 | if(!input.valid()) return; 35 | 36 | // 2. calculate 37 | const binToDec = binary ? `${binary} = ${math.number('0b'+binary)}` : ''; 38 | const decToBin = decimal ? `${decimal} = ${math.bin(decimal).replace('0b','')}` : ''; 39 | 40 | // 3. output 41 | _('bin_to_dec').innerHTML = binToDec; 42 | _('dec_to_bin').innerHTML = decToBin; 43 | break; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assets/js/chart.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | let theme = 'light'; 4 | if (localStorage.getItem('theme') === 'dark' || (localStorage.getItem('theme') === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)) theme = 'dark'; 5 | 6 | Chart.defaults.borderColor = '#000'; 7 | 8 | const colors = { 9 | light: { 10 | purple: '#A78BFA', 11 | yellow: '#FBBF24', 12 | sky: '#7DD3FC', 13 | blue: '#1D4ED8', 14 | textColor: '#6B7280', 15 | yellowGradientStart: 'rgba(250, 219, 139, 0.33)', 16 | purpleGradientStart: 'rgba(104, 56, 248, 0.16)', 17 | skyGradientStart: 'rgba(56, 187, 248, 0.16)', 18 | tealGradientStart: 'rgba(56, 248, 222, 0.16)', 19 | yellowGradientStop: 'rgba(250, 219, 139, 0)', 20 | purpleGradientStop: 'rgba(104, 56, 248, 0)', 21 | gridColor: '#DBEAFE', 22 | tooltipBackground: '#fff', 23 | fractionColor: '#EDE9FE', 24 | }, 25 | dark: { 26 | purple: '#7C3AED', 27 | yellow: '#D97706', 28 | sky: '#0284C7', 29 | blue: '#101E47', 30 | textColor: '#fff', 31 | yellowGradientStart: 'rgba(146, 123, 67, 0.23)', 32 | purpleGradientStart: 'rgba(78, 55, 144, 0.11)', 33 | skyGradientStart: 'rgba(56, 187, 248, 0.16)', 34 | tealGradientStart: 'rgba(56, 248, 222, 0.16)', 35 | yellowGradientStop: 'rgba(250, 219, 139, 0)', 36 | purpleGradientStop: 'rgba(104, 56, 248, 0)', 37 | gridColor: '#162B64', 38 | tooltipBackground: '#1C3782', 39 | fractionColor: '#41467D', 40 | }, 41 | }; 42 | 43 | class Custom extends LineController { 44 | draw() { 45 | super.draw(arguments); 46 | 47 | const ctx = this.chart.ctx; 48 | let _stroke = ctx.stroke; 49 | 50 | ctx.stroke = function () { 51 | ctx.save(); 52 | ctx.shadowColor = 'black'; 53 | ctx.shadowBlur = 20; 54 | ctx.shadowOffsetX = 0; 55 | ctx.shadowOffsetY = 20; 56 | _stroke.apply(this, arguments); 57 | ctx.restore(); 58 | }; 59 | } 60 | } 61 | 62 | Custom.id = 'shadowLine'; 63 | Custom.defaults = LineController.defaults; 64 | 65 | Chart.register(Custom); 66 | 67 | let switchTheme = [] 68 | 69 | if (document.getElementById('chartC150')) { 70 | let ctx = document.getElementById('chartC150').getContext('2d'); 71 | 72 | let purpleGradient = ctx.createLinearGradient(0, 0, 2048, 0); 73 | purpleGradient.addColorStop(0, 'rgba(152, 96, 250, 0)'); 74 | purpleGradient.addColorStop(1, 'rgba(152, 96, 250, .8)'); 75 | 76 | const dataCharts = { 77 | labels: [0, 1, 2, 3, 4, 5, 6], 78 | datasets: [ 79 | { 80 | label: 'D1', 81 | data: [{ x: 4, y: 40 }], 82 | backgroundColor: '#7C3AED', 83 | borderWidth: 0, 84 | radius: 6, 85 | hoverRadius: 6, 86 | type: 'scatter', 87 | stacked: true, 88 | order: 0, 89 | }, 90 | { 91 | label: 'D2', 92 | data: [0, 10, 20, 40, 60, 80, 100], 93 | borderColor: colors[theme].purple, 94 | type: 'line', 95 | fill: '-1', 96 | order: 1, 97 | pointHoverRadius: 0, 98 | }, 99 | { 100 | label: 'D3', 101 | data: [0, 5, 5, 15, 25, 35, 45], 102 | borderColor: colors[theme].purple, 103 | backgroundColor: purpleGradient, 104 | type: 'line', 105 | fill: '-1', 106 | order: 1, 107 | pointHoverRadius: 0, 108 | }, 109 | ], 110 | }; 111 | 112 | let chart = new Chart(document.getElementById('chartC150'), { 113 | data: dataCharts, 114 | options: { 115 | stepSize: 1, 116 | response: true, 117 | elements: { 118 | point: { 119 | radius: 0, 120 | }, 121 | }, 122 | plugins: { 123 | legend: { 124 | display: false, 125 | }, 126 | tooltip: false, 127 | }, 128 | interaction: { 129 | mode: 'index', 130 | intersect: false, 131 | }, 132 | scales: { 133 | y: { 134 | max: 100, 135 | grid: { 136 | tickLength: 0, 137 | color: colors[theme].gridColor, 138 | }, 139 | ticks: { 140 | display: false, 141 | stepSize: 25, 142 | }, 143 | border: { 144 | color: colors[theme].gridColor, 145 | }, 146 | }, 147 | x: { 148 | stacked: false, 149 | border: { 150 | color: colors[theme].gridColor, 151 | }, 152 | ticks: { 153 | display: false, 154 | color: colors[theme].gridColor, 155 | stepSize: 1, 156 | }, 157 | grid: { 158 | tickLength: 0, 159 | color: colors[theme].gridColor, 160 | }, 161 | }, 162 | }, 163 | }, 164 | }); 165 | 166 | let switchThemeChartC150 = function(theme) { 167 | let y = chart.config.options.scales.y 168 | let x = chart.config.options.scales.x 169 | let data = chart.config.data 170 | y.grid.color = colors[theme].gridColor; 171 | y.border.color = colors[theme].gridColor; 172 | x.border.color = colors[theme].gridColor; 173 | x.grid.color = colors[theme].gridColor; 174 | x.ticks.color = colors[theme].gridColor; 175 | data.datasets[1].borderColor = colors[theme].purple; 176 | data.datasets[2].borderColor = colors[theme].purple; 177 | chart.update() 178 | } 179 | 180 | switchTheme.push(switchThemeChartC150) 181 | 182 | } -------------------------------------------------------------------------------- /assets/js/datepicker.js: -------------------------------------------------------------------------------- 1 | document.querySelectorAll('.datepicker_us').forEach((datepicker) => { 2 | new AirDatepicker(datepicker, { 3 | dateFormat: 'MM/dd/yyyy', 4 | autoClose: true, 5 | onSelect: function(event){ 6 | return updateDate(event.datepicker.$el); 7 | }, 8 | // visible: true, 9 | prevHtml: 10 | '', 11 | nextHtml: 12 | '', 13 | locale: { 14 | months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 15 | monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 16 | days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 17 | daysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], 18 | daysMin: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], 19 | }, 20 | }); 21 | }); 22 | 23 | document.querySelectorAll('.datepicker').forEach((datepicker) => { 24 | new AirDatepicker(datepicker, { 25 | dateFormat: 'yyyy-MM-dd', 26 | autoClose: true, 27 | onSelect: function(event){ 28 | return updateDate(event.datepicker.$el); 29 | }, 30 | // visible: true, 31 | prevHtml: 32 | '', 33 | nextHtml: 34 | '', 35 | locale: { 36 | months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 37 | monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 38 | days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 39 | daysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], 40 | daysMin: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], 41 | }, 42 | }); 43 | }); -------------------------------------------------------------------------------- /assets/js/dialog-table.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | $$('.result-table__dialog').forEach(element => { 4 | const ELEMENT_OPEN = element.querySelector('.result-table__open'); 5 | ELEMENT_OPEN.addEventListener('click', () => { 6 | element.classList.toggle('result-table__dialog--active'); 7 | }) 8 | }) -------------------------------------------------------------------------------- /assets/js/dropdown-icon.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const setSelect = (list, index) => { 4 | list.forEach(item => { 5 | item.classList.remove('dropdown-select--selected') 6 | }) 7 | list[index].classList.add('dropdown-select--selected') 8 | } 9 | 10 | const setValue = (input, value, index) => { 11 | if(index !== undefined) { 12 | setTab(index) 13 | } 14 | input.innerHTML = value 15 | } 16 | 17 | const setTab = (index) => { 18 | document.querySelectorAll(`[data-tab]`)?.forEach(element => { 19 | if(element.getAttribute('data-tab') == index) { 20 | element.classList.add('tab--active'); 21 | } else { 22 | element.classList.remove('tab--active'); 23 | element.classList.remove('tab--active') 24 | } 25 | }) 26 | } 27 | 28 | const DROPDOWN_WRAPPER = document.querySelectorAll('.dropdown-wrapper') 29 | 30 | 31 | DROPDOWN_WRAPPER.forEach(wrapper => { 32 | // CLOSE DROPDOWN WHEN CLICK OUTSIDE 33 | window.addEventListener('click', (e) => { 34 | if(!(e.composedPath().includes(wrapper))) { 35 | wrapper.classList.remove('dropdown-wrapper--active') 36 | } 37 | }) 38 | 39 | const DROPDOWN_FIELD = wrapper.querySelector('.input-field') 40 | const DROPDOWN_VALUE = wrapper.querySelector('.input-field__text') 41 | const DROPDOWN_SELECTS = wrapper.querySelectorAll('.dropdown-select') 42 | // DEFAULT TAB 43 | setTab(0) 44 | 45 | // OPEN DROPDOWN WHEN CLICK ON INPUT 46 | DROPDOWN_FIELD.addEventListener('click', () => { 47 | // CLOSE OTHERS DROPDOWN 48 | if(!wrapper.classList.contains('dropdown-wrapper--active')) { 49 | DROPDOWN_WRAPPER.forEach(wrapper => {wrapper.classList.remove('dropdown-wrapper--active')}) 50 | } 51 | // OPEN THIS DROPDOWN 52 | wrapper.classList.toggle('dropdown-wrapper--active') 53 | }) 54 | 55 | // SET EVENT LISTENERS FOR SELECT 56 | DROPDOWN_SELECTS.forEach((select, index) => { 57 | const SELECT_VALUE = select.innerHTML 58 | select.addEventListener('click', () => { 59 | wrapper.classList.remove('dropdown-wrapper--active') 60 | 61 | // SET SELECT FOR DROPDOWN 62 | setSelect(DROPDOWN_SELECTS, index) 63 | 64 | // SET VALUE FOR DROPDOWN 65 | if(select.classList.contains('dropdown-select--tab')) { 66 | // IF DROPDOWN IS DROPDOWN TAB : example due-date-calculator dropdown "Calculate based on" 67 | setValue(DROPDOWN_VALUE,SELECT_VALUE, index) 68 | } else { 69 | setValue(DROPDOWN_VALUE,SELECT_VALUE) 70 | } 71 | }) 72 | }) 73 | }) -------------------------------------------------------------------------------- /assets/js/fractions.js: -------------------------------------------------------------------------------- 1 | const Fractions = { 2 | // helpers 3 | isCorrectMixed(whole, num, denom){ 4 | return !(!whole && !num && !denom || !num && denom || num && !denom); 5 | }, 6 | buildFrac(whole, num, denom){ 7 | whole = Number(whole); 8 | num = Number(num); 9 | denom = Number(denom); 10 | return num && denom ? 11 | math.fraction( 12 | (math.sign(whole) || 1) * (math.sign(num) || 1) * (math.sign(denom) || 1) * 13 | (math.abs(whole) * math.abs(denom) + math.abs(num)), math.abs(denom) 14 | ) : 15 | math.fraction(whole, 1) 16 | ; 17 | }, 18 | getFracPart(frac){ 19 | return frac.d != 1 ? { 20 | num: frac.n % frac.d, denom: frac.d, 21 | } : ''; 22 | }, 23 | getWholePart(frac){ 24 | const sign = frac.s == -1 ? '-' : ''; 25 | const wholePart = (frac.n - frac.n % frac.d) / frac.d; 26 | if(wholePart == 0 && this.getFracPart(frac)) return sign; 27 | return sign + wholePart; 28 | }, 29 | getChartData(frac){ 30 | const fracPart = this.getFracPart(frac); 31 | const wholePart = this.getWholePart(frac); 32 | return fracPart ? [fracPart.num, fracPart.denom-fracPart.num] : (wholePart == 0 ? [0,1]:[1,0]); 33 | }, 34 | outputFrac(frac, prefix){ 35 | const isWhole = frac.d == 1; 36 | const sign = frac.s == -1 ? '-' : ''; 37 | _(prefix+'Whole').classList[!isWhole && !sign ? 'add':'remove']('hidden'); 38 | _(prefix+'Whole').innerText = sign + (isWhole ? frac.n : ''); 39 | _(prefix+'Frac').classList[isWhole?'add':'remove']('hidden'); 40 | _(prefix+'Num').innerText = frac.n; 41 | _(prefix+'Denom').innerText = frac.d; 42 | }, 43 | outputMixed(frac, prefix){ 44 | const fracPart = this.getFracPart(frac); 45 | const wholePart = this.getWholePart(frac); 46 | _(prefix+'Whole').classList[!wholePart?'add':'remove']('hidden'); 47 | _(prefix+'Whole').innerText = wholePart; 48 | _(prefix+'Frac').classList[!fracPart?'add':'remove']('hidden'); 49 | _(prefix+'Num').innerText = fracPart.num; 50 | _(prefix+'Denom').innerText = fracPart.denom; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /assets/js/functions.js: -------------------------------------------------------------------------------- 1 | window.log = console.log; 2 | 3 | window.setValue = function (inputId, value, index){ 4 | _(inputId).value = value; 5 | _(inputId).index = index; 6 | } 7 | 8 | window.switcher = function(button, id, action) { 9 | $('#' + id).value = button.value; 10 | $('#' + id).onchange && $('#' + id).onchange(button.value); 11 | $('#' + id + '-a')?.classList.remove("button-switcher--active"); 12 | $('#' + id + '-b')?.classList.remove("button-switcher--active"); 13 | $('#' + id + '-c')?.classList.remove("button-switcher--active"); 14 | $('#' + id + '-d')?.classList.remove("button-switcher--active"); 15 | $('#' + id + '-e')?.classList.remove("button-switcher--active"); 16 | button.classList.add("button-switcher--active"); 17 | toggleRelatedInputs(button, id, action); 18 | } 19 | 20 | window.toggleRelatedInputs = function(element, id, action){ 21 | element = element instanceof Event ? element.target : element 22 | id = id ?? element.id; 23 | let value = element.value; 24 | if(element.type == 'select-one') value = element.selectedIndex; 25 | $$('.' + id).forEach(element => { 26 | if(action === "disabled") { 27 | element.classList.remove("disabled"); 28 | } else if (action === "finding") { 29 | element.classList.remove("disabled"); 30 | if(element.querySelector('.input-field__input').value === "???") { 31 | element.querySelector('.input-field__input').value = "" 32 | } 33 | } else { 34 | element.classList.add("related-item-hidden"); 35 | } 36 | }); 37 | $$('.related-to-' + id + '-' + value)?.forEach(element => { 38 | if(action === "disabled") { 39 | element.classList.add("disabled"); 40 | } else if (action === "finding") { 41 | element.querySelector('.input-field__input').value = "???" 42 | element.classList.add("disabled"); 43 | } else { 44 | element.classList.remove("related-item-hidden"); 45 | } 46 | }); 47 | } 48 | 49 | window.switch_data_tab = function(owner, index, value){ 50 | $$('[data-tab]')?.forEach(element => { 51 | if(element.getAttribute('data-tab') == index) { 52 | element.classList.add('tab--active'); 53 | owner.classList.add('tab--active'); 54 | } else { 55 | element.classList.remove('tab--active'); 56 | } 57 | }); 58 | } 59 | 60 | window.isMetricSystem = function() { 61 | return $('.system-switcher').classList.contains('system-switcher--active'); 62 | } 63 | 64 | window.setSystem = function(system) { 65 | const add = (system == "metric" ? ".imperial-system-item" : ".metric-system-item"); 66 | $$(".system-item-hidden").forEach(element => { 67 | element.classList.remove("system-item-hidden"); 68 | }); 69 | $$(add).forEach(element => { 70 | element.classList.add("system-item-hidden"); 71 | }); 72 | localStorage.setItem("system", system); 73 | } 74 | 75 | window.toggleSystem = function(button) { 76 | button.classList.toggle('system-switcher--active'); 77 | if(button.classList.contains('system-switcher--active')) { 78 | return setSystem('metric'); 79 | } 80 | return setSystem('imperial'); 81 | } 82 | 83 | window.isHidden = function(element) { 84 | const styles = window.getComputedStyle(element); 85 | return styles.display === 'none' || styles.visibility === 'hidden'; 86 | } 87 | 88 | window.output = { 89 | value: null, 90 | val: function(value){ 91 | this.value = value; 92 | return this; 93 | }, 94 | replace: function(search, replacement) { 95 | this.value = this.value.replace(search, replacement); 96 | return this; 97 | }, 98 | set: function(elementId){ 99 | _(elementId).innerHTML = this.value; 100 | return this; 101 | } 102 | }; 103 | 104 | // check erroneous result of expression (or if it's not string - check itself) 105 | // usefull in cases when erroneous values of input fields are unknown 106 | window.calc = (expression,scope,resultType) => { 107 | let result = expression; 108 | scope = scope || {}; 109 | if(typeof expression == 'string'){ 110 | result = math.evaluate(expression,scope); // can throw error as well 111 | } 112 | let valid = true; 113 | switch(resultType){ 114 | case 'positive': valid = result > 0; 115 | } 116 | if(isNaN(result)||result.im||!valid) { 117 | const args = Object.keys(scope).map(arg=>arg+'='+scope[arg]); 118 | throw new Error( 119 | `result of expression ${expression} is ${result}.` 120 | + (resultType ? `
Should be ${resultType}.`:'') 121 | + (args.length != 0 ? `
Args: ${args.join(', ')}.`:'') 122 | ); 123 | } 124 | return result; 125 | }; 126 | 127 | // allows to show accurate results with fixed precision/length (instead of using BigNumber) 128 | window.format = number => math.format(number,{precision:7}) 129 | 130 | window.input = { 131 | box: $('#error-box'), 132 | list: $('#error-list'), 133 | value: null, 134 | elementId: null, 135 | shown: false, 136 | processed: false, 137 | silent: false, 138 | reset: function(){ 139 | this.shown = false; 140 | this.box.classList.remove('calculator-result--error-active'); 141 | $$('.input-field--error')?.forEach(el => el.classList.remove('input-field--error')) 142 | $$('.calculator-result:not(.calculator-result--error)').forEach(el => el.classList.remove('calculator-result--hidden')) 143 | }, 144 | error: function (inputId, message = `Incorrect value for "${inputId}"`, last = false) { 145 | if(this.silent) return; 146 | if(this.processed) this.reset(); 147 | if(!Array.isArray(inputId)) inputId = [inputId]; 148 | for(const inputIdItem of inputId) _(inputIdItem).parentNode.classList.add('input-field--error'); 149 | if(!this.shown){ 150 | this.processed = false; 151 | this.shown = true; 152 | this.list.innerHTML = ''; 153 | this.box.classList.add('calculator-result--error-active'); 154 | $$('.calculator-result:not(.calculator-result--error)').forEach(el => el.classList.add('calculator-result--hidden')) 155 | } 156 | const element = document.createElement('p'); 157 | element.classList.add('calculator-error__item'); 158 | element.innerHTML = message; 159 | this.list.append(element); 160 | if(last) this.processed = true; 161 | }, 162 | // sometimes it's complicated to check input values 163 | // so we're checking `calc` result for an erroneous result, show exception and return 164 | // e.g.: try{calc(...);}catch(e){input.exception(field{s},e);return;} 165 | exception(inputId, message){ 166 | if(typeof message != 'string'){ 167 | let error = ''; 168 | if(message instanceof Error){ 169 | error = message.toString(); 170 | } 171 | // default message 172 | if(Array.isArray(inputId) && inputId.length == 0){ 173 | message = `${error}`; 174 | } else { 175 | message = `Value${Array.isArray(inputId)?'s':` "${this.get(inputId).value}"`} of "${inputId}" ${Array.isArray(inputId)?'are':'is'} invalid.
${error}`; 176 | } 177 | } 178 | return this.error(inputId, message, true); 179 | }, 180 | valid: function(){ 181 | if(!this.shown || this.processed) this.reset(); 182 | this.processed = true; 183 | this.silent = false; 184 | return !this.shown; 185 | }, 186 | get: function(elementId){ 187 | this.elementId = elementId; 188 | let element = _(elementId); 189 | this.silent = false; 190 | if(element == null){ 191 | this.value = null; 192 | } else { 193 | this.value = element.value; 194 | for (; element && element !== document; element = element.parentNode ) { 195 | if(element.classList.contains('related-item-hidden')) this.silent = true; 196 | } 197 | } 198 | return this; 199 | }, 200 | index: function(){ 201 | this.value = _(this.elementId).selectedIndex; 202 | return this; 203 | }, 204 | checked: function(elementId){ 205 | this.value = _(this.elementId).checked; 206 | return this; 207 | }, 208 | split: function(separator){ 209 | this.value = this.value.split(separator); 210 | return this; 211 | }, 212 | replace: function(pattern, replacement){ 213 | this.value = this.value.replace(pattern, replacement); 214 | return this; 215 | }, 216 | default: function(value){ 217 | if(!this.value) this.value = value; 218 | return this; 219 | }, 220 | optional: function(value){ 221 | if(!this.value) this.silent = true; 222 | return this; 223 | }, 224 | gt: function(compare = 0, errorText = `The ${this.elementId} must be greater than ${compare}.`){ 225 | if (this.value instanceof Date) { 226 | compare = compare instanceof Date ? compare : new Date(_(compare).value); 227 | if (this.value.getTime() <= compare.getTime()) this.error(this.elementId, errorText); 228 | } else { 229 | compare = isNaN(compare) ? Number(_(compare).value) : compare; 230 | if(this.value === '' || isNaN(Number(this.value))) 231 | this.error(this.elementId, `The ${this.elementId} must be a number.`); 232 | else 233 | if (Number(this.value) <= compare) this.error(this.elementId, errorText); 234 | } 235 | return this; 236 | }, 237 | gte: function(compare = 0, errorText = `The ${this.elementId} must be greater than or equal to ${compare}.`){ 238 | if (this.value instanceof Date) { 239 | compare = compare instanceof Date ? compare : new Date(_(compare).value); 240 | if (this.value.getTime() < compare.getTime()) this.error(this.elementId, errorText); 241 | } else { 242 | compare = isNaN(compare) ? Number(_(compare).value) : compare; 243 | if(this.value === '' || isNaN(Number(this.value))) 244 | this.error(this.elementId, `The ${this.elementId} must be a number.`); 245 | else 246 | if (Number(this.value) < compare) this.error(this.elementId, errorText); 247 | } 248 | return this; 249 | }, 250 | lt: function(compare = 0, errorText = `The ${this.elementId} must be less than ${compare}.`){ 251 | if (this.value instanceof Date) { 252 | compare = compare instanceof Date ? compare : new Date(_(compare).value); 253 | if (this.value.getTime() >= compare.getTime()) this.error(this.elementId, errorText); 254 | } else { 255 | compare = isNaN(compare) ? Number(_(compare).value) : compare; 256 | if(this.value === '' || isNaN(Number(this.value))) 257 | this.error(this.elementId, `The ${this.elementId} must be a number.`); 258 | else 259 | if (Number(this.value) >= compare) this.error(this.elementId, errorText); 260 | } 261 | return this; 262 | }, 263 | lte: function(compare = 0, errorText = `The ${this.elementId} must be less than or equal to ${compare}.`){ 264 | if (this.value instanceof Date) { 265 | compare = compare instanceof Date ? compare : new Date(_(compare).value); 266 | if (this.value.getTime() > compare.getTime()) this.error(this.elementId, errorText); 267 | } else { 268 | compare = isNaN(compare) ? Number(_(compare).value) : compare; 269 | if(this.value === '' || isNaN(Number(this.value))) 270 | this.error(this.elementId, `The ${this.elementId} must be a number.`); 271 | else 272 | if (Number(this.value) > compare) this.error(this.elementId, errorText); 273 | } 274 | return this; 275 | }, 276 | integer: function(errorText = `The ${this.elementId} must be integer number (-3, -2, -1, 0, 1, 2, 3, ...).`){ 277 | if (!this.value.match(/^-?(0|[1-9]\d*)$/)) this.error(this.elementId, errorText); 278 | return this; 279 | }, 280 | _naturalRegexp: /^([1-9]\d*)$/, 281 | natural: function(errorText = `The ${this.elementId} must be a natural number (1, 2, 3, ...).`){ 282 | if (!this.value.match(this._naturalRegexp)) this.error(this.elementId, errorText); 283 | return this; 284 | }, 285 | natural_numbers: function(errorText = `The ${this.elementId} must be a set of natural numbers (1, 2, 3, ...).`){ 286 | this.split(/[ ,]+/); 287 | if (!this.value.every(value=>value.match(this._naturalRegexp))) this.error(this.elementId, errorText); 288 | return this; 289 | }, 290 | _mixedRegexp: /^(0|-?[1-9]\d*|-?[1-9]\d*\/[1-9]\d*|-?[1-9]\d*\s[1-9]\d*\/[1-9]\d*)$/, 291 | mixed: function(errorText = `The ${this.elementId} must be an integer/fraction/mixed number (1, 2/3, 4 5/6, ...).`){ 292 | if (!this.value.match(this._mixedRegexp)) this.error(this.elementId, errorText); 293 | return this; 294 | }, 295 | mixed_numbers: function(errorText = `The ${this.elementId} must be a set of integer/fraction/mixed numbers (1, 2/3, 4 5/6, ...).`){ 296 | this.split(/,\s*/); 297 | if (!this.value.every(value=>value.match(this._mixedRegexp))) this.error(this.elementId, errorText); 298 | return this; 299 | }, 300 | number: function(errorText = `The "${this.elementId}" must be a number.`){ 301 | if(this.value === '' || isNaN(Number(this.value))) this.error(this.elementId, errorText); 302 | return this; 303 | }, 304 | probability: function(errorText = `The "${this.elementId}" must be a number between 0 and 1.`){ 305 | if(this.value === '' || isNaN(Number(this.value)) || Number(this.value) < 0 || Number(this.value) > 1) 306 | this.error(this.elementId, errorText); 307 | return this; 308 | }, 309 | percentage: function(errorText = `The "${this.elementId}" must be a number between 0 and 100.`){ 310 | if(this.value === '' || isNaN(Number(this.value)) || Number(this.value) < 0 || Number(this.value) > 100) 311 | this.error(this.elementId, errorText); 312 | return this; 313 | }, 314 | numbers: function(errorText = `The ${this.elementId} must be a set of numbers.`){ 315 | if (this.value.filter(value => isNaN(Number(value))).length) this.error(this.elementId, errorText); 316 | return this; 317 | }, 318 | whole: function(errorText = `The ${this.elementId} must be a whole number.`){ 319 | if (!this.value.match(/^(0|[1-9]\d*)$/)) this.error(this.elementId, errorText); 320 | return this; 321 | }, 322 | positive: function(errorText = `The ${this.elementId} must be greater than 0.`){ 323 | this.gt(0, errorText); 324 | return this; 325 | }, 326 | nonZero: function(errorText = `The ${this.elementId} must be non-zero.`){ 327 | if(this.value === '' || isNaN(Number(this.value))) 328 | this.error(this.elementId, `The ${this.elementId} must be a number.`); 329 | else 330 | if(Number(this.value) == 0) this.error(this.elementId, errorText); 331 | return this; 332 | }, 333 | nonNegative: function(errorText = `The ${this.elementId} must be greater than or equal to 0.`){ 334 | this.gte(0, errorText); 335 | return this; 336 | }, 337 | negative: function(errorText = `The ${this.elementId} must be less than 0.`){ 338 | this.lt(0, errorText); 339 | return this; 340 | }, 341 | scientific: function(errorText = `The ${this.elementId} must be in scientific notation.`){ 342 | if (!this.value.match(/^(-|\+)?((0|[1-9]\d*)(\.\d*)?|(\.\d+))((e|\s?(\*|x)\s?10\^)(-|\+)?(0|[1-9]\d*))?$/i)) this.error(this.elementId, errorText); 343 | return this; 344 | }, 345 | periodic: function(errorText = `The ${this.elementId} must be regular or periodic number.`){ 346 | if (this.value === '' || isNaN(Number(this.value)) && !this.value.match(/\.\d*\(\d+\)$/)) this.error(this.elementId, errorText); 347 | return this; 348 | }, 349 | time: function(format = 'hh:mm:ss', errorText = `The ${this.elementId} must be in format ${format}.`){ 350 | let regex = new RegExp("^" + format.replace(/[\:\-\/\\]/g, '\\$&').replace(/h|m|s/g, '\\d') + "$"); 351 | if (!this.value.match(regex) || isNaN(this.value = new Date(`1900-01-01 ${this.value}`))) this.error(this.elementId, errorText); 352 | return this; 353 | }, 354 | date: function(format = 'yyyy-mm-dd', errorText = `The ${this.elementId} is required field.`){ 355 | let regex = new RegExp("^" + format.replace(/[\:\-\/\\]/g, '\\$&').replace(/y|m|d|h|s/g, '\\d') + "$"); 356 | if (!this.value.match(regex) || isNaN(this.value = new Date(this.value))) this.error(this.elementId, errorText); 357 | this.value = convertTZ(this.value, "UTC"); 358 | return this; 359 | }, 360 | bool: function(){ 361 | return !!this.value; 362 | }, 363 | val: function(){ 364 | if(this.value === '' || this.value === null) return null; 365 | return Number(this.value); 366 | }, 367 | vals: function(){ 368 | return this.value.map(value => Number(value)); 369 | }, 370 | raw: function(){ 371 | return this.value; 372 | }, 373 | group(name,ids){ 374 | const result = ids.split('|') 375 | .reduce((result,ids)=>{ 376 | const obj = ids.split('.').every(id=>_(name+id.match(/^[_a-zA-Z]+/)[0]).value) ? 377 | ids.split('.').reduce((obj,id)=>{ 378 | let type = 'number'; 379 | let getter = 'val'; 380 | switch((id.match(/[^_a-zA-Z]+$/)||[])[0]){ 381 | case '+': type = 'positive'; break; 382 | case '!0': type = 'nonZero'; break; 383 | case '#': getter = 'raw'; break; 384 | default: /* custom modificator */; break; 385 | } 386 | id = id.match(/^[_a-zA-Z]+/)[0]; 387 | return {...obj, ...{ 388 | [id]: input.get(name+id)[type]()[getter]() 389 | }}; 390 | }, {}) : null; 391 | if(!result && !obj) return null; 392 | return {...result,...obj}; 393 | }, null); 394 | return result; 395 | }, 396 | } 397 | 398 | window.sysnumconv = function(element){ 399 | const id = element.dataset.target; 400 | const metric = _(id); 401 | const imperial = _(id + "_imperial"); 402 | if(window.isMetricSystem()){ 403 | let value = metric.value; 404 | imperial.value = eval(imperial.dataset.formula).toFixed(2); 405 | } else { 406 | let value = imperial.value; 407 | metric.value = eval(metric.dataset.formula).toFixed(2); 408 | } 409 | }; 410 | 411 | window.updateHeight = function(element){ 412 | var id = element.dataset.target; 413 | var cm = _(id); 414 | var feet = _(id + "_ft"); 415 | var inches = _(id + "_in"); 416 | if(window.isMetricSystem()){ 417 | feet.value = Math.floor(cm.value * 0.393701 / 12); 418 | inches.value = (cm.value * 0.393701 % 12).toFixed(2); 419 | } else { 420 | cm.value = ((feet.value * 30.48) + (inches.value * 2.54)).toFixed(2); 421 | } 422 | }; 423 | 424 | window.setDate = function (id, suffix) { 425 | var date = new Date(); 426 | var date_m = _(id); 427 | var date_us = _(id + "_us"); 428 | date.setDate(date.getDate() + suffix); 429 | date_us.value = ("0" + (date.getMonth() + 1)).slice(-2) + '/' + ("0" + date.getDate()).slice(-2) + '/' + date.getFullYear(); 430 | date_m.value = date.getFullYear() + '-' + ("0" + (date.getMonth() + 1)).slice(-2) + '-' + ("0" + date.getDate()).slice(-2); 431 | } 432 | 433 | window.updateDate = function(element){ 434 | var id = element.dataset.target; 435 | var date_m = _(id); 436 | var date_us = _(id + "_us"); 437 | if(window.isMetricSystem()){ 438 | let date = new Date(Date.parse(date_m.value)); 439 | date_us.value = ("0" + (date.getMonth() + 1)).slice(-2) + '/' + ("0" + date.getDate()).slice(-2) + '/' + date.getFullYear(); 440 | } else { 441 | let date = new Date(Date.parse(date_us.value)); 442 | date_m.value = date.getFullYear() + '-' + ("0" + (date.getMonth() + 1)).slice(-2) + '-' + ("0" + date.getDate()).slice(-2); 443 | } 444 | }; 445 | 446 | window.switchTab = function (event, index) { 447 | if(index !== undefined && index !== null) { 448 | if(event.target.classList.contains('tab-item')) { 449 | $$(`.${event.target.classList[0]}`).forEach((tab, i) => { 450 | if(index === i) { 451 | tab.classList.add('tab-item--active') 452 | } else { 453 | tab.classList.remove('tab-item--active') 454 | } 455 | }) 456 | } 457 | } 458 | $$(`[data-tab]`).forEach(element => { 459 | if(element.dataset.tab == event.selectedIndex || element.dataset.tab == index) { 460 | element.classList.add('tab--active') 461 | } else { 462 | element.classList.remove('tab--active') 463 | } 464 | }) 465 | } 466 | 467 | window.setMaxLength = function(element, maxLength) { 468 | if(getComputedStyle(element).getPropertyValue('--fontStep') !== '') { 469 | element.style = `--maxWidth: ${Number(getComputedStyle(element).getPropertyValue('--fontStep').replace(/px/gi, '')) * (element.value.length === 0 ? 1 : element.value.length > maxLength ? maxLength : element.value.length) }px` 470 | } 471 | if(element.value.length > maxLength) { 472 | element.value = element.value.substring(0, maxLength); 473 | } 474 | } 475 | 476 | window.relatedToggle = function(element, related, action) { 477 | if(action === "disabled") { 478 | if(element.target.checked) { 479 | $$(`.related-to-${related}`)?.forEach(el => el.classList.remove('disabled')) 480 | } else { 481 | $$(`.related-to-${related}`)?.forEach(el => el.classList.add('disabled')) 482 | } 483 | } else { 484 | if(element.target.checked) { 485 | $$(`.related-to-${related}-a`)?.forEach(el => el.classList.add('related-item-hidden')) 486 | $$(`.related-to-${related}-b`)?.forEach(el => el.classList.remove('related-item-hidden')) 487 | } else { 488 | $$(`.related-to-${related}-a`)?.forEach(el => el.classList.remove('related-item-hidden')) 489 | $$(`.related-to-${related}-b`)?.forEach(el => el.classList.add('related-item-hidden')) 490 | } 491 | } 492 | } 493 | 494 | window.roundTo = function (num, decimals = 5) { 495 | if (typeof num !== 'number' || !isFinite(num)) return num; 496 | if (num.toString().includes('e')) { 497 | const splitted = num.toString().split('e'); 498 | return roundTo(+splitted[0], decimals) + `e${splitted[1]}`; 499 | }; 500 | return +(Math.round(num + `e+${decimals}`) + `e-${decimals}`); 501 | } 502 | 503 | window.delay = ms => new Promise(resolve => setTimeout(resolve, ms)); 504 | window.generateRandomDigit = () => Math.floor(Math.random() * 10); 505 | window.convertTZ = (date, tzString) => new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {timeZone: tzString})); 506 | window.animateElement = async (element, isText) => { 507 | const originalText = element.innerHTML; 508 | let digitIndices = []; 509 | let originalDigits = []; 510 | 511 | [...originalText].forEach((char, index) => { 512 | if (!isNaN(parseInt(char, 10)) && char !== ' ') { 513 | digitIndices.push(index); 514 | originalDigits.push(char); 515 | } 516 | }); 517 | 518 | for (let i = 0; i < 10; i++) { 519 | let textArray = [...originalText]; 520 | digitIndices.forEach(index => { 521 | textArray[index] = generateRandomDigit(); 522 | }); 523 | element.innerHTML = textArray.join(''); 524 | await delay(30); 525 | } 526 | 527 | digitIndices.forEach((index, digitIndex) => { 528 | let textArray = [...originalText]; 529 | textArray[index] = originalDigits[digitIndex]; 530 | element.innerHTML = textArray.join(''); 531 | }); 532 | }; 533 | window.animateElements = function(){ 534 | $$('.animate').forEach(async (element) => animateElement(element)); 535 | $$('.animate-text').forEach(async (element) => animateElement(element, true)); 536 | } 537 | window.plural = function (number, versions, options = { showNumber: true, localize: true, locale: null }) { 538 | const words = { 539 | zero: "", 540 | one: "", 541 | two: "", 542 | few: "", 543 | many: "", 544 | other: "" 545 | }; 546 | const parts = versions.split(':'); 547 | if (parts.length === 1) { 548 | Object.keys(words).forEach(key => words[key] = versions); 549 | } else { 550 | let i = 0; 551 | for (let key in words) { 552 | words[key] = parts[i] || parts[0]; 553 | i++; 554 | } 555 | } 556 | const rule = new Intl.PluralRules(options.locale ?? window.locale).select(Math.floor(number)); 557 | return `${options.showNumber ? `${options.localize ? number.toLocaleString(options.locale ?? window.locale) : number} ` : ''}${words[rule]}`; 558 | }; 559 | 560 | window.numberToWords = function(num) { 561 | if (num === 0) return 'zero'; 562 | const belowTwenty = [ 563 | '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 564 | 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 565 | 'sixteen', 'seventeen', 'eighteen', 'nineteen']; 566 | 567 | const tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']; 568 | 569 | const hundreds = [ 570 | '', 'one hundred', 'two hundred', 'three hundred', 'four hundred', 'five hundred', 571 | 'six hundred', 'seven hundred', 'eight hundred', 'nine hundred']; 572 | 573 | const integerScales = [ 574 | 'thousands:thousand:thousands:thousands:thousands:thousands', 'millions:million:millions:millions:millions:millions', 'billions:billion:billions:billions:billions:billions', 'trillions:trillion:trillions:trillions:trillions:trillions', 'quadrillions:quadrillion:quadrillions:quadrillions:quadrillions:quadrillions', 575 | 'quintillions:quintillion:quintillions:quintillions:quintillions:quintillions', 'sextillions:sextillion:sextillions:sextillions:sextillions:sextillions', 'septillions:septillion:septillions:septillions:septillions:septillions', 'octillions:octillion:octillions:octillions:octillions:octillions', 'nonillions:nonillion:nonillions:nonillions:nonillions:nonillions', 576 | 'decillions:decillion:decillions:decillions:decillions:decillions', 'undecillions:undecillion:undecillions:undecillions:undecillions:undecillions', 'duodecillions:duodecillion:duodecillions:duodecillions:duodecillions:duodecillions', 'tredecillions:tredecillion:tredecillions:tredecillions:tredecillions:tredecillions', 'quattuordecillions:quattuordecillion:quattuordecillions:quattuordecillions:quattuordecillions:quattuordecillions', 577 | 'quindecillions:quindecillion:quindecillions:quindecillions:quindecillions:quindecillions', 'sexdecillions:sexdecillion:sexdecillions:sexdecillions:sexdecillions:sexdecillions', 'septendecillions:septendecillion:septendecillions:septendecillions:septendecillions:septendecillions', 'octodecillions:octodecillion:octodecillions:octodecillions:octodecillions:octodecillions', 578 | 'novemdecillions:novemdecillion:novemdecillions:novemdecillions:novemdecillions:novemdecillions', 'vigintillions:vigintillion:vigintillions:vigintillions:vigintillions:vigintillions']; 579 | 580 | const decimalScales = [ 581 | 'tenths:tenth:tenths:tenths:tenths:tenths', 'hundredths:hundredth:hundredths:hundredths:hundredths:hundredths', 'thousandths:thousandth:thousandths:thousandths:thousandths:thousandths', 'ten-thousandths:ten-thousandth:ten-thousandths:ten-thousandths:ten-thousandths:ten-thousandths', 'hundred-thousandths:hundred-thousandth:hundred-thousandths:hundred-thousandths:hundred-thousandths:hundred-thousandths', 'millionths:millionth:millionths:millionths:millionths:millionths', 582 | 'ten-millionths:ten-millionth:ten-millionths:ten-millionths:ten-millionths:ten-millionths', 'hundred-millionths:hundred-millionth:hundred-millionths:hundred-millionths:hundred-millionths:hundred-millionths', 'billionths:billionth:billionths:billionths:billionths:billionths', 'ten-billionths:ten-billionth:ten-billionths:ten-billionths:ten-billionths:ten-billionths', 'hundred-billionths:hundred-billionth:hundred-billionths:hundred-billionths:hundred-billionths:hundred-billionths', 583 | 'trillionths:trillionth:trillionths:trillionths:trillionths:trillionths', 'ten-trillionths:ten-trillionth:ten-trillionths:ten-trillionths:ten-trillionths:ten-trillionths', 'hundred-trillionths:hundred-trillionth:hundred-trillionths:hundred-trillionths:hundred-trillionths:hundred-trillionths', 'quadrillionths:quadrillionth:quadrillionths:quadrillionths:quadrillionths:quadrillionths', 'ten-quadrillionths:ten-quadrillionth:ten-quadrillionths:ten-quadrillionths:ten-quadrillionths:ten-quadrillionths', 584 | 'hundred-quadrillionths:hundred-quadrillionth:hundred-quadrillionths:hundred-quadrillionths:hundred-quadrillionths:hundred-quadrillionths', 'quintillionths:quintillionth:quintillionths:quintillionths:quintillionths:quintillionths', 'ten-quintillionths:ten-quintillionth:ten-quintillionths:ten-quintillionths:ten-quintillionths:ten-quintillionths', 'hundred-quintillionths:hundred-quintillionth:hundred-quintillionths:hundred-quintillionths:hundred-quintillionths:hundred-quintillionths', 585 | 'sextillionths:sextillionth:sextillionths:sextillionths:sextillionths:sextillionths', 'septillionths:septillionth:septillionths:septillionths:septillionths:septillionths', 'octillionths:octillionth:octillionths:octillionths:octillionths:octillionths', 'nonillionths:nonillionth:nonillionths:nonillionths:nonillionths:nonillionths', 'decillionths:decillionth:decillionths:decillionths:decillionths:decillionths', 586 | 'undecillionths:undecillionth:undecillionths:undecillionths:undecillionths:undecillionths', 'duodecillionths:duodecillionth:duodecillionths:duodecillionths:duodecillionths:duodecillionths', 'tredecillionths:tredecillionth:tredecillionths:tredecillionths:tredecillionths:tredecillionths', 'quattuordecillionths:quattuordecillionth:quattuordecillionths:quattuordecillionths:quattuordecillionths:quattuordecillionths', 'quindecillionths:quindecillionth:quindecillionths:quindecillionths:quindecillionths:quindecillionths', 587 | 'sexdecillionths:sexdecillionth:sexdecillionths:sexdecillionths:sexdecillionths:sexdecillionths', 'septendecillionths:septendecillionth:septendecillionths:septendecillionths:septendecillionths:septendecillionths', 'octodecillionths:octodecillionth:octodecillionths:octodecillionths:octodecillionths:octodecillionths', 'novemdecillionths:novemdecillionth:novemdecillionths:novemdecillionths:novemdecillionths:novemdecillionths', 'vigintillionths:vigintillionth:vigintillionths:vigintillionths:vigintillionths:vigintillionths']; 588 | 589 | let chunks = []; 590 | let currentNum = BigInt(Math.floor(num)); 591 | 592 | while (currentNum > 0n) { 593 | chunks.unshift(currentNum % 1000n); 594 | currentNum = currentNum / 1000n; 595 | } 596 | 597 | if (chunks.length === 0) chunks.push(0n); // Handle numbers less than 1 598 | 599 | let integerWords = chunks.map((chunk, index) => { 600 | chunk = Number(chunk); 601 | if (chunk === 0) return ''; 602 | const hundred = Math.floor(chunk / 100); 603 | const tenUnit = chunk % 100; 604 | const ten = Math.floor(tenUnit / 10); 605 | const unit = tenUnit % 10; 606 | 607 | let chunkText = ''; 608 | 609 | if (hundred > 0) chunkText += hundreds[hundred] + ' '; 610 | if (tenUnit >= 20) { 611 | chunkText += tens[ten] + ' '; 612 | if (unit > 0) chunkText += belowTwenty[unit]; 613 | } else if (tenUnit > 0) { 614 | chunkText += belowTwenty[tenUnit]; 615 | } 616 | 617 | if (chunk > 0 && index < chunks.length - 1) { 618 | let scale = integerScales[chunks.length - index - 2]; 619 | return chunkText.trim() + ' ' + plural(chunk, scale, {showNumber: false}); 620 | } 621 | return chunkText.trim(); 622 | }).join(' ').trim(); 623 | 624 | let decimalPart = (num - Math.floor(num)).toFixed(num.toString().split('.')?.[1]?.length).toString().slice(2); 625 | let decimalLength = decimalPart > 0 ? decimalPart.toString().replace('-', '').length : 0; 626 | 627 | return (integerWords.length > 0 ? integerWords : 'zero') + (decimalLength > 0 ? ' point ' + numberToWords(decimalPart) + ' ' + plural(decimalPart, decimalScales[decimalLength-1], {showNumber: false}) : ''); 628 | } 629 | 630 | window.toSentenceCase = function(str){ 631 | const firstLetter = str.substr(0, 1); 632 | return firstLetter.toUpperCase() + str.substr(1).toLowerCase(); 633 | } 634 | 635 | window.toTitleCase = function(str) { 636 | return str.toLowerCase().split(' ').map(function(word) { 637 | return (word.charAt(0).toUpperCase() + word.slice(1)); 638 | }).join(' '); 639 | } 640 | 641 | window.setCookie = function(key, value){ 642 | const date = new Date(); 643 | date.setTime(date.getTime() + (10 * 365 * 24 * 60 * 60 * 1000)); 644 | document.cookie = `${key}=${value};expires=${date.toUTCString()};path=/`; 645 | } 646 | 647 | window.getCookie = function(key) { 648 | let nameEQ = key + "="; 649 | let ca = document.cookie.split(';'); 650 | for (let i = 0; i < ca.length; i++) { 651 | let c = ca[i]; 652 | while (c.charAt(0) === ' ') c = c.substring(1); 653 | if (c.indexOf(nameEQ) === 0) { 654 | return decodeURIComponent(c.substring(nameEQ.length, c.length)); 655 | } 656 | } 657 | return null; 658 | } -------------------------------------------------------------------------------- /assets/js/hourpicker.js: -------------------------------------------------------------------------------- 1 | const INPUTS = $$('.hourpicker-input'); 2 | let timepickerFormat = true 3 | let currentInput = { 4 | input: null, 5 | hour: null, 6 | minute: null, 7 | } 8 | 9 | function createTimepicker() { 10 | const TIMEPICKER = document.createElement('div'); 11 | const {top, left} = currentInput.input.getBoundingClientRect() 12 | const {offsetHeight} = currentInput.input 13 | const VALUE = currentInput.input.value.split(':') 14 | 15 | TIMEPICKER.classList.add('timepicker'); 16 | TIMEPICKER.classList.add('timepicker--hourpicker'); 17 | TIMEPICKER.innerHTML = ` 18 |
19 |
20 |
21 |

Hour

22 | 23 |
24 |

:

25 |
26 |

Minute

27 | 28 |
29 |
30 |
31 | 34 | 37 |
38 |
39 | 40 | 49 | ` 50 | document.body.appendChild(TIMEPICKER); 51 | TIMEPICKER.style.top = top + window.scrollY + 9 + offsetHeight + 'px'; 52 | TIMEPICKER.style.left = left - 13 + 'px'; 53 | TIMEPICKER.classList.add('timepicker--active'); 54 | 55 | const TIMEPICKER_DONE = document.getElementById('timepicker_done') 56 | const TIMEPICKER_CANCEL = document.getElementById('timepicker_cancel') 57 | const TIMEPICKER_HOUR = document.getElementById('timepicker_hour') 58 | const TIMEPICKER_MINUTE = document.getElementById('timepicker_minute') 59 | const TIMEPICKER_FORMAT_SWITCHER = document.getElementById('timepicker_format_switcher') 60 | const TIMEPICKER_FORMAT = document.getElementById('timepicker_format') 61 | const SWITCH_TO_AM = document.getElementById('switch_to_am') 62 | const SWITCH_TO_PM = document.getElementById('switch_to_pm') 63 | 64 | SWITCH_TO_AM.addEventListener('click', () => { 65 | SWITCH_TO_PM.classList.remove('button-switcher--active') 66 | SWITCH_TO_AM.classList.add('button-switcher--active') 67 | }) 68 | 69 | SWITCH_TO_PM.addEventListener('click', () => { 70 | SWITCH_TO_AM.classList.remove('button-switcher--active') 71 | SWITCH_TO_PM.classList.add('button-switcher--active') 72 | }) 73 | 74 | TIMEPICKER_HOUR.addEventListener('input', (event) => { 75 | limitLengthHandler(event.target, 2) 76 | currentInput.hour = event.target.value 77 | if(event.target.value.length === 2) TIMEPICKER_MINUTE.focus() 78 | }) 79 | TIMEPICKER_MINUTE.addEventListener('input', (event) => { 80 | limitLengthHandler(event.target, 2) 81 | currentInput.minute = event.target.value 82 | }) 83 | 84 | TIMEPICKER_FORMAT_SWITCHER.addEventListener('input', (event) => { 85 | if(event.target.checked) { 86 | TIMEPICKER_FORMAT.style.display = 'none' 87 | timepickerFormat = false 88 | } 89 | else { 90 | TIMEPICKER_FORMAT.style.display = 'flex' 91 | timepickerFormat = true 92 | } 93 | }) 94 | 95 | TIMEPICKER_DONE.addEventListener('click', onDoneTimepicker) 96 | window.addEventListener('keydown', onDoneTimepickerEnter) 97 | 98 | TIMEPICKER_CANCEL.addEventListener('click', () => { 99 | onCloseTimepicker(); 100 | }) 101 | } 102 | 103 | function limitLengthHandler(input, limit) { 104 | if(input.value.length > limit) { 105 | input.value = input.value.slice(0, limit); 106 | } 107 | return input.value; 108 | } 109 | 110 | function onDoneTimepickerEnter (event) { 111 | if(event.key === 'Enter') { 112 | onDoneTimepicker(); 113 | } 114 | } 115 | 116 | function onDoneTimepicker () { 117 | let hours = currentInput.hour < 10 ? '0' + currentInput.hour : currentInput.hour 118 | let minutes = currentInput.minute < 10 ? '0' + currentInput.minute : currentInput.minute 119 | 120 | currentInput.input.value = `${hours > 0 ? hours : '00'}:${minutes > 0 ? minutes : '00'}` 121 | onCloseTimepicker(); 122 | window.removeEventListener('keydown', onDoneTimepickerEnter) 123 | window.removeEventListener('click', onCloseTimepickerOutside) 124 | } 125 | 126 | function onCloseTimepicker() { 127 | currentInput.input = null 128 | document.body.removeChild($('.timepicker')); 129 | window.removeEventListener('click', onCloseTimepickerOutside) 130 | } 131 | 132 | function onCloseTimepickerOutside(event) { 133 | if($('.timepicker') && !(event.composedPath().includes($('.timepicker')) || event.composedPath().includes(currentInput.input))) { 134 | onCloseTimepicker(); 135 | } 136 | } 137 | 138 | window.timepicker = (event) => { 139 | if($('.timepicker')) { 140 | onCloseTimepicker(); 141 | } else { 142 | currentInput.input = event.target 143 | createTimepicker() 144 | window.addEventListener('click', onCloseTimepickerOutside) 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /assets/js/lib/chartjs/helpers.d.ts: -------------------------------------------------------------------------------- 1 | import { Color } from '@kurkle/color'; 2 | import { P as Point$1, f as ChartArea, e as ChartEvent, C as Chart, au as ChartMeta, b as PointElement, cn as TRBL, co as TRBLCorners, aZ as FontSpec, b9 as PointStyle, ck as Color$1, cp as RoundedRect } from './chunks/helpers.core.js'; 3 | export { cg as EasingFunction, cE as MergeOptions, cL as _capitalize, cI as _deprecated, cB as _elementsEqual, cP as _isClickEvent, cD as _merger, cH as _mergerIf, cJ as _splitKey, cz as callback, cC as clone, cM as defined, cA as each, cv as finiteOrDefault, ct as isArray, cq as isFinite, cN as isFunction, cs as isNullOrUndef, cu as isObject, cF as merge, cG as mergeIf, n as noop, cK as resolveObjectKey, cO as setsEqual, cy as toDimension, cx as toPercentage, cr as uid, cw as valueOrDefault } from './chunks/helpers.core.js'; 4 | 5 | declare function isPatternOrGradient(value: unknown): value is CanvasPattern | CanvasGradient; 6 | declare function color(value: CanvasGradient): CanvasGradient; 7 | declare function color(value: CanvasPattern): CanvasPattern; 8 | declare function color(value: string | { 9 | r: number; 10 | g: number; 11 | b: number; 12 | a: number; 13 | } | [number, number, number] | [number, number, number, number]): Color; 14 | declare function getHoverColor(value: CanvasGradient): CanvasGradient; 15 | declare function getHoverColor(value: CanvasPattern): CanvasPattern; 16 | declare function getHoverColor(value: string): string; 17 | 18 | /** 19 | * Note: typedefs are auto-exported, so use a made-up `canvas` namespace where 20 | * necessary to avoid duplicates with `export * from './helpers`; see 21 | * https://github.com/microsoft/TypeScript/issues/46011 22 | */ 23 | type Point = Point$1; 24 | 25 | /** 26 | * Binary search 27 | * @param table - the table search. must be sorted! 28 | * @param value - value to find 29 | * @param cmp 30 | * @private 31 | */ 32 | declare function _lookup(table: number[], value: number, cmp?: (value: number) => boolean): { 33 | lo: number; 34 | hi: number; 35 | }; 36 | declare function _lookup(table: T[], value: number, cmp: (value: number) => boolean): { 37 | lo: number; 38 | hi: number; 39 | }; 40 | /** 41 | * Binary search 42 | * @param table - the table search. must be sorted! 43 | * @param key - property name for the value in each entry 44 | * @param value - value to find 45 | * @param last - lookup last index 46 | * @private 47 | */ 48 | declare const _lookupByKey: (table: Record[], key: string, value: number, last?: boolean) => { 49 | lo: number; 50 | hi: number; 51 | }; 52 | /** 53 | * Reverse binary search 54 | * @param table - the table search. must be sorted! 55 | * @param key - property name for the value in each entry 56 | * @param value - value to find 57 | * @private 58 | */ 59 | declare const _rlookupByKey: (table: Record[], key: string, value: number) => { 60 | lo: number; 61 | hi: number; 62 | }; 63 | /** 64 | * Return subset of `values` between `min` and `max` inclusive. 65 | * Values are assumed to be in sorted order. 66 | * @param values - sorted array of values 67 | * @param min - min value 68 | * @param max - max value 69 | */ 70 | declare function _filterBetween(values: number[], min: number, max: number): number[]; 71 | interface ArrayListener { 72 | _onDataPush?(...item: T[]): void; 73 | _onDataPop?(): void; 74 | _onDataShift?(): void; 75 | _onDataSplice?(index: number, deleteCount: number, ...items: T[]): void; 76 | _onDataUnshift?(...item: T[]): void; 77 | } 78 | /** 79 | * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', 80 | * 'unshift') and notify the listener AFTER the array has been altered. Listeners are 81 | * called on the '_onData*' callbacks (e.g. _onDataPush, etc.) with same arguments. 82 | */ 83 | declare function listenArrayEvents(array: T[], listener: ArrayListener): void; 84 | /** 85 | * Removes the given array event listener and cleanup extra attached properties (such as 86 | * the _chartjs stub and overridden methods) if array doesn't have any more listeners. 87 | */ 88 | declare function unlistenArrayEvents(array: T[], listener: ArrayListener): void; 89 | /** 90 | * @param items 91 | */ 92 | declare function _arrayUnique(items: T[]): T[]; 93 | 94 | interface SplinePoint { 95 | x: number; 96 | y: number; 97 | skip?: boolean; 98 | cp1x?: number; 99 | cp1y?: number; 100 | cp2x?: number; 101 | cp2y?: number; 102 | } 103 | declare function splineCurve(firstPoint: SplinePoint, middlePoint: SplinePoint, afterPoint: SplinePoint, t: number): { 104 | previous: SplinePoint; 105 | next: SplinePoint; 106 | }; 107 | /** 108 | * This function calculates Bézier control points in a similar way than |splineCurve|, 109 | * but preserves monotonicity of the provided data and ensures no local extremums are added 110 | * between the dataset discrete points due to the interpolation. 111 | * See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation 112 | */ 113 | declare function splineCurveMonotone(points: SplinePoint[], indexAxis?: 'x' | 'y'): void; 114 | /** 115 | * @private 116 | */ 117 | declare function _updateBezierControlPoints(points: SplinePoint[], options: any, area: ChartArea, loop: boolean, indexAxis: 'x' | 'y'): void; 118 | 119 | /** 120 | * Note: typedefs are auto-exported, so use a made-up `dom` namespace where 121 | * necessary to avoid duplicates with `export * from './helpers`; see 122 | * https://github.com/microsoft/TypeScript/issues/46011 123 | * @typedef { import("../core/core.controller").default } dom.Chart 124 | * @typedef { import('../../types').ChartEvent } ChartEvent 125 | */ 126 | /** 127 | * @private 128 | */ 129 | declare function _isDomSupported(): boolean; 130 | /** 131 | * @private 132 | */ 133 | declare function _getParentNode(domNode: HTMLCanvasElement): HTMLCanvasElement; 134 | declare function getStyle(el: HTMLElement, property: string): string; 135 | /** 136 | * Gets an event's x, y coordinates, relative to the chart area 137 | * @param event 138 | * @param chart 139 | * @returns x and y coordinates of the event 140 | */ 141 | declare function getRelativePosition(event: Event | ChartEvent | TouchEvent | MouseEvent, chart: Chart): { 142 | x: number; 143 | y: number; 144 | }; 145 | declare function getMaximumSize(canvas: HTMLCanvasElement, bbWidth?: number, bbHeight?: number, aspectRatio?: number): { 146 | width: number; 147 | height: number; 148 | }; 149 | /** 150 | * @param chart 151 | * @param forceRatio 152 | * @param forceStyle 153 | * @returns True if the canvas context size or transformation has changed. 154 | */ 155 | declare function retinaScale(chart: Chart, forceRatio: number, forceStyle?: boolean): boolean | void; 156 | /** 157 | * Detects support for options object argument in addEventListener. 158 | * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support 159 | * @private 160 | */ 161 | declare const supportsEventListenerOptions: boolean; 162 | /** 163 | * The "used" size is the final value of a dimension property after all calculations have 164 | * been performed. This method uses the computed style of `element` but returns undefined 165 | * if the computed style is not expressed in pixels. That can happen in some cases where 166 | * `element` has a size relative to its parent and this last one is not yet displayed, 167 | * for example because of `display: none` on a parent node. 168 | * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value 169 | * @returns Size in pixels or undefined if unknown. 170 | */ 171 | declare function readUsedSize(element: HTMLElement, property: 'width' | 'height'): number | undefined; 172 | 173 | declare function fontString(pixelSize: number, fontStyle: string, fontFamily: string): string; 174 | /** 175 | * Request animation polyfill 176 | */ 177 | declare const requestAnimFrame: (((callback: FrameRequestCallback) => number) & typeof requestAnimationFrame) | ((callback: any) => any); 178 | /** 179 | * Throttles calling `fn` once per animation frame 180 | * Latest arguments are used on the actual call 181 | */ 182 | declare function throttled>(fn: (...args: TArgs) => void, thisArg: any): (...args: TArgs) => void; 183 | /** 184 | * Debounces calling `fn` for `delay` ms 185 | */ 186 | declare function debounce>(fn: (...args: TArgs) => void, delay: number): (...args: TArgs) => number; 187 | /** 188 | * Converts 'start' to 'left', 'end' to 'right' and others to 'center' 189 | * @private 190 | */ 191 | declare const _toLeftRightCenter: (align: 'start' | 'end' | 'center') => "center" | "right" | "left"; 192 | /** 193 | * Returns `start`, `end` or `(start + end) / 2` depending on `align`. Defaults to `center` 194 | * @private 195 | */ 196 | declare const _alignStartEnd: (align: 'start' | 'end' | 'center', start: number, end: number) => number; 197 | /** 198 | * Returns `left`, `right` or `(left + right) / 2` depending on `align`. Defaults to `left` 199 | * @private 200 | */ 201 | declare const _textX: (align: 'left' | 'right' | 'center', left: number, right: number, rtl: boolean) => number; 202 | /** 203 | * Return start and count of visible points. 204 | * @private 205 | */ 206 | declare function _getStartAndCountOfVisiblePoints(meta: ChartMeta<'line' | 'scatter'>, points: PointElement[], animationsDisabled: boolean): { 207 | start: number; 208 | count: number; 209 | }; 210 | /** 211 | * Checks if the scale ranges have changed. 212 | * @param {object} meta - dataset meta. 213 | * @returns {boolean} 214 | * @private 215 | */ 216 | declare function _scaleRangesChanged(meta: any): boolean; 217 | 218 | /** 219 | * @private 220 | */ 221 | declare function _pointInLine(p1: Point$1, p2: Point$1, t: number, mode?: any): { 222 | x: number; 223 | y: number; 224 | }; 225 | /** 226 | * @private 227 | */ 228 | declare function _steppedInterpolation(p1: Point$1, p2: Point$1, t: number, mode: 'middle' | 'after' | unknown): { 229 | x: number; 230 | y: number; 231 | }; 232 | /** 233 | * @private 234 | */ 235 | declare function _bezierInterpolation(p1: SplinePoint, p2: SplinePoint, t: number, mode?: any): { 236 | x: number; 237 | y: number; 238 | }; 239 | 240 | declare function formatNumber(num: number, locale: string, options?: Intl.NumberFormatOptions): string; 241 | 242 | /** 243 | * @alias Chart.helpers.options 244 | * @namespace 245 | */ 246 | /** 247 | * Converts the given line height `value` in pixels for a specific font `size`. 248 | * @param value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). 249 | * @param size - The font size (in pixels) used to resolve relative `value`. 250 | * @returns The effective line height in pixels (size * 1.2 if value is invalid). 251 | * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height 252 | * @since 2.7.0 253 | */ 254 | declare function toLineHeight(value: number | string, size: number): number; 255 | /** 256 | * @param value 257 | * @param props 258 | */ 259 | declare function _readValueToProps(value: number | Record, props: K[]): Record; 260 | declare function _readValueToProps(value: number | Record, props: Record): Record; 261 | /** 262 | * Converts the given value into a TRBL object. 263 | * @param value - If a number, set the value to all TRBL component, 264 | * else, if an object, use defined properties and sets undefined ones to 0. 265 | * x / y are shorthands for same value for left/right and top/bottom. 266 | * @returns The padding values (top, right, bottom, left) 267 | * @since 3.0.0 268 | */ 269 | declare function toTRBL(value: number | TRBL | Point): Record<"top" | "right" | "bottom" | "left", number>; 270 | /** 271 | * Converts the given value into a TRBL corners object (similar with css border-radius). 272 | * @param value - If a number, set the value to all TRBL corner components, 273 | * else, if an object, use defined properties and sets undefined ones to 0. 274 | * @returns The TRBL corner values (topLeft, topRight, bottomLeft, bottomRight) 275 | * @since 3.0.0 276 | */ 277 | declare function toTRBLCorners(value: number | TRBLCorners): Record<"topLeft" | "topRight" | "bottomLeft" | "bottomRight", number>; 278 | /** 279 | * Converts the given value into a padding object with pre-computed width/height. 280 | * @param value - If a number, set the value to all TRBL component, 281 | * else, if an object, use defined properties and sets undefined ones to 0. 282 | * x / y are shorthands for same value for left/right and top/bottom. 283 | * @returns The padding values (top, right, bottom, left, width, height) 284 | * @since 2.7.0 285 | */ 286 | declare function toPadding(value?: number | TRBL): ChartArea; 287 | interface CanvasFontSpec extends FontSpec { 288 | string: string; 289 | } 290 | /** 291 | * Parses font options and returns the font object. 292 | * @param options - A object that contains font options to be parsed. 293 | * @param fallback - A object that contains fallback font options. 294 | * @return The font object. 295 | * @private 296 | */ 297 | declare function toFont(options: Partial, fallback?: Partial): { 298 | family: string; 299 | lineHeight: number; 300 | size: number; 301 | style: "normal" | "italic" | "oblique" | "initial" | "inherit"; 302 | weight: string; 303 | string: string; 304 | }; 305 | /** 306 | * Evaluates the given `inputs` sequentially and returns the first defined value. 307 | * @param inputs - An array of values, falling back to the last value. 308 | * @param context - If defined and the current value is a function, the value 309 | * is called with `context` as first argument and the result becomes the new input. 310 | * @param index - If defined and the current value is an array, the value 311 | * at `index` become the new input. 312 | * @param info - object to return information about resolution in 313 | * @param info.cacheable - Will be set to `false` if option is not cacheable. 314 | * @since 2.7.0 315 | */ 316 | declare function resolve(inputs: Array, context?: object, index?: number, info?: { 317 | cacheable: boolean; 318 | }): unknown; 319 | /** 320 | * @param minmax 321 | * @param grace 322 | * @param beginAtZero 323 | * @private 324 | */ 325 | declare function _addGrace(minmax: { 326 | min: number; 327 | max: number; 328 | }, grace: number | string, beginAtZero: boolean): { 329 | min: number; 330 | max: number; 331 | }; 332 | /** 333 | * Create a context inheriting parentContext 334 | * @param parentContext 335 | * @param context 336 | * @returns 337 | */ 338 | declare function createContext

(parentContext: P, context: T): P extends null ? T : P & T; 339 | 340 | /** 341 | * @alias Chart.helpers.math 342 | * @namespace 343 | */ 344 | declare const PI: number; 345 | declare const TAU: number; 346 | declare const PITAU: number; 347 | declare const INFINITY: number; 348 | declare const RAD_PER_DEG: number; 349 | declare const HALF_PI: number; 350 | declare const QUARTER_PI: number; 351 | declare const TWO_THIRDS_PI: number; 352 | declare const log10: (x: number) => number; 353 | declare const sign: (x: number) => number; 354 | declare function almostEquals(x: number, y: number, epsilon: number): boolean; 355 | /** 356 | * Implementation of the nice number algorithm used in determining where axis labels will go 357 | */ 358 | declare function niceNum(range: number): number; 359 | /** 360 | * Returns an array of factors sorted from 1 to sqrt(value) 361 | * @private 362 | */ 363 | declare function _factorize(value: number): number[]; 364 | declare function isNumber(n: unknown): n is number; 365 | declare function almostWhole(x: number, epsilon: number): boolean; 366 | /** 367 | * @private 368 | */ 369 | declare function _setMinAndMaxByKey(array: Record[], target: { 370 | min: number; 371 | max: number; 372 | }, property: string): void; 373 | declare function toRadians(degrees: number): number; 374 | declare function toDegrees(radians: number): number; 375 | /** 376 | * Returns the number of decimal places 377 | * i.e. the number of digits after the decimal point, of the value of this Number. 378 | * @param x - A number. 379 | * @returns The number of decimal places. 380 | * @private 381 | */ 382 | declare function _decimalPlaces(x: number): number; 383 | declare function getAngleFromPoint(centrePoint: Point$1, anglePoint: Point$1): { 384 | angle: number; 385 | distance: number; 386 | }; 387 | declare function distanceBetweenPoints(pt1: Point$1, pt2: Point$1): number; 388 | /** 389 | * Shortest distance between angles, in either direction. 390 | * @private 391 | */ 392 | declare function _angleDiff(a: number, b: number): number; 393 | /** 394 | * Normalize angle to be between 0 and 2*PI 395 | * @private 396 | */ 397 | declare function _normalizeAngle(a: number): number; 398 | /** 399 | * @private 400 | */ 401 | declare function _angleBetween(angle: number, start: number, end: number, sameAngleIsFullCircle?: boolean): boolean; 402 | /** 403 | * Limit `value` between `min` and `max` 404 | * @param value 405 | * @param min 406 | * @param max 407 | * @private 408 | */ 409 | declare function _limitValue(value: number, min: number, max: number): number; 410 | /** 411 | * @param {number} value 412 | * @private 413 | */ 414 | declare function _int16Range(value: number): number; 415 | /** 416 | * @param value 417 | * @param start 418 | * @param end 419 | * @param [epsilon] 420 | * @private 421 | */ 422 | declare function _isBetween(value: number, start: number, end: number, epsilon?: number): boolean; 423 | 424 | interface RTLAdapter { 425 | x(x: number): number; 426 | setWidth(w: number): void; 427 | textAlign(align: 'center' | 'left' | 'right'): 'center' | 'left' | 'right'; 428 | xPlus(x: number, value: number): number; 429 | leftForLtr(x: number, itemWidth: number): number; 430 | } 431 | declare function getRtlAdapter(rtl: boolean, rectX: number, width: number): RTLAdapter; 432 | declare function overrideTextDirection(ctx: CanvasRenderingContext2D, direction: 'ltr' | 'rtl'): void; 433 | declare function restoreTextDirection(ctx: CanvasRenderingContext2D, original?: [string, string]): void; 434 | 435 | declare function clearCanvas(canvas: HTMLCanvasElement, ctx?: CanvasRenderingContext2D): void; 436 | 437 | declare function clipArea(ctx: CanvasRenderingContext2D, area: ChartArea): void; 438 | 439 | declare function unclipArea(ctx: CanvasRenderingContext2D): void; 440 | 441 | interface DrawPointOptions { 442 | pointStyle: PointStyle; 443 | rotation?: number; 444 | radius: number; 445 | borderWidth: number; 446 | } 447 | 448 | declare function drawPoint(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number): void; 449 | 450 | declare function drawPointLegend(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number, w: number): void; 451 | 452 | /** 453 | * Converts the given font object into a CSS font string. 454 | * @param font a font object 455 | * @return The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font 456 | */ 457 | declare function toFontString(font: { size: number; family: string; style?: string; weight?: string }): string | null; 458 | 459 | interface RenderTextOpts { 460 | /** 461 | * The fill color of the text. If unset, the existing 462 | * fillStyle property of the canvas is unchanged. 463 | */ 464 | color?: Color$1; 465 | 466 | /** 467 | * The width of the strikethrough / underline 468 | * @default 2 469 | */ 470 | decorationWidth?: number; 471 | 472 | /** 473 | * The max width of the text in pixels 474 | */ 475 | maxWidth?: number; 476 | 477 | /** 478 | * A rotation to be applied to the canvas 479 | * This is applied after the translation is applied 480 | */ 481 | rotation?: number; 482 | 483 | /** 484 | * Apply a strikethrough effect to the text 485 | */ 486 | strikethrough?: boolean; 487 | 488 | /** 489 | * The color of the text stroke. If unset, the existing 490 | * strokeStyle property of the context is unchanged 491 | */ 492 | strokeColor?: Color$1; 493 | 494 | /** 495 | * The text stroke width. If unset, the existing 496 | * lineWidth property of the context is unchanged 497 | */ 498 | strokeWidth?: number; 499 | 500 | /** 501 | * The text alignment to use. If unset, the existing 502 | * textAlign property of the context is unchanged 503 | */ 504 | textAlign: CanvasTextAlign; 505 | 506 | /** 507 | * The text baseline to use. If unset, the existing 508 | * textBaseline property of the context is unchanged 509 | */ 510 | textBaseline: CanvasTextBaseline; 511 | 512 | /** 513 | * If specified, a translation to apply to the context 514 | */ 515 | translation?: [number, number]; 516 | 517 | /** 518 | * Underline the text 519 | */ 520 | underline?: boolean; 521 | } 522 | 523 | declare function renderText( 524 | ctx: CanvasRenderingContext2D, 525 | text: string | string[], 526 | x: number, 527 | y: number, 528 | font: CanvasFontSpec, 529 | opts?: RenderTextOpts 530 | ): void; 531 | 532 | declare function addRoundedRectPath(ctx: CanvasRenderingContext2D, rect: RoundedRect): void; 533 | 534 | export { ArrayListener, CanvasFontSpec, DrawPointOptions, HALF_PI, INFINITY, PI, PITAU, QUARTER_PI, RAD_PER_DEG, RTLAdapter, RenderTextOpts, SplinePoint, TAU, TWO_THIRDS_PI, _addGrace, _alignStartEnd, _angleBetween, _angleDiff, _arrayUnique, _bezierInterpolation, _decimalPlaces, _factorize, _filterBetween, _getParentNode, _getStartAndCountOfVisiblePoints, _int16Range, _isBetween, _isDomSupported, _limitValue, _lookup, _lookupByKey, _normalizeAngle, _pointInLine, _readValueToProps, _rlookupByKey, _scaleRangesChanged, _setMinAndMaxByKey, _steppedInterpolation, _textX, _toLeftRightCenter, _updateBezierControlPoints, addRoundedRectPath, almostEquals, almostWhole, clearCanvas, clipArea, color, createContext, debounce, distanceBetweenPoints, drawPoint, drawPointLegend, fontString, formatNumber, getAngleFromPoint, getHoverColor, getMaximumSize, getRelativePosition, getRtlAdapter, getStyle, isNumber, isPatternOrGradient, listenArrayEvents, log10, niceNum, overrideTextDirection, readUsedSize, renderText, requestAnimFrame, resolve, restoreTextDirection, retinaScale, sign, splineCurve, splineCurveMonotone, supportsEventListenerOptions, throttled, toDegrees, toFont, toFontString, toLineHeight, toPadding, toRadians, toTRBL, toTRBLCorners, unclipArea, unlistenArrayEvents }; 535 | -------------------------------------------------------------------------------- /assets/js/lib/chartjs/helpers.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Chart.js v4.0.1 3 | * https://www.chartjs.org 4 | * (c) 2022 Chart.js Contributors 5 | * Released under the MIT License 6 | */ 7 | export { H as HALF_PI, b2 as INFINITY, P as PI, b1 as PITAU, b4 as QUARTER_PI, b3 as RAD_PER_DEG, T as TAU, b5 as TWO_THIRDS_PI, R as _addGrace, X as _alignPixel, a2 as _alignStartEnd, p as _angleBetween, b6 as _angleDiff, _ as _arrayUnique, a8 as _attachContext, as as _bezierCurveTo, ap as _bezierInterpolation, ax as _boundSegment, an as _boundSegments, a5 as _capitalize, am as _computeSegments, a9 as _createResolver, aK as _decimalPlaces, aV as _deprecated, aa as _descriptors, ah as _elementsEqual, N as _factorize, aO as _filterBetween, I as _getParentNode, q as _getStartAndCountOfVisiblePoints, W as _int16Range, aj as _isBetween, ai as _isClickEvent, M as _isDomSupported, C as _isPointInArea, S as _limitValue, aN as _longestText, aP as _lookup, B as _lookupByKey, V as _measureText, aT as _merger, aU as _mergerIf, ay as _normalizeAngle, y as _parseObjectDataRadialScale, aq as _pointInLine, ak as _readValueToProps, A as _rlookupByKey, w as _scaleRangesChanged, aG as _setMinAndMaxByKey, aW as _splitKey, ao as _steppedInterpolation, ar as _steppedLineTo, aB as _textX, a1 as _toLeftRightCenter, al as _updateBezierControlPoints, au as addRoundedRectPath, aJ as almostEquals, aI as almostWhole, Q as callback, af as clearCanvas, Y as clipArea, aS as clone, c as color, j as createContext, ad as debounce, h as defined, aE as distanceBetweenPoints, at as drawPoint, aD as drawPointLegend, F as each, e as easingEffects, O as finiteOrDefault, a$ as fontString, o as formatNumber, D as getAngleFromPoint, aR as getHoverColor, G as getMaximumSize, z as getRelativePosition, az as getRtlAdapter, a_ as getStyle, b as isArray, g as isFinite, a7 as isFunction, k as isNullOrUndef, x as isNumber, i as isObject, aQ as isPatternOrGradient, l as listenArrayEvents, aM as log10, a4 as merge, ab as mergeIf, aH as niceNum, aF as noop, aA as overrideTextDirection, J as readUsedSize, Z as renderText, r as requestAnimFrame, a as resolve, f as resolveObjectKey, aC as restoreTextDirection, ae as retinaScale, ag as setsEqual, s as sign, aY as splineCurve, aZ as splineCurveMonotone, K as supportsEventListenerOptions, L as throttled, U as toDegrees, n as toDimension, a0 as toFont, aX as toFontString, b0 as toLineHeight, E as toPadding, m as toPercentage, t as toRadians, av as toTRBL, aw as toTRBLCorners, ac as uid, $ as unclipArea, u as unlistenArrayEvents, v as valueOrDefault } from './chunks/helpers.segment.js'; 8 | //# sourceMappingURL=helpers.js.map 9 | -------------------------------------------------------------------------------- /assets/js/lib/chartjs/helpers.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"helpers.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"} -------------------------------------------------------------------------------- /assets/js/lib/katex/auto-render.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var i=r[e];if(void 0!==i)return i.exports;var a=r[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var i={};return function(){n.d(i,{default:function(){return s}});var e=n(771),t=n.n(e),r=function(e,t,r){for(var n=r,i=0,a=e.length;n0&&(i.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));var l=t.findIndex((function(t){return e.startsWith(t.left)}));if(-1===(n=r(t[l].right,e,t[l].left.length)))break;var d=e.slice(0,n+t[l].right.length),s=a.test(d)?d:e.slice(t[l].left.length,n);i.push({type:"math",data:s,rawData:d,display:t[l].display}),e=e.slice(n+t[l].right.length)}return""!==e&&i.push({type:"text",data:e}),i},l=function(e,r){var n=o(e,r.delimiters);if(1===n.length&&"text"===n[0].type)return null;for(var i=document.createDocumentFragment(),a=0;a.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} 2 | -------------------------------------------------------------------------------- /assets/js/lib/lazysizes.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v5.3.2 */ 2 | 3 | !function(e){var t=function(u,D,f){"use strict";var k,H;if(function(){var e;var t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",fastLoadedClass:"ls-is-cached",iframeLoadMode:0,srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:true,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:true,ricTimeout:0,throttleDelay:125};H=u.lazySizesConfig||u.lazysizesConfig||{};for(e in t){if(!(e in H)){H[e]=t[e]}}}(),!D||!D.getElementsByClassName){return{init:function(){},cfg:H,noSupport:true}}var O=D.documentElement,i=u.HTMLPictureElement,P="addEventListener",$="getAttribute",q=u[P].bind(u),I=u.setTimeout,U=u.requestAnimationFrame||I,o=u.requestIdleCallback,j=/^picture$/i,r=["load","error","lazyincluded","_lazyloaded"],a={},G=Array.prototype.forEach,J=function(e,t){if(!a[t]){a[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")}return a[t].test(e[$]("class")||"")&&a[t]},K=function(e,t){if(!J(e,t)){e.setAttribute("class",(e[$]("class")||"").trim()+" "+t)}},Q=function(e,t){var a;if(a=J(e,t)){e.setAttribute("class",(e[$]("class")||"").replace(a," "))}},V=function(t,a,e){var i=e?P:"removeEventListener";if(e){V(t,a)}r.forEach(function(e){t[i](e,a)})},X=function(e,t,a,i,r){var n=D.createEvent("Event");if(!a){a={}}a.instance=k;n.initEvent(t,!i,!r);n.detail=a;e.dispatchEvent(n);return n},Y=function(e,t){var a;if(!i&&(a=u.picturefill||H.pf)){if(t&&t.src&&!e[$]("srcset")){e.setAttribute("srcset",t.src)}a({reevaluate:true,elements:[e]})}else if(t&&t.src){e.src=t.src}},Z=function(e,t){return(getComputedStyle(e,null)||{})[t]},s=function(e,t,a){a=a||e.offsetWidth;while(a49?function(){o(t,{timeout:n});if(n!==H.ricTimeout){n=H.ricTimeout}}:te(function(){I(t)},true);return function(e){var t;if(e=e===true){n=33}if(a){return}a=true;t=r-(f.now()-i);if(t<0){t=0}if(e||t<9){s()}else{I(s,t)}}},ie=function(e){var t,a;var i=99;var r=function(){t=null;e()};var n=function(){var e=f.now()-a;if(e0;if(r&&Z(i,"overflow")!="visible"){a=i.getBoundingClientRect();r=C>a.left&&pa.top-1&&g500&&O.clientWidth>500?500:370:H.expand;k._defEx=u;f=u*H.expFactor;c=H.hFac;A=null;if(w2&&h>2&&!D.hidden){w=f;N=0}else if(h>1&&N>1&&M<6){w=u}else{w=_}}if(l!==n){y=innerWidth+n*c;z=innerHeight+n;s=n*-1;l=n}a=d[t].getBoundingClientRect();if((b=a.bottom)>=s&&(g=a.top)<=z&&(C=a.right)>=s*c&&(p=a.left)<=y&&(b||C||p||g)&&(H.loadHidden||x(d[t]))&&(m&&M<3&&!o&&(h<3||N<4)||W(d[t],n))){R(d[t]);r=true;if(M>9){break}}else if(!r&&m&&!i&&M<4&&N<4&&h>2&&(v[0]||H.preloadAfterLoad)&&(v[0]||!o&&(b||C||p||g||d[t][$](H.sizesAttr)!="auto"))){i=v[0]||d[t]}}if(i&&!r){R(i)}}};var a=ae(t);var S=function(e){var t=e.target;if(t._lazyCache){delete t._lazyCache;return}L(e);K(t,H.loadedClass);Q(t,H.loadingClass);V(t,B);X(t,"lazyloaded")};var i=te(S);var B=function(e){i({target:e.target})};var T=function(e,t){var a=e.getAttribute("data-load-mode")||H.iframeLoadMode;if(a==0){e.contentWindow.location.replace(t)}else if(a==1){e.src=t}};var F=function(e){var t;var a=e[$](H.srcsetAttr);if(t=H.customMedia[e[$]("data-media")||e[$]("media")]){e.setAttribute("media",t)}if(a){e.setAttribute("srcset",a)}};var s=te(function(t,e,a,i,r){var n,s,o,l,u,f;if(!(u=X(t,"lazybeforeunveil",e)).defaultPrevented){if(i){if(a){K(t,H.autosizesClass)}else{t.setAttribute("sizes",i)}}s=t[$](H.srcsetAttr);n=t[$](H.srcAttr);if(r){o=t.parentNode;l=o&&j.test(o.nodeName||"")}f=e.firesLoad||"src"in t&&(s||n||l);u={target:t};K(t,H.loadingClass);if(f){clearTimeout(c);c=I(L,2500);V(t,B,true)}if(l){G.call(o.getElementsByTagName("source"),F)}if(s){t.setAttribute("srcset",s)}else if(n&&!l){if(d.test(t.nodeName)){T(t,n)}else{t.src=n}}if(r&&(s||l)){Y(t,{src:n})}}if(t._lazyRace){delete t._lazyRace}Q(t,H.lazyClass);ee(function(){var e=t.complete&&t.naturalWidth>1;if(!f||e){if(e){K(t,H.fastLoadedClass)}S(u);t._lazyCache=true;I(function(){if("_lazyCache"in t){delete t._lazyCache}},9)}if(t.loading=="lazy"){M--}},true)});var R=function(e){if(e._lazyRace){return}var t;var a=n.test(e.nodeName);var i=a&&(e[$](H.sizesAttr)||e[$]("sizes"));var r=i=="auto";if((r||!m)&&a&&(e[$]("src")||e.srcset)&&!e.complete&&!J(e,H.errorClass)&&J(e,H.lazyClass)){return}t=X(e,"lazyunveilread").detail;if(r){re.updateElem(e,true,e.offsetWidth)}e._lazyRace=true;M++;s(e,t,r,i,a)};var r=ie(function(){H.loadMode=3;a()});var o=function(){if(H.loadMode==3){H.loadMode=2}r()};var l=function(){if(m){return}if(f.now()-e<999){I(l,999);return}m=true;H.loadMode=3;a();q("scroll",o,true)};return{_:function(){e=f.now();k.elements=D.getElementsByClassName(H.lazyClass);v=D.getElementsByClassName(H.lazyClass+" "+H.preloadClass);q("scroll",a,true);q("resize",a,true);q("pageshow",function(e){if(e.persisted){var t=D.querySelectorAll("."+H.loadingClass);if(t.length&&t.forEach){U(function(){t.forEach(function(e){if(e.complete){R(e)}})})}}});if(u.MutationObserver){new MutationObserver(a).observe(O,{childList:true,subtree:true,attributes:true})}else{O[P]("DOMNodeInserted",a,true);O[P]("DOMAttrModified",a,true);setInterval(a,999)}q("hashchange",a,true);["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){D[P](e,a,true)});if(/d$|^c/.test(D.readyState)){l()}else{q("load",l);D[P]("DOMContentLoaded",a);I(l,2e4)}if(k.elements.length){t();ee._lsFlush()}else{a()}},checkElems:a,unveil:R,_aLSL:o}}(),re=function(){var a;var n=te(function(e,t,a,i){var r,n,s;e._lazysizesWidth=i;i+="px";e.setAttribute("sizes",i);if(j.test(t.nodeName||"")){r=t.getElementsByTagName("source");for(n=0,s=r.length;n { 4 | const OPTION_HEAD = option.querySelector('.calculator-content-head') 5 | 6 | OPTION_HEAD.addEventListener('click', (event) => { 7 | 8 | if(!event.composedPath().includes($('.js-add-button'))) { 9 | option.classList.toggle('calculator-content--active') 10 | } 11 | }) 12 | }) -------------------------------------------------------------------------------- /assets/js/themes.js: -------------------------------------------------------------------------------- 1 | const setActiveThemeButton = (theme) => { 2 | document.querySelectorAll('.header-popup__button').forEach(button => { 3 | if(button.classList.contains(`${theme}-theme`)) button.classList.add('header-popup__button--active') 4 | else button.classList.remove('header-popup__button--active') 5 | }) 6 | } 7 | 8 | switch (localStorage.getItem('theme')) { 9 | case 'light': 10 | document.documentElement.classList = ''; 11 | console.log('Theme: Light'); 12 | localStorage.setItem('theme', 'light'); 13 | window.addEventListener('DOMContentLoaded', () => { 14 | setActiveThemeButton('light') 15 | }) 16 | break; 17 | case 'dark': 18 | document.documentElement.classList = 'dark'; 19 | console.log('Theme: Dark'); 20 | localStorage.setItem('theme', 'dark'); 21 | window.addEventListener('DOMContentLoaded', () => { 22 | setActiveThemeButton('dark') 23 | }) 24 | break; 25 | case 'system': 26 | default: 27 | document.documentElement.classList = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : ''; 28 | console.log('Theme: System'); 29 | localStorage.setItem('theme', 'system'); 30 | window.addEventListener('DOMContentLoaded', () => { 31 | setActiveThemeButton('system') 32 | }) 33 | } -------------------------------------------------------------------------------- /assets/js/timepicker.js: -------------------------------------------------------------------------------- 1 | const INPUTS = $$('.timepicker-input'); 2 | let timepickerFormat = true 3 | let currentInput = { 4 | input: null, 5 | hour: null, 6 | minute: null, 7 | second: null, 8 | } 9 | 10 | function createTimepicker() { 11 | const TIMEPICKER = document.createElement('div'); 12 | const {top, left} = currentInput.input.getBoundingClientRect() 13 | const {offsetHeight} = currentInput.input 14 | const VALUE = currentInput.input.value.split(':') 15 | 16 | TIMEPICKER.classList.add('timepicker'); 17 | TIMEPICKER.innerHTML = ` 18 |

19 |
20 |
21 |

Hour

22 | 23 |
24 |

:

25 |
26 |

Minute

27 | 28 |
29 |

:

30 |
31 |

Second

32 | 33 |
34 |
35 |
36 | 39 | 42 |
43 |
44 | 45 | 54 | ` 55 | document.body.appendChild(TIMEPICKER); 56 | TIMEPICKER.style.top = top + window.scrollY + 9 + offsetHeight + 'px'; 57 | TIMEPICKER.style.left = left - 13 + 'px'; 58 | TIMEPICKER.classList.add('timepicker--active'); 59 | 60 | const TIMEPICKER_DONE = document.getElementById('timepicker_done') 61 | const TIMEPICKER_CANCEL = document.getElementById('timepicker_cancel') 62 | const TIMEPICKER_HOUR = document.getElementById('timepicker_hour') 63 | const TIMEPICKER_MINUTE = document.getElementById('timepicker_minute') 64 | const TIMEPICKER_SECOND = document.getElementById('timepicker_second') 65 | const TIMEPICKER_FORMAT_SWITCHER = document.getElementById('timepicker_format_switcher') 66 | const TIMEPICKER_FORMAT = document.getElementById('timepicker_format') 67 | const SWITCH_TO_AM = document.getElementById('switch_to_am') 68 | const SWITCH_TO_PM = document.getElementById('switch_to_pm') 69 | 70 | SWITCH_TO_AM.addEventListener('click', () => { 71 | SWITCH_TO_PM.classList.remove('button-switcher--active') 72 | SWITCH_TO_AM.classList.add('button-switcher--active') 73 | }) 74 | 75 | SWITCH_TO_PM.addEventListener('click', () => { 76 | SWITCH_TO_AM.classList.remove('button-switcher--active') 77 | SWITCH_TO_PM.classList.add('button-switcher--active') 78 | }) 79 | 80 | TIMEPICKER_HOUR.addEventListener('input', (event) => { 81 | limitLengthHandler(event.target, 2) 82 | currentInput.hour = event.target.value 83 | if(event.target.value.length === 2) TIMEPICKER_MINUTE.focus() 84 | }) 85 | TIMEPICKER_MINUTE.addEventListener('input', (event) => { 86 | limitLengthHandler(event.target, 2) 87 | currentInput.minute = event.target.value 88 | if(event.target.value.length === 2) TIMEPICKER_SECOND.focus() 89 | }) 90 | TIMEPICKER_SECOND.addEventListener('input', (event) => { 91 | currentInput.second = event.target.value 92 | limitLengthHandler(event.target, 2) 93 | }) 94 | 95 | TIMEPICKER_FORMAT_SWITCHER.addEventListener('input', (event) => { 96 | if(event.target.checked) { 97 | TIMEPICKER_FORMAT.style.display = 'none' 98 | timepickerFormat = false 99 | } 100 | else { 101 | TIMEPICKER_FORMAT.style.display = 'flex' 102 | timepickerFormat = true 103 | } 104 | }) 105 | 106 | TIMEPICKER_DONE.addEventListener('click', onDoneTimepicker) 107 | window.addEventListener('keydown', onDoneTimepickerEnter) 108 | 109 | TIMEPICKER_CANCEL.addEventListener('click', () => { 110 | onCloseTimepicker(); 111 | }) 112 | } 113 | 114 | function limitLengthHandler(input, limit) { 115 | if(input.value.length > limit) { 116 | input.value = input.value.slice(0, limit); 117 | } 118 | return input.value; 119 | } 120 | 121 | function onDoneTimepickerEnter (event) { 122 | if(event.key === 'Enter') { 123 | onDoneTimepicker(); 124 | } 125 | } 126 | 127 | function onDoneTimepicker () { 128 | let hours = currentInput.hour < 10 ? '0' + currentInput.hour : currentInput.hour 129 | let minutes = currentInput.minute < 10 ? '0' + currentInput.minute : currentInput.minute 130 | let seconds = currentInput.second < 10 ? '0' + currentInput.second : currentInput.second 131 | 132 | currentInput.input.value = `${hours > 0 ? hours : '00'}:${minutes > 0 ? minutes : '00'}:${seconds > 0 ? seconds : '00'}` 133 | onCloseTimepicker(); 134 | window.removeEventListener('keydown', onDoneTimepickerEnter) 135 | window.removeEventListener('click', onCloseTimepickerOutside) 136 | } 137 | 138 | function onCloseTimepicker() { 139 | currentInput.input = null 140 | document.body.removeChild($('.timepicker')); 141 | window.removeEventListener('click', onCloseTimepickerOutside) 142 | } 143 | 144 | function onCloseTimepickerOutside(event) { 145 | if($('.timepicker') && !(event.composedPath().includes($('.timepicker')) || event.composedPath().includes(currentInput.input))) { 146 | onCloseTimepicker(); 147 | } 148 | } 149 | 150 | window.timepicker = (event) => { 151 | if($('.timepicker')) { 152 | onCloseTimepicker(); 153 | } else { 154 | currentInput.input = event.target 155 | createTimepicker() 156 | window.addEventListener('click', onCloseTimepickerOutside) 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /ci_binary_calculator.php: -------------------------------------------------------------------------------- 1 | Binary Calculator
'; 20 | } 21 | 22 | 23 | add_shortcode( 'ci_binary_calculator', 'display_calcio_ci_binary_calculator' ); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Binary Calculator 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 |
28 |
29 |
30 | 31 | 32 |
33 |
34 |
35 |
43 |
44 | 51 | 57 | 63 | 69 |
70 |
71 |
79 |
80 |
81 |
82 |
90 |
91 |
99 |
100 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
129 |
130 |
131 |
132 |
133 |
134 | 135 | 139 | 140 |

There was an error with your calculation.

141 |
142 |
143 |
144 |

Answer

145 |
146 |

101110110

147 |
148 |
149 | 150 |
151 |
152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 |
Answer
Binary to Decimal10101010 = 170
Decimal to Binary170 = 10101010
169 |
170 |
171 |
172 |
173 |
174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /plugin.php: -------------------------------------------------------------------------------- 1 | Binary Calculator
'; 20 | } 21 | 22 | add_shortcode( 'ci_binary_calculator', 'display_ci_binary_calculator' ); -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Binary Calculator Widget for WordPress 2 | 3 | Binary calculator for binary to decimal conversion, decimal to binary conversion, binary operations – addition, subtraction, multiplication, division. 4 | 5 | ![Binary Calculator Input Form](/assets/images/screenshot-1.png "Binary Calculator Input Form") 6 | 7 | ## Installation 8 | 9 | 1. [Download](https://github.com/pub-calculator-io/binary-calculator/archive/refs/heads/master.zip) the ZIP file of this repository. 10 | 2. Upload the /binary-calculator-master/ folder to the /wp-content/plugins/ directory. 11 | 3. Activate the [Binary Calculator](https://www.calculator.io/binary-calculator/ "Binary Calculator Homepage") plugin through the "Plugins" menu in WordPress. 12 | 13 | ## Usage 14 | * Add the shortcode `[ci_binary_calculator]` to your page, post or sidebar. 15 | * Or add the following code: `` to your template where you would like the Binary Calculator to appear. 16 | 17 | ## Libraries in Use 18 | 1. https://mathjs.org/ 19 | 2. https://katex.org/ 20 | 3. https://github.com/aFarkas/lazysizes 21 | 4. https://github.com/RobinHerbots/Inputmask 22 | 5. https://air-datepicker.com/ 23 | 6. https://www.chartjs.org/ 24 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === CI Binary calculator === 2 | Contributors: calculatorio 3 | Tags: binary calculator, binary arithmetic, add binary numbers, binary addition online, binary subtraction tool, binary math calculator, binary to decimal conversion, calculate binary equations, online binary computation, bitwise operations calculator 4 | Requires at least: 5.0 5 | Tested up to: 6.4.0 6 | Stable tag: 1.0.0 7 | License: GPLv2 or later 8 | License URI: https://www.gnu.org/licenses/gpl-2.0.html 9 | 10 | Binary calculator for binary to decimal conversion, decimal to binary conversion, binary operations – addition, subtraction, multiplication, division. 11 | 12 | [https://www.calculator.io/binary-calculator/](https://www.calculator.io/binary-calculator/) 13 | 14 | == Usage == 15 | 16 | Add the Binary Calculator shortcode to your page, post or sidebar: 17 | 18 | `[ci_binary_calculator]` 19 | 20 | Add the following code to your template where you would like the Binary Calculator to appear: 21 | 22 | `` 23 | 24 | == Screenshots == 25 | 26 | 1. The Binary Calculator Input Form. 27 | 28 | == Installation == 29 | 30 | 1. Upload the Binary Calculator /ci_binary_calculator/ folder to the /wp-content/plugins/ directory. 31 | 2. Activate the Binary Calculator plugin through the "Plugins" menu in WordPress. 32 | 33 | == Changelog == 34 | 35 | = 1.0.0 = 36 | * Initial release of Binary Calculator 37 | --------------------------------------------------------------------------------