<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.davidl.me/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=David</id>
	<title>David&#039;s Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.davidl.me/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=David"/>
	<link rel="alternate" type="text/html" href="https://wiki.davidl.me/view/Special:Contributions/David"/>
	<updated>2026-05-29T15:21:56Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Investing&amp;diff=7208</id>
		<title>Investing</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Investing&amp;diff=7208"/>
		<updated>2026-05-10T04:09:12Z</updated>

		<summary type="html">&lt;p&gt;David: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In general, you should save money in the following accounts in order:&lt;br /&gt;
&lt;br /&gt;
# 401k, 403b, or thrift savings&lt;br /&gt;
# Traditional or Roth IRA (up to IRS limit)&lt;br /&gt;
# Investing account&lt;br /&gt;
# High-yield Savings, Cash account, or CD&lt;br /&gt;
# Checking account&lt;br /&gt;
&lt;br /&gt;
* 1-3 will be tax-advantaged (either tax-free or tax-deferred) since they are retirement accounts&lt;br /&gt;
* 4-6 will not be tax-advantaged&lt;br /&gt;
&lt;br /&gt;
==401(k)/403(b)==&lt;br /&gt;
A 401(k) or 403(b) is an employer-sponsored retirement plan.&amp;lt;br&amp;gt;&lt;br /&gt;
That means, it is managed by a company cooperating with your employer.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for a for-profit company, you will have a 401k.&lt;br /&gt;
If you work for a public school or non-profit company, you get a 403b.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for the federal government, you will have a thrift savings plan.&amp;lt;br&amp;gt;&lt;br /&gt;
For the most part, 401k and 403b rules are identical.&lt;br /&gt;
&lt;br /&gt;
* Employees can contribute up to $19,500 for 2020 ($19,000 in 2019) [https://www.irs.gov/retirement-plans/plan-participant-employee/retirement-topics-401k-and-profit-sharing-plan-contribution-limits]&lt;br /&gt;
** These are called &amp;quot;elective deferrals&amp;quot; which are tax-deferred. You may also contribute after-tax deferrals subject to the total maximum contribution below.&lt;br /&gt;
* In total, you can add up to $57,000 to your 401k each year, or up to 100% of your income, whichever is lower. This includes both your contributions and your employer&#039;s contributions&lt;br /&gt;
&lt;br /&gt;
==Individual Retirement Account (IRA)==&lt;br /&gt;
A tax-advantaged retirement account you can control.&amp;lt;br&amp;gt;&lt;br /&gt;
The IRS allows you to deposit up to $6000 ($7000 if 50 or older) per year or up to your income, whichever is lower.&lt;br /&gt;
Note that this limit is for all your IRAs combined.&lt;br /&gt;
Typically, you should save in a Roth IRA unless you surpass the income limit.&lt;br /&gt;
If you&#039;re not eligible for the Roth IRA, you may consider the backdoor Roth IRA.&lt;br /&gt;
&lt;br /&gt;
===Traditional IRA===&lt;br /&gt;
In a traditional IRA, you deposit pre-tax money (see notes).&lt;br /&gt;
Thus, your deposit counts as a tax-deduction.&lt;br /&gt;
You pay taxes when you withdraw your money.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* Early withdraws (before age 59.5) are subject to a 10% penalty plus taxes&lt;br /&gt;
* You must start taking required minimum distributions (RMDs) at age 72&lt;br /&gt;
* No more contributions after age 70.5&lt;br /&gt;
* While there are no income limits to contributing to a traditional IRA, there are income limits to deducting from your taxes&lt;br /&gt;
** See [https://www.irs.gov/retirement-plans/ira-deduction-limits IRA Deduction Limits]&lt;br /&gt;
** To avoid being double taxed on your Traditional IRA contributions, be sure to complete [https://www.irs.gov/forms-pubs/about-form-8606 IRS Form 8606]&lt;br /&gt;
&lt;br /&gt;
===Roth IRA===&lt;br /&gt;
In a Roth IRA, you deposit post-tax money. However, your money grows tax-free.&amp;lt;br&amp;gt;&lt;br /&gt;
There is an income limit to the Roth IRA of $124,000 in 2020.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* No required minimum distributions on your own Roth IRAs&lt;br /&gt;
** There are RMDs on inherited Roth IRAs&lt;br /&gt;
* You can withdraw your contributions (but not earnings) without penalty&lt;br /&gt;
** Note that any further contributions will count towards your annual limit so you cannot &amp;quot;borrow&amp;quot; from your Roth IRA.&lt;br /&gt;
* No age limits on contributions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Backdoor Roth IRA===&lt;br /&gt;
If you are a high-earner and believe you will earn more money in retirement,&lt;br /&gt;
you may want to do a backdoor Roth IRA to grow your retirement account tax-free rather than tax-deferred.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea&lt;br /&gt;
* Contribute to a traditional IRA&lt;br /&gt;
* Convert the traditional IRA into a Roth IRA&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* To avoid tax complications, you should eliminate all other pre-tax IRAs beforehand by rolling them over to a 401k. Otherwise, you will be subject to the pro-rata rule.&lt;br /&gt;
&lt;br /&gt;
===Mega Backdoor Roth===&lt;br /&gt;
Requirements: Your 401k allows after-tax contributions and non-hardship withdrawals.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea: &lt;br /&gt;
* Max out after-tax contributions to your 401k&lt;br /&gt;
* Rollover or withdraw the after-tax portion to a Roth IRA or Roth 401K&lt;br /&gt;
&lt;br /&gt;
==ETFs==&lt;br /&gt;
{{main | Exchange-traded fund}}&lt;br /&gt;
&lt;br /&gt;
Exchange-traded funds. Typically these will have a fee called an expense ratio.&amp;lt;br&amp;gt;&lt;br /&gt;
The expense ratio is measured in basis points.&amp;lt;br&amp;gt;&lt;br /&gt;
25 basis points is an annual fee of 0.25%.&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Investing&amp;diff=7207</id>
		<title>Investing</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Investing&amp;diff=7207"/>
		<updated>2026-05-10T04:09:02Z</updated>

		<summary type="html">&lt;p&gt;David: /* Brokerages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In general, you should save money in the following accounts in order:&lt;br /&gt;
&lt;br /&gt;
# 401k, 403b, or thrift savings&lt;br /&gt;
# Traditional or Roth IRA (up to IRS limit)&lt;br /&gt;
# Investing account&lt;br /&gt;
# High-yield Savings, Cash account, or CD&lt;br /&gt;
# Checking account&lt;br /&gt;
&lt;br /&gt;
* 1-3 will be tax-advantaged (either tax-free or tax-deferred) since they are retirement accounts&lt;br /&gt;
* 4-6 will not be tax-advantaged&lt;br /&gt;
&lt;br /&gt;
==401(k)/403(b)==&lt;br /&gt;
A 401(k) or 403(b) is an employer-sponsored retirement plan.&amp;lt;br&amp;gt;&lt;br /&gt;
That means, it is managed by a company cooperating with your employer.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for a for-profit company, you will have a 401k.&lt;br /&gt;
If you work for a public school or non-profit company, you get a 403b.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for the federal government, you will have a thrift savings plan.&amp;lt;br&amp;gt;&lt;br /&gt;
For the most part, 401k and 403b rules are identical.&lt;br /&gt;
&lt;br /&gt;
* Employees can contribute up to $19,500 for 2020 ($19,000 in 2019) [https://www.irs.gov/retirement-plans/plan-participant-employee/retirement-topics-401k-and-profit-sharing-plan-contribution-limits]&lt;br /&gt;
** These are called &amp;quot;elective deferrals&amp;quot; which are tax-deferred. You may also contribute after-tax deferrals subject to the total maximum contribution below.&lt;br /&gt;
* In total, you can add up to $57,000 to your 401k each year, or up to 100% of your income, whichever is lower. This includes both your contributions and your employer&#039;s contributions&lt;br /&gt;
&lt;br /&gt;
==Individual Retirement Account (IRA)==&lt;br /&gt;
A tax-advantaged retirement account you can control.&amp;lt;br&amp;gt;&lt;br /&gt;
The IRS allows you to deposit up to $6000 ($7000 if 50 or older) per year or up to your income, whichever is lower.&lt;br /&gt;
Note that this limit is for all your IRAs combined.&lt;br /&gt;
Typically, you should save in a Roth IRA unless you surpass the income limit.&lt;br /&gt;
If you&#039;re not eligible for the Roth IRA, you may consider the backdoor Roth IRA.&lt;br /&gt;
&lt;br /&gt;
===Traditional IRA===&lt;br /&gt;
In a traditional IRA, you deposit pre-tax money (see notes).&lt;br /&gt;
Thus, your deposit counts as a tax-deduction.&lt;br /&gt;
You pay taxes when you withdraw your money.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* Early withdraws (before age 59.5) are subject to a 10% penalty plus taxes&lt;br /&gt;
* You must start taking required minimum distributions (RMDs) at age 72&lt;br /&gt;
* No more contributions after age 70.5&lt;br /&gt;
* While there are no income limits to contributing to a traditional IRA, there are income limits to deducting from your taxes&lt;br /&gt;
** See [https://www.irs.gov/retirement-plans/ira-deduction-limits IRA Deduction Limits]&lt;br /&gt;
** To avoid being double taxed on your Traditional IRA contributions, be sure to complete [https://www.irs.gov/forms-pubs/about-form-8606 IRS Form 8606]&lt;br /&gt;
&lt;br /&gt;
===Roth IRA===&lt;br /&gt;
In a Roth IRA, you deposit post-tax money. However, your money grows tax-free.&amp;lt;br&amp;gt;&lt;br /&gt;
There is an income limit to the Roth IRA of $124,000 in 2020.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* No required minimum distributions on your own Roth IRAs&lt;br /&gt;
** There are RMDs on inherited Roth IRAs&lt;br /&gt;
* You can withdraw your contributions (but not earnings) without penalty&lt;br /&gt;
** Note that any further contributions will count towards your annual limit so you cannot &amp;quot;borrow&amp;quot; from your Roth IRA.&lt;br /&gt;
* No age limits on contributions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Backdoor Roth IRA===&lt;br /&gt;
If you are a high-earner and believe you will earn more money in retirement,&lt;br /&gt;
you may want to do a backdoor Roth IRA to grow your retirement account tax-free rather than tax-deferred.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea&lt;br /&gt;
* Contribute to a traditional IRA&lt;br /&gt;
* Convert the traditional IRA into a Roth IRA&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* To avoid tax complications, you should eliminate all other pre-tax IRAs beforehand by rolling them over to a 401k. Otherwise, you will be subject to the pro-rata rule.&lt;br /&gt;
&lt;br /&gt;
===Mega Backdoor Roth===&lt;br /&gt;
Requirements: Your 401k allows after-tax contributions and non-hardship withdrawals.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea: &lt;br /&gt;
* Max out after-tax contributions to your 401k&lt;br /&gt;
* Rollover or withdraw the after-tax portion to a Roth IRA or Roth 401K&lt;br /&gt;
&lt;br /&gt;
==ETFs==&lt;br /&gt;
{{main | Exchange-traded fund}}&lt;br /&gt;
&lt;br /&gt;
Exchange-traded funds. Typically these will have a fee called an expense ratio.&amp;lt;br&amp;gt;&lt;br /&gt;
The expense ratio is measured in basis points.&amp;lt;br&amp;gt;&lt;br /&gt;
25 basis points is an annual fee of 0.25%.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{reflist|refs=&lt;br /&gt;
&amp;lt;ref name=&amp;quot;wealthfrontfdic&amp;quot;&amp;gt;https://www.wealthfront.com/blog/wealthfront-fdic-insurance/&amp;lt;/ref&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Investing&amp;diff=7206</id>
		<title>Investing</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Investing&amp;diff=7206"/>
		<updated>2026-05-04T06:08:43Z</updated>

		<summary type="html">&lt;p&gt;David: /* ETFs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In general, you should save money in the following accounts in order:&lt;br /&gt;
&lt;br /&gt;
# 401k, 403b, or thrift savings&lt;br /&gt;
# Traditional or Roth IRA (up to IRS limit)&lt;br /&gt;
# Investing account&lt;br /&gt;
# High-yield Savings, Cash account, or CD&lt;br /&gt;
# Checking account&lt;br /&gt;
&lt;br /&gt;
* 1-3 will be tax-advantaged (either tax-free or tax-deferred) since they are retirement accounts&lt;br /&gt;
* 4-6 will not be tax-advantaged&lt;br /&gt;
&lt;br /&gt;
==401(k)/403(b)==&lt;br /&gt;
A 401(k) or 403(b) is an employer-sponsored retirement plan.&amp;lt;br&amp;gt;&lt;br /&gt;
That means, it is managed by a company cooperating with your employer.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for a for-profit company, you will have a 401k.&lt;br /&gt;
If you work for a public school or non-profit company, you get a 403b.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for the federal government, you will have a thrift savings plan.&amp;lt;br&amp;gt;&lt;br /&gt;
For the most part, 401k and 403b rules are identical.&lt;br /&gt;
&lt;br /&gt;
* Employees can contribute up to $19,500 for 2020 ($19,000 in 2019) [https://www.irs.gov/retirement-plans/plan-participant-employee/retirement-topics-401k-and-profit-sharing-plan-contribution-limits]&lt;br /&gt;
** These are called &amp;quot;elective deferrals&amp;quot; which are tax-deferred. You may also contribute after-tax deferrals subject to the total maximum contribution below.&lt;br /&gt;
* In total, you can add up to $57,000 to your 401k each year, or up to 100% of your income, whichever is lower. This includes both your contributions and your employer&#039;s contributions&lt;br /&gt;
&lt;br /&gt;
==Individual Retirement Account (IRA)==&lt;br /&gt;
A tax-advantaged retirement account you can control.&amp;lt;br&amp;gt;&lt;br /&gt;
The IRS allows you to deposit up to $6000 ($7000 if 50 or older) per year or up to your income, whichever is lower.&lt;br /&gt;
Note that this limit is for all your IRAs combined.&lt;br /&gt;
Typically, you should save in a Roth IRA unless you surpass the income limit.&lt;br /&gt;
If you&#039;re not eligible for the Roth IRA, you may consider the backdoor Roth IRA.&lt;br /&gt;
&lt;br /&gt;
===Traditional IRA===&lt;br /&gt;
In a traditional IRA, you deposit pre-tax money (see notes).&lt;br /&gt;
Thus, your deposit counts as a tax-deduction.&lt;br /&gt;
You pay taxes when you withdraw your money.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* Early withdraws (before age 59.5) are subject to a 10% penalty plus taxes&lt;br /&gt;
* You must start taking required minimum distributions (RMDs) at age 72&lt;br /&gt;
* No more contributions after age 70.5&lt;br /&gt;
* While there are no income limits to contributing to a traditional IRA, there are income limits to deducting from your taxes&lt;br /&gt;
** See [https://www.irs.gov/retirement-plans/ira-deduction-limits IRA Deduction Limits]&lt;br /&gt;
** To avoid being double taxed on your Traditional IRA contributions, be sure to complete [https://www.irs.gov/forms-pubs/about-form-8606 IRS Form 8606]&lt;br /&gt;
&lt;br /&gt;
===Roth IRA===&lt;br /&gt;
In a Roth IRA, you deposit post-tax money. However, your money grows tax-free.&amp;lt;br&amp;gt;&lt;br /&gt;
There is an income limit to the Roth IRA of $124,000 in 2020.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* No required minimum distributions on your own Roth IRAs&lt;br /&gt;
** There are RMDs on inherited Roth IRAs&lt;br /&gt;
* You can withdraw your contributions (but not earnings) without penalty&lt;br /&gt;
** Note that any further contributions will count towards your annual limit so you cannot &amp;quot;borrow&amp;quot; from your Roth IRA.&lt;br /&gt;
* No age limits on contributions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Backdoor Roth IRA===&lt;br /&gt;
If you are a high-earner and believe you will earn more money in retirement,&lt;br /&gt;
you may want to do a backdoor Roth IRA to grow your retirement account tax-free rather than tax-deferred.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea&lt;br /&gt;
* Contribute to a traditional IRA&lt;br /&gt;
* Convert the traditional IRA into a Roth IRA&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* To avoid tax complications, you should eliminate all other pre-tax IRAs beforehand by rolling them over to a 401k. Otherwise, you will be subject to the pro-rata rule.&lt;br /&gt;
&lt;br /&gt;
===Mega Backdoor Roth===&lt;br /&gt;
Requirements: Your 401k allows after-tax contributions and non-hardship withdrawals.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea: &lt;br /&gt;
* Max out after-tax contributions to your 401k&lt;br /&gt;
* Rollover or withdraw the after-tax portion to a Roth IRA or Roth 401K&lt;br /&gt;
&lt;br /&gt;
==ETFs==&lt;br /&gt;
{{main | Exchange-traded fund}}&lt;br /&gt;
&lt;br /&gt;
Exchange-traded funds. Typically these will have a fee called an expense ratio.&amp;lt;br&amp;gt;&lt;br /&gt;
The expense ratio is measured in basis points.&amp;lt;br&amp;gt;&lt;br /&gt;
25 basis points is an annual fee of 0.25%.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Brokerages==&lt;br /&gt;
&lt;br /&gt;
===Fidelity===&lt;br /&gt;
&lt;br /&gt;
===Wealthfront===&lt;br /&gt;
{{main | Wealthfront }}&lt;br /&gt;
; [https://www.wealthfront.com/c/affiliates/invited/AFFA-BMT8-AIJ3-FS7E Referral]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Cash Account&lt;br /&gt;
Wealthfront offers a cash account.&lt;br /&gt;
This account is distributed between up to several banks so it is FDIC Insured up to $3 million &amp;lt;ref name=&amp;quot;wealthfrontfdic&amp;quot; /&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{reflist|refs=&lt;br /&gt;
&amp;lt;ref name=&amp;quot;wealthfrontfdic&amp;quot;&amp;gt;https://www.wealthfront.com/blog/wealthfront-fdic-insurance/&amp;lt;/ref&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Investing&amp;diff=7205</id>
		<title>Investing</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Investing&amp;diff=7205"/>
		<updated>2026-05-04T06:08:06Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In general, you should save money in the following accounts in order:&lt;br /&gt;
&lt;br /&gt;
# 401k, 403b, or thrift savings&lt;br /&gt;
# Traditional or Roth IRA (up to IRS limit)&lt;br /&gt;
# Investing account&lt;br /&gt;
# High-yield Savings, Cash account, or CD&lt;br /&gt;
# Checking account&lt;br /&gt;
&lt;br /&gt;
* 1-3 will be tax-advantaged (either tax-free or tax-deferred) since they are retirement accounts&lt;br /&gt;
* 4-6 will not be tax-advantaged&lt;br /&gt;
&lt;br /&gt;
==401(k)/403(b)==&lt;br /&gt;
A 401(k) or 403(b) is an employer-sponsored retirement plan.&amp;lt;br&amp;gt;&lt;br /&gt;
That means, it is managed by a company cooperating with your employer.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for a for-profit company, you will have a 401k.&lt;br /&gt;
If you work for a public school or non-profit company, you get a 403b.&amp;lt;br&amp;gt;&lt;br /&gt;
If you work for the federal government, you will have a thrift savings plan.&amp;lt;br&amp;gt;&lt;br /&gt;
For the most part, 401k and 403b rules are identical.&lt;br /&gt;
&lt;br /&gt;
* Employees can contribute up to $19,500 for 2020 ($19,000 in 2019) [https://www.irs.gov/retirement-plans/plan-participant-employee/retirement-topics-401k-and-profit-sharing-plan-contribution-limits]&lt;br /&gt;
** These are called &amp;quot;elective deferrals&amp;quot; which are tax-deferred. You may also contribute after-tax deferrals subject to the total maximum contribution below.&lt;br /&gt;
* In total, you can add up to $57,000 to your 401k each year, or up to 100% of your income, whichever is lower. This includes both your contributions and your employer&#039;s contributions&lt;br /&gt;
&lt;br /&gt;
==Individual Retirement Account (IRA)==&lt;br /&gt;
A tax-advantaged retirement account you can control.&amp;lt;br&amp;gt;&lt;br /&gt;
The IRS allows you to deposit up to $6000 ($7000 if 50 or older) per year or up to your income, whichever is lower.&lt;br /&gt;
Note that this limit is for all your IRAs combined.&lt;br /&gt;
Typically, you should save in a Roth IRA unless you surpass the income limit.&lt;br /&gt;
If you&#039;re not eligible for the Roth IRA, you may consider the backdoor Roth IRA.&lt;br /&gt;
&lt;br /&gt;
===Traditional IRA===&lt;br /&gt;
In a traditional IRA, you deposit pre-tax money (see notes).&lt;br /&gt;
Thus, your deposit counts as a tax-deduction.&lt;br /&gt;
You pay taxes when you withdraw your money.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* Early withdraws (before age 59.5) are subject to a 10% penalty plus taxes&lt;br /&gt;
* You must start taking required minimum distributions (RMDs) at age 72&lt;br /&gt;
* No more contributions after age 70.5&lt;br /&gt;
* While there are no income limits to contributing to a traditional IRA, there are income limits to deducting from your taxes&lt;br /&gt;
** See [https://www.irs.gov/retirement-plans/ira-deduction-limits IRA Deduction Limits]&lt;br /&gt;
** To avoid being double taxed on your Traditional IRA contributions, be sure to complete [https://www.irs.gov/forms-pubs/about-form-8606 IRS Form 8606]&lt;br /&gt;
&lt;br /&gt;
===Roth IRA===&lt;br /&gt;
In a Roth IRA, you deposit post-tax money. However, your money grows tax-free.&amp;lt;br&amp;gt;&lt;br /&gt;
There is an income limit to the Roth IRA of $124,000 in 2020.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* No required minimum distributions on your own Roth IRAs&lt;br /&gt;
** There are RMDs on inherited Roth IRAs&lt;br /&gt;
* You can withdraw your contributions (but not earnings) without penalty&lt;br /&gt;
** Note that any further contributions will count towards your annual limit so you cannot &amp;quot;borrow&amp;quot; from your Roth IRA.&lt;br /&gt;
* No age limits on contributions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Backdoor Roth IRA===&lt;br /&gt;
If you are a high-earner and believe you will earn more money in retirement,&lt;br /&gt;
you may want to do a backdoor Roth IRA to grow your retirement account tax-free rather than tax-deferred.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea&lt;br /&gt;
* Contribute to a traditional IRA&lt;br /&gt;
* Convert the traditional IRA into a Roth IRA&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* To avoid tax complications, you should eliminate all other pre-tax IRAs beforehand by rolling them over to a 401k. Otherwise, you will be subject to the pro-rata rule.&lt;br /&gt;
&lt;br /&gt;
===Mega Backdoor Roth===&lt;br /&gt;
Requirements: Your 401k allows after-tax contributions and non-hardship withdrawals.&lt;br /&gt;
&lt;br /&gt;
;Basic Idea: &lt;br /&gt;
* Max out after-tax contributions to your 401k&lt;br /&gt;
* Rollover or withdraw the after-tax portion to a Roth IRA or Roth 401K&lt;br /&gt;
&lt;br /&gt;
==ETFs==&lt;br /&gt;
{{main | Exchange-traded fund}}&lt;br /&gt;
&lt;br /&gt;
Exchange-traded funds. Typically these will have a fee called an expense ratio.&amp;lt;br&amp;gt;&lt;br /&gt;
However, since they are not usually actively managed, their fees are often lower than mutual funds.&amp;lt;br&amp;gt;&lt;br /&gt;
The expense ratio is measured in basis points.&amp;lt;br&amp;gt;&lt;br /&gt;
25 basis points is an annual fee of 0.25%.&amp;lt;br&amp;gt;&lt;br /&gt;
The following classifications are stolen from Wealthfront and Acorns&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Brokerages==&lt;br /&gt;
&lt;br /&gt;
===Fidelity===&lt;br /&gt;
&lt;br /&gt;
===Wealthfront===&lt;br /&gt;
{{main | Wealthfront }}&lt;br /&gt;
; [https://www.wealthfront.com/c/affiliates/invited/AFFA-BMT8-AIJ3-FS7E Referral]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Cash Account&lt;br /&gt;
Wealthfront offers a cash account.&lt;br /&gt;
This account is distributed between up to several banks so it is FDIC Insured up to $3 million &amp;lt;ref name=&amp;quot;wealthfrontfdic&amp;quot; /&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{reflist|refs=&lt;br /&gt;
&amp;lt;ref name=&amp;quot;wealthfrontfdic&amp;quot;&amp;gt;https://www.wealthfront.com/blog/wealthfront-fdic-insurance/&amp;lt;/ref&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7204</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7204"/>
		<updated>2025-12-24T03:40:12Z</updated>

		<summary type="html">&lt;p&gt;David: /* Generate a config and install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Install ==&lt;br /&gt;
The graphical installer is trivial. However, the minimal ISO doesn&#039;t handle partitioning for you.&lt;br /&gt;
&lt;br /&gt;
=== Partitioning and Formatting ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;gt;&lt;br /&gt;
# Create a new GPT partition table&lt;br /&gt;
parted /dev/sda -- mklabel gpt&lt;br /&gt;
&lt;br /&gt;
# Create the EFI Boot partition&lt;br /&gt;
parted /dev/sda -- mkpart ESP fat32 1MB 512MB&lt;br /&gt;
parted /dev/sda -- set 1 esp on&lt;br /&gt;
&lt;br /&gt;
# Create the Root partition (ext4)&lt;br /&gt;
parted /dev/sda -- mkpart primary ext4 512MB 100%&lt;br /&gt;
&lt;br /&gt;
# Format partitions&lt;br /&gt;
mkfs.fat -F 32 -n boot /dev/sda1&lt;br /&gt;
mkfs.ext4 -L nixos /dev/sda2&lt;br /&gt;
&lt;br /&gt;
# Mount the root partition&lt;br /&gt;
mount /dev/disk/by-label/nixos /mnt&lt;br /&gt;
&lt;br /&gt;
# Mount the boot partition&lt;br /&gt;
mkdir -p /mnt/boot&lt;br /&gt;
mount /dev/disk/by-label/boot /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create a 4GB swapfile (adjust size as needed)&lt;br /&gt;
dd if=/dev/zero of=/mnt/swapfile bs=1M count=4096&lt;br /&gt;
chmod 600 /mnt/swapfile&lt;br /&gt;
mkswap /mnt/swapfile&lt;br /&gt;
swapon /mnt/swapfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generate a config and install===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nixos-generate-config --root /mnt&lt;br /&gt;
# Edit the config to your desire&lt;br /&gt;
nano /mnt/etc/nixos/configuration.nix&lt;br /&gt;
&lt;br /&gt;
nixos-install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ config, pkgs, ... }:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  imports = [ ./hardware-configuration.nix ];&lt;br /&gt;
&lt;br /&gt;
  # Bootloader settings&lt;br /&gt;
  boot.loader.systemd-boot.enable = true;&lt;br /&gt;
  boot.loader.efi.canTouchEfiVariables = true;&lt;br /&gt;
&lt;br /&gt;
  # 1. ZFS Support for additional drives&lt;br /&gt;
  boot.supportedFilesystems = [ &amp;quot;zfs&amp;quot; ];&lt;br /&gt;
  networking.hostId = &amp;quot;8425e349&amp;quot;; # Required for ZFS; use 8 random hex digits&lt;br /&gt;
&lt;br /&gt;
  # 2. Static IP Configuration&lt;br /&gt;
  # Replace &#039;eth0&#039; with your actual interface name found via &#039;ip link&#039;&lt;br /&gt;
  networking.useDHCP = false;&lt;br /&gt;
  networking.interfaces.eth0.ipv4.addresses = [{&lt;br /&gt;
    address = &amp;quot;192.168.1.50&amp;quot;;&lt;br /&gt;
    prefixLength = 24;&lt;br /&gt;
  }];&lt;br /&gt;
  networking.defaultGateway = &amp;quot;192.168.1.1&amp;quot;;&lt;br /&gt;
  networking.nameservers = [ &amp;quot;1.1.1.1&amp;quot; &amp;quot;8.8.8.8&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
  # 3. Swapfile declaration&lt;br /&gt;
  swapDevices = [ {&lt;br /&gt;
    device = &amp;quot;/swapfile&amp;quot;;&lt;br /&gt;
    size = 4096; # In MB&lt;br /&gt;
  } ];&lt;br /&gt;
&lt;br /&gt;
  # Standard System Settings&lt;br /&gt;
  system.stateVersion = &amp;quot;24.11&amp;quot;; # Check the current version on the ISO&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install on VPS ===&lt;br /&gt;
For a VPS, first install Ubuntu or Debian.&lt;br /&gt;
Then run https://github.com/elitak/nixos-infect.&lt;br /&gt;
&lt;br /&gt;
== Resources==&lt;br /&gt;
* https://nixos.org/manual/nixos/stable/&lt;br /&gt;
* https://wiki.nixos.org/wiki/NixOS_Wiki&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7203</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7203"/>
		<updated>2025-12-21T23:16:02Z</updated>

		<summary type="html">&lt;p&gt;David: /* Generate a config and install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Install ==&lt;br /&gt;
The graphical installer is trivial. However, the minimal ISO doesn&#039;t handle partitioning for you.&lt;br /&gt;
&lt;br /&gt;
=== Partitioning and Formatting ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;gt;&lt;br /&gt;
# Create a new GPT partition table&lt;br /&gt;
parted /dev/sda -- mklabel gpt&lt;br /&gt;
&lt;br /&gt;
# Create the EFI Boot partition&lt;br /&gt;
parted /dev/sda -- mkpart ESP fat32 1MB 512MB&lt;br /&gt;
parted /dev/sda -- set 1 esp on&lt;br /&gt;
&lt;br /&gt;
# Create the Root partition (ext4)&lt;br /&gt;
parted /dev/sda -- mkpart primary ext4 512MB 100%&lt;br /&gt;
&lt;br /&gt;
# Format partitions&lt;br /&gt;
mkfs.fat -F 32 -n boot /dev/sda1&lt;br /&gt;
mkfs.ext4 -L nixos /dev/sda2&lt;br /&gt;
&lt;br /&gt;
# Mount the root partition&lt;br /&gt;
mount /dev/disk/by-label/nixos /mnt&lt;br /&gt;
&lt;br /&gt;
# Mount the boot partition&lt;br /&gt;
mkdir -p /mnt/boot&lt;br /&gt;
mount /dev/disk/by-label/boot /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create a 4GB swapfile (adjust size as needed)&lt;br /&gt;
dd if=/dev/zero of=/mnt/swapfile bs=1M count=4096&lt;br /&gt;
chmod 600 /mnt/swapfile&lt;br /&gt;
mkswap /mnt/swapfile&lt;br /&gt;
swapon /mnt/swapfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generate a config and install===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nixos-generate-config --root /mnt&lt;br /&gt;
# Edit the config to your desire&lt;br /&gt;
nano /mnt/etc/nixos/configuration.nix&lt;br /&gt;
&lt;br /&gt;
nixos-install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Make sure to add the swap config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
swapDevices = [ {&lt;br /&gt;
  device = &amp;quot;/swapfile&amp;quot;;&lt;br /&gt;
  size = 4096; # In MB&lt;br /&gt;
} ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install on VPS ===&lt;br /&gt;
For a VPS, first install Ubuntu or Debian.&lt;br /&gt;
Then run https://github.com/elitak/nixos-infect.&lt;br /&gt;
&lt;br /&gt;
== Resources==&lt;br /&gt;
* https://nixos.org/manual/nixos/stable/&lt;br /&gt;
* https://wiki.nixos.org/wiki/NixOS_Wiki&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Linux&amp;diff=7202</id>
		<title>Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Linux&amp;diff=7202"/>
		<updated>2025-12-21T23:12:51Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A collection of notes on using Linux systems.&lt;br /&gt;
Notes here are for Ubuntu but should work on similar debian derivative distros.&lt;br /&gt;
See also [[NixOS]].&lt;br /&gt;
&lt;br /&gt;
==Basic Terminal Commands==&lt;br /&gt;
{{see also | Bash (Unix shell)}}&lt;br /&gt;
===List===&lt;br /&gt;
&amp;lt;code&amp;gt;ls&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt; shows long format&lt;br /&gt;
* &amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt; shows all files including hidden files, current directory &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;, and parent directory &amp;lt;code&amp;gt;..&amp;lt;/code&amp;gt;.&lt;br /&gt;
** &amp;lt;code&amp;gt;-A&amp;lt;/code&amp;gt; omits &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;..&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt; human readable file sizes&lt;br /&gt;
* &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; shows blocks taken up by the file (i.e. size on disk)&lt;br /&gt;
&lt;br /&gt;
There are also other commands like &amp;lt;code&amp;gt;lsblk&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;lscpu&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;lshw&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Disk Space===&lt;br /&gt;
* &amp;lt;code&amp;gt;du&amp;lt;/code&amp;gt; Disk Usage&lt;br /&gt;
** &amp;lt;code&amp;gt;du -sh&amp;lt;/code&amp;gt; Show size of current directory&lt;br /&gt;
** &amp;lt;code&amp;gt;du -h --max-depth=1&amp;lt;/code&amp;gt; Show size of files and folders in current directory. I have &amp;lt;code&amp;gt;du&amp;lt;/code&amp;gt; aliased to this.&lt;br /&gt;
** Flags:&lt;br /&gt;
*** &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt; human readable (adds M or G)&lt;br /&gt;
*** &amp;lt;code&amp;gt;--max-depth&amp;lt;/code&amp;gt; depth to recurse. Default is &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;df&amp;lt;/code&amp;gt; Disk Filesystems&lt;br /&gt;
** Shows usage, total space available, and mount position&lt;br /&gt;
** &amp;lt;code&amp;gt; df -Ph .&amp;lt;/code&amp;gt; See free space in current directory&lt;br /&gt;
&lt;br /&gt;
If looking to free up space, I recommend installing &amp;lt;code&amp;gt;ncdu&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Monitoring===&lt;br /&gt;
* &amp;lt;code&amp;gt;htop&amp;lt;/code&amp;gt; - basic terminal system monitor, enhanced version of &amp;lt;code&amp;gt;top&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;watch -n 0.5 &amp;lt;program&amp;gt;&amp;lt;/code&amp;gt; - repeatedly call &amp;lt;program&amp;gt; every 0.5 seconds&lt;br /&gt;
&lt;br /&gt;
===Standard Streams===&lt;br /&gt;
* &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; will pipe stdout to the stdin of another process&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; will redirect stdout to a file&lt;br /&gt;
* &amp;lt;code&amp;gt;2&amp;gt;&amp;amp;1&amp;lt;/code&amp;gt; will redirect stderr (2) to stdout (1)&lt;br /&gt;
* [https://www.gnu.org/software/coreutils/manual/html_node/tee-invocation.html &amp;lt;code&amp;gt;tee&amp;lt;/code&amp;gt;] will redirect stdout to multiple files and show it in the terminal&lt;br /&gt;
&lt;br /&gt;
===Shutdown===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
shutdown -h [now | -t &amp;lt;time&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt; poweroff, the default&lt;br /&gt;
* &amp;lt;code&amp;gt;-t time&amp;lt;/code&amp;gt; schedule a shutdown in &#039;&#039;time&#039;&#039; seconds&lt;br /&gt;
* &amp;lt;code&amp;gt;-r&amp;lt;/code&amp;gt; restart&lt;br /&gt;
* &amp;lt;code&amp;gt;-c&amp;lt;/code&amp;gt; cancel pending shutdown&lt;br /&gt;
&lt;br /&gt;
==Package Management==&lt;br /&gt;
See [https://www.digitalocean.com/community/tutorials/package-management-basics-apt-yum-dnf-pkg DigitalOcean: Package management basics]&lt;br /&gt;
&lt;br /&gt;
===apt===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# List all installed packages&lt;br /&gt;
apt list --installed&lt;br /&gt;
&lt;br /&gt;
# Search repos for package&lt;br /&gt;
apt search libdpkg-dev&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Repositories&lt;br /&gt;
Repository sources are saved in&lt;br /&gt;
* A line in &amp;lt;code&amp;gt;/etc/apt/sources.list&amp;lt;/code&amp;gt;&lt;br /&gt;
* A file in &amp;lt;code&amp;gt;/etc/apt/sources.list.d/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Application desktop icons are stored in &amp;lt;code&amp;gt;/usr/share/applications/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The update notifications are in &amp;lt;code&amp;gt;/etc/apt/apt.conf.d/99update-notifier&amp;lt;/code&amp;gt;. Comment these out to disable them.&amp;lt;br&amp;gt;&lt;br /&gt;
Unattended-updates are in &amp;lt;code&amp;gt;/etc/apt/apt.conf.d/50unattended-upgrades&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{hidden | dpkg |&lt;br /&gt;
===dpkg===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# List everything&lt;br /&gt;
sudo dpkg -l&lt;br /&gt;
&lt;br /&gt;
# List things with apache in the name&lt;br /&gt;
sudo dpkg -l | grep apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{hidden | yum |&lt;br /&gt;
===yum===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Update package lists, typically not necessary&lt;br /&gt;
yum check-update&lt;br /&gt;
&lt;br /&gt;
# Upgrade packages&lt;br /&gt;
yum update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==SSH==&lt;br /&gt;
===SSH Keys===&lt;br /&gt;
Generate an ssh-key for every client&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -t ed25519 [-C &amp;quot;comment your client name&amp;quot;] [-f output_path]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some older software such as Solid file explorer require RSA keys in PEM key format&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -t rsa -b 4096 -m PEM [-C &amp;quot;comment your client name&amp;quot;] [-f output_path]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also convert existing keys to PEM format&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -p -m PEM [-C &amp;quot;comment your client name&amp;quot;] [-f output_path]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to change the comment on your key&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -c -C &amp;quot;New comment&amp;quot; -f path_to_key&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manage ssh keys&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# On the client&lt;br /&gt;
ssh-copy-id &amp;lt;host&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# On the server&lt;br /&gt;
vim ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
* According to [https://security.stackexchange.com/questions/143442/what-are-ssh-keygen-best-practices this] you should avoid using ECDSA and DSA keys.&lt;br /&gt;
&lt;br /&gt;
===Disable password authentication===&lt;br /&gt;
# Edit &amp;lt;code&amp;gt;/etc/ssh/sshd_config&amp;lt;/code&amp;gt;&lt;br /&gt;
# Set &amp;lt;code&amp;gt;PasswordAuthentication&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;&lt;br /&gt;
# Set &amp;lt;code&amp;gt;ChallengeResponseAuthentication&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;&lt;br /&gt;
# Test by ssh&#039;ing into the machine using &amp;lt;code&amp;gt;-o PreferredAuthentications=password -o PubkeyAuthentication=no&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Port Forwarding===&lt;br /&gt;
Also known as: SSH Tunneling, SSH Proxy, SSH Reverse Proxy&lt;br /&gt;
&lt;br /&gt;
If you need to access a port on the remote computer, you can use the &amp;lt;code&amp;gt;-L&amp;lt;/code&amp;gt; option to forward ports from the remote to the local machine.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -L &amp;lt;localport&amp;gt;:localhost:&amp;lt;remoteport&amp;gt; &amp;lt;remoteurl&amp;gt;&lt;br /&gt;
# E.g. ssh -L 8080:localhost:80 david@davidl.me&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the reverse, giving the remote access to a local port using &amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -R &amp;lt;localport&amp;gt;:host:&amp;lt;remoteport&amp;gt; &amp;lt;remoteurl&amp;gt;&lt;br /&gt;
# E.g. ssh -R 8080:localhost:80 david@davidl.me&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* You can also run this without creating a shell using &amp;lt;code&amp;gt;-N&amp;lt;/code&amp;gt;. This will block your shell. See [https://unix.stackexchange.com/questions/100859/ssh-tunnel-without-shell-on-ssh-server SE Answer].&lt;br /&gt;
* Adding &amp;lt;code&amp;gt;-f&amp;lt;/code&amp;gt; pushes ssh to the background.&lt;br /&gt;
** This will implicitly add &amp;lt;code&amp;gt;-n&amp;lt;/code&amp;gt; which redirects &amp;lt;code&amp;gt;stdin&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;/dev/null&amp;lt;/code&amp;gt;.&lt;br /&gt;
** If you want to be able to foreground this again, the use &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt; or &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt;+&amp;lt;kbd&amp;gt;z&amp;lt;/kbd&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
===alias===&lt;br /&gt;
You can create aliases in your &amp;lt;code&amp;gt;.ssh/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host my_alias&lt;br /&gt;
  User my_username&lt;br /&gt;
  Hostname my_server@my_domain.com&lt;br /&gt;
  Port 52&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==VNC==&lt;br /&gt;
===x11vnc===&lt;br /&gt;
[https://askubuntu.com/questions/1033274/ubuntu-18-04-connect-to-login-screen-over-vnc Reference]&lt;br /&gt;
&lt;br /&gt;
I recommend not exposing VNC. Set it to localhost only and use ssh port forwarding.&lt;br /&gt;
&lt;br /&gt;
===Remmina===&lt;br /&gt;
If using a wired connection, you can save a preset to &amp;lt;code&amp;gt;localhost:5901&amp;lt;/code&amp;gt; or similar.&lt;br /&gt;
&lt;br /&gt;
Note that the Remmina which ships with Ubuntu 18.04 is outdated and buggy.&lt;br /&gt;
You can upgrade it by adding the Remmina PPA.&lt;br /&gt;
See [https://remmina.org/how-to-install-remmina/ https://remmina.org/how-to-install-remmina/] for details.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-add-repository ppa:remmina-ppa-team/remmina-next&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install remmina remmina-plugin-rdp remmina-plugin-secret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Nvidia==&lt;br /&gt;
&lt;br /&gt;
===Driver Installation===&lt;br /&gt;
# Run &amp;lt;code&amp;gt;ubuntu-drivers list&amp;lt;/code&amp;gt; to get a list of drivers&lt;br /&gt;
# Install the latest driver&lt;br /&gt;
#* E.g. &amp;lt;code&amp;gt;sudo apt install nvidia-driver-460&amp;lt;/code&amp;gt;&lt;br /&gt;
# If you have secure boot enabled, you will be asked for a password during installation&lt;br /&gt;
#* This is because the driver is a DKMS module.&lt;br /&gt;
#* After installation, reboot your computer and select &amp;quot;Enroll MOK&amp;quot; and enter that password in.&lt;br /&gt;
#* &#039;&#039;&#039;Note&#039;&#039;&#039; Failure to do this will result in the driver not working&lt;br /&gt;
# Validate your installation by running &amp;lt;code&amp;gt;nvidia-smi&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* &amp;lt;code&amp;gt;nvidia-smi&amp;lt;/code&amp;gt; shows the latest cuda version supported by the driver, not the cuda version installed.&lt;br /&gt;
&lt;br /&gt;
===Cuda Installation===&lt;br /&gt;
Download cuda from the nvidia website or add the cuda repo to your apt sources.&lt;br /&gt;
&lt;br /&gt;
===Switching between Nvidia and Intel===&lt;br /&gt;
[https://www.linuxbabe.com/desktop-linux/switch-intel-nvidia-graphics-card-ubuntu Reference]&lt;br /&gt;
&lt;br /&gt;
Make sure the Nvidia graphics drivers are installed. Then you can select between Nvidia and Intel GPUs using the Nvidia X Server Settings application &amp;lt;code&amp;gt;nvidia-settings&amp;lt;/code&amp;gt;. Alternatively, you can use the following commands in the terminal.&amp;lt;br&amp;gt;&lt;br /&gt;
To switch to the Nvidia GPU:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo prime-select nvidia&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
To switch back to the Intel GPU:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo prime-select intel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;prime-select query&amp;lt;/code&amp;gt; will print either &amp;lt;code&amp;gt;nvidia&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;intel&amp;lt;/code&amp;gt; to stdout.&lt;br /&gt;
&lt;br /&gt;
===Fix tearing on laptops===&lt;br /&gt;
[https://ubuntuhandbook.org/index.php/2018/07/fix-screen-tearing-ubuntu-18-04-optimus-laptops/ Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
# Add &amp;lt;code&amp;gt;options nvidia-drm modeset=1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;/etc/modprobe.d/nvidia-drm-nomodeset.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
# Run &amp;lt;code&amp;gt;sudo update-initramfs -u&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Environment Variables==&lt;br /&gt;
[https://help.ubuntu.com/community/EnvironmentVariables Ubuntu Help Reference]&lt;br /&gt;
&lt;br /&gt;
==Tmux==&lt;br /&gt;
[https://tmuxcheatsheet.com/ Tmux cheat sheet]&lt;br /&gt;
&lt;br /&gt;
Tmux, or Terminal Multiplexer is an alternative to screen.&amp;lt;br&amp;gt;&lt;br /&gt;
Use it to keep terminals open and tasks running after you disconnect your SSH connection.&amp;lt;br&amp;gt;&lt;br /&gt;
Getting Started:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make a new session&lt;br /&gt;
tmux&lt;br /&gt;
# Make a new named session&lt;br /&gt;
tmux new -s my_session&lt;br /&gt;
# Rename a session&lt;br /&gt;
# Keybinding: Ctrl + b, $&lt;br /&gt;
tmux rename-session [-t current-name] [new-name]&lt;br /&gt;
# Detach from a session&lt;br /&gt;
# Keybinding: Ctrl + b, d&lt;br /&gt;
tmux detach&lt;br /&gt;
# List windows&lt;br /&gt;
tmux ls&lt;br /&gt;
# Attach to a session&lt;br /&gt;
tmux attach -t my_session&lt;br /&gt;
# Renumber windows&lt;br /&gt;
:movew&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mouse scrolling===&lt;br /&gt;
Set &amp;lt;code&amp;gt;set -g mouse on&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;~/.tmux.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Manager==&lt;br /&gt;
The default file manager in Ubuntu is Nautilus&lt;br /&gt;
&lt;br /&gt;
===Add to context menu===&lt;br /&gt;
[https://askubuntu.com/questions/1030940/nautilus-actions-in-18-04 AskUbuntu]&lt;br /&gt;
&lt;br /&gt;
;22.04&lt;br /&gt;
See [https://github.com/harry-cpp/code-nautilus https://github.com/harry-cpp/code-nautilus]&lt;br /&gt;
&lt;br /&gt;
;20.04&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo add-apt-repository universe&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install filemanager-actions nautilus-actions nautilus-extension-fma&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Etcher==&lt;br /&gt;
[https://github.com/balena-io/etcher Github]&amp;lt;br&amp;gt;&lt;br /&gt;
Installing etcher&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;deb https://deb.etcher.io stable etcher&amp;quot; | sudo tee /etc/apt/sources.list.d/balena-etcher.list&lt;br /&gt;
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install balena-etcher-electron&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Logs==&lt;br /&gt;
Logs are stored under &amp;lt;code&amp;gt;/var/log&amp;lt;/code&amp;gt;. These can end up taking up a lot of space.&amp;lt;br&amp;gt;&lt;br /&gt;
You can delete logs in the journal folder [https://unix.stackexchange.com/questions/130786/can-i-remove-files-in-var-log-journal-and-var-cache-abrt-di-usr Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Default gcc/g++ version==&lt;br /&gt;
See [https://askubuntu.com/questions/26498/how-to-choose-the-default-gcc-and-g-version https://askubuntu.com/questions/26498/how-to-choose-the-default-gcc-and-g-version].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Install&lt;br /&gt;
sudo update-alternatives --remove-all gcc &lt;br /&gt;
sudo update-alternatives --remove-all g++&lt;br /&gt;
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 10&lt;br /&gt;
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 20&lt;br /&gt;
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 10&lt;br /&gt;
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 20&lt;br /&gt;
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30&lt;br /&gt;
sudo update-alternatives --set cc /usr/bin/gcc&lt;br /&gt;
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30&lt;br /&gt;
sudo update-alternatives --set c++ /usr/bin/g++&lt;br /&gt;
&lt;br /&gt;
# Select&lt;br /&gt;
sudo update-alternatives --config gcc&lt;br /&gt;
sudo update-alternatives --config g++&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Power Management==&lt;br /&gt;
===tlp===&lt;br /&gt;
[https://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html Website]&amp;lt;br&amp;gt;&lt;br /&gt;
Battery power management&lt;br /&gt;
&lt;br /&gt;
==Virtual Machines (VM)==&lt;br /&gt;
===Guest VMs===&lt;br /&gt;
Using Ubuntu as a guest:&lt;br /&gt;
* Install &amp;lt;code&amp;gt;open-vm-tools-desktop&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===KVM===&lt;br /&gt;
{{main | Archwiki: KVM}}&lt;br /&gt;
&lt;br /&gt;
===Docker===&lt;br /&gt;
{{main | Docker (software)}}&lt;br /&gt;
&lt;br /&gt;
==Services and Scheduling==&lt;br /&gt;
===crontab===&lt;br /&gt;
The following will open a list of cron jobs you have.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
crontab -e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The default editor is nano. You can change it to vim using &amp;lt;code&amp;gt;VISUAL=vim&amp;lt;/code&amp;gt; env variable or with &amp;lt;code&amp;gt;select-editor&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===systemd service===&lt;br /&gt;
See [https://wiki.debian.org/systemd/Services debian/systemd Services]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.freedesktop.org/software/systemd/man/systemd.service.html manual]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
System-wide services are in &amp;lt;code&amp;gt;/etc/systemd/system/&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
User services are in &amp;lt;code&amp;gt;~/.config/systemd/user/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{hidden|A basic systemd service file|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Contents of /etc/systemd/system/myservice.service&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=My Service&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
Restart=always&lt;br /&gt;
WorkingDirectory=/usr/local/bin&lt;br /&gt;
ExecStart=/usr/local/bin/myservice&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable with &amp;lt;code&amp;gt;sudo systemctl enable myservice&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
;Usage&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl enable &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl status &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl start &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl stop &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl restart &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl disable &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* Type should be &amp;lt;code&amp;gt;forking&amp;lt;/code&amp;gt; if your service runs and then ends&lt;br /&gt;
* See service log with &amp;lt;code&amp;gt;sudo journalctl myservice&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Management==&lt;br /&gt;
===rsync===&lt;br /&gt;
{{main | rsync}}&lt;br /&gt;
&lt;br /&gt;
[https://linux.die.net/man/1/rsync Documentation]&lt;br /&gt;
&lt;br /&gt;
Use this to sync folders between directories of across networks&lt;br /&gt;
&lt;br /&gt;
;Common Flags&lt;br /&gt;
* &amp;lt;code&amp;gt;-a, --archive&amp;lt;/code&amp;gt; archive mode; equals -rlptgoD&lt;br /&gt;
* &amp;lt;code&amp;gt;--info=progress2&amp;lt;/code&amp;gt; show progress&lt;br /&gt;
&lt;br /&gt;
See [[ArchWiki: rsync]] to learn how to use rclone for incremental backups (a la time machine).&lt;br /&gt;
&lt;br /&gt;
===rclone===&lt;br /&gt;
{{ main | rclone }}&lt;br /&gt;
Similar to rsync but for cloud services such as Dropbox and Google Drive.&amp;lt;br&amp;gt;&lt;br /&gt;
I recommend installing from their website to get the latest version.&lt;br /&gt;
&lt;br /&gt;
===scp===&lt;br /&gt;
Usage&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp [source_machine]:[source_file] [target_machine]:[target_file]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;Flags&lt;br /&gt;
* &amp;lt;code&amp;gt;-r&amp;lt;/code&amp;gt; recursive, needed to scp directories&lt;br /&gt;
* &amp;lt;code&amp;gt;-P [port]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* The machine can be an alias or user@domain&lt;br /&gt;
&lt;br /&gt;
===7z===&lt;br /&gt;
7zip CLI&amp;lt;br&amp;gt;&lt;br /&gt;
Install with &amp;lt;code&amp;gt;sudo apt install p7zip-full&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;gt;&lt;br /&gt;
# Archive&lt;br /&gt;
7z a &amp;lt;output_file&amp;gt; &amp;lt;input_file/folder&amp;gt;&lt;br /&gt;
# Archive with password&lt;br /&gt;
7z a &amp;lt;output_file&amp;gt; &amp;lt;input_file&amp;gt; -p -mhe=on&lt;br /&gt;
&lt;br /&gt;
# Extract &lt;br /&gt;
7z x &amp;lt;file&amp;gt; [-o{dir}]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-mhe=on&amp;lt;/code&amp;gt; hides file stuctures&lt;br /&gt;
&lt;br /&gt;
===zip/unzip===&lt;br /&gt;
Note that p7zip-full also includes the ability to zip/unzip .zip files.&amp;lt;br&amp;gt;&lt;br /&gt;
;Zip a folder&lt;br /&gt;
&amp;lt;code&amp;gt;zip -r file.zip folder&amp;lt;/code&amp;gt;&lt;br /&gt;
;Unzip an archive&lt;br /&gt;
&amp;lt;code&amp;gt;unzip file.zip [-d destination]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===diff===&lt;br /&gt;
[https://www.geeksforgeeks.org/diff-command-linux-examples/ diff examples]&lt;br /&gt;
&lt;br /&gt;
;Important flags&lt;br /&gt;
* &amp;lt;code&amp;gt;--strip-trailing-cr&amp;lt;/code&amp;gt; Ignores &amp;lt;code&amp;gt;\r&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===tar===&lt;br /&gt;
{{ main | tar (computing) }}&lt;br /&gt;
;Extraction&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tar xzvf archive.tar.gz&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Archive&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tar czpvf archive.tar.gz files&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===find===&lt;br /&gt;
Find files by their filename&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find &amp;lt;folder&amp;gt; [args] -name &amp;lt;name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-maxdepth &amp;lt;num&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===grep===&lt;br /&gt;
Find files containing a pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
grep -r &amp;lt;pattern&amp;gt; *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dual Booting==&lt;br /&gt;
===Fix time difference between Windows===&lt;br /&gt;
By default, Windows stores the local time in the hardware clock while Ubuntu stores UTC time.&lt;br /&gt;
&lt;br /&gt;
Set ubuntu to store UTC time:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
timedatectl set-local-rtc 0 --adjust-system-clock&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set Windows to store UTC time:&lt;br /&gt;
https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows&lt;br /&gt;
&lt;br /&gt;
===Recover GRUB after installing Windows===&lt;br /&gt;
[https://help.ubuntu.com/community/RecoveringUbuntuAfterInstallingWindows Ubuntu Help]&amp;lt;br&amp;gt;&lt;br /&gt;
If you install windows after installing Ubuntu&lt;br /&gt;
&lt;br /&gt;
===GrubReboot===&lt;br /&gt;
[https://wiki.debian.org/GrubReboot GrubReboot]&amp;lt;br&amp;gt;&lt;br /&gt;
Allows you to reboot into an OS one time.&amp;lt;br&amp;gt;&lt;br /&gt;
i.e. If you are ssh&#039;d into linux and want to boot into Windows one time.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Encryption===&lt;br /&gt;
[https://www.mikekasberg.com/blog/2020/04/08/dual-boot-ubuntu-and-windows-with-encryption.html https://www.mikekasberg.com/blog/2020/04/08/dual-boot-ubuntu-and-windows-with-encryption.html]&lt;br /&gt;
&lt;br /&gt;
==Users and Groups==&lt;br /&gt;
===Users===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make a new user&lt;br /&gt;
adduser &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Add user to admins&lt;br /&gt;
usermod -aG sudo &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Change the password of a user&lt;br /&gt;
passwd&lt;br /&gt;
passwd &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete a user&lt;br /&gt;
# -r will also delete their home directory&lt;br /&gt;
userdel -r &amp;lt;user&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make a group&lt;br /&gt;
groupadd &amp;lt;group&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete a group&lt;br /&gt;
groupdel &amp;lt;group&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# List members in groups&lt;br /&gt;
getent group &amp;lt;group&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Add user to group&lt;br /&gt;
usermod -a -G &amp;lt;group&amp;gt; &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Remove user from group&lt;br /&gt;
gpasswd -d &amp;lt;user&amp;gt; &amp;lt;group&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Permissions==&lt;br /&gt;
In unix filesystems, files and folders have individual permissions.&amp;lt;br&amp;gt;&lt;br /&gt;
You can set permissions for each file/folder independently and for the following sets of users:&lt;br /&gt;
* User/Owner &amp;lt;code&amp;gt;u&amp;lt;/code&amp;gt;&lt;br /&gt;
* Group &amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt;&lt;br /&gt;
* Other &amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt;&lt;br /&gt;
You can also set permissions for all of the above with:&lt;br /&gt;
* All &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;&lt;br /&gt;
Each file and folder can have the following permission for each set of user:&lt;br /&gt;
* Read &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;&lt;br /&gt;
* Write &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&lt;br /&gt;
* Execute &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;&lt;br /&gt;
The above totals 9 bits (3 sets of users times 3 permissions).&lt;br /&gt;
&lt;br /&gt;
In addition to the above, there are 3 special bits:&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sticky_bit Sticky bit &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt;] - only allow the owners of subfiles/subfolders to modify them&lt;br /&gt;
** Useful for shared folders such as /tmp&lt;br /&gt;
* Setuid - automatically elevate execution of this file to the owner&#039;s priviledges&lt;br /&gt;
* Setgid - automatically elevate execution of this file to the group&#039;s priviledges&lt;br /&gt;
&lt;br /&gt;
In total, permissions for each file and folder can be stored in 16 bits or 2 bytes.&lt;br /&gt;
&lt;br /&gt;
===chmod===&lt;br /&gt;
change mode&lt;br /&gt;
&lt;br /&gt;
===chown===&lt;br /&gt;
change owner&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown [-r] &amp;lt;user&amp;gt;[:&amp;lt;group&amp;gt;] &amp;lt;item&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===chgrp===&lt;br /&gt;
&lt;br /&gt;
===Access Control Lists (ACL)===&lt;br /&gt;
&lt;br /&gt;
==Display Scaling (HiDPI)==&lt;br /&gt;
See [https://wiki.archlinux.org/index.php/HiDPI Arch Wiki HiDPI]  &lt;br /&gt;
&lt;br /&gt;
Fractional scaling is natively available in Ubuntu 20.04+.&lt;br /&gt;
&lt;br /&gt;
{{hidden | Ubuntu 18.04 |&lt;br /&gt;
;Xorg&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Find your display&lt;br /&gt;
xrandr&lt;br /&gt;
xrandr --output &amp;lt;display&amp;gt; --scale 1.25x1.25&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Wayland&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gsettings set org.gnome.mutter experimental-features &amp;quot;[&#039;scale-monitor-framebuffer&#039;]&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I have the following script run at startup&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
gsettings set org.gnome.desktop.interface scaling-factor 2&lt;br /&gt;
gsettings set org.gnome.settings-daemon.plugins.xsettings overrides &amp;quot;{&#039;Gdk/WindowScalingFactor&#039;: &amp;lt;2&amp;gt;}&amp;quot;&lt;br /&gt;
xrandr --output DP-2 --scale 1.3x1.3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Clock==&lt;br /&gt;
See [https://help.ubuntu.com/lts/serverguide/NTP.html Ubuntu Time Synchronization]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Install chrony&lt;br /&gt;
sudo apt install chrony&lt;br /&gt;
# Synchronize time&lt;br /&gt;
sudo chronyd -q&lt;br /&gt;
# Check time synchronization&lt;br /&gt;
sudo chronyd -Q&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes&lt;br /&gt;
* Syncing over the internet will be off by a few milliseconds (e.g. 0.003 seconds).&lt;br /&gt;
* Syncing with another computer over lan&lt;br /&gt;
&lt;br /&gt;
===Syncing with another computer===&lt;br /&gt;
See [https://askubuntu.com/questions/787855/how-to-use-chrony-to-synchronize-timestamp-on-two-computers/1018204 askubuntu]&amp;lt;br&amp;gt;&lt;br /&gt;
;On the server&lt;br /&gt;
Add the following to &amp;lt;code&amp;gt;/etc/chrony.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# make it serve time even if it is not synced (as it can&#039;t reach out)&lt;br /&gt;
local stratum 8&lt;br /&gt;
# allow the IP of your peer to connect (192.168 subnet)&lt;br /&gt;
allow 192.168&lt;br /&gt;
# Or&lt;br /&gt;
# allow all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;On the client&lt;br /&gt;
Add the following to &amp;lt;code&amp;gt;/etc/chrony.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set the servers IP here to sync to it&lt;br /&gt;
server &amp;lt;Server_IP&amp;gt; iburst&lt;br /&gt;
# remove the default servers in the config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;code&amp;gt;/dev/&amp;lt;/code&amp;gt;==&lt;br /&gt;
See [[Wikipedia: Device file#Pseudo-devices]]&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;===&lt;br /&gt;
Discards all input.  &lt;br /&gt;
Produces EOF.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;random&amp;lt;/code&amp;gt;===&lt;br /&gt;
See [https://security.stackexchange.com/questions/3936/is-a-rand-from-dev-urandom-secure-for-a-login-key/3939#3939 stackexchange]&amp;lt;br&amp;gt;&lt;br /&gt;
See [https://www.2uo.de/myths-about-urandom/ Myths about urandom]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;TLDR&amp;amp;#58; Use &amp;lt;code&amp;gt;/dev/urandom&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;/dev/random&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;urandom&amp;lt;/code&amp;gt;===&lt;br /&gt;
Produces random numbers.&lt;br /&gt;
&lt;br /&gt;
On my system, it&#039;s limited to about 60 MB/s. If you need faster randomness, you can encrypt from &amp;lt;code&amp;gt;/dev/zero&amp;lt;/code&amp;gt; to get 2.7 GB/s.  &lt;br /&gt;
See [https://serverfault.com/questions/6440/is-there-an-alternative-to-dev-urandom/415962#415962 reference].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Using urandom&lt;br /&gt;
pv &amp;lt; /dev/urandom &amp;gt; /dev/ull&lt;br /&gt;
&lt;br /&gt;
# Using encryption&lt;br /&gt;
openssl enc -pbkdf2 -iter 100000 -aes-256-ctr -pass pass:&amp;quot;$(dd if=/dev/urandom bs=128 count=1 2&amp;gt;/dev/null | base64)&amp;quot; -nosalt &amp;lt; /dev/zero | pv &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
# Create a 4 GB file.&lt;br /&gt;
dd if=/dev/zero bs=4M count=1024 | openssl enc -pbkdf2 -iter 100000 -aes-256-ctr -pass pass:&amp;quot;$(dd if=/dev/urandom bs=128 count=1 2&amp;gt;/dev/null | base64)&amp;quot; -nosalt | pv &amp;gt; random.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gnome==&lt;br /&gt;
===Tweaks===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install gnome-tweaks&lt;br /&gt;
sudo apt install chrome-gnome-shell&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Auto Reboot==&lt;br /&gt;
[https://unix.stackexchange.com/questions/141095/automatically-reboot-if-no-wifi-connection-for-a-certain-time reference]&lt;br /&gt;
&lt;br /&gt;
{{hidden | Auto Reboot Script |&lt;br /&gt;
Auto reboot if no internet is detected:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
TMP_FILE=/tmp/inet_up&lt;br /&gt;
&lt;br /&gt;
# Edit this function if you want to do something besides reboot&lt;br /&gt;
no_inet_action() {&lt;br /&gt;
    if [ &amp;quot;$1&amp;quot; -eq 1 ]; then&lt;br /&gt;
        systemctl restart network-manager&lt;br /&gt;
    elif [ &amp;quot;$1&amp;quot; -ge 2 ]; then&lt;br /&gt;
        rm -f $TMP_FILE&lt;br /&gt;
        shutdown -r now &amp;quot;No Internet&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
increment_tmp_file() {&lt;br /&gt;
    if [ ! -f $TMP_FILE ]; then&lt;br /&gt;
       echo 0 &amp;gt; $TMP_FILE&lt;br /&gt;
    fi&lt;br /&gt;
    oldnum=$(cut -d &#039;,&#039; -f2 $TMP_FILE)&lt;br /&gt;
    newnum=$((&amp;quot;$oldnum&amp;quot; + 1))&lt;br /&gt;
    sed -i &amp;quot;s/$oldnum\$/$newnum/g&amp;quot; $TMP_FILE&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if ping -c5 google.com; then&lt;br /&gt;
    echo 0 &amp;gt; $TMP_FILE&lt;br /&gt;
    date &amp;gt; /tmp/inet_up_last_check&lt;br /&gt;
else&lt;br /&gt;
    increment_tmp_file&lt;br /&gt;
    oldnum=$(cut -d &#039;,&#039; -f2 $TMP_FILE)&lt;br /&gt;
    no_inet_action &amp;quot;$oldnum&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add to sudo&#039;s crontab to run every 10 minutes&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*/10 * * * * /home/david/bin/check_inet.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Encryption==&lt;br /&gt;
For encrypting entire drives, I recommend LUKS.&amp;lt;br&amp;gt;&lt;br /&gt;
If you want encrypt a directly, you can use fscrypt (ext4 only).&lt;br /&gt;
&lt;br /&gt;
Note that ecryptfs is deprecated and shouldn&#039;t be used.&lt;br /&gt;
&lt;br /&gt;
===Encrypt Home After Install===&lt;br /&gt;
See [[Archwiki: Fscrypt#Encrypt_a_home_directory]].  &lt;br /&gt;
See [https://tlbdk.github.io/ubuntu/2018/10/22/fscrypt.html https://tlbdk.github.io/ubuntu/2018/10/22/fscrypt.html].&lt;br /&gt;
&lt;br /&gt;
This uses the newer fscrypt and requires Ubuntu 18.10+.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Install fscrypt and do setup&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install fscrypt libpam-fscrypt&lt;br /&gt;
sudo fscrypt setup&lt;br /&gt;
sudo fscrypt setup /&lt;br /&gt;
sudo tune2fs -O encrypt /dev/&amp;lt;yourdevice&amp;gt;&lt;br /&gt;
# E.g. sudo tune2fs -O encrypt /dev/sda5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Create a new temp sudo user and login to it&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Create the encrypted home folder&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
export USERNAME=david&lt;br /&gt;
# Move old home folder&lt;br /&gt;
sudo mv /home/$USERNAME /home/$USERNAME.bak&lt;br /&gt;
&lt;br /&gt;
# Create a new home folder and encrypt it&lt;br /&gt;
mkdir /home/$USERNAME&lt;br /&gt;
chown $USERNAME:$USERNAME /home/$USERNAME&lt;br /&gt;
fscrypt encrypt /home/$USERNAME --user=$USERNAME&lt;br /&gt;
&lt;br /&gt;
# Copy files to the new home folder using cp or rsync&lt;br /&gt;
# cp -a -T /home/$USERNAME.bak /home&lt;br /&gt;
rsync -aHX --info=progress2 /home/$USERNAME.bak/ /home/$USERNAME/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Test the encrypted home folder by logging into your user&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Cleanup by removing the temporary user and deleting the old home folder&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
shred /home/$USERNAME.bak/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes and Caveats&lt;br /&gt;
* &amp;lt;code&amp;gt;systemd&amp;lt;/code&amp;gt; will no longer have access to your home so all startup apps should be placed elsewhere&lt;br /&gt;
** E.g. Move all startup scripts in your &amp;lt;code&amp;gt;~/.local/bin&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;/usr/local/bin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; will not work until home has been decrypted since the authorized keys are in &amp;lt;code&amp;gt;~/.ssh/authorized_keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{hidden | SSH Workaround |&lt;br /&gt;
Getting SSH to work with an encrypted home dir is a giant pain.  &lt;br /&gt;
Also things like tmux still won&#039;t work.  &lt;br /&gt;
Overall I do not recommend doing this on a server.&lt;br /&gt;
&lt;br /&gt;
# Move ssh keys elsewhere such as &amp;lt;code&amp;gt;/etc/ssh/authorized_keys/&amp;lt;user&amp;gt;&amp;lt;/code&amp;gt;. &lt;br /&gt;
#* Add &amp;lt;code&amp;gt;/etc/ssh/authorized_keys/%u&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;AuthorizedKeysFile&amp;lt;/code&amp;gt; line in &amp;lt;code&amp;gt;/etc/ssh/sshd_config&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Create a sudo user with and unencrypted home directory.&lt;br /&gt;
# After every restart, ssh into the unencrypted sudo user and decrypt your home directory: &lt;br /&gt;
#* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sudo fscrypt unlock /home/david --user=david&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Then ssh into your account.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==SFTP==&lt;br /&gt;
You can create a specific user with a chroot to limit SFTP to specific folders.  &lt;br /&gt;
See [[Archwiki: SFTP chroot]] for details.&lt;br /&gt;
/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Subsystem sftp /usr/lib/ssh/sftp-server&lt;br /&gt;
&lt;br /&gt;
Match Group sftponly&lt;br /&gt;
  ChrootDirectory %h&lt;br /&gt;
  ForceCommand internal-sftp&lt;br /&gt;
  AllowTcpForwarding no&lt;br /&gt;
  X11Forwarding no&lt;br /&gt;
  PasswordAuthentication no&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hardware Info==&lt;br /&gt;
&lt;br /&gt;
;Benchmarking&lt;br /&gt;
Basic CPU benchmark&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sysbench cpu --threads=2 run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==MOTD==&lt;br /&gt;
Message of the day is the text you see when you login via SSH.  &lt;br /&gt;
Ubuntu stores its MOTD in &amp;lt;code&amp;gt;/etc/update-motd.d/&amp;lt;/code&amp;gt;. Other distros use &amp;lt;code&amp;gt;/etc/motd/&amp;lt;/code&amp;gt;.  &lt;br /&gt;
You can disable the Ubuntu news motd in &amp;lt;code&amp;gt;/etc/default/motd-news&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==System Administration==&lt;br /&gt;
{{main | Linux Administration}}&lt;br /&gt;
&lt;br /&gt;
==Installing Binaries==&lt;br /&gt;
# Copy your binary to &amp;lt;code&amp;gt;/usr/local/bin/&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;~/.local/bin/&amp;lt;/code&amp;gt;&lt;br /&gt;
# Copy your man page to &amp;lt;code&amp;gt;/usr/local/share/man/man1/&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;~/.local/share/man/man1/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Network Troubleshooting==&lt;br /&gt;
On one of my OptiPlex 5060 servers, the network adapter would reset on git ssh clones.&amp;lt;br&amp;gt;&lt;br /&gt;
This would appear in &amp;lt;code&amp;gt;/var/log/syslog&amp;lt;/code&amp;gt; as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Feb  8 22:22:01 optiplex5060-2 kernel: [ 4378.992607] e1000e 0000:00:1f.6 eno1: Reset adapter unexpectedly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This was resolved by disabling TCP Segmentation Offload:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo ethtool -K eno1 tso off&lt;br /&gt;
&lt;br /&gt;
# Verify tso is disabled&lt;br /&gt;
ethtool -k eno1 | grep tcp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make this persist across reboots:&lt;br /&gt;
{{hidden | Script |&lt;br /&gt;
If you&#039;re using netplan (default for Ubuntu):&amp;lt;br&amp;gt;&lt;br /&gt;
[https://michael.mulqueen.me.uk/2018/08/disable-offloading-netplan-ubuntu/ Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
output_path=/usr/lib/networkd-dispatcher/routable.d/10-disable-offloading&lt;br /&gt;
sudo tee $output_path &amp;lt;&amp;lt;EOF&amp;gt; /dev/null&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
ethtool -K eno1 tso off&lt;br /&gt;
EOF&lt;br /&gt;
sudo chmod +x $output_path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If using ifupdown:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
output_path=/etc/network/if-up.d/disable-tso&lt;br /&gt;
sudo tee $output_path &amp;lt;&amp;lt;EOF&amp;gt; /dev/null&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
ethtool -K eno1 tso off&lt;br /&gt;
EOF&lt;br /&gt;
sudo chmod +x $output_path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Cloning to a new disk==&lt;br /&gt;
The easiest way is to use gparted.&lt;br /&gt;
&lt;br /&gt;
{{hidden | Terminal Guide |&lt;br /&gt;
To do this in the terminal:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
OLD_DRIVE=/dev/sda&lt;br /&gt;
NEW_DRIVE=/dev/sdb&lt;br /&gt;
&lt;br /&gt;
# Show old drive partitions in sectors&lt;br /&gt;
parted $OLD_DRIVE unit s print free&lt;br /&gt;
&lt;br /&gt;
# Apply GPT&lt;br /&gt;
parted $NEW_DRIVE mklabel gpt&lt;br /&gt;
# Copy new EFI partition with start 1024s and end 1050623s&lt;br /&gt;
parted $NEW_DRIVE mkpart primary fat32 2048s 1050623s&lt;br /&gt;
# Apply boot and esp flags.&lt;br /&gt;
parted $NEW_DRIVE set 1 boot on&lt;br /&gt;
parted $NEW_DRIVE set 1 esp on&lt;br /&gt;
parted $NEW_DRIVE name 1 &#039;EFI System Partition&#039;&lt;br /&gt;
# dd the old to the new&lt;br /&gt;
dd if=${OLD_DRIVE}1 of=${NEW_DRIVE}1 bs=4k&lt;br /&gt;
&lt;br /&gt;
# Make a new partition. Make sure start and end sectors are aligned.&lt;br /&gt;
# i.e. start % 8 == 0 and end % 8 == 7 if your physical sector size is 4096 bytes, typical for new HDDs and SSDs.&lt;br /&gt;
parted $NEW_DRIVE mkpart primary btrfs 1050624s 488396791s&lt;br /&gt;
parted $NEW_DRIVE align-check opt 2&lt;br /&gt;
&lt;br /&gt;
# Copy the filesystem&lt;br /&gt;
mkfs.btrfs ${NEW_DRIVE}2&lt;br /&gt;
mkdir /media/${NEW_DRIVE}&lt;br /&gt;
mount -t btrfs -o compress=zstd /media/${NEW_DRIVE}2&lt;br /&gt;
rsync -axHAWXS --numeric-ids --info=progress2 /media/${NEW_DRIVE}2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://superuser.com/questions/307541/copy-entire-file-system-hierarchy-from-one-drive-to-another rsync reference]&lt;br /&gt;
&lt;br /&gt;
;rsync options&lt;br /&gt;
* -a     archive mode&lt;br /&gt;
* -x     one file system&lt;br /&gt;
* -H     preserve hard links&lt;br /&gt;
* -A     preserve ACLs&lt;br /&gt;
* -W     copy whole files instead of deltas&lt;br /&gt;
* -X     preserve extended attributes&lt;br /&gt;
* -S     handle sparse files efficiently&lt;br /&gt;
* --numeric-ids    use id instead of uid/gid&lt;br /&gt;
&lt;br /&gt;
To copy a root partition, make sure you change the following on the new drive:&lt;br /&gt;
* Update the UUID and mount options in &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
* Update the UUID in &amp;lt;code&amp;gt;/boot/grub/grub.cfg&amp;lt;/code&amp;gt; and run &amp;lt;code&amp;gt;update-grub&amp;lt;/code&amp;gt;&lt;br /&gt;
* Update the UUID in &amp;lt;code&amp;gt;/boot/EFI/ubuntu/grub.cfg&amp;lt;/code&amp;gt;&lt;br /&gt;
* Run [https://help.ubuntu.com/community/Boot-Repair boot-repair] from a live disk if you run into any issues.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Ubuntu==&lt;br /&gt;
Ubuntu-specific notes&lt;br /&gt;
&lt;br /&gt;
===Disable ESM message===&lt;br /&gt;
[https://askubuntu.com/questions/1453749/inhibit-esm-messages-at-login Reference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Disable MOTD&lt;br /&gt;
sudo chmod -x /etc/update-motd.d/88-esm-announce&lt;br /&gt;
sudo chmod -x /etc/update-motd.d/91-contract-ua-esm-status&lt;br /&gt;
&lt;br /&gt;
# Disable APT check&lt;br /&gt;
sudo sed -Ezi.orig \&lt;br /&gt;
  -e &#039;s/(def _output_esm_service_status.outstream, have_esm_service, service_type.:\n)/\1    return\n/&#039; \&lt;br /&gt;
  -e &#039;s/(def _output_esm_package_alert.*?\n.*?\n.:\n)/\1    return\n/&#039; \&lt;br /&gt;
  /usr/lib/update-notifier/apt_check.py&lt;br /&gt;
sudo /usr/lib/update-notifier/update-motd-updates-available --force&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Main_Page&amp;diff=7201</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Main_Page&amp;diff=7201"/>
		<updated>2025-12-21T23:12:07Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to David Li&#039;s wiki.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:flex;flex-direction:row;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;main-card-container&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Programming&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[C++]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[JavaScript]], [[TypeScript]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[NodeJS]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Python]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Bash (Unix shell) | Bash]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Libraries&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[PyTorch]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[TensorFlow]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[OpenCV]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Frameworks&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Laravel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Unity]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[React (JavaScript library) | React]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Angular (web framework) | Angular]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Software Tools&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Git]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[FFmpeg]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Rclone]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Theory&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Geometric Computer Vision | 3D Vision]], [[Visual Learning and Recognition | Recognition]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Computer Graphics | Graphics]], [[Advanced Computer Graphics | Advanced Graphics]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Machine Learning]], [[Deep Learning]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Typesetting&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Latex]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Markdown]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Wikitext]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Operating Systems&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Linux]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[macOS]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[NixOS]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Windows]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Editors&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Visual Studio Code]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Vim (text editor) | Vim]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Containers&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Docker (software) | Docker]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Kubernetes]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
===General Purpose===&lt;br /&gt;
* [[C (programming_language)]]&lt;br /&gt;
* [[C++]]&lt;br /&gt;
* [[Rust (programming language)]]&lt;br /&gt;
* [[C Sharp|C#]]&lt;br /&gt;
* [[Java]]&lt;br /&gt;
* [[Kotlin]]&lt;br /&gt;
* [[Bash (Unix shell)]]&lt;br /&gt;
&lt;br /&gt;
===Web Programming===&lt;br /&gt;
* [[JavaScript]]&lt;br /&gt;
* [[NodeJS]]&lt;br /&gt;
* [[WebGL]]&lt;br /&gt;
* [[PHP]]&lt;br /&gt;
* [[HTML]]&lt;br /&gt;
* [[Cascading Style Sheets | Cascading Style Sheets (CSS)]]&lt;br /&gt;
* [[Apache HTTP Server]]&lt;br /&gt;
* [[Caddy (web server)]]&lt;br /&gt;
&lt;br /&gt;
===Numerical Computation===&lt;br /&gt;
* [[Julia]]&lt;br /&gt;
* [[MATLAB]]&lt;br /&gt;
* [[Python]]&lt;br /&gt;
* [[Cython]]&lt;br /&gt;
* [[R]]&lt;br /&gt;
&lt;br /&gt;
===GPU Programming===&lt;br /&gt;
* [[CUDA]]&lt;br /&gt;
* [[OpenCL]]&lt;br /&gt;
* [[ROCm]]&lt;br /&gt;
* [[SYCL]]&lt;br /&gt;
&lt;br /&gt;
====Shader Languages====&lt;br /&gt;
* [[GLSL]]&lt;br /&gt;
* [[HLSL]]&lt;br /&gt;
&lt;br /&gt;
===Typesetting===&lt;br /&gt;
* [[Latex]]&lt;br /&gt;
** [[PGF/TikZ | TikZ]]&lt;br /&gt;
* [[Markdown]]&lt;br /&gt;
* [[Markdeep]]&lt;br /&gt;
&lt;br /&gt;
==Frameworks==&lt;br /&gt;
&lt;br /&gt;
===Game Development===&lt;br /&gt;
* [[Unity]]&lt;br /&gt;
&lt;br /&gt;
===Web Development===&lt;br /&gt;
&lt;br /&gt;
;Front-end Frameworks&lt;br /&gt;
* [[Angular (web framework)]]&lt;br /&gt;
* [[React (JavaScript library)]] See ([[Next.js]])&lt;br /&gt;
* [[Vue.js]]&lt;br /&gt;
&lt;br /&gt;
;Back-end Frameworks&lt;br /&gt;
* [[Laravel]]&lt;br /&gt;
* [[Express.js]]&lt;br /&gt;
&lt;br /&gt;
;CSS Libraries&lt;br /&gt;
* [[Bootstrap]]&lt;br /&gt;
* [https://bulma.io/ Bulma]&lt;br /&gt;
&lt;br /&gt;
;Databases&lt;br /&gt;
* [[MySQL]]&lt;br /&gt;
&lt;br /&gt;
===App Development===&lt;br /&gt;
* [[Android System Development]]&lt;br /&gt;
* [[Android App Development]]&lt;br /&gt;
* [[Android Native Development]]&lt;br /&gt;
&lt;br /&gt;
==Machine Learning==&lt;br /&gt;
* [[Hyperparameters]]&lt;br /&gt;
* [[Machine Learning Glossary]]&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
* [[Flux]]&lt;br /&gt;
* [[TensorFlow]]&lt;br /&gt;
* [[PyTorch]]&lt;br /&gt;
&lt;br /&gt;
====Visualization Tools====&lt;br /&gt;
* [[TensorBoard]]&lt;br /&gt;
&lt;br /&gt;
===Applications===&lt;br /&gt;
* [[Neural Physics]]&lt;br /&gt;
* [https://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/ Fizz Buzz]&lt;br /&gt;
&lt;br /&gt;
===Architectures===&lt;br /&gt;
* [[Convolutional neural network | Convolutional neural network (CNNs)]]&lt;br /&gt;
* [[Generative adversarial network | Generative Adversarial Networks (GANs)]]&lt;br /&gt;
* [[Long short-term memory | Long short-term memory (LSTM)]] &lt;br /&gt;
* [[Transformer (machine learning model)]]&lt;br /&gt;
* [[Capsule neural network]]&lt;br /&gt;
* [[Siamese neural network]]&lt;br /&gt;
* [[Graph neural network]]&lt;br /&gt;
&lt;br /&gt;
===Research Areas===&lt;br /&gt;
* [[Adversarial machine learning]]&lt;br /&gt;
** [[Adversarial Examples]]&lt;br /&gt;
** [[Poisoning Attacks]]&lt;br /&gt;
* [[Zero-Shot Learning]]&lt;br /&gt;
&lt;br /&gt;
==Computer Vision==&lt;br /&gt;
* [[List of Feature Descriptors]]&lt;br /&gt;
* [[Essential Matrix]]&lt;br /&gt;
&lt;br /&gt;
==Libraries==&lt;br /&gt;
;Video and Audio&lt;br /&gt;
* [[FFmpeg]]&lt;br /&gt;
&lt;br /&gt;
;Graphics&lt;br /&gt;
* [[GLFW]]&lt;br /&gt;
* [[three.js]]&lt;br /&gt;
* [[Open3D]]&lt;br /&gt;
&lt;br /&gt;
;Vision&lt;br /&gt;
* [[OpenCV]]&lt;br /&gt;
&lt;br /&gt;
;Math&lt;br /&gt;
* [[Eigen (C++ library)]]&lt;br /&gt;
&lt;br /&gt;
;Web Development&lt;br /&gt;
* [[Webpack]]&lt;br /&gt;
&lt;br /&gt;
==Software and Tools==&lt;br /&gt;
&lt;br /&gt;
===Software Engineering===&lt;br /&gt;
* [[CMake]]&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Git]], [[GitLab]]&lt;br /&gt;
* [[GNU Compiler Collection | GNU Compiler Collection (GCC)]]&lt;br /&gt;
&lt;br /&gt;
===Text Editors and IDEs===&lt;br /&gt;
* [[Visual Studio Code]]&lt;br /&gt;
* [[Emacs]]&lt;br /&gt;
* [[Vim (text editor)]]&lt;br /&gt;
&lt;br /&gt;
===Photo/Video Editing===&lt;br /&gt;
* [[Adobe Premiere Pro]]&lt;br /&gt;
* [[DaVinci Resolve]]&lt;br /&gt;
&lt;br /&gt;
===3D Modeling===&lt;br /&gt;
* [[Blender (software)]]&lt;br /&gt;
&lt;br /&gt;
===Office===&lt;br /&gt;
* [[Microsoft Powerpoint]]&lt;br /&gt;
&lt;br /&gt;
===Misc===&lt;br /&gt;
* [[Useful Node Programs]]&lt;br /&gt;
* [[Google Chrome]]&lt;br /&gt;
* [[Conda (package manager)]]&lt;br /&gt;
&lt;br /&gt;
==Operating Systems==&lt;br /&gt;
* [[Linux]]&lt;br /&gt;
* [[macOS]]&lt;br /&gt;
* [[Windows]]&lt;br /&gt;
* [[Android (operating system) | Android]]&lt;br /&gt;
&lt;br /&gt;
===Environments===&lt;br /&gt;
* [[Cygwin]]&lt;br /&gt;
* [[MSYS2]]&lt;br /&gt;
* [[Kernel-based Virtual Machine | Kernel-based Virtual Machine (KVM)]]&lt;br /&gt;
&lt;br /&gt;
===Containers===&lt;br /&gt;
* [[Docker (software)]]&lt;br /&gt;
* [[Kubernetes]]&lt;br /&gt;
&lt;br /&gt;
==Research==&lt;br /&gt;
&lt;br /&gt;
===Surveys===&lt;br /&gt;
* [[Steganography]]&lt;br /&gt;
* [[Natural language processing]]&lt;br /&gt;
* [[Spherical Harmonics]]&lt;br /&gt;
* [[Image Compression]]&lt;br /&gt;
* [[Video Compression]]&lt;br /&gt;
* [[Depth Estimation]]&lt;br /&gt;
* [[Single Image Animation]]&lt;br /&gt;
* [[Foveated Rendering]]&lt;br /&gt;
* [[Texture Synthesis]]&lt;br /&gt;
* [[Image Registration]]&lt;br /&gt;
* [[Image quality assessment]]&lt;br /&gt;
* [[Image-based rendering]]&lt;br /&gt;
&lt;br /&gt;
===Communication===&lt;br /&gt;
* [[Computer Science Conferences]]&lt;br /&gt;
* [[Giving Talks]]&lt;br /&gt;
* [[Writing Papers]]&lt;br /&gt;
* [[Reading Papers]]&lt;br /&gt;
* [[Reviewing Papers]]&lt;br /&gt;
* [[Writing Rebuttals]]&lt;br /&gt;
&lt;br /&gt;
==Math and Theory==&lt;br /&gt;
&lt;br /&gt;
===Machine Learning===&lt;br /&gt;
* [[Machine Learning]]&lt;br /&gt;
** [[Supervised Learning]]&lt;br /&gt;
** [[Unsupervised Learning]]&lt;br /&gt;
** [[Reinforcement Learning]]&lt;br /&gt;
** [[Transfer Learning]]&lt;br /&gt;
** Domain Adaptation&lt;br /&gt;
** [[Ensemble Learning]]&lt;br /&gt;
&lt;br /&gt;
* [[Deep Learning]]&lt;br /&gt;
&lt;br /&gt;
===Mathematics===&lt;br /&gt;
* [[Advanced Calculus]]&lt;br /&gt;
* [[Linear Algebra]]&lt;br /&gt;
* [[Probability]]&lt;br /&gt;
** [[Stochastic Processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Statistics]]&lt;br /&gt;
* [[Numerical Analysis]]&lt;br /&gt;
** [[Numerical Optimization]]&lt;br /&gt;
&lt;br /&gt;
===Computer Science===&lt;br /&gt;
* [[Algorithms]]&lt;br /&gt;
** [[Interview Algorithms]]&lt;br /&gt;
** [[Parallel Algorithms]]&lt;br /&gt;
** [[Graph Theory]]&lt;br /&gt;
&lt;br /&gt;
* [[Computer Graphics]]&lt;br /&gt;
** [[Advanced Computer Graphics]]&lt;br /&gt;
&lt;br /&gt;
* [[Computer Vision]]&lt;br /&gt;
** [[Geometric Computer Vision]]&lt;br /&gt;
** [[Visual Learning and Recognition]]&lt;br /&gt;
&lt;br /&gt;
* [[Data Structures]]&lt;br /&gt;
** [[Multidimensional Data Structures]]&lt;br /&gt;
&lt;br /&gt;
* Computer Systems&lt;br /&gt;
** Computer Architecture&lt;br /&gt;
** [[Computer Networking]]&lt;br /&gt;
&lt;br /&gt;
==Glossaries==&lt;br /&gt;
* [[Machine Learning Glossary]]&lt;br /&gt;
* [[New Technology Glossary]]&lt;br /&gt;
&lt;br /&gt;
==Misc==&lt;br /&gt;
* [[MediaWiki]]&lt;br /&gt;
* [[Regular Expressions|Regular Expressions (Regex)]]&lt;br /&gt;
* [[Preprocessor Macros]]&lt;br /&gt;
* [[Credit Cards]]&lt;br /&gt;
* [[Investing]]&lt;br /&gt;
* [[Technical Interviews]]&lt;br /&gt;
* [[Datasets]]&lt;br /&gt;
* [[Homelab]]&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Main_Page&amp;diff=7200</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Main_Page&amp;diff=7200"/>
		<updated>2025-12-21T23:11:46Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to David Li&#039;s wiki.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:flex;flex-direction:row;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;main-card-container&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Programming&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[C++]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[JavaScript]], [[TypeScript]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[NodeJS]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Python]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Bash (Unix shell) | Bash]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Libraries&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[PyTorch]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[TensorFlow]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[OpenCV]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Frameworks&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Laravel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Unity]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[React (JavaScript library) | React]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Angular (web framework) | Angular]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Software Tools&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Git]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[FFmpeg]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Rclone]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Theory&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Geometric Computer Vision | 3D Vision]], [[Visual Learning and Recognition | Recognition]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Computer Graphics | Graphics]], [[Advanced Computer Graphics | Advanced Graphics]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Machine Learning]], [[Deep Learning]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Typesetting&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Latex]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Markdown]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Wikitext]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Operating Systems&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Linux]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[macOS]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[NixOS]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Editors&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Visual Studio Code]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Vim (text editor) | Vim]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;main-flex-card&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;main-card-header&amp;quot;&amp;gt;Containers&amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Docker (software) | Docker]]&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;[[Kubernetes]]&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
===General Purpose===&lt;br /&gt;
* [[C (programming_language)]]&lt;br /&gt;
* [[C++]]&lt;br /&gt;
* [[Rust (programming language)]]&lt;br /&gt;
* [[C Sharp|C#]]&lt;br /&gt;
* [[Java]]&lt;br /&gt;
* [[Kotlin]]&lt;br /&gt;
* [[Bash (Unix shell)]]&lt;br /&gt;
&lt;br /&gt;
===Web Programming===&lt;br /&gt;
* [[JavaScript]]&lt;br /&gt;
* [[NodeJS]]&lt;br /&gt;
* [[WebGL]]&lt;br /&gt;
* [[PHP]]&lt;br /&gt;
* [[HTML]]&lt;br /&gt;
* [[Cascading Style Sheets | Cascading Style Sheets (CSS)]]&lt;br /&gt;
* [[Apache HTTP Server]]&lt;br /&gt;
* [[Caddy (web server)]]&lt;br /&gt;
&lt;br /&gt;
===Numerical Computation===&lt;br /&gt;
* [[Julia]]&lt;br /&gt;
* [[MATLAB]]&lt;br /&gt;
* [[Python]]&lt;br /&gt;
* [[Cython]]&lt;br /&gt;
* [[R]]&lt;br /&gt;
&lt;br /&gt;
===GPU Programming===&lt;br /&gt;
* [[CUDA]]&lt;br /&gt;
* [[OpenCL]]&lt;br /&gt;
* [[ROCm]]&lt;br /&gt;
* [[SYCL]]&lt;br /&gt;
&lt;br /&gt;
====Shader Languages====&lt;br /&gt;
* [[GLSL]]&lt;br /&gt;
* [[HLSL]]&lt;br /&gt;
&lt;br /&gt;
===Typesetting===&lt;br /&gt;
* [[Latex]]&lt;br /&gt;
** [[PGF/TikZ | TikZ]]&lt;br /&gt;
* [[Markdown]]&lt;br /&gt;
* [[Markdeep]]&lt;br /&gt;
&lt;br /&gt;
==Frameworks==&lt;br /&gt;
&lt;br /&gt;
===Game Development===&lt;br /&gt;
* [[Unity]]&lt;br /&gt;
&lt;br /&gt;
===Web Development===&lt;br /&gt;
&lt;br /&gt;
;Front-end Frameworks&lt;br /&gt;
* [[Angular (web framework)]]&lt;br /&gt;
* [[React (JavaScript library)]] See ([[Next.js]])&lt;br /&gt;
* [[Vue.js]]&lt;br /&gt;
&lt;br /&gt;
;Back-end Frameworks&lt;br /&gt;
* [[Laravel]]&lt;br /&gt;
* [[Express.js]]&lt;br /&gt;
&lt;br /&gt;
;CSS Libraries&lt;br /&gt;
* [[Bootstrap]]&lt;br /&gt;
* [https://bulma.io/ Bulma]&lt;br /&gt;
&lt;br /&gt;
;Databases&lt;br /&gt;
* [[MySQL]]&lt;br /&gt;
&lt;br /&gt;
===App Development===&lt;br /&gt;
* [[Android System Development]]&lt;br /&gt;
* [[Android App Development]]&lt;br /&gt;
* [[Android Native Development]]&lt;br /&gt;
&lt;br /&gt;
==Machine Learning==&lt;br /&gt;
* [[Hyperparameters]]&lt;br /&gt;
* [[Machine Learning Glossary]]&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
* [[Flux]]&lt;br /&gt;
* [[TensorFlow]]&lt;br /&gt;
* [[PyTorch]]&lt;br /&gt;
&lt;br /&gt;
====Visualization Tools====&lt;br /&gt;
* [[TensorBoard]]&lt;br /&gt;
&lt;br /&gt;
===Applications===&lt;br /&gt;
* [[Neural Physics]]&lt;br /&gt;
* [https://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/ Fizz Buzz]&lt;br /&gt;
&lt;br /&gt;
===Architectures===&lt;br /&gt;
* [[Convolutional neural network | Convolutional neural network (CNNs)]]&lt;br /&gt;
* [[Generative adversarial network | Generative Adversarial Networks (GANs)]]&lt;br /&gt;
* [[Long short-term memory | Long short-term memory (LSTM)]] &lt;br /&gt;
* [[Transformer (machine learning model)]]&lt;br /&gt;
* [[Capsule neural network]]&lt;br /&gt;
* [[Siamese neural network]]&lt;br /&gt;
* [[Graph neural network]]&lt;br /&gt;
&lt;br /&gt;
===Research Areas===&lt;br /&gt;
* [[Adversarial machine learning]]&lt;br /&gt;
** [[Adversarial Examples]]&lt;br /&gt;
** [[Poisoning Attacks]]&lt;br /&gt;
* [[Zero-Shot Learning]]&lt;br /&gt;
&lt;br /&gt;
==Computer Vision==&lt;br /&gt;
* [[List of Feature Descriptors]]&lt;br /&gt;
* [[Essential Matrix]]&lt;br /&gt;
&lt;br /&gt;
==Libraries==&lt;br /&gt;
;Video and Audio&lt;br /&gt;
* [[FFmpeg]]&lt;br /&gt;
&lt;br /&gt;
;Graphics&lt;br /&gt;
* [[GLFW]]&lt;br /&gt;
* [[three.js]]&lt;br /&gt;
* [[Open3D]]&lt;br /&gt;
&lt;br /&gt;
;Vision&lt;br /&gt;
* [[OpenCV]]&lt;br /&gt;
&lt;br /&gt;
;Math&lt;br /&gt;
* [[Eigen (C++ library)]]&lt;br /&gt;
&lt;br /&gt;
;Web Development&lt;br /&gt;
* [[Webpack]]&lt;br /&gt;
&lt;br /&gt;
==Software and Tools==&lt;br /&gt;
&lt;br /&gt;
===Software Engineering===&lt;br /&gt;
* [[CMake]]&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Git]], [[GitLab]]&lt;br /&gt;
* [[GNU Compiler Collection | GNU Compiler Collection (GCC)]]&lt;br /&gt;
&lt;br /&gt;
===Text Editors and IDEs===&lt;br /&gt;
* [[Visual Studio Code]]&lt;br /&gt;
* [[Emacs]]&lt;br /&gt;
* [[Vim (text editor)]]&lt;br /&gt;
&lt;br /&gt;
===Photo/Video Editing===&lt;br /&gt;
* [[Adobe Premiere Pro]]&lt;br /&gt;
* [[DaVinci Resolve]]&lt;br /&gt;
&lt;br /&gt;
===3D Modeling===&lt;br /&gt;
* [[Blender (software)]]&lt;br /&gt;
&lt;br /&gt;
===Office===&lt;br /&gt;
* [[Microsoft Powerpoint]]&lt;br /&gt;
&lt;br /&gt;
===Misc===&lt;br /&gt;
* [[Useful Node Programs]]&lt;br /&gt;
* [[Google Chrome]]&lt;br /&gt;
* [[Conda (package manager)]]&lt;br /&gt;
&lt;br /&gt;
==Operating Systems==&lt;br /&gt;
* [[Linux]]&lt;br /&gt;
* [[macOS]]&lt;br /&gt;
* [[Windows]]&lt;br /&gt;
* [[Android (operating system) | Android]]&lt;br /&gt;
&lt;br /&gt;
===Environments===&lt;br /&gt;
* [[Cygwin]]&lt;br /&gt;
* [[MSYS2]]&lt;br /&gt;
* [[Kernel-based Virtual Machine | Kernel-based Virtual Machine (KVM)]]&lt;br /&gt;
&lt;br /&gt;
===Containers===&lt;br /&gt;
* [[Docker (software)]]&lt;br /&gt;
* [[Kubernetes]]&lt;br /&gt;
&lt;br /&gt;
==Research==&lt;br /&gt;
&lt;br /&gt;
===Surveys===&lt;br /&gt;
* [[Steganography]]&lt;br /&gt;
* [[Natural language processing]]&lt;br /&gt;
* [[Spherical Harmonics]]&lt;br /&gt;
* [[Image Compression]]&lt;br /&gt;
* [[Video Compression]]&lt;br /&gt;
* [[Depth Estimation]]&lt;br /&gt;
* [[Single Image Animation]]&lt;br /&gt;
* [[Foveated Rendering]]&lt;br /&gt;
* [[Texture Synthesis]]&lt;br /&gt;
* [[Image Registration]]&lt;br /&gt;
* [[Image quality assessment]]&lt;br /&gt;
* [[Image-based rendering]]&lt;br /&gt;
&lt;br /&gt;
===Communication===&lt;br /&gt;
* [[Computer Science Conferences]]&lt;br /&gt;
* [[Giving Talks]]&lt;br /&gt;
* [[Writing Papers]]&lt;br /&gt;
* [[Reading Papers]]&lt;br /&gt;
* [[Reviewing Papers]]&lt;br /&gt;
* [[Writing Rebuttals]]&lt;br /&gt;
&lt;br /&gt;
==Math and Theory==&lt;br /&gt;
&lt;br /&gt;
===Machine Learning===&lt;br /&gt;
* [[Machine Learning]]&lt;br /&gt;
** [[Supervised Learning]]&lt;br /&gt;
** [[Unsupervised Learning]]&lt;br /&gt;
** [[Reinforcement Learning]]&lt;br /&gt;
** [[Transfer Learning]]&lt;br /&gt;
** Domain Adaptation&lt;br /&gt;
** [[Ensemble Learning]]&lt;br /&gt;
&lt;br /&gt;
* [[Deep Learning]]&lt;br /&gt;
&lt;br /&gt;
===Mathematics===&lt;br /&gt;
* [[Advanced Calculus]]&lt;br /&gt;
* [[Linear Algebra]]&lt;br /&gt;
* [[Probability]]&lt;br /&gt;
** [[Stochastic Processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Statistics]]&lt;br /&gt;
* [[Numerical Analysis]]&lt;br /&gt;
** [[Numerical Optimization]]&lt;br /&gt;
&lt;br /&gt;
===Computer Science===&lt;br /&gt;
* [[Algorithms]]&lt;br /&gt;
** [[Interview Algorithms]]&lt;br /&gt;
** [[Parallel Algorithms]]&lt;br /&gt;
** [[Graph Theory]]&lt;br /&gt;
&lt;br /&gt;
* [[Computer Graphics]]&lt;br /&gt;
** [[Advanced Computer Graphics]]&lt;br /&gt;
&lt;br /&gt;
* [[Computer Vision]]&lt;br /&gt;
** [[Geometric Computer Vision]]&lt;br /&gt;
** [[Visual Learning and Recognition]]&lt;br /&gt;
&lt;br /&gt;
* [[Data Structures]]&lt;br /&gt;
** [[Multidimensional Data Structures]]&lt;br /&gt;
&lt;br /&gt;
* Computer Systems&lt;br /&gt;
** Computer Architecture&lt;br /&gt;
** [[Computer Networking]]&lt;br /&gt;
&lt;br /&gt;
==Glossaries==&lt;br /&gt;
* [[Machine Learning Glossary]]&lt;br /&gt;
* [[New Technology Glossary]]&lt;br /&gt;
&lt;br /&gt;
==Misc==&lt;br /&gt;
* [[MediaWiki]]&lt;br /&gt;
* [[Regular Expressions|Regular Expressions (Regex)]]&lt;br /&gt;
* [[Preprocessor Macros]]&lt;br /&gt;
* [[Credit Cards]]&lt;br /&gt;
* [[Investing]]&lt;br /&gt;
* [[Technical Interviews]]&lt;br /&gt;
* [[Datasets]]&lt;br /&gt;
* [[Homelab]]&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7199</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7199"/>
		<updated>2025-12-21T23:10:29Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Install ==&lt;br /&gt;
The graphical installer is trivial. However, the minimal ISO doesn&#039;t handle partitioning for you.&lt;br /&gt;
&lt;br /&gt;
=== Partitioning and Formatting ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;gt;&lt;br /&gt;
# Create a new GPT partition table&lt;br /&gt;
parted /dev/sda -- mklabel gpt&lt;br /&gt;
&lt;br /&gt;
# Create the EFI Boot partition&lt;br /&gt;
parted /dev/sda -- mkpart ESP fat32 1MB 512MB&lt;br /&gt;
parted /dev/sda -- set 1 esp on&lt;br /&gt;
&lt;br /&gt;
# Create the Root partition (ext4)&lt;br /&gt;
parted /dev/sda -- mkpart primary ext4 512MB 100%&lt;br /&gt;
&lt;br /&gt;
# Format partitions&lt;br /&gt;
mkfs.fat -F 32 -n boot /dev/sda1&lt;br /&gt;
mkfs.ext4 -L nixos /dev/sda2&lt;br /&gt;
&lt;br /&gt;
# Mount the root partition&lt;br /&gt;
mount /dev/disk/by-label/nixos /mnt&lt;br /&gt;
&lt;br /&gt;
# Mount the boot partition&lt;br /&gt;
mkdir -p /mnt/boot&lt;br /&gt;
mount /dev/disk/by-label/boot /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create a 4GB swapfile (adjust size as needed)&lt;br /&gt;
dd if=/dev/zero of=/mnt/swapfile bs=1M count=4096&lt;br /&gt;
chmod 600 /mnt/swapfile&lt;br /&gt;
mkswap /mnt/swapfile&lt;br /&gt;
swapon /mnt/swapfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generate a config and install===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nixos-generate-config --root /mnt&lt;br /&gt;
# Edit the config to your desire&lt;br /&gt;
nano /mnt/etc/nixos/configuration.nix&lt;br /&gt;
&lt;br /&gt;
nixos-install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resources==&lt;br /&gt;
* https://nixos.org/manual/nixos/stable/&lt;br /&gt;
* https://wiki.nixos.org/wiki/NixOS_Wiki&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7198</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=NixOS&amp;diff=7198"/>
		<updated>2025-12-21T23:10:03Z</updated>

		<summary type="html">&lt;p&gt;David: Created page with &amp;quot; == Install == The graphical installer is trivial. However, the minimal ISO doesn&amp;#039;t handle partitioning for you.  === Partitioning and Formatting === ```bash # Create a new GPT partition table parted /dev/sda -- mklabel gpt  # Create the EFI Boot partition parted /dev/sda -- mkpart ESP fat32 1MB 512MB parted /dev/sda -- set 1 esp on  # Create the Root partition (ext4) parted /dev/sda -- mkpart primary ext4 512MB 100%  # Format partitions mkfs.fat -F 32 -n boot /dev/sda1...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Install ==&lt;br /&gt;
The graphical installer is trivial. However, the minimal ISO doesn&#039;t handle partitioning for you.&lt;br /&gt;
&lt;br /&gt;
=== Partitioning and Formatting ===&lt;br /&gt;
```bash&lt;br /&gt;
# Create a new GPT partition table&lt;br /&gt;
parted /dev/sda -- mklabel gpt&lt;br /&gt;
&lt;br /&gt;
# Create the EFI Boot partition&lt;br /&gt;
parted /dev/sda -- mkpart ESP fat32 1MB 512MB&lt;br /&gt;
parted /dev/sda -- set 1 esp on&lt;br /&gt;
&lt;br /&gt;
# Create the Root partition (ext4)&lt;br /&gt;
parted /dev/sda -- mkpart primary ext4 512MB 100%&lt;br /&gt;
&lt;br /&gt;
# Format partitions&lt;br /&gt;
mkfs.fat -F 32 -n boot /dev/sda1&lt;br /&gt;
mkfs.ext4 -L nixos /dev/sda2&lt;br /&gt;
&lt;br /&gt;
# Mount the root partition&lt;br /&gt;
mount /dev/disk/by-label/nixos /mnt&lt;br /&gt;
&lt;br /&gt;
# Mount the boot partition&lt;br /&gt;
mkdir -p /mnt/boot&lt;br /&gt;
mount /dev/disk/by-label/boot /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create a 4GB swapfile (adjust size as needed)&lt;br /&gt;
dd if=/dev/zero of=/mnt/swapfile bs=1M count=4096&lt;br /&gt;
chmod 600 /mnt/swapfile&lt;br /&gt;
mkswap /mnt/swapfile&lt;br /&gt;
swapon /mnt/swapfile&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
=== Generate a config and install===&lt;br /&gt;
```&lt;br /&gt;
nixos-generate-config --root /mnt&lt;br /&gt;
# Edit the config to your desire&lt;br /&gt;
nano /mnt/etc/nixos/configuration.nix&lt;br /&gt;
&lt;br /&gt;
nixos-install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
== Resources==&lt;br /&gt;
* https://nixos.org/manual/nixos/stable/&lt;br /&gt;
* https://wiki.nixos.org/wiki/NixOS_Wiki&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7197</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7197"/>
		<updated>2025-11-23T03:13:45Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Reset italic styling set by user agent */&lt;br /&gt;
cite, dfn {&lt;br /&gt;
	font-style: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Straight quote marks for &amp;lt;q&amp;gt; */&lt;br /&gt;
q {&lt;br /&gt;
	quotes: &#039;&amp;quot;&#039; &#039;&amp;quot;&#039; &amp;quot;&#039;&amp;quot; &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid collision of blockquote with floating elements by swapping margin and padding */&lt;br /&gt;
blockquote {&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	margin: 1em 0;&lt;br /&gt;
	padding: 0 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* give pre a float clearing new block formatting context */&lt;br /&gt;
/* Also break any really long words/urls to keep them visible in that case */&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
	overflow-x: hidden;&lt;br /&gt;
	overflow-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Consistent size for &amp;lt;small&amp;gt;, &amp;lt;sub&amp;gt; and &amp;lt;sup&amp;gt; */&lt;br /&gt;
small {&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content sub,&lt;br /&gt;
.mw-body-content sup,&lt;br /&gt;
span.reference /* for Parsoid */ {&lt;br /&gt;
	font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Same spacing for indented and unindented paragraphs on talk pages */&lt;br /&gt;
.ns-talk .mw-body-content dd {&lt;br /&gt;
	margin-top: 0.4em;&lt;br /&gt;
	margin-bottom: 0.4em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main page fixes */&lt;br /&gt;
#interwiki-completelist {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reduce page jumps by hiding collapsed/dismissed content */&lt;br /&gt;
.client-js .mw-special-Watchlist #watchlist-message,&lt;br /&gt;
.client-js .NavFrame.collapsed .NavContent,&lt;br /&gt;
.client-js .collapsible:not( .mw-made-collapsible).collapsed &amp;gt; tbody &amp;gt; tr:not(:first-child) {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Adds padding above Watchlist announcements where new recentchanges/watchlist filters are enabled */&lt;br /&gt;
.mw-rcfilters-enabled .mw-specialpage-summary {&lt;br /&gt;
	margin-top: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide charinsert base for those not using the gadget */&lt;br /&gt;
#editpage-specialchars {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight linked elements (such as clicked references) in blue */&lt;br /&gt;
body.action-info .mw-body-content :target,&lt;br /&gt;
.citation:target {&lt;br /&gt;
	background-color: #def;  /* Fallback */&lt;br /&gt;
	background-color: rgba(0, 127, 255, 0.133);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for citations. Breaks long urls, etc., rather than overflowing box */&lt;br /&gt;
.citation {&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For linked citation numbers and document IDs, where the number need not be shown&lt;br /&gt;
   on a screen or a handheld, but should be included in the printed version */&lt;br /&gt;
@media screen, handheld {&lt;br /&gt;
	.citation .printonly {&lt;br /&gt;
		display: none;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make the list of references smaller */&lt;br /&gt;
/* Keep in sync with Template:Refbegin/styles.css */&lt;br /&gt;
ol.references,&lt;br /&gt;
div.reflist {&lt;br /&gt;
	font-size: 90%;            /* Default font-size */&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.reflist ol.references {&lt;br /&gt;
	font-size: 100%;           /* Reset font-size when nested in div.reflist */&lt;br /&gt;
	margin-bottom: 0;          /* Avoid double margin when nested in div.reflist */&lt;br /&gt;
	list-style-type: inherit;  /* Enable custom list style types */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow hidden ref errors to be shown by user CSS */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
span.brokenref {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reset top margin for lists embedded in columns */&lt;br /&gt;
div.columns {&lt;br /&gt;
	margin-top: 0.3em;&lt;br /&gt;
}&lt;br /&gt;
div.columns dl,&lt;br /&gt;
div.columns ol,&lt;br /&gt;
div.columns ul {&lt;br /&gt;
	margin-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid elements breaking between columns */&lt;br /&gt;
.nocolbreak,&lt;br /&gt;
div.columns li,&lt;br /&gt;
div.columns dd dd {&lt;br /&gt;
	-webkit-column-break-inside: avoid;&lt;br /&gt;
	page-break-inside: avoid;&lt;br /&gt;
	break-inside: avoid-column;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for horizontal lists (separator following item).&lt;br /&gt;
   @source mediawiki.org/wiki/Snippets/Horizontal_lists&lt;br /&gt;
   @revision 8 (2016-05-21)&lt;br /&gt;
   @author [[User:Edokter]]&lt;br /&gt;
 */&lt;br /&gt;
.hlist dl,&lt;br /&gt;
.hlist ol,&lt;br /&gt;
.hlist ul {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Display list items inline */&lt;br /&gt;
.hlist dd,&lt;br /&gt;
.hlist dt,&lt;br /&gt;
.hlist li {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Display nested lists inline */&lt;br /&gt;
.hlist.inline,&lt;br /&gt;
.hlist.inline dl,&lt;br /&gt;
.hlist.inline ol,&lt;br /&gt;
.hlist.inline ul,&lt;br /&gt;
.hlist dl dl, .hlist dl ol, .hlist dl ul,&lt;br /&gt;
.hlist ol dl, .hlist ol ol, .hlist ol ul,&lt;br /&gt;
.hlist ul dl, .hlist ul ol, .hlist ul ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Hide empty list items */&lt;br /&gt;
.hlist .mw-empty-li {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Generate interpuncts */&lt;br /&gt;
.hlist dt:after {&lt;br /&gt;
	content: &amp;quot;: &amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * Note hlist style usage differd in&lt;br /&gt;
 * the Minerva skin. Remember .hlist is a class defined in core as well! Please check Minerva desktop (and Minerva.css) when changing&lt;br /&gt;
 * See https://phabricator.wikimedia.org/T213239&lt;br /&gt;
 */&lt;br /&gt;
.hlist dd:after,&lt;br /&gt;
.hlist li:after {&lt;br /&gt;
	content: &amp;quot; · &amp;quot;;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd:last-child:after,&lt;br /&gt;
.hlist dt:last-child:after,&lt;br /&gt;
.hlist li:last-child:after {&lt;br /&gt;
	content: none;&lt;br /&gt;
}&lt;br /&gt;
/* Add parentheses around nested lists */&lt;br /&gt;
.hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before,&lt;br /&gt;
.hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before,&lt;br /&gt;
.hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after,&lt;br /&gt;
.hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after,&lt;br /&gt;
.hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after {&lt;br /&gt;
	content: &amp;quot;)&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
/* Put ordinals in front of ordered list items */&lt;br /&gt;
.hlist ol {&lt;br /&gt;
	counter-reset: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li {&lt;br /&gt;
	counter-increment: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li:before {&lt;br /&gt;
	content: &amp;quot; &amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist dt ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist li ol &amp;gt; li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Unbulleted lists */&lt;br /&gt;
.plainlist ol,&lt;br /&gt;
.plainlist ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.plainlist ol li,&lt;br /&gt;
.plainlist ul li {&lt;br /&gt;
	margin-bottom: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default style for navigation boxes */&lt;br /&gt;
.navbox {                     /* Navbox container style */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	padding: 1px;&lt;br /&gt;
	margin: 1em auto 0;       /* Prevent preceding content from clinging to navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbox {&lt;br /&gt;
	margin-top: 0;            /* No top margin for nested navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox + .navbox {&lt;br /&gt;
	margin-top: -1px;         /* Single pixel border between adjacent navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox-inner,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-group,&lt;br /&gt;
.navbox-title,&lt;br /&gt;
.navbox-abovebelow {&lt;br /&gt;
	padding: 0.25em 1em;      /* Title, group and above/below styles */&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
th.navbox-group {             /* Group style */&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.navbox,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	background-color: #fdfdfd; /* Background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-list {&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	border-color: #fdfdfd;    /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
/* cell spacing for navbox cells */&lt;br /&gt;
tr + tr &amp;gt; .navbox-abovebelow,&lt;br /&gt;
tr + tr &amp;gt; .navbox-group,&lt;br /&gt;
tr + tr &amp;gt; .navbox-image,&lt;br /&gt;
tr + tr &amp;gt; .navbox-list {    /* Borders above 2nd, 3rd, etc. rows */&lt;br /&gt;
	border-top: 2px solid #fdfdfd; /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox th,&lt;br /&gt;
.navbox-title {&lt;br /&gt;
	background-color: #ccccff;      /* Level 1 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-abovebelow,&lt;br /&gt;
th.navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-title {&lt;br /&gt;
	background-color: #ddddff;      /* Level 2 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-subgroup .navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-abovebelow {&lt;br /&gt;
	background-color: #e6e6ff;      /* Level 3 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-even {&lt;br /&gt;
	background-color: #f7f7f7;      /* Even row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox-odd {&lt;br /&gt;
	background-color: transparent;  /* Odd row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox .hlist td dl,&lt;br /&gt;
.navbox .hlist td ol,&lt;br /&gt;
.navbox .hlist td ul,&lt;br /&gt;
.navbox td.hlist dl,&lt;br /&gt;
.navbox td.hlist ol,&lt;br /&gt;
.navbox td.hlist ul {&lt;br /&gt;
	padding: 0.125em 0;       /* Adjust hlist padding in navboxes */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default styling for Navbar template */&lt;br /&gt;
.navbar {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.navbar ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content .navbar ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
}&lt;br /&gt;
.navbar li {&lt;br /&gt;
	word-spacing: -0.125em;&lt;br /&gt;
}&lt;br /&gt;
.navbar.mini li abbr[title] {&lt;br /&gt;
	font-variant: small-caps;&lt;br /&gt;
	border-bottom: none;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	cursor: inherit;&lt;br /&gt;
}&lt;br /&gt;
/* Navbar styling when nested in infobox and navbox */&lt;br /&gt;
.infobox .navbar {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbar {&lt;br /&gt;
	display: block;&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-title .navbar {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin-right: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for JQuery makeCollapsible, matching that of collapseButton */&lt;br /&gt;
.mw-parser-output .mw-collapsible-toggle {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	padding-right: 0.2em;&lt;br /&gt;
	padding-left: 0.2em;&lt;br /&gt;
}&lt;br /&gt;
.mw-collapsible-leftside-toggle .mw-collapsible-toggle {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Infobox template style */&lt;br /&gt;
.infobox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	border-spacing: 3px;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	color: black;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0.5em 0 0.5em 1em;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
}&lt;br /&gt;
.infobox caption {&lt;br /&gt;
	font-size: 125%;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.infobox td,&lt;br /&gt;
.infobox th {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered td,&lt;br /&gt;
.infobox.bordered th {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered .borderless td,&lt;br /&gt;
.infobox.bordered .borderless th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.sisterproject {&lt;br /&gt;
	width: 20em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
.infobox.standard-talk.bordered td,&lt;br /&gt;
.infobox.standard-talk.bordered th {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* styles for bordered infobox with merged rows */&lt;br /&gt;
.infobox.bordered .mergedtoprow td,&lt;br /&gt;
.infobox.bordered .mergedtoprow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.bordered .mergedrow td,&lt;br /&gt;
.infobox.bordered .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styles for geography infoboxes, eg countries,&lt;br /&gt;
   country subdivisions, cities, etc.            */&lt;br /&gt;
.infobox.geography {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	line-height: 1.2em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography  td,&lt;br /&gt;
.infobox.geography  th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.infobox.geography .mergedtoprow td,&lt;br /&gt;
.infobox.geography .mergedtoprow th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedrow td,&lt;br /&gt;
.infobox.geography .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedbottomrow td,&lt;br /&gt;
.infobox.geography .mergedbottomrow th {&lt;br /&gt;
	border-top: 0;&lt;br /&gt;
	border-bottom: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .maptable td,&lt;br /&gt;
.infobox.geography .maptable th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Normal font styling for wikitable row headers with scope=&amp;quot;row&amp;quot; tag */&lt;br /&gt;
.wikitable.plainrowheaders th[scope=row] {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Lists in wikitable data cells are always left-aligned */&lt;br /&gt;
.wikitable td ul,&lt;br /&gt;
.wikitable td ol,&lt;br /&gt;
.wikitable td dl {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
/* ...unless they also use the hlist class */&lt;br /&gt;
.toc.hlist ul,&lt;br /&gt;
#toc.hlist ul,&lt;br /&gt;
.wikitable.hlist td ul,&lt;br /&gt;
.wikitable.hlist td ol,&lt;br /&gt;
.wikitable.hlist td dl {&lt;br /&gt;
	text-align: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icons for medialist templates [[Template:Listen]],&lt;br /&gt;
   [[Template:Multi-listen_start]], [[Template:Video]],&lt;br /&gt;
   [[Template:Multi-video_start]] */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
div.listenlist {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/4/47/Sound-icon.svg&amp;quot;) no-repeat scroll 0 0 transparent;&lt;br /&gt;
	background-size: 30px;&lt;br /&gt;
	padding-left: 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for hieroglyphs specificity issue in infoboxes ([[phab:T43869]]) */&lt;br /&gt;
table.mw-hiero-table td {&lt;br /&gt;
	vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Change the external link icon to an Adobe icon for all PDF files */&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.pdf&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf#&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.PDF&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF#&amp;quot;].external {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/2/23/Icons-mini-file_acrobat.gif&amp;quot;) no-repeat right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-right: 18px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Messagebox templates */&lt;br /&gt;
.messagebox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	width: 80%;&lt;br /&gt;
	margin: 0 auto 1em auto;&lt;br /&gt;
	padding: .2em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.merge {&lt;br /&gt;
	border: 1px solid #c0b8cc;&lt;br /&gt;
	background-color: #f0e5ff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.cleanup {&lt;br /&gt;
	border: 1px solid #9f9fff;&lt;br /&gt;
	background-color: #efefff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	margin: 4px auto;&lt;br /&gt;
}&lt;br /&gt;
/* For old WikiProject banners inside banner shells. */&lt;br /&gt;
.mbox-inside .standard-talk,&lt;br /&gt;
.messagebox.nested-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	margin: 2px 0;&lt;br /&gt;
	padding: 2px;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small-talk {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */&lt;br /&gt;
th.mbox-text, td.mbox-text {   /* The message body cell(s) */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 0.25em 0.9em;     /* 0.9em left/right */&lt;br /&gt;
	width: 100%;               /* Make all mboxes the same width regardless of text length */&lt;br /&gt;
}&lt;br /&gt;
td.mbox-image {                /* The left image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.9em;  /* 0.9em left, 0px right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-imageright {           /* The right image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.9em 2px 0;  /* 0px left, 0.9em right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-empty-cell {           /* An empty narrow cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Article message box styles */&lt;br /&gt;
table.ambox {&lt;br /&gt;
	margin: 0 10%;                  /* 10% = Will not overlap with other elements */&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;  /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.ambox + table.ambox {      /* Single border between stacked boxes. */&lt;br /&gt;
	margin-top: -1px;&lt;br /&gt;
}&lt;br /&gt;
.ambox th.mbox-text,&lt;br /&gt;
.ambox td.mbox-text {            /* The message body cell(s) */&lt;br /&gt;
	padding: 0.25em 0.5em;       /* 0.5em left/right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-image {           /* The left image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.5em;    /* 0.5em left, 0px right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-imageright {      /* The right image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.5em 2px 0;    /* 0px left, 0.5em right */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-notice {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-speedy {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;          /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-delete {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-content {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-style {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-move {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-protection {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Image message box styles */&lt;br /&gt;
table.imbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 3px solid #36c;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.imbox .mbox-text .imbox {  /* For imboxes inside imbox-text cells. */&lt;br /&gt;
	margin: 0 -0.5em;       /* 0.9 - 0.5 = 0.4em left/right.        */&lt;br /&gt;
	display: block;         /* Fix for webkit to force 100% width.  */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .imbox {       /* For imboxes inside other templates.  */&lt;br /&gt;
	margin: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-notice {&lt;br /&gt;
	border: 3px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-speedy {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-delete {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-content {&lt;br /&gt;
	border: 3px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-style {&lt;br /&gt;
	border: 3px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-move {&lt;br /&gt;
	border: 3px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-protection {&lt;br /&gt;
	border: 3px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-license {&lt;br /&gt;
	border: 3px solid #88a;       /* Dark gray */&lt;br /&gt;
	background-color: #f7f8ff;    /* Light gray */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-featured {&lt;br /&gt;
	border: 3px solid #cba135;    /* Brown-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Category message box styles */&lt;br /&gt;
table.cmbox {&lt;br /&gt;
	margin: 3px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #dfe8ff;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-notice {&lt;br /&gt;
	background-color: #d8e8ff;    /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-speedy {&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
	border: 4px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-delete {&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-content {&lt;br /&gt;
	background-color: #ffe7ce;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-style {&lt;br /&gt;
	background-color: #fff9db;    /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-move {&lt;br /&gt;
	background-color: #e4d8ff;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-protection {&lt;br /&gt;
	background-color: #efefe1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Other pages message box styles */&lt;br /&gt;
table.ombox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Default &amp;quot;notice&amp;quot; gray */&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-notice {&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Gray */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-content {&lt;br /&gt;
	border: 1px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-style {&lt;br /&gt;
	border: 1px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-move {&lt;br /&gt;
	border: 1px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-protection {&lt;br /&gt;
	border: 2px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Talk page message box styles */&lt;br /&gt;
table.tmbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #c0c090;    /* Default &amp;quot;notice&amp;quot; gray-brown */&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	min-width: 80%;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.tmbox.mbox-small {&lt;br /&gt;
	min-width: 0;                /* reset the min-width of tmbox above        */&lt;br /&gt;
}&lt;br /&gt;
.mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The &amp;quot;mediawiki&amp;quot; class ensures that */&lt;br /&gt;
	margin: 2px 0;               /* this declaration overrides other styles (including mbox-small above)   */&lt;br /&gt;
	width: 100%;                 /* For Safari and Opera */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .tmbox.mbox-small { /* &amp;quot;small&amp;quot; tmboxes should not be small when  */&lt;br /&gt;
	line-height: 1.5em;          /* also &amp;quot;nested&amp;quot;, so reset styles that are   */&lt;br /&gt;
	font-size: 100%;             /* set in &amp;quot;mbox-small&amp;quot; above.                */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-content {&lt;br /&gt;
	border: 2px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-style {&lt;br /&gt;
	border: 2px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-move {&lt;br /&gt;
	border: 2px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-protection,&lt;br /&gt;
table.tmbox-notice {&lt;br /&gt;
	border: 1px solid #c0c090;    /* Gray-brown */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Footer and header message box styles */&lt;br /&gt;
table.fmbox {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;     /* Default &amp;quot;system&amp;quot; gray */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-system {&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-warning {&lt;br /&gt;
	border: 1px solid #bb7070;  /* Dark pink */&lt;br /&gt;
	background-color: #ffdbdb;  /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-editnotice {&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
}&lt;br /&gt;
/* Div based &amp;quot;warning&amp;quot; style fmbox messages. */&lt;br /&gt;
div.mw-warning-with-logexcerpt,&lt;br /&gt;
div.mw-lag-warn-high,&lt;br /&gt;
div.mw-cascadeprotectedwarning,&lt;br /&gt;
div#mw-protect-cascadeon,&lt;br /&gt;
div.titleblacklist-warning,&lt;br /&gt;
div.locked-warning {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	border: 1px solid #bb7070;&lt;br /&gt;
	background-color: #ffdbdb;&lt;br /&gt;
	padding: 0.25em 0.9em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* These mbox-small classes must be placed after all other&lt;br /&gt;
   ambox/tmbox/ombox etc classes. &amp;quot;html body.mediawiki&amp;quot; is so&lt;br /&gt;
   they override &amp;quot;table.ambox + table.ambox&amp;quot; above. */&lt;br /&gt;
html body.mediawiki .mbox-small {   /* For the &amp;quot;small=yes&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 0 4px 1em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
html body.mediawiki .mbox-small-left {   /* For the &amp;quot;small=left&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 1em 4px 0;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for compact ambox */&lt;br /&gt;
/* Hide the images */&lt;br /&gt;
.compact-ambox table .mbox-image,&lt;br /&gt;
.compact-ambox table .mbox-imageright,&lt;br /&gt;
.compact-ambox table .mbox-empty-cell {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Remove borders, backgrounds, padding, etc. */&lt;br /&gt;
.compact-ambox table.ambox {&lt;br /&gt;
	border: none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
	margin: 0 0 0 1.6em !important;&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
body.mediawiki .compact-ambox table.mbox-small-left {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Style the text cell as a list item and remove its padding */&lt;br /&gt;
.compact-ambox table .mbox-text {&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
.compact-ambox table .mbox-text-span {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	list-style-type: square;&lt;br /&gt;
	list-style-image: url(/w/skins/MonoBook/resources/images/bullet.svg);&lt;br /&gt;
}&lt;br /&gt;
.skin-vector .compact-ambox table .mbox-text-span {&lt;br /&gt;
	list-style-type: disc;&lt;br /&gt;
	list-style-image: url(/w/skins/Vector/images/bullet-icon.svg);&lt;br /&gt;
}&lt;br /&gt;
/* Allow for hiding text in compact form */&lt;br /&gt;
.compact-ambox .hide-when-compact {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide (formatting) elements from screen, but not from screenreaders */&lt;br /&gt;
.visualhide {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: -10000px;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
	height: 1px;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Suppress missing interwiki image links where #ifexist cannot&lt;br /&gt;
   be used due to high number of requests. See .hidden-redlink on&lt;br /&gt;
   [[m:MediaWiki:Common.css]] */&lt;br /&gt;
.check-icon a.new {&lt;br /&gt;
	display: none;&lt;br /&gt;
	speak: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove underlines from certain links */&lt;br /&gt;
.nounderlines a,&lt;br /&gt;
.IPA a:link, .IPA a:visited {&lt;br /&gt;
	text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Standard Navigationsleisten, aka box hiding thingy&lt;br /&gt;
   from .de.  Documentation at [[Wikipedia:NavFrame]]. */&lt;br /&gt;
div.NavFrame {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 4px;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 95%;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame + div.NavFrame {&lt;br /&gt;
	border-top-style: none;&lt;br /&gt;
	border-top-style: hidden;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame div.NavHead {&lt;br /&gt;
	line-height: 1.6em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	background-color: #ccf;&lt;br /&gt;
	position: relative;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame p,&lt;br /&gt;
div.NavFrame div.NavContent,&lt;br /&gt;
div.NavFrame div.NavContent p {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
a.NavToggle {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	top: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	right: 3px;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hatnotes and disambiguation notices */&lt;br /&gt;
.hatnote {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
}&lt;br /&gt;
.hatnote i {&lt;br /&gt;
	font-style: normal;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-left: 1.6em;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote + div.hatnote {&lt;br /&gt;
	margin-top: -0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow transcluded pages to display in lists rather than a table. */&lt;br /&gt;
.listify td {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
}&lt;br /&gt;
.listify tr {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
.listify table {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Geographical coordinates defaults. See [[Template:Coord/link]]&lt;br /&gt;
   for how these are used. The classes &amp;quot;geo&amp;quot;, &amp;quot;longitude&amp;quot;, and&lt;br /&gt;
   &amp;quot;latitude&amp;quot; are used by the [[Geo microformat]]. */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.geo-default, .geo-dms, .geo-dec {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
.geo-nondefault, .geo-multi-punct {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.longitude, .latitude {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* User block messages */&lt;br /&gt;
div.user-block {&lt;br /&gt;
	padding: 5px;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
	border: 1px solid #a9a9a9;&lt;br /&gt;
	background-color: #ffefd5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent line breaks in silly places:&lt;br /&gt;
   1) Where desired&lt;br /&gt;
   2) Links when we don&#039;t want them to&lt;br /&gt;
   3) Bold &amp;quot;links&amp;quot; to the page itself */&lt;br /&gt;
.nowrap,&lt;br /&gt;
.nowraplinks a,&lt;br /&gt;
.nowraplinks .selflink {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.nowrap pre {&lt;br /&gt;
	white-space: pre;&lt;br /&gt;
}&lt;br /&gt;
/* But allow wrapping where desired: */&lt;br /&gt;
.wrap,&lt;br /&gt;
.wraplinks a {&lt;br /&gt;
	white-space: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For template documentation */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.template-documentation {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 1em 0 0 0;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #ecfcf4;&lt;br /&gt;
	padding: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Increase the height of the image upload box */&lt;br /&gt;
#wpUploadDescription {&lt;br /&gt;
	height: 13em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Minimum thumb width */&lt;br /&gt;
.thumbinner {&lt;br /&gt;
	min-width: 100px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent floating boxes from overlapping any category listings,&lt;br /&gt;
   file histories, edit previews, and edit [Show changes] views. */&lt;br /&gt;
#mw-subcategories, #mw-pages, #mw-category-media,&lt;br /&gt;
#filehistory, #wikiPreview, #wikiDiff {&lt;br /&gt;
	clear: both;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Selectively hide headers in WikiProject banners */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.wpb .wpb-header {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: block;            /* for IE */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: table-row;        /* for real browsers */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb-outside {&lt;br /&gt;
	display: none;             /* hide things that should only display outside shells */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for Abuse Filter tags */&lt;br /&gt;
.mw-tag-markers {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide stuff meant for accounts with special permissions. Made visible again in&lt;br /&gt;
   [[MediaWiki:Group-checkuser.css]], [[MediaWiki:Group-sysop.css]], [[MediaWiki:Group-patroller.css]],&lt;br /&gt;
   [[MediaWiki:Group-templateeditor.css]], [[MediaWiki:Group-extendedmover.css]],&lt;br /&gt;
   [[MediaWiki:Group-extendedconfirmed.css]], and [[Mediawiki:Group-autoconfirmed.css]]. */&lt;br /&gt;
.checkuser-show,&lt;br /&gt;
.sysop-show,&lt;br /&gt;
.patroller-show,&lt;br /&gt;
.templateeditor-show,&lt;br /&gt;
.extendedmover-show,&lt;br /&gt;
.extendedconfirmed-show,&lt;br /&gt;
.autoconfirmed-show,&lt;br /&gt;
.user-show {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide the redlink generated by {{Editnotice}},&lt;br /&gt;
   this overrides the &amp;quot;.sysop-show { display: none; }&amp;quot; above that applies&lt;br /&gt;
   to the same link as well. See [[phab:T45013]]&lt;br /&gt;
&lt;br /&gt;
   Hide the images in editnotices to keep them readable in VE view.&lt;br /&gt;
   Long term, editnotices should become a core feature so that they can be designed responsive. */&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .editnotice-redlink,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-image,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-imageright {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove bullets when there are multiple edit page warnings */&lt;br /&gt;
ul.permissions-errors &amp;gt; li {&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
}&lt;br /&gt;
ul.permissions-errors {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Generic class for Times-based serif, texhtml class for inline math */&lt;br /&gt;
.times-serif,&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	font-family: &amp;quot;Nimbus Roman No9 L&amp;quot;, &amp;quot;Times New Roman&amp;quot;, Times, serif;&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
	line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml span.texhtml {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
span.mwe-math-mathml-inline {&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force tabular and lining display for digits and texhtml */&lt;br /&gt;
.digits,&lt;br /&gt;
.texhtml {&lt;br /&gt;
	-moz-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	-webkit-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-variant-numeric: lining-nums tabular-nums;&lt;br /&gt;
	font-kerning: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make &amp;lt;math display=&amp;quot;block&amp;quot;&amp;gt; be left aligned with one space indent for compatibility with style conventions */&lt;br /&gt;
.mwe-math-fallback-image-display,&lt;br /&gt;
.mwe-math-mathml-display {&lt;br /&gt;
	margin-left: 1.6em !important;&lt;br /&gt;
	margin-top: 0.6em;&lt;br /&gt;
	margin-bottom: 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.mwe-math-mathml-display math {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix styling of transcluded prefindex tables */&lt;br /&gt;
table#mw-prefixindex-list-table,&lt;br /&gt;
table#mw-prefixindex-nav-table {&lt;br /&gt;
	width: 98%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make it possible to hide checkboxes in &amp;lt;inputbox&amp;gt; */&lt;br /&gt;
.inputbox-hidecheckboxes form .inputbox-element,&lt;br /&gt;
.inputbox-hidecheckboxes .mw-ui-checkbox {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Work-around for [[phab:T25965]] / [[phab:T100106]] (Kaltura advertisement) */&lt;br /&gt;
.k-player .k-attribution {&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Move &#039;play&#039; button of video player to bottom left corner */&lt;br /&gt;
.PopUpMediaTransform a .play-btn-large {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	right: auto;&lt;br /&gt;
	bottom: 0;&lt;br /&gt;
	left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide FlaggedRevs notice UI when there are no pending changes */&lt;br /&gt;
.flaggedrevs_draft_synced,&lt;br /&gt;
.flaggedrevs_stable_synced {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force imgs in galleries to have borders by wrapping them in class=bordered-images */&lt;br /&gt;
.bordered-images img {&lt;br /&gt;
	border: solid #ddd 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Gallery styles background changes are restricted to screen view. In printing we should avoid applying backgrounds. */&lt;br /&gt;
@media screen {&lt;br /&gt;
	/* The backgrounds for galleries. */&lt;br /&gt;
	#content .gallerybox div.thumb {&lt;br /&gt;
		/* Light gray padding */&lt;br /&gt;
		background-color: #f8f9fa;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/* Put a chequered background behind images, only visible if they have transparency.&lt;br /&gt;
	&#039;.filehistory a img&#039; and &#039;#file img:hover&#039; are handled by MediaWiki core (as of 1.19) */&lt;br /&gt;
	.gallerybox .thumb img {&lt;br /&gt;
		background: #fff url(//upload.wikimedia.org/wikipedia/commons/5/5d/Checker-16x16.png) repeat;&lt;br /&gt;
	}&lt;br /&gt;
	/* But not on articles, user pages, portals or with opt-out. */&lt;br /&gt;
	.ns-0 .gallerybox .thumb img,&lt;br /&gt;
	.ns-2 .gallerybox .thumb img,&lt;br /&gt;
	.ns-100 .gallerybox .thumb img,&lt;br /&gt;
	.nochecker .gallerybox .thumb img {&lt;br /&gt;
		background-image: none;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display &amp;quot;From Wikipedia, the free encyclopedia&amp;quot; in skins that support it, do not apply to print mode */&lt;br /&gt;
/*@media screen {&lt;br /&gt;
	#siteSub {&lt;br /&gt;
		display: block;&lt;br /&gt;
	}&lt;br /&gt;
}*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki to Noto Sans (does not include headings or monospaced text): */&lt;br /&gt;
body {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Sans&amp;quot;, sans-serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki headings to Noto Serif: */&lt;br /&gt;
#content h1, &lt;br /&gt;
#content h2 {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Serif&amp;quot;, serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-wiki-logo {&lt;br /&gt;
  background-size: 135px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kbd {&lt;br /&gt;
  background: #eee;&lt;br /&gt;
  border: 0.05rem #aaa solid;&lt;br /&gt;
  padding: 0rem 0.2rem;&lt;br /&gt;
  border-radius: 0.2rem;&lt;br /&gt;
  font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-logo-wordmark {&lt;br /&gt;
	font-size: 1.3rem;&lt;br /&gt;
	font-family: &#039;Roboto&#039;, sans-serif;&lt;br /&gt;
	color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*CSS For the main page*/&lt;br /&gt;
  .main-card-container {&lt;br /&gt;
    height: fit-content;&lt;br /&gt;
    height: -moz-fit-content;&lt;br /&gt;
    flex-grow:1;&lt;br /&gt;
    display:flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    padding: 0rem 0.5rem;&lt;br /&gt;
    justify-content: left;&lt;br /&gt;
    align-items: stretch;&lt;br /&gt;
    align-content: stretch;&lt;br /&gt;
    margin: -0.2rem 0rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card {&lt;br /&gt;
    border: 0px;&lt;br /&gt;
    border-radius: 1rem;&lt;br /&gt;
    background: #F7F9F8;&lt;br /&gt;
    box-shadow: 0.1rem 0.1rem 0.4rem black;&lt;br /&gt;
    padding: 0.3rem;&lt;br /&gt;
    margin: 0.2rem;&lt;br /&gt;
    flex: 1 1 30%;&lt;br /&gt;
    max-width: 29%;&lt;br /&gt;
    min-width: 8rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-container h6 {&lt;br /&gt;
    text-align:center&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 80%;&lt;br /&gt;
     margin: auto;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul li {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-header{&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-align: center; &lt;br /&gt;
    margin-top: 0.3rem;&lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7196</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7196"/>
		<updated>2025-11-23T03:13:04Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Reset italic styling set by user agent */&lt;br /&gt;
cite, dfn {&lt;br /&gt;
	font-style: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Straight quote marks for &amp;lt;q&amp;gt; */&lt;br /&gt;
q {&lt;br /&gt;
	quotes: &#039;&amp;quot;&#039; &#039;&amp;quot;&#039; &amp;quot;&#039;&amp;quot; &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid collision of blockquote with floating elements by swapping margin and padding */&lt;br /&gt;
blockquote {&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	margin: 1em 0;&lt;br /&gt;
	padding: 0 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* give pre a float clearing new block formatting context */&lt;br /&gt;
/* Also break any really long words/urls to keep them visible in that case */&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
	overflow-x: hidden;&lt;br /&gt;
	overflow-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Consistent size for &amp;lt;small&amp;gt;, &amp;lt;sub&amp;gt; and &amp;lt;sup&amp;gt; */&lt;br /&gt;
small {&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content sub,&lt;br /&gt;
.mw-body-content sup,&lt;br /&gt;
span.reference /* for Parsoid */ {&lt;br /&gt;
	font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Same spacing for indented and unindented paragraphs on talk pages */&lt;br /&gt;
.ns-talk .mw-body-content dd {&lt;br /&gt;
	margin-top: 0.4em;&lt;br /&gt;
	margin-bottom: 0.4em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main page fixes */&lt;br /&gt;
#interwiki-completelist {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reduce page jumps by hiding collapsed/dismissed content */&lt;br /&gt;
.client-js .mw-special-Watchlist #watchlist-message,&lt;br /&gt;
.client-js .NavFrame.collapsed .NavContent,&lt;br /&gt;
.client-js .collapsible:not( .mw-made-collapsible).collapsed &amp;gt; tbody &amp;gt; tr:not(:first-child) {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Adds padding above Watchlist announcements where new recentchanges/watchlist filters are enabled */&lt;br /&gt;
.mw-rcfilters-enabled .mw-specialpage-summary {&lt;br /&gt;
	margin-top: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide charinsert base for those not using the gadget */&lt;br /&gt;
#editpage-specialchars {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight linked elements (such as clicked references) in blue */&lt;br /&gt;
body.action-info .mw-body-content :target,&lt;br /&gt;
.citation:target {&lt;br /&gt;
	background-color: #def;  /* Fallback */&lt;br /&gt;
	background-color: rgba(0, 127, 255, 0.133);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for citations. Breaks long urls, etc., rather than overflowing box */&lt;br /&gt;
.citation {&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For linked citation numbers and document IDs, where the number need not be shown&lt;br /&gt;
   on a screen or a handheld, but should be included in the printed version */&lt;br /&gt;
@media screen, handheld {&lt;br /&gt;
	.citation .printonly {&lt;br /&gt;
		display: none;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make the list of references smaller */&lt;br /&gt;
/* Keep in sync with Template:Refbegin/styles.css */&lt;br /&gt;
ol.references,&lt;br /&gt;
div.reflist {&lt;br /&gt;
	font-size: 90%;            /* Default font-size */&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.reflist ol.references {&lt;br /&gt;
	font-size: 100%;           /* Reset font-size when nested in div.reflist */&lt;br /&gt;
	margin-bottom: 0;          /* Avoid double margin when nested in div.reflist */&lt;br /&gt;
	list-style-type: inherit;  /* Enable custom list style types */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow hidden ref errors to be shown by user CSS */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
span.brokenref {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reset top margin for lists embedded in columns */&lt;br /&gt;
div.columns {&lt;br /&gt;
	margin-top: 0.3em;&lt;br /&gt;
}&lt;br /&gt;
div.columns dl,&lt;br /&gt;
div.columns ol,&lt;br /&gt;
div.columns ul {&lt;br /&gt;
	margin-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid elements breaking between columns */&lt;br /&gt;
.nocolbreak,&lt;br /&gt;
div.columns li,&lt;br /&gt;
div.columns dd dd {&lt;br /&gt;
	-webkit-column-break-inside: avoid;&lt;br /&gt;
	page-break-inside: avoid;&lt;br /&gt;
	break-inside: avoid-column;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for horizontal lists (separator following item).&lt;br /&gt;
   @source mediawiki.org/wiki/Snippets/Horizontal_lists&lt;br /&gt;
   @revision 8 (2016-05-21)&lt;br /&gt;
   @author [[User:Edokter]]&lt;br /&gt;
 */&lt;br /&gt;
.hlist dl,&lt;br /&gt;
.hlist ol,&lt;br /&gt;
.hlist ul {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Display list items inline */&lt;br /&gt;
.hlist dd,&lt;br /&gt;
.hlist dt,&lt;br /&gt;
.hlist li {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Display nested lists inline */&lt;br /&gt;
.hlist.inline,&lt;br /&gt;
.hlist.inline dl,&lt;br /&gt;
.hlist.inline ol,&lt;br /&gt;
.hlist.inline ul,&lt;br /&gt;
.hlist dl dl, .hlist dl ol, .hlist dl ul,&lt;br /&gt;
.hlist ol dl, .hlist ol ol, .hlist ol ul,&lt;br /&gt;
.hlist ul dl, .hlist ul ol, .hlist ul ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Hide empty list items */&lt;br /&gt;
.hlist .mw-empty-li {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Generate interpuncts */&lt;br /&gt;
.hlist dt:after {&lt;br /&gt;
	content: &amp;quot;: &amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * Note hlist style usage differd in&lt;br /&gt;
 * the Minerva skin. Remember .hlist is a class defined in core as well! Please check Minerva desktop (and Minerva.css) when changing&lt;br /&gt;
 * See https://phabricator.wikimedia.org/T213239&lt;br /&gt;
 */&lt;br /&gt;
.hlist dd:after,&lt;br /&gt;
.hlist li:after {&lt;br /&gt;
	content: &amp;quot; · &amp;quot;;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd:last-child:after,&lt;br /&gt;
.hlist dt:last-child:after,&lt;br /&gt;
.hlist li:last-child:after {&lt;br /&gt;
	content: none;&lt;br /&gt;
}&lt;br /&gt;
/* Add parentheses around nested lists */&lt;br /&gt;
.hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before,&lt;br /&gt;
.hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before,&lt;br /&gt;
.hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after,&lt;br /&gt;
.hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after,&lt;br /&gt;
.hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after {&lt;br /&gt;
	content: &amp;quot;)&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
/* Put ordinals in front of ordered list items */&lt;br /&gt;
.hlist ol {&lt;br /&gt;
	counter-reset: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li {&lt;br /&gt;
	counter-increment: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li:before {&lt;br /&gt;
	content: &amp;quot; &amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist dt ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist li ol &amp;gt; li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Unbulleted lists */&lt;br /&gt;
.plainlist ol,&lt;br /&gt;
.plainlist ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.plainlist ol li,&lt;br /&gt;
.plainlist ul li {&lt;br /&gt;
	margin-bottom: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default style for navigation boxes */&lt;br /&gt;
.navbox {                     /* Navbox container style */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	padding: 1px;&lt;br /&gt;
	margin: 1em auto 0;       /* Prevent preceding content from clinging to navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbox {&lt;br /&gt;
	margin-top: 0;            /* No top margin for nested navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox + .navbox {&lt;br /&gt;
	margin-top: -1px;         /* Single pixel border between adjacent navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox-inner,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-group,&lt;br /&gt;
.navbox-title,&lt;br /&gt;
.navbox-abovebelow {&lt;br /&gt;
	padding: 0.25em 1em;      /* Title, group and above/below styles */&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
th.navbox-group {             /* Group style */&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.navbox,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	background-color: #fdfdfd; /* Background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-list {&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	border-color: #fdfdfd;    /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
/* cell spacing for navbox cells */&lt;br /&gt;
tr + tr &amp;gt; .navbox-abovebelow,&lt;br /&gt;
tr + tr &amp;gt; .navbox-group,&lt;br /&gt;
tr + tr &amp;gt; .navbox-image,&lt;br /&gt;
tr + tr &amp;gt; .navbox-list {    /* Borders above 2nd, 3rd, etc. rows */&lt;br /&gt;
	border-top: 2px solid #fdfdfd; /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox th,&lt;br /&gt;
.navbox-title {&lt;br /&gt;
	background-color: #ccccff;      /* Level 1 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-abovebelow,&lt;br /&gt;
th.navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-title {&lt;br /&gt;
	background-color: #ddddff;      /* Level 2 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-subgroup .navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-abovebelow {&lt;br /&gt;
	background-color: #e6e6ff;      /* Level 3 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-even {&lt;br /&gt;
	background-color: #f7f7f7;      /* Even row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox-odd {&lt;br /&gt;
	background-color: transparent;  /* Odd row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox .hlist td dl,&lt;br /&gt;
.navbox .hlist td ol,&lt;br /&gt;
.navbox .hlist td ul,&lt;br /&gt;
.navbox td.hlist dl,&lt;br /&gt;
.navbox td.hlist ol,&lt;br /&gt;
.navbox td.hlist ul {&lt;br /&gt;
	padding: 0.125em 0;       /* Adjust hlist padding in navboxes */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default styling for Navbar template */&lt;br /&gt;
.navbar {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.navbar ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content .navbar ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
}&lt;br /&gt;
.navbar li {&lt;br /&gt;
	word-spacing: -0.125em;&lt;br /&gt;
}&lt;br /&gt;
.navbar.mini li abbr[title] {&lt;br /&gt;
	font-variant: small-caps;&lt;br /&gt;
	border-bottom: none;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	cursor: inherit;&lt;br /&gt;
}&lt;br /&gt;
/* Navbar styling when nested in infobox and navbox */&lt;br /&gt;
.infobox .navbar {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbar {&lt;br /&gt;
	display: block;&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-title .navbar {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin-right: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for JQuery makeCollapsible, matching that of collapseButton */&lt;br /&gt;
.mw-parser-output .mw-collapsible-toggle {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	padding-right: 0.2em;&lt;br /&gt;
	padding-left: 0.2em;&lt;br /&gt;
}&lt;br /&gt;
.mw-collapsible-leftside-toggle .mw-collapsible-toggle {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Infobox template style */&lt;br /&gt;
.infobox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	border-spacing: 3px;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	color: black;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0.5em 0 0.5em 1em;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
}&lt;br /&gt;
.infobox caption {&lt;br /&gt;
	font-size: 125%;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.infobox td,&lt;br /&gt;
.infobox th {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered td,&lt;br /&gt;
.infobox.bordered th {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered .borderless td,&lt;br /&gt;
.infobox.bordered .borderless th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.sisterproject {&lt;br /&gt;
	width: 20em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
.infobox.standard-talk.bordered td,&lt;br /&gt;
.infobox.standard-talk.bordered th {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* styles for bordered infobox with merged rows */&lt;br /&gt;
.infobox.bordered .mergedtoprow td,&lt;br /&gt;
.infobox.bordered .mergedtoprow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.bordered .mergedrow td,&lt;br /&gt;
.infobox.bordered .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styles for geography infoboxes, eg countries,&lt;br /&gt;
   country subdivisions, cities, etc.            */&lt;br /&gt;
.infobox.geography {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	line-height: 1.2em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography  td,&lt;br /&gt;
.infobox.geography  th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.infobox.geography .mergedtoprow td,&lt;br /&gt;
.infobox.geography .mergedtoprow th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedrow td,&lt;br /&gt;
.infobox.geography .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedbottomrow td,&lt;br /&gt;
.infobox.geography .mergedbottomrow th {&lt;br /&gt;
	border-top: 0;&lt;br /&gt;
	border-bottom: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .maptable td,&lt;br /&gt;
.infobox.geography .maptable th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Normal font styling for wikitable row headers with scope=&amp;quot;row&amp;quot; tag */&lt;br /&gt;
.wikitable.plainrowheaders th[scope=row] {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Lists in wikitable data cells are always left-aligned */&lt;br /&gt;
.wikitable td ul,&lt;br /&gt;
.wikitable td ol,&lt;br /&gt;
.wikitable td dl {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
/* ...unless they also use the hlist class */&lt;br /&gt;
.toc.hlist ul,&lt;br /&gt;
#toc.hlist ul,&lt;br /&gt;
.wikitable.hlist td ul,&lt;br /&gt;
.wikitable.hlist td ol,&lt;br /&gt;
.wikitable.hlist td dl {&lt;br /&gt;
	text-align: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icons for medialist templates [[Template:Listen]],&lt;br /&gt;
   [[Template:Multi-listen_start]], [[Template:Video]],&lt;br /&gt;
   [[Template:Multi-video_start]] */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
div.listenlist {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/4/47/Sound-icon.svg&amp;quot;) no-repeat scroll 0 0 transparent;&lt;br /&gt;
	background-size: 30px;&lt;br /&gt;
	padding-left: 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for hieroglyphs specificity issue in infoboxes ([[phab:T43869]]) */&lt;br /&gt;
table.mw-hiero-table td {&lt;br /&gt;
	vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Change the external link icon to an Adobe icon for all PDF files */&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.pdf&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf#&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.PDF&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF#&amp;quot;].external {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/2/23/Icons-mini-file_acrobat.gif&amp;quot;) no-repeat right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-right: 18px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Messagebox templates */&lt;br /&gt;
.messagebox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	width: 80%;&lt;br /&gt;
	margin: 0 auto 1em auto;&lt;br /&gt;
	padding: .2em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.merge {&lt;br /&gt;
	border: 1px solid #c0b8cc;&lt;br /&gt;
	background-color: #f0e5ff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.cleanup {&lt;br /&gt;
	border: 1px solid #9f9fff;&lt;br /&gt;
	background-color: #efefff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	margin: 4px auto;&lt;br /&gt;
}&lt;br /&gt;
/* For old WikiProject banners inside banner shells. */&lt;br /&gt;
.mbox-inside .standard-talk,&lt;br /&gt;
.messagebox.nested-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	margin: 2px 0;&lt;br /&gt;
	padding: 2px;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small-talk {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */&lt;br /&gt;
th.mbox-text, td.mbox-text {   /* The message body cell(s) */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 0.25em 0.9em;     /* 0.9em left/right */&lt;br /&gt;
	width: 100%;               /* Make all mboxes the same width regardless of text length */&lt;br /&gt;
}&lt;br /&gt;
td.mbox-image {                /* The left image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.9em;  /* 0.9em left, 0px right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-imageright {           /* The right image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.9em 2px 0;  /* 0px left, 0.9em right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-empty-cell {           /* An empty narrow cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Article message box styles */&lt;br /&gt;
table.ambox {&lt;br /&gt;
	margin: 0 10%;                  /* 10% = Will not overlap with other elements */&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;  /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.ambox + table.ambox {      /* Single border between stacked boxes. */&lt;br /&gt;
	margin-top: -1px;&lt;br /&gt;
}&lt;br /&gt;
.ambox th.mbox-text,&lt;br /&gt;
.ambox td.mbox-text {            /* The message body cell(s) */&lt;br /&gt;
	padding: 0.25em 0.5em;       /* 0.5em left/right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-image {           /* The left image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.5em;    /* 0.5em left, 0px right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-imageright {      /* The right image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.5em 2px 0;    /* 0px left, 0.5em right */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-notice {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-speedy {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;          /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-delete {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-content {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-style {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-move {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-protection {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Image message box styles */&lt;br /&gt;
table.imbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 3px solid #36c;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.imbox .mbox-text .imbox {  /* For imboxes inside imbox-text cells. */&lt;br /&gt;
	margin: 0 -0.5em;       /* 0.9 - 0.5 = 0.4em left/right.        */&lt;br /&gt;
	display: block;         /* Fix for webkit to force 100% width.  */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .imbox {       /* For imboxes inside other templates.  */&lt;br /&gt;
	margin: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-notice {&lt;br /&gt;
	border: 3px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-speedy {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-delete {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-content {&lt;br /&gt;
	border: 3px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-style {&lt;br /&gt;
	border: 3px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-move {&lt;br /&gt;
	border: 3px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-protection {&lt;br /&gt;
	border: 3px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-license {&lt;br /&gt;
	border: 3px solid #88a;       /* Dark gray */&lt;br /&gt;
	background-color: #f7f8ff;    /* Light gray */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-featured {&lt;br /&gt;
	border: 3px solid #cba135;    /* Brown-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Category message box styles */&lt;br /&gt;
table.cmbox {&lt;br /&gt;
	margin: 3px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #dfe8ff;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-notice {&lt;br /&gt;
	background-color: #d8e8ff;    /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-speedy {&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
	border: 4px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-delete {&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-content {&lt;br /&gt;
	background-color: #ffe7ce;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-style {&lt;br /&gt;
	background-color: #fff9db;    /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-move {&lt;br /&gt;
	background-color: #e4d8ff;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-protection {&lt;br /&gt;
	background-color: #efefe1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Other pages message box styles */&lt;br /&gt;
table.ombox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Default &amp;quot;notice&amp;quot; gray */&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-notice {&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Gray */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-content {&lt;br /&gt;
	border: 1px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-style {&lt;br /&gt;
	border: 1px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-move {&lt;br /&gt;
	border: 1px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-protection {&lt;br /&gt;
	border: 2px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Talk page message box styles */&lt;br /&gt;
table.tmbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #c0c090;    /* Default &amp;quot;notice&amp;quot; gray-brown */&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	min-width: 80%;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.tmbox.mbox-small {&lt;br /&gt;
	min-width: 0;                /* reset the min-width of tmbox above        */&lt;br /&gt;
}&lt;br /&gt;
.mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The &amp;quot;mediawiki&amp;quot; class ensures that */&lt;br /&gt;
	margin: 2px 0;               /* this declaration overrides other styles (including mbox-small above)   */&lt;br /&gt;
	width: 100%;                 /* For Safari and Opera */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .tmbox.mbox-small { /* &amp;quot;small&amp;quot; tmboxes should not be small when  */&lt;br /&gt;
	line-height: 1.5em;          /* also &amp;quot;nested&amp;quot;, so reset styles that are   */&lt;br /&gt;
	font-size: 100%;             /* set in &amp;quot;mbox-small&amp;quot; above.                */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-content {&lt;br /&gt;
	border: 2px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-style {&lt;br /&gt;
	border: 2px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-move {&lt;br /&gt;
	border: 2px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-protection,&lt;br /&gt;
table.tmbox-notice {&lt;br /&gt;
	border: 1px solid #c0c090;    /* Gray-brown */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Footer and header message box styles */&lt;br /&gt;
table.fmbox {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;     /* Default &amp;quot;system&amp;quot; gray */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-system {&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-warning {&lt;br /&gt;
	border: 1px solid #bb7070;  /* Dark pink */&lt;br /&gt;
	background-color: #ffdbdb;  /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-editnotice {&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
}&lt;br /&gt;
/* Div based &amp;quot;warning&amp;quot; style fmbox messages. */&lt;br /&gt;
div.mw-warning-with-logexcerpt,&lt;br /&gt;
div.mw-lag-warn-high,&lt;br /&gt;
div.mw-cascadeprotectedwarning,&lt;br /&gt;
div#mw-protect-cascadeon,&lt;br /&gt;
div.titleblacklist-warning,&lt;br /&gt;
div.locked-warning {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	border: 1px solid #bb7070;&lt;br /&gt;
	background-color: #ffdbdb;&lt;br /&gt;
	padding: 0.25em 0.9em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* These mbox-small classes must be placed after all other&lt;br /&gt;
   ambox/tmbox/ombox etc classes. &amp;quot;html body.mediawiki&amp;quot; is so&lt;br /&gt;
   they override &amp;quot;table.ambox + table.ambox&amp;quot; above. */&lt;br /&gt;
html body.mediawiki .mbox-small {   /* For the &amp;quot;small=yes&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 0 4px 1em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
html body.mediawiki .mbox-small-left {   /* For the &amp;quot;small=left&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 1em 4px 0;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for compact ambox */&lt;br /&gt;
/* Hide the images */&lt;br /&gt;
.compact-ambox table .mbox-image,&lt;br /&gt;
.compact-ambox table .mbox-imageright,&lt;br /&gt;
.compact-ambox table .mbox-empty-cell {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Remove borders, backgrounds, padding, etc. */&lt;br /&gt;
.compact-ambox table.ambox {&lt;br /&gt;
	border: none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
	margin: 0 0 0 1.6em !important;&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
body.mediawiki .compact-ambox table.mbox-small-left {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Style the text cell as a list item and remove its padding */&lt;br /&gt;
.compact-ambox table .mbox-text {&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
.compact-ambox table .mbox-text-span {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	list-style-type: square;&lt;br /&gt;
	list-style-image: url(/w/skins/MonoBook/resources/images/bullet.svg);&lt;br /&gt;
}&lt;br /&gt;
.skin-vector .compact-ambox table .mbox-text-span {&lt;br /&gt;
	list-style-type: disc;&lt;br /&gt;
	list-style-image: url(/w/skins/Vector/images/bullet-icon.svg);&lt;br /&gt;
}&lt;br /&gt;
/* Allow for hiding text in compact form */&lt;br /&gt;
.compact-ambox .hide-when-compact {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide (formatting) elements from screen, but not from screenreaders */&lt;br /&gt;
.visualhide {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: -10000px;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
	height: 1px;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Suppress missing interwiki image links where #ifexist cannot&lt;br /&gt;
   be used due to high number of requests. See .hidden-redlink on&lt;br /&gt;
   [[m:MediaWiki:Common.css]] */&lt;br /&gt;
.check-icon a.new {&lt;br /&gt;
	display: none;&lt;br /&gt;
	speak: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove underlines from certain links */&lt;br /&gt;
.nounderlines a,&lt;br /&gt;
.IPA a:link, .IPA a:visited {&lt;br /&gt;
	text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Standard Navigationsleisten, aka box hiding thingy&lt;br /&gt;
   from .de.  Documentation at [[Wikipedia:NavFrame]]. */&lt;br /&gt;
div.NavFrame {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 4px;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 95%;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame + div.NavFrame {&lt;br /&gt;
	border-top-style: none;&lt;br /&gt;
	border-top-style: hidden;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame div.NavHead {&lt;br /&gt;
	line-height: 1.6em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	background-color: #ccf;&lt;br /&gt;
	position: relative;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame p,&lt;br /&gt;
div.NavFrame div.NavContent,&lt;br /&gt;
div.NavFrame div.NavContent p {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
a.NavToggle {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	top: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	right: 3px;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hatnotes and disambiguation notices */&lt;br /&gt;
.hatnote {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
}&lt;br /&gt;
.hatnote i {&lt;br /&gt;
	font-style: normal;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-left: 1.6em;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote + div.hatnote {&lt;br /&gt;
	margin-top: -0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow transcluded pages to display in lists rather than a table. */&lt;br /&gt;
.listify td {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
}&lt;br /&gt;
.listify tr {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
.listify table {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Geographical coordinates defaults. See [[Template:Coord/link]]&lt;br /&gt;
   for how these are used. The classes &amp;quot;geo&amp;quot;, &amp;quot;longitude&amp;quot;, and&lt;br /&gt;
   &amp;quot;latitude&amp;quot; are used by the [[Geo microformat]]. */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.geo-default, .geo-dms, .geo-dec {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
.geo-nondefault, .geo-multi-punct {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.longitude, .latitude {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* User block messages */&lt;br /&gt;
div.user-block {&lt;br /&gt;
	padding: 5px;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
	border: 1px solid #a9a9a9;&lt;br /&gt;
	background-color: #ffefd5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent line breaks in silly places:&lt;br /&gt;
   1) Where desired&lt;br /&gt;
   2) Links when we don&#039;t want them to&lt;br /&gt;
   3) Bold &amp;quot;links&amp;quot; to the page itself */&lt;br /&gt;
.nowrap,&lt;br /&gt;
.nowraplinks a,&lt;br /&gt;
.nowraplinks .selflink {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.nowrap pre {&lt;br /&gt;
	white-space: pre;&lt;br /&gt;
}&lt;br /&gt;
/* But allow wrapping where desired: */&lt;br /&gt;
.wrap,&lt;br /&gt;
.wraplinks a {&lt;br /&gt;
	white-space: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For template documentation */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.template-documentation {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 1em 0 0 0;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #ecfcf4;&lt;br /&gt;
	padding: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Increase the height of the image upload box */&lt;br /&gt;
#wpUploadDescription {&lt;br /&gt;
	height: 13em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Minimum thumb width */&lt;br /&gt;
.thumbinner {&lt;br /&gt;
	min-width: 100px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent floating boxes from overlapping any category listings,&lt;br /&gt;
   file histories, edit previews, and edit [Show changes] views. */&lt;br /&gt;
#mw-subcategories, #mw-pages, #mw-category-media,&lt;br /&gt;
#filehistory, #wikiPreview, #wikiDiff {&lt;br /&gt;
	clear: both;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Selectively hide headers in WikiProject banners */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.wpb .wpb-header {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: block;            /* for IE */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: table-row;        /* for real browsers */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb-outside {&lt;br /&gt;
	display: none;             /* hide things that should only display outside shells */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for Abuse Filter tags */&lt;br /&gt;
.mw-tag-markers {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide stuff meant for accounts with special permissions. Made visible again in&lt;br /&gt;
   [[MediaWiki:Group-checkuser.css]], [[MediaWiki:Group-sysop.css]], [[MediaWiki:Group-patroller.css]],&lt;br /&gt;
   [[MediaWiki:Group-templateeditor.css]], [[MediaWiki:Group-extendedmover.css]],&lt;br /&gt;
   [[MediaWiki:Group-extendedconfirmed.css]], and [[Mediawiki:Group-autoconfirmed.css]]. */&lt;br /&gt;
.checkuser-show,&lt;br /&gt;
.sysop-show,&lt;br /&gt;
.patroller-show,&lt;br /&gt;
.templateeditor-show,&lt;br /&gt;
.extendedmover-show,&lt;br /&gt;
.extendedconfirmed-show,&lt;br /&gt;
.autoconfirmed-show,&lt;br /&gt;
.user-show {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide the redlink generated by {{Editnotice}},&lt;br /&gt;
   this overrides the &amp;quot;.sysop-show { display: none; }&amp;quot; above that applies&lt;br /&gt;
   to the same link as well. See [[phab:T45013]]&lt;br /&gt;
&lt;br /&gt;
   Hide the images in editnotices to keep them readable in VE view.&lt;br /&gt;
   Long term, editnotices should become a core feature so that they can be designed responsive. */&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .editnotice-redlink,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-image,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-imageright {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove bullets when there are multiple edit page warnings */&lt;br /&gt;
ul.permissions-errors &amp;gt; li {&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
}&lt;br /&gt;
ul.permissions-errors {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Generic class for Times-based serif, texhtml class for inline math */&lt;br /&gt;
.times-serif,&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	font-family: &amp;quot;Nimbus Roman No9 L&amp;quot;, &amp;quot;Times New Roman&amp;quot;, Times, serif;&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
	line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml span.texhtml {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
span.mwe-math-mathml-inline {&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force tabular and lining display for digits and texhtml */&lt;br /&gt;
.digits,&lt;br /&gt;
.texhtml {&lt;br /&gt;
	-moz-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	-webkit-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-variant-numeric: lining-nums tabular-nums;&lt;br /&gt;
	font-kerning: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make &amp;lt;math display=&amp;quot;block&amp;quot;&amp;gt; be left aligned with one space indent for compatibility with style conventions */&lt;br /&gt;
.mwe-math-fallback-image-display,&lt;br /&gt;
.mwe-math-mathml-display {&lt;br /&gt;
	margin-left: 1.6em !important;&lt;br /&gt;
	margin-top: 0.6em;&lt;br /&gt;
	margin-bottom: 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.mwe-math-mathml-display math {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix styling of transcluded prefindex tables */&lt;br /&gt;
table#mw-prefixindex-list-table,&lt;br /&gt;
table#mw-prefixindex-nav-table {&lt;br /&gt;
	width: 98%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make it possible to hide checkboxes in &amp;lt;inputbox&amp;gt; */&lt;br /&gt;
.inputbox-hidecheckboxes form .inputbox-element,&lt;br /&gt;
.inputbox-hidecheckboxes .mw-ui-checkbox {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Work-around for [[phab:T25965]] / [[phab:T100106]] (Kaltura advertisement) */&lt;br /&gt;
.k-player .k-attribution {&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Move &#039;play&#039; button of video player to bottom left corner */&lt;br /&gt;
.PopUpMediaTransform a .play-btn-large {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	right: auto;&lt;br /&gt;
	bottom: 0;&lt;br /&gt;
	left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide FlaggedRevs notice UI when there are no pending changes */&lt;br /&gt;
.flaggedrevs_draft_synced,&lt;br /&gt;
.flaggedrevs_stable_synced {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force imgs in galleries to have borders by wrapping them in class=bordered-images */&lt;br /&gt;
.bordered-images img {&lt;br /&gt;
	border: solid #ddd 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Gallery styles background changes are restricted to screen view. In printing we should avoid applying backgrounds. */&lt;br /&gt;
@media screen {&lt;br /&gt;
	/* The backgrounds for galleries. */&lt;br /&gt;
	#content .gallerybox div.thumb {&lt;br /&gt;
		/* Light gray padding */&lt;br /&gt;
		background-color: #f8f9fa;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/* Put a chequered background behind images, only visible if they have transparency.&lt;br /&gt;
	&#039;.filehistory a img&#039; and &#039;#file img:hover&#039; are handled by MediaWiki core (as of 1.19) */&lt;br /&gt;
	.gallerybox .thumb img {&lt;br /&gt;
		background: #fff url(//upload.wikimedia.org/wikipedia/commons/5/5d/Checker-16x16.png) repeat;&lt;br /&gt;
	}&lt;br /&gt;
	/* But not on articles, user pages, portals or with opt-out. */&lt;br /&gt;
	.ns-0 .gallerybox .thumb img,&lt;br /&gt;
	.ns-2 .gallerybox .thumb img,&lt;br /&gt;
	.ns-100 .gallerybox .thumb img,&lt;br /&gt;
	.nochecker .gallerybox .thumb img {&lt;br /&gt;
		background-image: none;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display &amp;quot;From Wikipedia, the free encyclopedia&amp;quot; in skins that support it, do not apply to print mode */&lt;br /&gt;
/*@media screen {&lt;br /&gt;
	#siteSub {&lt;br /&gt;
		display: block;&lt;br /&gt;
	}&lt;br /&gt;
}*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki to Noto Sans (does not include headings or monospaced text): */&lt;br /&gt;
body {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Sans&amp;quot;, sans-serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki headings to Noto Serif: */&lt;br /&gt;
#content h1, &lt;br /&gt;
#content h2 {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Serif&amp;quot;, serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-wiki-logo {&lt;br /&gt;
  background-size: 135px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kbd {&lt;br /&gt;
  background: #eee;&lt;br /&gt;
  border: 0.05rem #aaa solid;&lt;br /&gt;
  padding: 0rem 0.2rem;&lt;br /&gt;
  border-radius: 0.2rem;&lt;br /&gt;
  font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-logo-wordmark {&lt;br /&gt;
	font-size: 1.3rem;&lt;br /&gt;
	font-family: &#039;Roboto&#039;, sans-serif;&lt;br /&gt;
	color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*CSS For the main page*/&lt;br /&gt;
  .main-card-container {&lt;br /&gt;
    height: fit-content;&lt;br /&gt;
    height: -moz-fit-content;&lt;br /&gt;
    flex-grow:1;&lt;br /&gt;
    display:flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    padding: 0rem 0.5rem;&lt;br /&gt;
    justify-content: left;&lt;br /&gt;
    align-items: stretch;&lt;br /&gt;
    align-content: stretch;&lt;br /&gt;
    margin: -0.2rem 0rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card {&lt;br /&gt;
    border: 0px;&lt;br /&gt;
    border-radius: 1rem;&lt;br /&gt;
    background: #F7F9F8;&lt;br /&gt;
    box-shadow: 0.1rem 0.1rem 0.25rem black;&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
    padding: 0.3rem;&lt;br /&gt;
    margin: 0.2rem;&lt;br /&gt;
    flex: 1 1 30%;&lt;br /&gt;
    max-width: 29%;&lt;br /&gt;
    min-width: 8rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card:hover {&lt;br /&gt;
    box-shadow: 0.1rem 0.1rem 0.35rem black;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-container h6 {&lt;br /&gt;
    text-align:center&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 80%;&lt;br /&gt;
     margin: auto;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul li {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-header{&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-align: center; &lt;br /&gt;
    margin-top: 0.3rem;&lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7195</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7195"/>
		<updated>2025-11-23T01:30:38Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Reset italic styling set by user agent */&lt;br /&gt;
cite, dfn {&lt;br /&gt;
	font-style: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Straight quote marks for &amp;lt;q&amp;gt; */&lt;br /&gt;
q {&lt;br /&gt;
	quotes: &#039;&amp;quot;&#039; &#039;&amp;quot;&#039; &amp;quot;&#039;&amp;quot; &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid collision of blockquote with floating elements by swapping margin and padding */&lt;br /&gt;
blockquote {&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	margin: 1em 0;&lt;br /&gt;
	padding: 0 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* give pre a float clearing new block formatting context */&lt;br /&gt;
/* Also break any really long words/urls to keep them visible in that case */&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
	overflow-x: hidden;&lt;br /&gt;
	overflow-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Consistent size for &amp;lt;small&amp;gt;, &amp;lt;sub&amp;gt; and &amp;lt;sup&amp;gt; */&lt;br /&gt;
small {&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content sub,&lt;br /&gt;
.mw-body-content sup,&lt;br /&gt;
span.reference /* for Parsoid */ {&lt;br /&gt;
	font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Same spacing for indented and unindented paragraphs on talk pages */&lt;br /&gt;
.ns-talk .mw-body-content dd {&lt;br /&gt;
	margin-top: 0.4em;&lt;br /&gt;
	margin-bottom: 0.4em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main page fixes */&lt;br /&gt;
#interwiki-completelist {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reduce page jumps by hiding collapsed/dismissed content */&lt;br /&gt;
.client-js .mw-special-Watchlist #watchlist-message,&lt;br /&gt;
.client-js .NavFrame.collapsed .NavContent,&lt;br /&gt;
.client-js .collapsible:not( .mw-made-collapsible).collapsed &amp;gt; tbody &amp;gt; tr:not(:first-child) {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Adds padding above Watchlist announcements where new recentchanges/watchlist filters are enabled */&lt;br /&gt;
.mw-rcfilters-enabled .mw-specialpage-summary {&lt;br /&gt;
	margin-top: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide charinsert base for those not using the gadget */&lt;br /&gt;
#editpage-specialchars {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight linked elements (such as clicked references) in blue */&lt;br /&gt;
body.action-info .mw-body-content :target,&lt;br /&gt;
.citation:target {&lt;br /&gt;
	background-color: #def;  /* Fallback */&lt;br /&gt;
	background-color: rgba(0, 127, 255, 0.133);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for citations. Breaks long urls, etc., rather than overflowing box */&lt;br /&gt;
.citation {&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For linked citation numbers and document IDs, where the number need not be shown&lt;br /&gt;
   on a screen or a handheld, but should be included in the printed version */&lt;br /&gt;
@media screen, handheld {&lt;br /&gt;
	.citation .printonly {&lt;br /&gt;
		display: none;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make the list of references smaller */&lt;br /&gt;
/* Keep in sync with Template:Refbegin/styles.css */&lt;br /&gt;
ol.references,&lt;br /&gt;
div.reflist {&lt;br /&gt;
	font-size: 90%;            /* Default font-size */&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.reflist ol.references {&lt;br /&gt;
	font-size: 100%;           /* Reset font-size when nested in div.reflist */&lt;br /&gt;
	margin-bottom: 0;          /* Avoid double margin when nested in div.reflist */&lt;br /&gt;
	list-style-type: inherit;  /* Enable custom list style types */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow hidden ref errors to be shown by user CSS */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
span.brokenref {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reset top margin for lists embedded in columns */&lt;br /&gt;
div.columns {&lt;br /&gt;
	margin-top: 0.3em;&lt;br /&gt;
}&lt;br /&gt;
div.columns dl,&lt;br /&gt;
div.columns ol,&lt;br /&gt;
div.columns ul {&lt;br /&gt;
	margin-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid elements breaking between columns */&lt;br /&gt;
.nocolbreak,&lt;br /&gt;
div.columns li,&lt;br /&gt;
div.columns dd dd {&lt;br /&gt;
	-webkit-column-break-inside: avoid;&lt;br /&gt;
	page-break-inside: avoid;&lt;br /&gt;
	break-inside: avoid-column;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for horizontal lists (separator following item).&lt;br /&gt;
   @source mediawiki.org/wiki/Snippets/Horizontal_lists&lt;br /&gt;
   @revision 8 (2016-05-21)&lt;br /&gt;
   @author [[User:Edokter]]&lt;br /&gt;
 */&lt;br /&gt;
.hlist dl,&lt;br /&gt;
.hlist ol,&lt;br /&gt;
.hlist ul {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Display list items inline */&lt;br /&gt;
.hlist dd,&lt;br /&gt;
.hlist dt,&lt;br /&gt;
.hlist li {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Display nested lists inline */&lt;br /&gt;
.hlist.inline,&lt;br /&gt;
.hlist.inline dl,&lt;br /&gt;
.hlist.inline ol,&lt;br /&gt;
.hlist.inline ul,&lt;br /&gt;
.hlist dl dl, .hlist dl ol, .hlist dl ul,&lt;br /&gt;
.hlist ol dl, .hlist ol ol, .hlist ol ul,&lt;br /&gt;
.hlist ul dl, .hlist ul ol, .hlist ul ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Hide empty list items */&lt;br /&gt;
.hlist .mw-empty-li {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Generate interpuncts */&lt;br /&gt;
.hlist dt:after {&lt;br /&gt;
	content: &amp;quot;: &amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * Note hlist style usage differd in&lt;br /&gt;
 * the Minerva skin. Remember .hlist is a class defined in core as well! Please check Minerva desktop (and Minerva.css) when changing&lt;br /&gt;
 * See https://phabricator.wikimedia.org/T213239&lt;br /&gt;
 */&lt;br /&gt;
.hlist dd:after,&lt;br /&gt;
.hlist li:after {&lt;br /&gt;
	content: &amp;quot; · &amp;quot;;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd:last-child:after,&lt;br /&gt;
.hlist dt:last-child:after,&lt;br /&gt;
.hlist li:last-child:after {&lt;br /&gt;
	content: none;&lt;br /&gt;
}&lt;br /&gt;
/* Add parentheses around nested lists */&lt;br /&gt;
.hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before,&lt;br /&gt;
.hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before,&lt;br /&gt;
.hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after,&lt;br /&gt;
.hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after,&lt;br /&gt;
.hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after {&lt;br /&gt;
	content: &amp;quot;)&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
/* Put ordinals in front of ordered list items */&lt;br /&gt;
.hlist ol {&lt;br /&gt;
	counter-reset: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li {&lt;br /&gt;
	counter-increment: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li:before {&lt;br /&gt;
	content: &amp;quot; &amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist dt ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist li ol &amp;gt; li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Unbulleted lists */&lt;br /&gt;
.plainlist ol,&lt;br /&gt;
.plainlist ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.plainlist ol li,&lt;br /&gt;
.plainlist ul li {&lt;br /&gt;
	margin-bottom: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default style for navigation boxes */&lt;br /&gt;
.navbox {                     /* Navbox container style */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	padding: 1px;&lt;br /&gt;
	margin: 1em auto 0;       /* Prevent preceding content from clinging to navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbox {&lt;br /&gt;
	margin-top: 0;            /* No top margin for nested navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox + .navbox {&lt;br /&gt;
	margin-top: -1px;         /* Single pixel border between adjacent navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox-inner,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-group,&lt;br /&gt;
.navbox-title,&lt;br /&gt;
.navbox-abovebelow {&lt;br /&gt;
	padding: 0.25em 1em;      /* Title, group and above/below styles */&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
th.navbox-group {             /* Group style */&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.navbox,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	background-color: #fdfdfd; /* Background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-list {&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	border-color: #fdfdfd;    /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
/* cell spacing for navbox cells */&lt;br /&gt;
tr + tr &amp;gt; .navbox-abovebelow,&lt;br /&gt;
tr + tr &amp;gt; .navbox-group,&lt;br /&gt;
tr + tr &amp;gt; .navbox-image,&lt;br /&gt;
tr + tr &amp;gt; .navbox-list {    /* Borders above 2nd, 3rd, etc. rows */&lt;br /&gt;
	border-top: 2px solid #fdfdfd; /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox th,&lt;br /&gt;
.navbox-title {&lt;br /&gt;
	background-color: #ccccff;      /* Level 1 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-abovebelow,&lt;br /&gt;
th.navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-title {&lt;br /&gt;
	background-color: #ddddff;      /* Level 2 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-subgroup .navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-abovebelow {&lt;br /&gt;
	background-color: #e6e6ff;      /* Level 3 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-even {&lt;br /&gt;
	background-color: #f7f7f7;      /* Even row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox-odd {&lt;br /&gt;
	background-color: transparent;  /* Odd row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox .hlist td dl,&lt;br /&gt;
.navbox .hlist td ol,&lt;br /&gt;
.navbox .hlist td ul,&lt;br /&gt;
.navbox td.hlist dl,&lt;br /&gt;
.navbox td.hlist ol,&lt;br /&gt;
.navbox td.hlist ul {&lt;br /&gt;
	padding: 0.125em 0;       /* Adjust hlist padding in navboxes */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default styling for Navbar template */&lt;br /&gt;
.navbar {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.navbar ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content .navbar ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
}&lt;br /&gt;
.navbar li {&lt;br /&gt;
	word-spacing: -0.125em;&lt;br /&gt;
}&lt;br /&gt;
.navbar.mini li abbr[title] {&lt;br /&gt;
	font-variant: small-caps;&lt;br /&gt;
	border-bottom: none;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	cursor: inherit;&lt;br /&gt;
}&lt;br /&gt;
/* Navbar styling when nested in infobox and navbox */&lt;br /&gt;
.infobox .navbar {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbar {&lt;br /&gt;
	display: block;&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-title .navbar {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin-right: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for JQuery makeCollapsible, matching that of collapseButton */&lt;br /&gt;
.mw-parser-output .mw-collapsible-toggle {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	padding-right: 0.2em;&lt;br /&gt;
	padding-left: 0.2em;&lt;br /&gt;
}&lt;br /&gt;
.mw-collapsible-leftside-toggle .mw-collapsible-toggle {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Infobox template style */&lt;br /&gt;
.infobox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	border-spacing: 3px;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	color: black;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0.5em 0 0.5em 1em;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
}&lt;br /&gt;
.infobox caption {&lt;br /&gt;
	font-size: 125%;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.infobox td,&lt;br /&gt;
.infobox th {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered td,&lt;br /&gt;
.infobox.bordered th {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered .borderless td,&lt;br /&gt;
.infobox.bordered .borderless th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.sisterproject {&lt;br /&gt;
	width: 20em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
.infobox.standard-talk.bordered td,&lt;br /&gt;
.infobox.standard-talk.bordered th {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* styles for bordered infobox with merged rows */&lt;br /&gt;
.infobox.bordered .mergedtoprow td,&lt;br /&gt;
.infobox.bordered .mergedtoprow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.bordered .mergedrow td,&lt;br /&gt;
.infobox.bordered .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styles for geography infoboxes, eg countries,&lt;br /&gt;
   country subdivisions, cities, etc.            */&lt;br /&gt;
.infobox.geography {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	line-height: 1.2em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography  td,&lt;br /&gt;
.infobox.geography  th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.infobox.geography .mergedtoprow td,&lt;br /&gt;
.infobox.geography .mergedtoprow th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedrow td,&lt;br /&gt;
.infobox.geography .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedbottomrow td,&lt;br /&gt;
.infobox.geography .mergedbottomrow th {&lt;br /&gt;
	border-top: 0;&lt;br /&gt;
	border-bottom: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .maptable td,&lt;br /&gt;
.infobox.geography .maptable th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Normal font styling for wikitable row headers with scope=&amp;quot;row&amp;quot; tag */&lt;br /&gt;
.wikitable.plainrowheaders th[scope=row] {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Lists in wikitable data cells are always left-aligned */&lt;br /&gt;
.wikitable td ul,&lt;br /&gt;
.wikitable td ol,&lt;br /&gt;
.wikitable td dl {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
/* ...unless they also use the hlist class */&lt;br /&gt;
.toc.hlist ul,&lt;br /&gt;
#toc.hlist ul,&lt;br /&gt;
.wikitable.hlist td ul,&lt;br /&gt;
.wikitable.hlist td ol,&lt;br /&gt;
.wikitable.hlist td dl {&lt;br /&gt;
	text-align: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icons for medialist templates [[Template:Listen]],&lt;br /&gt;
   [[Template:Multi-listen_start]], [[Template:Video]],&lt;br /&gt;
   [[Template:Multi-video_start]] */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
div.listenlist {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/4/47/Sound-icon.svg&amp;quot;) no-repeat scroll 0 0 transparent;&lt;br /&gt;
	background-size: 30px;&lt;br /&gt;
	padding-left: 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for hieroglyphs specificity issue in infoboxes ([[phab:T43869]]) */&lt;br /&gt;
table.mw-hiero-table td {&lt;br /&gt;
	vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Change the external link icon to an Adobe icon for all PDF files */&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.pdf&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf#&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.PDF&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF#&amp;quot;].external {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/2/23/Icons-mini-file_acrobat.gif&amp;quot;) no-repeat right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-right: 18px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Messagebox templates */&lt;br /&gt;
.messagebox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	width: 80%;&lt;br /&gt;
	margin: 0 auto 1em auto;&lt;br /&gt;
	padding: .2em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.merge {&lt;br /&gt;
	border: 1px solid #c0b8cc;&lt;br /&gt;
	background-color: #f0e5ff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.cleanup {&lt;br /&gt;
	border: 1px solid #9f9fff;&lt;br /&gt;
	background-color: #efefff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	margin: 4px auto;&lt;br /&gt;
}&lt;br /&gt;
/* For old WikiProject banners inside banner shells. */&lt;br /&gt;
.mbox-inside .standard-talk,&lt;br /&gt;
.messagebox.nested-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	margin: 2px 0;&lt;br /&gt;
	padding: 2px;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small-talk {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */&lt;br /&gt;
th.mbox-text, td.mbox-text {   /* The message body cell(s) */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 0.25em 0.9em;     /* 0.9em left/right */&lt;br /&gt;
	width: 100%;               /* Make all mboxes the same width regardless of text length */&lt;br /&gt;
}&lt;br /&gt;
td.mbox-image {                /* The left image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.9em;  /* 0.9em left, 0px right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-imageright {           /* The right image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.9em 2px 0;  /* 0px left, 0.9em right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-empty-cell {           /* An empty narrow cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Article message box styles */&lt;br /&gt;
table.ambox {&lt;br /&gt;
	margin: 0 10%;                  /* 10% = Will not overlap with other elements */&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;  /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.ambox + table.ambox {      /* Single border between stacked boxes. */&lt;br /&gt;
	margin-top: -1px;&lt;br /&gt;
}&lt;br /&gt;
.ambox th.mbox-text,&lt;br /&gt;
.ambox td.mbox-text {            /* The message body cell(s) */&lt;br /&gt;
	padding: 0.25em 0.5em;       /* 0.5em left/right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-image {           /* The left image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.5em;    /* 0.5em left, 0px right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-imageright {      /* The right image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.5em 2px 0;    /* 0px left, 0.5em right */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-notice {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-speedy {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;          /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-delete {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-content {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-style {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-move {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-protection {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Image message box styles */&lt;br /&gt;
table.imbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 3px solid #36c;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.imbox .mbox-text .imbox {  /* For imboxes inside imbox-text cells. */&lt;br /&gt;
	margin: 0 -0.5em;       /* 0.9 - 0.5 = 0.4em left/right.        */&lt;br /&gt;
	display: block;         /* Fix for webkit to force 100% width.  */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .imbox {       /* For imboxes inside other templates.  */&lt;br /&gt;
	margin: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-notice {&lt;br /&gt;
	border: 3px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-speedy {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-delete {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-content {&lt;br /&gt;
	border: 3px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-style {&lt;br /&gt;
	border: 3px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-move {&lt;br /&gt;
	border: 3px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-protection {&lt;br /&gt;
	border: 3px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-license {&lt;br /&gt;
	border: 3px solid #88a;       /* Dark gray */&lt;br /&gt;
	background-color: #f7f8ff;    /* Light gray */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-featured {&lt;br /&gt;
	border: 3px solid #cba135;    /* Brown-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Category message box styles */&lt;br /&gt;
table.cmbox {&lt;br /&gt;
	margin: 3px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #dfe8ff;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-notice {&lt;br /&gt;
	background-color: #d8e8ff;    /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-speedy {&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
	border: 4px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-delete {&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-content {&lt;br /&gt;
	background-color: #ffe7ce;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-style {&lt;br /&gt;
	background-color: #fff9db;    /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-move {&lt;br /&gt;
	background-color: #e4d8ff;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-protection {&lt;br /&gt;
	background-color: #efefe1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Other pages message box styles */&lt;br /&gt;
table.ombox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Default &amp;quot;notice&amp;quot; gray */&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-notice {&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Gray */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-content {&lt;br /&gt;
	border: 1px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-style {&lt;br /&gt;
	border: 1px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-move {&lt;br /&gt;
	border: 1px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-protection {&lt;br /&gt;
	border: 2px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Talk page message box styles */&lt;br /&gt;
table.tmbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #c0c090;    /* Default &amp;quot;notice&amp;quot; gray-brown */&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	min-width: 80%;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.tmbox.mbox-small {&lt;br /&gt;
	min-width: 0;                /* reset the min-width of tmbox above        */&lt;br /&gt;
}&lt;br /&gt;
.mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The &amp;quot;mediawiki&amp;quot; class ensures that */&lt;br /&gt;
	margin: 2px 0;               /* this declaration overrides other styles (including mbox-small above)   */&lt;br /&gt;
	width: 100%;                 /* For Safari and Opera */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .tmbox.mbox-small { /* &amp;quot;small&amp;quot; tmboxes should not be small when  */&lt;br /&gt;
	line-height: 1.5em;          /* also &amp;quot;nested&amp;quot;, so reset styles that are   */&lt;br /&gt;
	font-size: 100%;             /* set in &amp;quot;mbox-small&amp;quot; above.                */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-content {&lt;br /&gt;
	border: 2px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-style {&lt;br /&gt;
	border: 2px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-move {&lt;br /&gt;
	border: 2px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-protection,&lt;br /&gt;
table.tmbox-notice {&lt;br /&gt;
	border: 1px solid #c0c090;    /* Gray-brown */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Footer and header message box styles */&lt;br /&gt;
table.fmbox {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;     /* Default &amp;quot;system&amp;quot; gray */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-system {&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-warning {&lt;br /&gt;
	border: 1px solid #bb7070;  /* Dark pink */&lt;br /&gt;
	background-color: #ffdbdb;  /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-editnotice {&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
}&lt;br /&gt;
/* Div based &amp;quot;warning&amp;quot; style fmbox messages. */&lt;br /&gt;
div.mw-warning-with-logexcerpt,&lt;br /&gt;
div.mw-lag-warn-high,&lt;br /&gt;
div.mw-cascadeprotectedwarning,&lt;br /&gt;
div#mw-protect-cascadeon,&lt;br /&gt;
div.titleblacklist-warning,&lt;br /&gt;
div.locked-warning {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	border: 1px solid #bb7070;&lt;br /&gt;
	background-color: #ffdbdb;&lt;br /&gt;
	padding: 0.25em 0.9em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* These mbox-small classes must be placed after all other&lt;br /&gt;
   ambox/tmbox/ombox etc classes. &amp;quot;html body.mediawiki&amp;quot; is so&lt;br /&gt;
   they override &amp;quot;table.ambox + table.ambox&amp;quot; above. */&lt;br /&gt;
html body.mediawiki .mbox-small {   /* For the &amp;quot;small=yes&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 0 4px 1em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
html body.mediawiki .mbox-small-left {   /* For the &amp;quot;small=left&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 1em 4px 0;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for compact ambox */&lt;br /&gt;
/* Hide the images */&lt;br /&gt;
.compact-ambox table .mbox-image,&lt;br /&gt;
.compact-ambox table .mbox-imageright,&lt;br /&gt;
.compact-ambox table .mbox-empty-cell {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Remove borders, backgrounds, padding, etc. */&lt;br /&gt;
.compact-ambox table.ambox {&lt;br /&gt;
	border: none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
	margin: 0 0 0 1.6em !important;&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
body.mediawiki .compact-ambox table.mbox-small-left {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Style the text cell as a list item and remove its padding */&lt;br /&gt;
.compact-ambox table .mbox-text {&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
.compact-ambox table .mbox-text-span {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	list-style-type: square;&lt;br /&gt;
	list-style-image: url(/w/skins/MonoBook/resources/images/bullet.svg);&lt;br /&gt;
}&lt;br /&gt;
.skin-vector .compact-ambox table .mbox-text-span {&lt;br /&gt;
	list-style-type: disc;&lt;br /&gt;
	list-style-image: url(/w/skins/Vector/images/bullet-icon.svg);&lt;br /&gt;
}&lt;br /&gt;
/* Allow for hiding text in compact form */&lt;br /&gt;
.compact-ambox .hide-when-compact {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide (formatting) elements from screen, but not from screenreaders */&lt;br /&gt;
.visualhide {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: -10000px;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
	height: 1px;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Suppress missing interwiki image links where #ifexist cannot&lt;br /&gt;
   be used due to high number of requests. See .hidden-redlink on&lt;br /&gt;
   [[m:MediaWiki:Common.css]] */&lt;br /&gt;
.check-icon a.new {&lt;br /&gt;
	display: none;&lt;br /&gt;
	speak: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove underlines from certain links */&lt;br /&gt;
.nounderlines a,&lt;br /&gt;
.IPA a:link, .IPA a:visited {&lt;br /&gt;
	text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Standard Navigationsleisten, aka box hiding thingy&lt;br /&gt;
   from .de.  Documentation at [[Wikipedia:NavFrame]]. */&lt;br /&gt;
div.NavFrame {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 4px;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 95%;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame + div.NavFrame {&lt;br /&gt;
	border-top-style: none;&lt;br /&gt;
	border-top-style: hidden;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame div.NavHead {&lt;br /&gt;
	line-height: 1.6em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	background-color: #ccf;&lt;br /&gt;
	position: relative;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame p,&lt;br /&gt;
div.NavFrame div.NavContent,&lt;br /&gt;
div.NavFrame div.NavContent p {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
a.NavToggle {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	top: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	right: 3px;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hatnotes and disambiguation notices */&lt;br /&gt;
.hatnote {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
}&lt;br /&gt;
.hatnote i {&lt;br /&gt;
	font-style: normal;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-left: 1.6em;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote + div.hatnote {&lt;br /&gt;
	margin-top: -0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow transcluded pages to display in lists rather than a table. */&lt;br /&gt;
.listify td {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
}&lt;br /&gt;
.listify tr {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
.listify table {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Geographical coordinates defaults. See [[Template:Coord/link]]&lt;br /&gt;
   for how these are used. The classes &amp;quot;geo&amp;quot;, &amp;quot;longitude&amp;quot;, and&lt;br /&gt;
   &amp;quot;latitude&amp;quot; are used by the [[Geo microformat]]. */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.geo-default, .geo-dms, .geo-dec {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
.geo-nondefault, .geo-multi-punct {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.longitude, .latitude {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* User block messages */&lt;br /&gt;
div.user-block {&lt;br /&gt;
	padding: 5px;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
	border: 1px solid #a9a9a9;&lt;br /&gt;
	background-color: #ffefd5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent line breaks in silly places:&lt;br /&gt;
   1) Where desired&lt;br /&gt;
   2) Links when we don&#039;t want them to&lt;br /&gt;
   3) Bold &amp;quot;links&amp;quot; to the page itself */&lt;br /&gt;
.nowrap,&lt;br /&gt;
.nowraplinks a,&lt;br /&gt;
.nowraplinks .selflink {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.nowrap pre {&lt;br /&gt;
	white-space: pre;&lt;br /&gt;
}&lt;br /&gt;
/* But allow wrapping where desired: */&lt;br /&gt;
.wrap,&lt;br /&gt;
.wraplinks a {&lt;br /&gt;
	white-space: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For template documentation */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.template-documentation {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 1em 0 0 0;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #ecfcf4;&lt;br /&gt;
	padding: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Increase the height of the image upload box */&lt;br /&gt;
#wpUploadDescription {&lt;br /&gt;
	height: 13em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Minimum thumb width */&lt;br /&gt;
.thumbinner {&lt;br /&gt;
	min-width: 100px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent floating boxes from overlapping any category listings,&lt;br /&gt;
   file histories, edit previews, and edit [Show changes] views. */&lt;br /&gt;
#mw-subcategories, #mw-pages, #mw-category-media,&lt;br /&gt;
#filehistory, #wikiPreview, #wikiDiff {&lt;br /&gt;
	clear: both;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Selectively hide headers in WikiProject banners */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.wpb .wpb-header {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: block;            /* for IE */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: table-row;        /* for real browsers */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb-outside {&lt;br /&gt;
	display: none;             /* hide things that should only display outside shells */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for Abuse Filter tags */&lt;br /&gt;
.mw-tag-markers {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide stuff meant for accounts with special permissions. Made visible again in&lt;br /&gt;
   [[MediaWiki:Group-checkuser.css]], [[MediaWiki:Group-sysop.css]], [[MediaWiki:Group-patroller.css]],&lt;br /&gt;
   [[MediaWiki:Group-templateeditor.css]], [[MediaWiki:Group-extendedmover.css]],&lt;br /&gt;
   [[MediaWiki:Group-extendedconfirmed.css]], and [[Mediawiki:Group-autoconfirmed.css]]. */&lt;br /&gt;
.checkuser-show,&lt;br /&gt;
.sysop-show,&lt;br /&gt;
.patroller-show,&lt;br /&gt;
.templateeditor-show,&lt;br /&gt;
.extendedmover-show,&lt;br /&gt;
.extendedconfirmed-show,&lt;br /&gt;
.autoconfirmed-show,&lt;br /&gt;
.user-show {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide the redlink generated by {{Editnotice}},&lt;br /&gt;
   this overrides the &amp;quot;.sysop-show { display: none; }&amp;quot; above that applies&lt;br /&gt;
   to the same link as well. See [[phab:T45013]]&lt;br /&gt;
&lt;br /&gt;
   Hide the images in editnotices to keep them readable in VE view.&lt;br /&gt;
   Long term, editnotices should become a core feature so that they can be designed responsive. */&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .editnotice-redlink,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-image,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-imageright {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove bullets when there are multiple edit page warnings */&lt;br /&gt;
ul.permissions-errors &amp;gt; li {&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
}&lt;br /&gt;
ul.permissions-errors {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Generic class for Times-based serif, texhtml class for inline math */&lt;br /&gt;
.times-serif,&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	font-family: &amp;quot;Nimbus Roman No9 L&amp;quot;, &amp;quot;Times New Roman&amp;quot;, Times, serif;&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
	line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml span.texhtml {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
span.mwe-math-mathml-inline {&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force tabular and lining display for digits and texhtml */&lt;br /&gt;
.digits,&lt;br /&gt;
.texhtml {&lt;br /&gt;
	-moz-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	-webkit-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-variant-numeric: lining-nums tabular-nums;&lt;br /&gt;
	font-kerning: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make &amp;lt;math display=&amp;quot;block&amp;quot;&amp;gt; be left aligned with one space indent for compatibility with style conventions */&lt;br /&gt;
.mwe-math-fallback-image-display,&lt;br /&gt;
.mwe-math-mathml-display {&lt;br /&gt;
	margin-left: 1.6em !important;&lt;br /&gt;
	margin-top: 0.6em;&lt;br /&gt;
	margin-bottom: 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.mwe-math-mathml-display math {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix styling of transcluded prefindex tables */&lt;br /&gt;
table#mw-prefixindex-list-table,&lt;br /&gt;
table#mw-prefixindex-nav-table {&lt;br /&gt;
	width: 98%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make it possible to hide checkboxes in &amp;lt;inputbox&amp;gt; */&lt;br /&gt;
.inputbox-hidecheckboxes form .inputbox-element,&lt;br /&gt;
.inputbox-hidecheckboxes .mw-ui-checkbox {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Work-around for [[phab:T25965]] / [[phab:T100106]] (Kaltura advertisement) */&lt;br /&gt;
.k-player .k-attribution {&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Move &#039;play&#039; button of video player to bottom left corner */&lt;br /&gt;
.PopUpMediaTransform a .play-btn-large {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	right: auto;&lt;br /&gt;
	bottom: 0;&lt;br /&gt;
	left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide FlaggedRevs notice UI when there are no pending changes */&lt;br /&gt;
.flaggedrevs_draft_synced,&lt;br /&gt;
.flaggedrevs_stable_synced {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force imgs in galleries to have borders by wrapping them in class=bordered-images */&lt;br /&gt;
.bordered-images img {&lt;br /&gt;
	border: solid #ddd 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Gallery styles background changes are restricted to screen view. In printing we should avoid applying backgrounds. */&lt;br /&gt;
@media screen {&lt;br /&gt;
	/* The backgrounds for galleries. */&lt;br /&gt;
	#content .gallerybox div.thumb {&lt;br /&gt;
		/* Light gray padding */&lt;br /&gt;
		background-color: #f8f9fa;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/* Put a chequered background behind images, only visible if they have transparency.&lt;br /&gt;
	&#039;.filehistory a img&#039; and &#039;#file img:hover&#039; are handled by MediaWiki core (as of 1.19) */&lt;br /&gt;
	.gallerybox .thumb img {&lt;br /&gt;
		background: #fff url(//upload.wikimedia.org/wikipedia/commons/5/5d/Checker-16x16.png) repeat;&lt;br /&gt;
	}&lt;br /&gt;
	/* But not on articles, user pages, portals or with opt-out. */&lt;br /&gt;
	.ns-0 .gallerybox .thumb img,&lt;br /&gt;
	.ns-2 .gallerybox .thumb img,&lt;br /&gt;
	.ns-100 .gallerybox .thumb img,&lt;br /&gt;
	.nochecker .gallerybox .thumb img {&lt;br /&gt;
		background-image: none;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display &amp;quot;From Wikipedia, the free encyclopedia&amp;quot; in skins that support it, do not apply to print mode */&lt;br /&gt;
/*@media screen {&lt;br /&gt;
	#siteSub {&lt;br /&gt;
		display: block;&lt;br /&gt;
	}&lt;br /&gt;
}*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki to Noto Sans (does not include headings or monospaced text): */&lt;br /&gt;
body {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Sans&amp;quot;, sans-serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki headings to Noto Serif: */&lt;br /&gt;
#content h1, &lt;br /&gt;
#content h2 {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Serif&amp;quot;, serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-wiki-logo {&lt;br /&gt;
  background-size: 135px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kbd {&lt;br /&gt;
  background: #eee;&lt;br /&gt;
  border: 0.05rem #aaa solid;&lt;br /&gt;
  padding: 0rem 0.2rem;&lt;br /&gt;
  border-radius: 0.2rem;&lt;br /&gt;
  font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-logo-wordmark {&lt;br /&gt;
	font-size: 1.3rem;&lt;br /&gt;
	font-family: &#039;Roboto&#039;, sans-serif;&lt;br /&gt;
	color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*CSS For the main page*/&lt;br /&gt;
  .main-card-container {&lt;br /&gt;
    height: fit-content;&lt;br /&gt;
    height: -moz-fit-content;&lt;br /&gt;
    flex-grow:1;&lt;br /&gt;
    display:flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    padding: 0rem 0.5rem;&lt;br /&gt;
    justify-content: left;&lt;br /&gt;
    align-items: stretch;&lt;br /&gt;
    align-content: stretch;&lt;br /&gt;
    margin: -0.2rem 0rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card {&lt;br /&gt;
    border: 0px;&lt;br /&gt;
    border-radius: 1rem;&lt;br /&gt;
    background: #F7F9F8;&lt;br /&gt;
    box-shadow: 0.1rem 0.1rem 0.5rem black;&lt;br /&gt;
    padding: 0.3rem;&lt;br /&gt;
    margin: 0.2rem;&lt;br /&gt;
    flex: 1 1 30%;&lt;br /&gt;
    max-width: 29%;&lt;br /&gt;
    min-width: 8rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-container h6 {&lt;br /&gt;
    text-align:center&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 80%;&lt;br /&gt;
     margin: auto;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul li {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-header{&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-align: center; &lt;br /&gt;
    margin-top: 0.3rem;&lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7194</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=MediaWiki:Common.css&amp;diff=7194"/>
		<updated>2025-11-23T01:28:24Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Reset italic styling set by user agent */&lt;br /&gt;
cite, dfn {&lt;br /&gt;
	font-style: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Straight quote marks for &amp;lt;q&amp;gt; */&lt;br /&gt;
q {&lt;br /&gt;
	quotes: &#039;&amp;quot;&#039; &#039;&amp;quot;&#039; &amp;quot;&#039;&amp;quot; &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid collision of blockquote with floating elements by swapping margin and padding */&lt;br /&gt;
blockquote {&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	margin: 1em 0;&lt;br /&gt;
	padding: 0 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* give pre a float clearing new block formatting context */&lt;br /&gt;
/* Also break any really long words/urls to keep them visible in that case */&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
	overflow-x: hidden;&lt;br /&gt;
	overflow-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Consistent size for &amp;lt;small&amp;gt;, &amp;lt;sub&amp;gt; and &amp;lt;sup&amp;gt; */&lt;br /&gt;
small {&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content sub,&lt;br /&gt;
.mw-body-content sup,&lt;br /&gt;
span.reference /* for Parsoid */ {&lt;br /&gt;
	font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Same spacing for indented and unindented paragraphs on talk pages */&lt;br /&gt;
.ns-talk .mw-body-content dd {&lt;br /&gt;
	margin-top: 0.4em;&lt;br /&gt;
	margin-bottom: 0.4em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main page fixes */&lt;br /&gt;
#interwiki-completelist {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reduce page jumps by hiding collapsed/dismissed content */&lt;br /&gt;
.client-js .mw-special-Watchlist #watchlist-message,&lt;br /&gt;
.client-js .NavFrame.collapsed .NavContent,&lt;br /&gt;
.client-js .collapsible:not( .mw-made-collapsible).collapsed &amp;gt; tbody &amp;gt; tr:not(:first-child) {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Adds padding above Watchlist announcements where new recentchanges/watchlist filters are enabled */&lt;br /&gt;
.mw-rcfilters-enabled .mw-specialpage-summary {&lt;br /&gt;
	margin-top: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide charinsert base for those not using the gadget */&lt;br /&gt;
#editpage-specialchars {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight linked elements (such as clicked references) in blue */&lt;br /&gt;
body.action-info .mw-body-content :target,&lt;br /&gt;
.citation:target {&lt;br /&gt;
	background-color: #def;  /* Fallback */&lt;br /&gt;
	background-color: rgba(0, 127, 255, 0.133);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for citations. Breaks long urls, etc., rather than overflowing box */&lt;br /&gt;
.citation {&lt;br /&gt;
	word-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For linked citation numbers and document IDs, where the number need not be shown&lt;br /&gt;
   on a screen or a handheld, but should be included in the printed version */&lt;br /&gt;
@media screen, handheld {&lt;br /&gt;
	.citation .printonly {&lt;br /&gt;
		display: none;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make the list of references smaller */&lt;br /&gt;
/* Keep in sync with Template:Refbegin/styles.css */&lt;br /&gt;
ol.references,&lt;br /&gt;
div.reflist {&lt;br /&gt;
	font-size: 90%;            /* Default font-size */&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.reflist ol.references {&lt;br /&gt;
	font-size: 100%;           /* Reset font-size when nested in div.reflist */&lt;br /&gt;
	margin-bottom: 0;          /* Avoid double margin when nested in div.reflist */&lt;br /&gt;
	list-style-type: inherit;  /* Enable custom list style types */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow hidden ref errors to be shown by user CSS */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
span.brokenref {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reset top margin for lists embedded in columns */&lt;br /&gt;
div.columns {&lt;br /&gt;
	margin-top: 0.3em;&lt;br /&gt;
}&lt;br /&gt;
div.columns dl,&lt;br /&gt;
div.columns ol,&lt;br /&gt;
div.columns ul {&lt;br /&gt;
	margin-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid elements breaking between columns */&lt;br /&gt;
.nocolbreak,&lt;br /&gt;
div.columns li,&lt;br /&gt;
div.columns dd dd {&lt;br /&gt;
	-webkit-column-break-inside: avoid;&lt;br /&gt;
	page-break-inside: avoid;&lt;br /&gt;
	break-inside: avoid-column;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for horizontal lists (separator following item).&lt;br /&gt;
   @source mediawiki.org/wiki/Snippets/Horizontal_lists&lt;br /&gt;
   @revision 8 (2016-05-21)&lt;br /&gt;
   @author [[User:Edokter]]&lt;br /&gt;
 */&lt;br /&gt;
.hlist dl,&lt;br /&gt;
.hlist ol,&lt;br /&gt;
.hlist ul {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Display list items inline */&lt;br /&gt;
.hlist dd,&lt;br /&gt;
.hlist dt,&lt;br /&gt;
.hlist li {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Display nested lists inline */&lt;br /&gt;
.hlist.inline,&lt;br /&gt;
.hlist.inline dl,&lt;br /&gt;
.hlist.inline ol,&lt;br /&gt;
.hlist.inline ul,&lt;br /&gt;
.hlist dl dl, .hlist dl ol, .hlist dl ul,&lt;br /&gt;
.hlist ol dl, .hlist ol ol, .hlist ol ul,&lt;br /&gt;
.hlist ul dl, .hlist ul ol, .hlist ul ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
/* Hide empty list items */&lt;br /&gt;
.hlist .mw-empty-li {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Generate interpuncts */&lt;br /&gt;
.hlist dt:after {&lt;br /&gt;
	content: &amp;quot;: &amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
/**&lt;br /&gt;
 * Note hlist style usage differd in&lt;br /&gt;
 * the Minerva skin. Remember .hlist is a class defined in core as well! Please check Minerva desktop (and Minerva.css) when changing&lt;br /&gt;
 * See https://phabricator.wikimedia.org/T213239&lt;br /&gt;
 */&lt;br /&gt;
.hlist dd:after,&lt;br /&gt;
.hlist li:after {&lt;br /&gt;
	content: &amp;quot; · &amp;quot;;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd:last-child:after,&lt;br /&gt;
.hlist dt:last-child:after,&lt;br /&gt;
.hlist li:last-child:after {&lt;br /&gt;
	content: none;&lt;br /&gt;
}&lt;br /&gt;
/* Add parentheses around nested lists */&lt;br /&gt;
.hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before,&lt;br /&gt;
.hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before,&lt;br /&gt;
.hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after,&lt;br /&gt;
.hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after,&lt;br /&gt;
.hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after {&lt;br /&gt;
	content: &amp;quot;)&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
/* Put ordinals in front of ordered list items */&lt;br /&gt;
.hlist ol {&lt;br /&gt;
	counter-reset: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li {&lt;br /&gt;
	counter-increment: listitem;&lt;br /&gt;
}&lt;br /&gt;
.hlist ol &amp;gt; li:before {&lt;br /&gt;
	content: &amp;quot; &amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
.hlist dd ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist dt ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist li ol &amp;gt; li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Unbulleted lists */&lt;br /&gt;
.plainlist ol,&lt;br /&gt;
.plainlist ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.plainlist ol li,&lt;br /&gt;
.plainlist ul li {&lt;br /&gt;
	margin-bottom: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default style for navigation boxes */&lt;br /&gt;
.navbox {                     /* Navbox container style */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	padding: 1px;&lt;br /&gt;
	margin: 1em auto 0;       /* Prevent preceding content from clinging to navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbox {&lt;br /&gt;
	margin-top: 0;            /* No top margin for nested navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox + .navbox {&lt;br /&gt;
	margin-top: -1px;         /* Single pixel border between adjacent navboxes */&lt;br /&gt;
}&lt;br /&gt;
.navbox-inner,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-group,&lt;br /&gt;
.navbox-title,&lt;br /&gt;
.navbox-abovebelow {&lt;br /&gt;
	padding: 0.25em 1em;      /* Title, group and above/below styles */&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
th.navbox-group {             /* Group style */&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.navbox,&lt;br /&gt;
.navbox-subgroup {&lt;br /&gt;
	background-color: #fdfdfd; /* Background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-list {&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	border-color: #fdfdfd;    /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
/* cell spacing for navbox cells */&lt;br /&gt;
tr + tr &amp;gt; .navbox-abovebelow,&lt;br /&gt;
tr + tr &amp;gt; .navbox-group,&lt;br /&gt;
tr + tr &amp;gt; .navbox-image,&lt;br /&gt;
tr + tr &amp;gt; .navbox-list {    /* Borders above 2nd, 3rd, etc. rows */&lt;br /&gt;
	border-top: 2px solid #fdfdfd; /* Must match background color */&lt;br /&gt;
}&lt;br /&gt;
.navbox th,&lt;br /&gt;
.navbox-title {&lt;br /&gt;
	background-color: #ccccff;      /* Level 1 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-abovebelow,&lt;br /&gt;
th.navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-title {&lt;br /&gt;
	background-color: #ddddff;      /* Level 2 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-subgroup .navbox-group,&lt;br /&gt;
.navbox-subgroup .navbox-abovebelow {&lt;br /&gt;
	background-color: #e6e6ff;      /* Level 3 color */&lt;br /&gt;
}&lt;br /&gt;
.navbox-even {&lt;br /&gt;
	background-color: #f7f7f7;      /* Even row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox-odd {&lt;br /&gt;
	background-color: transparent;  /* Odd row striping */&lt;br /&gt;
}&lt;br /&gt;
.navbox .hlist td dl,&lt;br /&gt;
.navbox .hlist td ol,&lt;br /&gt;
.navbox .hlist td ul,&lt;br /&gt;
.navbox td.hlist dl,&lt;br /&gt;
.navbox td.hlist ol,&lt;br /&gt;
.navbox td.hlist ul {&lt;br /&gt;
	padding: 0.125em 0;       /* Adjust hlist padding in navboxes */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Default styling for Navbar template */&lt;br /&gt;
.navbar {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.navbar ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.mw-body-content .navbar ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
}&lt;br /&gt;
.navbar li {&lt;br /&gt;
	word-spacing: -0.125em;&lt;br /&gt;
}&lt;br /&gt;
.navbar.mini li abbr[title] {&lt;br /&gt;
	font-variant: small-caps;&lt;br /&gt;
	border-bottom: none;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	cursor: inherit;&lt;br /&gt;
}&lt;br /&gt;
/* Navbar styling when nested in infobox and navbox */&lt;br /&gt;
.infobox .navbar {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox .navbar {&lt;br /&gt;
	display: block;&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
.navbox-title .navbar {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin-right: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for JQuery makeCollapsible, matching that of collapseButton */&lt;br /&gt;
.mw-parser-output .mw-collapsible-toggle {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	padding-right: 0.2em;&lt;br /&gt;
	padding-left: 0.2em;&lt;br /&gt;
}&lt;br /&gt;
.mw-collapsible-leftside-toggle .mw-collapsible-toggle {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Infobox template style */&lt;br /&gt;
.infobox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	border-spacing: 3px;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	color: black;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0.5em 0 0.5em 1em;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
}&lt;br /&gt;
.infobox caption {&lt;br /&gt;
	font-size: 125%;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.infobox td,&lt;br /&gt;
.infobox th {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered td,&lt;br /&gt;
.infobox.bordered th {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
.infobox.bordered .borderless td,&lt;br /&gt;
.infobox.bordered .borderless th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.sisterproject {&lt;br /&gt;
	width: 20em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
.infobox.standard-talk.bordered td,&lt;br /&gt;
.infobox.standard-talk.bordered th {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* styles for bordered infobox with merged rows */&lt;br /&gt;
.infobox.bordered .mergedtoprow td,&lt;br /&gt;
.infobox.bordered .mergedtoprow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.bordered .mergedrow td,&lt;br /&gt;
.infobox.bordered .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-right: 1px solid #a2a9b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styles for geography infoboxes, eg countries,&lt;br /&gt;
   country subdivisions, cities, etc.            */&lt;br /&gt;
.infobox.geography {&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	line-height: 1.2em;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography  td,&lt;br /&gt;
.infobox.geography  th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.infobox.geography .mergedtoprow td,&lt;br /&gt;
.infobox.geography .mergedtoprow th {&lt;br /&gt;
	border-top: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0.4em 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedrow td,&lt;br /&gt;
.infobox.geography .mergedrow th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0 0.6em 0.2em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .mergedbottomrow td,&lt;br /&gt;
.infobox.geography .mergedbottomrow th {&lt;br /&gt;
	border-top: 0;&lt;br /&gt;
	border-bottom: 1px solid #a2a9b1;&lt;br /&gt;
	padding: 0 0.6em 0.4em 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox.geography .maptable td,&lt;br /&gt;
.infobox.geography .maptable th {&lt;br /&gt;
	border: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Normal font styling for wikitable row headers with scope=&amp;quot;row&amp;quot; tag */&lt;br /&gt;
.wikitable.plainrowheaders th[scope=row] {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Lists in wikitable data cells are always left-aligned */&lt;br /&gt;
.wikitable td ul,&lt;br /&gt;
.wikitable td ol,&lt;br /&gt;
.wikitable td dl {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
/* ...unless they also use the hlist class */&lt;br /&gt;
.toc.hlist ul,&lt;br /&gt;
#toc.hlist ul,&lt;br /&gt;
.wikitable.hlist td ul,&lt;br /&gt;
.wikitable.hlist td ol,&lt;br /&gt;
.wikitable.hlist td dl {&lt;br /&gt;
	text-align: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icons for medialist templates [[Template:Listen]],&lt;br /&gt;
   [[Template:Multi-listen_start]], [[Template:Video]],&lt;br /&gt;
   [[Template:Multi-video_start]] */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
div.listenlist {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/4/47/Sound-icon.svg&amp;quot;) no-repeat scroll 0 0 transparent;&lt;br /&gt;
	background-size: 30px;&lt;br /&gt;
	padding-left: 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for hieroglyphs specificity issue in infoboxes ([[phab:T43869]]) */&lt;br /&gt;
table.mw-hiero-table td {&lt;br /&gt;
	vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Change the external link icon to an Adobe icon for all PDF files */&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.pdf&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf#&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.PDF&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF#&amp;quot;].external {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/2/23/Icons-mini-file_acrobat.gif&amp;quot;) no-repeat right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-right: 18px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Messagebox templates */&lt;br /&gt;
.messagebox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	width: 80%;&lt;br /&gt;
	margin: 0 auto 1em auto;&lt;br /&gt;
	padding: .2em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.merge {&lt;br /&gt;
	border: 1px solid #c0b8cc;&lt;br /&gt;
	background-color: #f0e5ff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.cleanup {&lt;br /&gt;
	border: 1px solid #9f9fff;&lt;br /&gt;
	background-color: #efefff;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	margin: 4px auto;&lt;br /&gt;
}&lt;br /&gt;
/* For old WikiProject banners inside banner shells. */&lt;br /&gt;
.mbox-inside .standard-talk,&lt;br /&gt;
.messagebox.nested-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	margin: 2px 0;&lt;br /&gt;
	padding: 2px;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
.messagebox.small-talk {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */&lt;br /&gt;
th.mbox-text, td.mbox-text {   /* The message body cell(s) */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 0.25em 0.9em;     /* 0.9em left/right */&lt;br /&gt;
	width: 100%;               /* Make all mboxes the same width regardless of text length */&lt;br /&gt;
}&lt;br /&gt;
td.mbox-image {                /* The left image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.9em;  /* 0.9em left, 0px right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-imageright {           /* The right image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.9em 2px 0;  /* 0px left, 0.9em right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
td.mbox-empty-cell {           /* An empty narrow cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Article message box styles */&lt;br /&gt;
table.ambox {&lt;br /&gt;
	margin: 0 10%;                  /* 10% = Will not overlap with other elements */&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;  /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.ambox + table.ambox {      /* Single border between stacked boxes. */&lt;br /&gt;
	margin-top: -1px;&lt;br /&gt;
}&lt;br /&gt;
.ambox th.mbox-text,&lt;br /&gt;
.ambox td.mbox-text {            /* The message body cell(s) */&lt;br /&gt;
	padding: 0.25em 0.5em;       /* 0.5em left/right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-image {           /* The left image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.5em;    /* 0.5em left, 0px right */&lt;br /&gt;
}&lt;br /&gt;
.ambox td.mbox-imageright {      /* The right image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.5em 2px 0;    /* 0px left, 0.5em right */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-notice {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-speedy {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;          /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-delete {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-content {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-style {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-move {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ambox-protection {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Image message box styles */&lt;br /&gt;
table.imbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 3px solid #36c;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.imbox .mbox-text .imbox {  /* For imboxes inside imbox-text cells. */&lt;br /&gt;
	margin: 0 -0.5em;       /* 0.9 - 0.5 = 0.4em left/right.        */&lt;br /&gt;
	display: block;         /* Fix for webkit to force 100% width.  */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .imbox {       /* For imboxes inside other templates.  */&lt;br /&gt;
	margin: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-notice {&lt;br /&gt;
	border: 3px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-speedy {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-delete {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-content {&lt;br /&gt;
	border: 3px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-style {&lt;br /&gt;
	border: 3px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-move {&lt;br /&gt;
	border: 3px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-protection {&lt;br /&gt;
	border: 3px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-license {&lt;br /&gt;
	border: 3px solid #88a;       /* Dark gray */&lt;br /&gt;
	background-color: #f7f8ff;    /* Light gray */&lt;br /&gt;
}&lt;br /&gt;
table.imbox-featured {&lt;br /&gt;
	border: 3px solid #cba135;    /* Brown-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Category message box styles */&lt;br /&gt;
table.cmbox {&lt;br /&gt;
	margin: 3px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #dfe8ff;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-notice {&lt;br /&gt;
	background-color: #d8e8ff;    /* Blue */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-speedy {&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
	border: 4px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-delete {&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-content {&lt;br /&gt;
	background-color: #ffe7ce;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-style {&lt;br /&gt;
	background-color: #fff9db;    /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-move {&lt;br /&gt;
	background-color: #e4d8ff;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.cmbox-protection {&lt;br /&gt;
	background-color: #efefe1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Other pages message box styles */&lt;br /&gt;
table.ombox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Default &amp;quot;notice&amp;quot; gray */&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-notice {&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Gray */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-content {&lt;br /&gt;
	border: 1px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-style {&lt;br /&gt;
	border: 1px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-move {&lt;br /&gt;
	border: 1px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.ombox-protection {&lt;br /&gt;
	border: 2px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Talk page message box styles */&lt;br /&gt;
table.tmbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #c0c090;    /* Default &amp;quot;notice&amp;quot; gray-brown */&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	min-width: 80%;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.tmbox.mbox-small {&lt;br /&gt;
	min-width: 0;                /* reset the min-width of tmbox above        */&lt;br /&gt;
}&lt;br /&gt;
.mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The &amp;quot;mediawiki&amp;quot; class ensures that */&lt;br /&gt;
	margin: 2px 0;               /* this declaration overrides other styles (including mbox-small above)   */&lt;br /&gt;
	width: 100%;                 /* For Safari and Opera */&lt;br /&gt;
}&lt;br /&gt;
.mbox-inside .tmbox.mbox-small { /* &amp;quot;small&amp;quot; tmboxes should not be small when  */&lt;br /&gt;
	line-height: 1.5em;          /* also &amp;quot;nested&amp;quot;, so reset styles that are   */&lt;br /&gt;
	font-size: 100%;             /* set in &amp;quot;mbox-small&amp;quot; above.                */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-content {&lt;br /&gt;
	border: 2px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-style {&lt;br /&gt;
	border: 2px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-move {&lt;br /&gt;
	border: 2px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
table.tmbox-protection,&lt;br /&gt;
table.tmbox-notice {&lt;br /&gt;
	border: 1px solid #c0c090;    /* Gray-brown */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Footer and header message box styles */&lt;br /&gt;
table.fmbox {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;     /* Default &amp;quot;system&amp;quot; gray */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-system {&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-warning {&lt;br /&gt;
	border: 1px solid #bb7070;  /* Dark pink */&lt;br /&gt;
	background-color: #ffdbdb;  /* Pink */&lt;br /&gt;
}&lt;br /&gt;
table.fmbox-editnotice {&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
}&lt;br /&gt;
/* Div based &amp;quot;warning&amp;quot; style fmbox messages. */&lt;br /&gt;
div.mw-warning-with-logexcerpt,&lt;br /&gt;
div.mw-lag-warn-high,&lt;br /&gt;
div.mw-cascadeprotectedwarning,&lt;br /&gt;
div#mw-protect-cascadeon,&lt;br /&gt;
div.titleblacklist-warning,&lt;br /&gt;
div.locked-warning {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	border: 1px solid #bb7070;&lt;br /&gt;
	background-color: #ffdbdb;&lt;br /&gt;
	padding: 0.25em 0.9em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* These mbox-small classes must be placed after all other&lt;br /&gt;
   ambox/tmbox/ombox etc classes. &amp;quot;html body.mediawiki&amp;quot; is so&lt;br /&gt;
   they override &amp;quot;table.ambox + table.ambox&amp;quot; above. */&lt;br /&gt;
html body.mediawiki .mbox-small {   /* For the &amp;quot;small=yes&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 0 4px 1em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
html body.mediawiki .mbox-small-left {   /* For the &amp;quot;small=left&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 1em 4px 0;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for compact ambox */&lt;br /&gt;
/* Hide the images */&lt;br /&gt;
.compact-ambox table .mbox-image,&lt;br /&gt;
.compact-ambox table .mbox-imageright,&lt;br /&gt;
.compact-ambox table .mbox-empty-cell {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
/* Remove borders, backgrounds, padding, etc. */&lt;br /&gt;
.compact-ambox table.ambox {&lt;br /&gt;
	border: none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
	margin: 0 0 0 1.6em !important;&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
body.mediawiki .compact-ambox table.mbox-small-left {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
/* Style the text cell as a list item and remove its padding */&lt;br /&gt;
.compact-ambox table .mbox-text {&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
.compact-ambox table .mbox-text-span {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	list-style-type: square;&lt;br /&gt;
	list-style-image: url(/w/skins/MonoBook/resources/images/bullet.svg);&lt;br /&gt;
}&lt;br /&gt;
.skin-vector .compact-ambox table .mbox-text-span {&lt;br /&gt;
	list-style-type: disc;&lt;br /&gt;
	list-style-image: url(/w/skins/Vector/images/bullet-icon.svg);&lt;br /&gt;
}&lt;br /&gt;
/* Allow for hiding text in compact form */&lt;br /&gt;
.compact-ambox .hide-when-compact {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide (formatting) elements from screen, but not from screenreaders */&lt;br /&gt;
.visualhide {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: -10000px;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
	height: 1px;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Suppress missing interwiki image links where #ifexist cannot&lt;br /&gt;
   be used due to high number of requests. See .hidden-redlink on&lt;br /&gt;
   [[m:MediaWiki:Common.css]] */&lt;br /&gt;
.check-icon a.new {&lt;br /&gt;
	display: none;&lt;br /&gt;
	speak: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove underlines from certain links */&lt;br /&gt;
.nounderlines a,&lt;br /&gt;
.IPA a:link, .IPA a:visited {&lt;br /&gt;
	text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Standard Navigationsleisten, aka box hiding thingy&lt;br /&gt;
   from .de.  Documentation at [[Wikipedia:NavFrame]]. */&lt;br /&gt;
div.NavFrame {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 4px;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 95%;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame + div.NavFrame {&lt;br /&gt;
	border-top-style: none;&lt;br /&gt;
	border-top-style: hidden;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame div.NavHead {&lt;br /&gt;
	line-height: 1.6em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	background-color: #ccf;&lt;br /&gt;
	position: relative;&lt;br /&gt;
}&lt;br /&gt;
div.NavFrame p,&lt;br /&gt;
div.NavFrame div.NavContent,&lt;br /&gt;
div.NavFrame div.NavContent p {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
a.NavToggle {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	top: 0;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	right: 3px;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hatnotes and disambiguation notices */&lt;br /&gt;
.hatnote {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
}&lt;br /&gt;
.hatnote i {&lt;br /&gt;
	font-style: normal;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-left: 1.6em;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
div.hatnote + div.hatnote {&lt;br /&gt;
	margin-top: -0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow transcluded pages to display in lists rather than a table. */&lt;br /&gt;
.listify td {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
}&lt;br /&gt;
.listify tr {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
.listify table {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Geographical coordinates defaults. See [[Template:Coord/link]]&lt;br /&gt;
   for how these are used. The classes &amp;quot;geo&amp;quot;, &amp;quot;longitude&amp;quot;, and&lt;br /&gt;
   &amp;quot;latitude&amp;quot; are used by the [[Geo microformat]]. */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.geo-default, .geo-dms, .geo-dec {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
.geo-nondefault, .geo-multi-punct {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.longitude, .latitude {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* User block messages */&lt;br /&gt;
div.user-block {&lt;br /&gt;
	padding: 5px;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
	border: 1px solid #a9a9a9;&lt;br /&gt;
	background-color: #ffefd5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent line breaks in silly places:&lt;br /&gt;
   1) Where desired&lt;br /&gt;
   2) Links when we don&#039;t want them to&lt;br /&gt;
   3) Bold &amp;quot;links&amp;quot; to the page itself */&lt;br /&gt;
.nowrap,&lt;br /&gt;
.nowraplinks a,&lt;br /&gt;
.nowraplinks .selflink {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.nowrap pre {&lt;br /&gt;
	white-space: pre;&lt;br /&gt;
}&lt;br /&gt;
/* But allow wrapping where desired: */&lt;br /&gt;
.wrap,&lt;br /&gt;
.wraplinks a {&lt;br /&gt;
	white-space: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For template documentation */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.template-documentation {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 1em 0 0 0;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #ecfcf4;&lt;br /&gt;
	padding: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Increase the height of the image upload box */&lt;br /&gt;
#wpUploadDescription {&lt;br /&gt;
	height: 13em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Minimum thumb width */&lt;br /&gt;
.thumbinner {&lt;br /&gt;
	min-width: 100px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent floating boxes from overlapping any category listings,&lt;br /&gt;
   file histories, edit previews, and edit [Show changes] views. */&lt;br /&gt;
#mw-subcategories, #mw-pages, #mw-category-media,&lt;br /&gt;
#filehistory, #wikiPreview, #wikiDiff {&lt;br /&gt;
	clear: both;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Selectively hide headers in WikiProject banners */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.wpb .wpb-header {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: block;            /* for IE */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: table-row;        /* for real browsers */&lt;br /&gt;
}&lt;br /&gt;
.wpbs-inner .wpb-outside {&lt;br /&gt;
	display: none;             /* hide things that should only display outside shells */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for Abuse Filter tags */&lt;br /&gt;
.mw-tag-markers {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide stuff meant for accounts with special permissions. Made visible again in&lt;br /&gt;
   [[MediaWiki:Group-checkuser.css]], [[MediaWiki:Group-sysop.css]], [[MediaWiki:Group-patroller.css]],&lt;br /&gt;
   [[MediaWiki:Group-templateeditor.css]], [[MediaWiki:Group-extendedmover.css]],&lt;br /&gt;
   [[MediaWiki:Group-extendedconfirmed.css]], and [[Mediawiki:Group-autoconfirmed.css]]. */&lt;br /&gt;
.checkuser-show,&lt;br /&gt;
.sysop-show,&lt;br /&gt;
.patroller-show,&lt;br /&gt;
.templateeditor-show,&lt;br /&gt;
.extendedmover-show,&lt;br /&gt;
.extendedconfirmed-show,&lt;br /&gt;
.autoconfirmed-show,&lt;br /&gt;
.user-show {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide the redlink generated by {{Editnotice}},&lt;br /&gt;
   this overrides the &amp;quot;.sysop-show { display: none; }&amp;quot; above that applies&lt;br /&gt;
   to the same link as well. See [[phab:T45013]]&lt;br /&gt;
&lt;br /&gt;
   Hide the images in editnotices to keep them readable in VE view.&lt;br /&gt;
   Long term, editnotices should become a core feature so that they can be designed responsive. */&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .editnotice-redlink,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-image,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-imageright {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove bullets when there are multiple edit page warnings */&lt;br /&gt;
ul.permissions-errors &amp;gt; li {&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
}&lt;br /&gt;
ul.permissions-errors {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Generic class for Times-based serif, texhtml class for inline math */&lt;br /&gt;
.times-serif,&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	font-family: &amp;quot;Nimbus Roman No9 L&amp;quot;, &amp;quot;Times New Roman&amp;quot;, Times, serif;&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
	line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
span.texhtml span.texhtml {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
span.mwe-math-mathml-inline {&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force tabular and lining display for digits and texhtml */&lt;br /&gt;
.digits,&lt;br /&gt;
.texhtml {&lt;br /&gt;
	-moz-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	-webkit-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-variant-numeric: lining-nums tabular-nums;&lt;br /&gt;
	font-kerning: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make &amp;lt;math display=&amp;quot;block&amp;quot;&amp;gt; be left aligned with one space indent for compatibility with style conventions */&lt;br /&gt;
.mwe-math-fallback-image-display,&lt;br /&gt;
.mwe-math-mathml-display {&lt;br /&gt;
	margin-left: 1.6em !important;&lt;br /&gt;
	margin-top: 0.6em;&lt;br /&gt;
	margin-bottom: 0.6em;&lt;br /&gt;
}&lt;br /&gt;
.mwe-math-mathml-display math {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix styling of transcluded prefindex tables */&lt;br /&gt;
table#mw-prefixindex-list-table,&lt;br /&gt;
table#mw-prefixindex-nav-table {&lt;br /&gt;
	width: 98%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make it possible to hide checkboxes in &amp;lt;inputbox&amp;gt; */&lt;br /&gt;
.inputbox-hidecheckboxes form .inputbox-element,&lt;br /&gt;
.inputbox-hidecheckboxes .mw-ui-checkbox {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Work-around for [[phab:T25965]] / [[phab:T100106]] (Kaltura advertisement) */&lt;br /&gt;
.k-player .k-attribution {&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Move &#039;play&#039; button of video player to bottom left corner */&lt;br /&gt;
.PopUpMediaTransform a .play-btn-large {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	right: auto;&lt;br /&gt;
	bottom: 0;&lt;br /&gt;
	left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide FlaggedRevs notice UI when there are no pending changes */&lt;br /&gt;
.flaggedrevs_draft_synced,&lt;br /&gt;
.flaggedrevs_stable_synced {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Force imgs in galleries to have borders by wrapping them in class=bordered-images */&lt;br /&gt;
.bordered-images img {&lt;br /&gt;
	border: solid #ddd 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Gallery styles background changes are restricted to screen view. In printing we should avoid applying backgrounds. */&lt;br /&gt;
@media screen {&lt;br /&gt;
	/* The backgrounds for galleries. */&lt;br /&gt;
	#content .gallerybox div.thumb {&lt;br /&gt;
		/* Light gray padding */&lt;br /&gt;
		background-color: #f8f9fa;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/* Put a chequered background behind images, only visible if they have transparency.&lt;br /&gt;
	&#039;.filehistory a img&#039; and &#039;#file img:hover&#039; are handled by MediaWiki core (as of 1.19) */&lt;br /&gt;
	.gallerybox .thumb img {&lt;br /&gt;
		background: #fff url(//upload.wikimedia.org/wikipedia/commons/5/5d/Checker-16x16.png) repeat;&lt;br /&gt;
	}&lt;br /&gt;
	/* But not on articles, user pages, portals or with opt-out. */&lt;br /&gt;
	.ns-0 .gallerybox .thumb img,&lt;br /&gt;
	.ns-2 .gallerybox .thumb img,&lt;br /&gt;
	.ns-100 .gallerybox .thumb img,&lt;br /&gt;
	.nochecker .gallerybox .thumb img {&lt;br /&gt;
		background-image: none;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display &amp;quot;From Wikipedia, the free encyclopedia&amp;quot; in skins that support it, do not apply to print mode */&lt;br /&gt;
/*@media screen {&lt;br /&gt;
	#siteSub {&lt;br /&gt;
		display: block;&lt;br /&gt;
	}&lt;br /&gt;
}*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki to Noto Sans (does not include headings or monospaced text): */&lt;br /&gt;
body {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Sans&amp;quot;, sans-serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Changes the default font used for MediaWiki headings to Noto Serif: */&lt;br /&gt;
#content h1, &lt;br /&gt;
#content h2 {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, &amp;quot;Noto Serif&amp;quot;, serif;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-wiki-logo {&lt;br /&gt;
  background-size: 135px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kbd {&lt;br /&gt;
  background: #eee;&lt;br /&gt;
  border: 0.05rem #aaa solid;&lt;br /&gt;
  padding: 0rem 0.2rem;&lt;br /&gt;
  border-radius: 0.2rem;&lt;br /&gt;
  font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-logo-wordmark {&lt;br /&gt;
	font-size: 1.3rem;&lt;br /&gt;
	font-family: &#039;Roboto&#039;, sans-serif;&lt;br /&gt;
	color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*CSS For the main page*/&lt;br /&gt;
  .main-card-container {&lt;br /&gt;
    height: fit-content;&lt;br /&gt;
    height: -moz-fit-content;&lt;br /&gt;
    flex-grow:1;&lt;br /&gt;
    display:flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    padding: 0rem 0.5rem;&lt;br /&gt;
    justify-content: left;&lt;br /&gt;
    align-items: stretch;&lt;br /&gt;
    align-content: stretch;&lt;br /&gt;
    margin: -0.2rem 0rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card {&lt;br /&gt;
    border: 0px;&lt;br /&gt;
    border-radius: 1rem;&lt;br /&gt;
    background: #F7F9F8;&lt;br /&gt;
    padding: 0.3rem;&lt;br /&gt;
    margin: 0.2rem;&lt;br /&gt;
    flex: 1 1 30%;&lt;br /&gt;
    max-width: 29%;&lt;br /&gt;
    min-width: 8rem;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-container h6 {&lt;br /&gt;
    text-align:center&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 80%;&lt;br /&gt;
     margin: auto;&lt;br /&gt;
  }&lt;br /&gt;
  .main-flex-card ul li {&lt;br /&gt;
     width: fit-content;&lt;br /&gt;
     width: -moz-fit-content;&lt;br /&gt;
     max-width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  .main-card-header{&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-align: center; &lt;br /&gt;
    margin-top: 0.3rem;&lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=C%2B%2B&amp;diff=7193</id>
		<title>C++</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=C%2B%2B&amp;diff=7193"/>
		<updated>2025-11-23T01:20:54Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
C++ is a very popular and powerful language which includes all the low-level features of [[C_(programming_language) | C]] (e.g. pointers, operator overloading) along with many high-level features (RAII, STD algorithms, STL containers) thanks to the C++ standard library.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
How to do things using the [https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library C++ standard library (stdlib)].&lt;br /&gt;
===Compilation===&lt;br /&gt;
{{See also|CMake|Makefile}}&lt;br /&gt;
====cmake====&lt;br /&gt;
&lt;br /&gt;
====g++====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
g++ my_driver.cpp [-Iincludefolder] -o my_program.out&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Standard optimizations&lt;br /&gt;
* &amp;lt;code&amp;gt;-std=c++17&amp;lt;/code&amp;gt; for C++17 support&lt;br /&gt;
* &amp;lt;code&amp;gt;-O3&amp;lt;/code&amp;gt; for level 3 optimizations&lt;br /&gt;
* &amp;lt;code&amp;gt;-g&amp;lt;/code&amp;gt; to include debugging info&lt;br /&gt;
* &amp;lt;code&amp;gt;-march=native&amp;lt;/code&amp;gt; - use all instructions available on the current CPU&lt;br /&gt;
* &amp;lt;code&amp;gt;-mtune=native&amp;lt;/code&amp;gt; - optimize for the current CPU&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
====Main====&lt;br /&gt;
All C++ programs launch in a &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; function.&lt;br /&gt;
Similar to [[C (programming language) | C]], the arguments are &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;char *argv[]&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
These can be easily converted to a &amp;lt;code&amp;gt;std::vector&amp;lt;std::string&amp;gt;&amp;lt;/code&amp;gt; for convenience.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
  std::vector&amp;lt;std::string&amp;gt; args(argv, argv + argc);&lt;br /&gt;
  // Your code here&lt;br /&gt;
  return EXIT_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Headers====&lt;br /&gt;
[https://stackoverflow.com/questions/10694255/cmath-vs-math-h-and-similar-c-prefixed-vs-h-extension-headers Reference]&lt;br /&gt;
&lt;br /&gt;
C++ includes C-headers such as &amp;lt;code&amp;gt;math.h&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cmath&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The C-style header will place everything in the global namespace while the C++ header will place everything in &amp;lt;code&amp;gt;std&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
You should use &amp;lt;code&amp;gt;cmath&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Lambda Expressions====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/lambda Reference]&lt;br /&gt;
&lt;br /&gt;
====Casting====&lt;br /&gt;
[https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used Types of casts]&lt;br /&gt;
&lt;br /&gt;
C++ has several types of casts including:&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/static_cast &amp;lt;code&amp;gt;static_cast&amp;lt;/code&amp;gt;] - your standard cast with conversion. Does not perform any checks.&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/dynamic_cast &amp;lt;code&amp;gt;dynamic_cast&amp;lt;/code&amp;gt;] - for casting objects with checking, requires a polymorphic base class (with a virtual function). Will return nullptr.&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/reinterpret_cast &amp;lt;code&amp;gt;reinterpret_cast&amp;lt;/code&amp;gt;] - cast without any conversion, for directly dealing with binary data, equivalent to &amp;lt;code&amp;gt;*(T*)&amp;lt;/code&amp;gt; in C.&lt;br /&gt;
&lt;br /&gt;
====References====&lt;br /&gt;
References are accepted or stored using &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
void healPerson(Person &amp;amp;person) {&lt;br /&gt;
  person.health = 100;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
References are like pointers since they do not copy the object except they cannot be null and they cannot be reassigned.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that primitives can also be used with references, in which case changes will propagate to the underlying value.&amp;lt;br&amp;gt;&lt;br /&gt;
You can also use them as class attributes, initializing them in the constructor&#039;s initializer list.&amp;lt;br&amp;gt;&lt;br /&gt;
To store references in a vector, you can use &amp;lt;code&amp;gt;std::reference_wrapper&amp;lt;/code&amp;gt; and include the &amp;lt;code&amp;gt;functional&amp;lt;/code&amp;gt; header.&lt;br /&gt;
&lt;br /&gt;
====Types====&lt;br /&gt;
For simple programs, you can use the standard types:&lt;br /&gt;
* &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;unsigned int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;size_t&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt;&lt;br /&gt;
See [https://stackoverflow.com/questions/6462439/whats-the-difference-between-long-long-and-long SO] for the standard and guaranteed precision of these built-in types.&lt;br /&gt;
&lt;br /&gt;
C++ also has fixed-width types in &amp;lt;code&amp;gt;#include &amp;lt;cstdint&amp;gt;&amp;lt;/code&amp;gt; (since C++11).&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/header/cstdint cppreference cstdint]&amp;lt;br&amp;gt;&lt;br /&gt;
I recommend using these for anything with specific or high precision requirements.&amp;lt;br&amp;gt;&lt;br /&gt;
Typically, I use:&lt;br /&gt;
* &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;std::byte&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;int64_t&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;long long&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;string&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t need to own the string, prefer to use &amp;lt;code&amp;gt;string_view&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// c-str to string&lt;br /&gt;
char *old_string = &amp;quot;my c-style string&amp;quot;;&lt;br /&gt;
std::string cpp_string(old_string);&lt;br /&gt;
&lt;br /&gt;
// string to c-str&lt;br /&gt;
cpp_string.c_str();&lt;br /&gt;
&lt;br /&gt;
// char to string&lt;br /&gt;
char my_char = &#039;a&#039;;&lt;br /&gt;
std::string my_str(1, my_char);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====String Interpolation====&lt;br /&gt;
[https://stackoverflow.com/questions/10410023/string-format-alternative-in-c Reference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    std::string a = &amp;quot;a&amp;quot;, b = &amp;quot;b&amp;quot;, c = &amp;quot;c&amp;quot;;&lt;br /&gt;
    // apply formatting&lt;br /&gt;
    std::stringstream s;&lt;br /&gt;
    s &amp;lt;&amp;lt; a &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; b &amp;lt;&amp;lt; &amp;quot; &amp;gt; &amp;quot; &amp;lt;&amp;lt; c;&lt;br /&gt;
    // assign to std::string&lt;br /&gt;
    std::string str = s.str();&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; str &amp;lt;&amp;lt; &amp;quot;\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Building Strings====&lt;br /&gt;
[https://www.fluentcpp.com/2017/12/19/build-strings-from-plain-string-up-to-boost-karma/ The Complete Guide to Building Strings In C++]&amp;lt;br&amp;gt;&lt;br /&gt;
There are multiple ways of buildings strings in C++.&amp;lt;br&amp;gt;&lt;br /&gt;
Strings are mutable in C++.&amp;lt;br&amp;gt;&lt;br /&gt;
I typically use &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ostringstream&amp;lt;/code&amp;gt; to build strings.&lt;br /&gt;
&lt;br /&gt;
====std::basic_string_view====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/string/basic_string_view std::basic_string_view]&lt;br /&gt;
&lt;br /&gt;
This is useful for writing functions which accept anything that looks like a string such as substrings, since typically &amp;lt;code&amp;gt;std::string::substr&amp;lt;/code&amp;gt; performs a copy.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;code&amp;gt;std::string_view&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;std::basic_string_view&amp;lt;char&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Filesystem===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;filesystem&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Convenient functions for filesystem. Added since C++17.&lt;br /&gt;
====Path====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/filesystem/path cppreference]&lt;br /&gt;
&lt;br /&gt;
Note if you use g++ &amp;lt;= version 9, you will need to add the flag &amp;lt;code&amp;gt;-lstdc++fs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
using std::filesystem::path;&lt;br /&gt;
&lt;br /&gt;
// Initialization&lt;br /&gt;
path my_path = &amp;quot;my_dir/my_file&amp;quot;;&lt;br /&gt;
// or my_path = path(&amp;quot;my_dir&amp;quot;) / &amp;quot;my_file&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Append to path&lt;br /&gt;
path(&amp;quot;foo&amp;quot;) / &amp;quot;bar&amp;quot;; // path(&amp;quot;foo/bar&amp;quot;)&lt;br /&gt;
path(&amp;quot;foo&amp;quot;) / &amp;quot;/bar&amp;quot;; // path(&amp;quot;/bar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
// Print&lt;br /&gt;
std::cout &amp;lt;&amp;lt; my_path &amp;lt;&amp;lt; std::endl; // prints &amp;quot;my_dir/my_file&amp;quot; with quotes&lt;br /&gt;
std::cout &amp;lt;&amp;lt; my_path.string() &amp;lt;&amp;lt; std::endl; // prints my_dir/my_file without quotes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* &amp;lt;code&amp;gt;path&amp;lt;/code&amp;gt; supports implicit conversion to &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Directories====&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/filesystem/create_directory &amp;lt;code&amp;gt;create_directory(path)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;create_directories(path)&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/filesystem/directory_iterator &amp;lt;code&amp;gt;directory_iterator(path)&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* &amp;lt;code&amp;gt;create_directory&amp;lt;/code&amp;gt; requires that the parent directory already exists&lt;br /&gt;
** If not, use &amp;lt;code&amp;gt;create_directories&amp;lt;/code&amp;gt; instead&lt;br /&gt;
&lt;br /&gt;
===Fstream===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;fstream&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Used for input/output of files&lt;br /&gt;
&lt;br /&gt;
====Reading and Writing====&lt;br /&gt;
Reading and writing is done using &amp;lt;code&amp;gt;fstream&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
If you don&#039;t need r/w, use &amp;lt;code&amp;gt;istream&amp;lt;/code&amp;gt; for reading or &amp;lt;code&amp;gt;ostream&amp;lt;/code&amp;gt; for writing.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  std::ifstream my_file(&amp;quot;my_file.txt&amp;quot;);&lt;br /&gt;
  std::string line;&lt;br /&gt;
  // Read line by line&lt;br /&gt;
  // You can also read using &amp;lt;&amp;lt;&lt;br /&gt;
  while (getline(my_file, line)) {&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Reading a whole file====&lt;br /&gt;
[https://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html Reference and comparison of different methods]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;cerrno&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;string_view&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;stdexcept&amp;gt;&lt;br /&gt;
#include &amp;lt;cstring&amp;gt; // for strerror&lt;br /&gt;
&lt;br /&gt;
std::string get_file_contents(std::string_view filename) {&lt;br /&gt;
  std::ifstream in(filename.data(), std::ios::in | std::ios::binary);&lt;br /&gt;
  if (in.good()) {&lt;br /&gt;
    std::string contents;&lt;br /&gt;
    in.seekg(0, std::ios::end);&lt;br /&gt;
    contents.resize(static_cast&amp;lt;unsigned int&amp;gt;(in.tellg()));&lt;br /&gt;
    in.seekg(0, std::ios::beg);&lt;br /&gt;
    in.read(&amp;amp;contents[0], contents.size());&lt;br /&gt;
    return contents;&lt;br /&gt;
  }&lt;br /&gt;
  std::cerr &amp;lt;&amp;lt; &amp;quot;Failed to open file: &amp;quot; &amp;lt;&amp;lt; filename &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
  throw std::runtime_error(std::strerror(errno));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Regular Expressions===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;regex&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://en.cppreference.com/w/cpp/regex Reference]&lt;br /&gt;
&lt;br /&gt;
===Thread===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;thread&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/thread/thread std::thread reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic Usage:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::thread my_thread(thread_function);&lt;br /&gt;
// Calling methods&lt;br /&gt;
// You can also pass in parameters as usual&lt;br /&gt;
std::thread my_thread(&amp;amp;Class::method, this);&lt;br /&gt;
// Lambda functions&lt;br /&gt;
std::thread my_thread([&amp;amp;]() {&lt;br /&gt;
 // do something&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Wait for thread to finish&lt;br /&gt;
my_thread.join();&lt;br /&gt;
&lt;br /&gt;
// get id of thread&lt;br /&gt;
std::thread::id my_id = my_thread.get_id();&lt;br /&gt;
&lt;br /&gt;
// get id of this thread&lt;br /&gt;
std::thread::id my_id = std::this_thread::get_id();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Sleep ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::this_thread::sleep_for(std::chrono::milliseconds(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====Parallel For====&lt;br /&gt;
[https://www.alecjacobson.com/weblog/?p=4544 Reference]&lt;br /&gt;
&lt;br /&gt;
===Memory===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;memory&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
====Smart Pointers====&lt;br /&gt;
[https://www.geeksforgeeks.org/auto_ptr-unique_ptr-shared_ptr-weak_ptr-2/ Smart Pointers]&amp;lt;br&amp;gt;&lt;br /&gt;
Smart pointers were added in C++11.&amp;lt;br&amp;gt;&lt;br /&gt;
There are 3 types of smart pointers:&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/memory/unique_ptr &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt;] - one piece of code &#039;&#039;owns&#039;&#039; the memory at any given time.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::shared_ptr&amp;lt;/code&amp;gt; - the memory has multiple owners.&lt;br /&gt;
* &amp;lt;code&amp;gt;std::weak_ptr&amp;lt;/code&amp;gt; - a non-owning reference to a shared_ptr.&lt;br /&gt;
&lt;br /&gt;
In general, there should be one object owning an object using a &amp;lt;code&amp;gt;unique_ptr&amp;lt;/code&amp;gt;. Whenever you pass the value around, other functions should receive the object as a reference making it clear that they do not have ownership of the object. Smart pointers are nullable and assignable similar to regular pointers.&lt;br /&gt;
&lt;br /&gt;
Prefer to use &amp;lt;code&amp;gt;make_unique&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;make_shared&amp;lt;/code&amp;gt; which will only make one memory allocation for both the object and the pointer rather than two memory allocations.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can call &amp;lt;code&amp;gt;my_ptr.reset(new Car())&amp;lt;/code&amp;gt; to change the pointer or &amp;lt;code&amp;gt;my_ptr.reset()&amp;lt;/code&amp;gt; to deallocate the object referenced by the pointer.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Block-scope car&lt;br /&gt;
Car my_car;&lt;br /&gt;
&lt;br /&gt;
// Old C++&lt;br /&gt;
// Must call delete my_car; to avoid memory leaks.&lt;br /&gt;
Car *my_car = new Car();&lt;br /&gt;
&lt;br /&gt;
// Using unique ptr&lt;br /&gt;
std::unique_ptr&amp;lt;Car&amp;gt; my_car(new Car());&lt;br /&gt;
&lt;br /&gt;
// Or starting from C++14&lt;br /&gt;
auto my_car = std::make_unique&amp;lt;Car&amp;gt;();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* If the object you need is not very large, you can consider just including it as part of your class (or leaving it on the stack) rather than use pointers.&lt;br /&gt;
* If you want to get a copy of the smart pointer to the current object, the object must &#039;&#039;&#039;publicly&#039;&#039;&#039; inherit &amp;lt;code&amp;gt;std::enable_shared_from_this&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Then you can call &amp;lt;code&amp;gt;shared_from_this()&amp;lt;/code&amp;gt; from within any method (not the constructor).&lt;br /&gt;
** May throw &amp;lt;code&amp;gt;bad_weak_ptr&amp;lt;/code&amp;gt; if you call &amp;lt;code&amp;gt;shared_from_this()&amp;lt;/code&amp;gt; without &amp;lt;code&amp;gt;make_shared&amp;lt;/code&amp;gt; or if you do not publicly inherit &amp;lt;code&amp;gt;std::enable_shared_from_this&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* When writing functions when do not operate on pointers and do not claim ownership of objects, you should just take a reference to the object as the argument.&lt;br /&gt;
* &amp;lt;code&amp;gt;std::auto_ptr&amp;lt;/code&amp;gt; was a predecessor to &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt; which allowed copies. It shouldn&#039;t be used anymore.&lt;br /&gt;
&lt;br /&gt;
====Garbage Collection====&lt;br /&gt;
Starting from C++11, you should use smart pointers such as [https://en.cppreference.com/w/cpp/memory/shared_ptr &amp;lt;code&amp;gt;shared_ptr&amp;lt;/code&amp;gt;] which have automatic garbage collection.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Traditional C++ does not have garbage collection.&amp;lt;br&amp;gt;&lt;br /&gt;
After using &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; to allocate an object, use &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; to deallocate it.  &amp;lt;br&amp;gt;&lt;br /&gt;
You can also use C allocation with &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;alloca&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt;, though it is [https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-and-or-new not recommended] since these are not type-safe.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Custom Deleter====&lt;br /&gt;
[https://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html Custom Deleters]&amp;lt;br&amp;gt;&lt;br /&gt;
When using smart pointers, the default deleter is the &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; function but you can also specify your own deleter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
# Using a functor&lt;br /&gt;
struct AVFrameDeleter {&lt;br /&gt;
  void operator()(AVFrame *p) { av_frame_free(&amp;amp;p); }&lt;br /&gt;
};&lt;br /&gt;
std::unique_ptr&amp;lt;AVFrame, AVFrameDeleter&amp;gt; rgb_frame(av_frame_alloc());&lt;br /&gt;
&lt;br /&gt;
# Using free&lt;br /&gt;
std::unique_ptr&amp;lt;void, decltype(&amp;amp;std::free)&amp;gt; my_buffer(std::malloc(10), std::free);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Deallocate====&lt;br /&gt;
Normally, containers such as &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; will automatically deallocate memory from the heap when the destructor is called. However, occasionally you may want to coerce this deallocation yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
There are a few ways to do this:&lt;br /&gt;
* Use smart pointers&lt;br /&gt;
* Swap&lt;br /&gt;
* Call a clear/shrink/deallocate function&lt;br /&gt;
Example [https://stackoverflow.com/questions/3054567/right-way-to-deallocate-an-stdvector-object Reference]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Using smart pointers&lt;br /&gt;
std::unique_ptr&amp;lt;std::vector&amp;lt;float&amp;gt;&amp;gt; my_vector = make_unique&amp;lt;std::vector&amp;lt;float&amp;gt;&amp;gt;(99);&lt;br /&gt;
my_vector.reset();&lt;br /&gt;
&lt;br /&gt;
// Swap&lt;br /&gt;
std::vector&amp;lt;float&amp;gt; my_vector(99);&lt;br /&gt;
my_vector = std::vector&amp;lt;float&amp;gt;();&lt;br /&gt;
// Or alternatively&lt;br /&gt;
// std::vector&amp;lt;float&amp;gt;().swap(my_vector);&lt;br /&gt;
// std::swap(my_vector, std::vector&amp;lt;float&amp;gt;());&lt;br /&gt;
&lt;br /&gt;
// Swap for cl::Buffer&lt;br /&gt;
cl::Buffer my_buf(context, CL_MEM_READ_WRITE, size);&lt;br /&gt;
my_buf = cl::Buffer();&lt;br /&gt;
&lt;br /&gt;
// Clear and shrink&lt;br /&gt;
// Specific to std::vector&lt;br /&gt;
std::vector&amp;lt;float&amp;gt; my_vector(99);&lt;br /&gt;
my_vector.clear();&lt;br /&gt;
my_vector.shrink_to_fit();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Limits===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;limits&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/types/numeric_limits Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
C++ has standard macros such as &amp;lt;code&amp;gt;INT_MAX&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The limits header adds these limits for every type.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Equivalent to FLT_MAX&lt;br /&gt;
std::numeric_limits&amp;lt;float&amp;gt;::max();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Utility===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;utility&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
====std::move====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/utility/move Ref]&amp;lt;br&amp;gt;&lt;br /&gt;
Use &amp;lt;code&amp;gt;std::move&amp;lt;/code&amp;gt; to move containers.&lt;br /&gt;
&lt;br /&gt;
===Algorithm===&lt;br /&gt;
====std::find====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/find Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::generate====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/generate cppreference]&amp;lt;br&amp;gt;&lt;br /&gt;
Allows you to fill a container using a function call&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;random&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    std::random_device rd;&lt;br /&gt;
    std::mt19937 gen(rd());&lt;br /&gt;
    // Fill with integers in [0, 10]&lt;br /&gt;
    std::uniform_int_distribution&amp;lt;&amp;gt; dis(0, 10);&lt;br /&gt;
&lt;br /&gt;
    std::vector&amp;lt;int&amp;gt; my_vec(10, 0);&lt;br /&gt;
    std::generate(my_vec.begin(), my_vec.end(), [&amp;amp;](){return dis(gen);});&lt;br /&gt;
     &lt;br /&gt;
    for (int v : my_vec) {&lt;br /&gt;
        std::cout &amp;lt;&amp;lt; v &amp;lt;&amp;lt; &amp;quot; &amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Numeric===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;numeric&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
====std::iota====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/iota Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Fills an array or vector with increasing values. Can pass in a starting number.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; v(60);&lt;br /&gt;
std::iota(v.begin(), v.end(), 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====std::accumulate====&lt;br /&gt;
Adds up numbers. Can pass in a starting number.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; v(60);&lt;br /&gt;
std::iota(v.begin(), v.end(), 0);&lt;br /&gt;
std::accumulate(v.begin(), v.end(), 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Chrono===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;chrono&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I now prefer using &amp;lt;code&amp;gt;absl::Time&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;absl::Duration&amp;lt;/code&amp;gt; over Chrono because they abstract away the underlying type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
auto start = std::chrono::high_resolution_clock::now();&lt;br /&gt;
// do something&lt;br /&gt;
auto end = std::chrono::high_resolution_clock::now();&lt;br /&gt;
std::cout &amp;lt;&amp;lt; &amp;quot;Time elapsed: &amp;quot; &lt;br /&gt;
          &amp;lt;&amp;lt; std::chrono::duration_cast&amp;lt;std::chrono::milliseconds&amp;gt;(end - start).count() &lt;br /&gt;
          &amp;lt;&amp;lt; &amp;quot; ms&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Execution===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;execution&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
The execution header gives you tools for parallel execution (since C++17).&amp;lt;br&amp;gt;&lt;br /&gt;
See [https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t execution_policy_tag].&amp;lt;br&amp;gt;&lt;br /&gt;
[https://devblogs.microsoft.com/cppblog/using-c17-parallel-algorithms-for-better-performance/ C++17 Parallel Algorithms blog].&amp;lt;br&amp;gt;&lt;br /&gt;
[https://developer.nvidia.com/blog/accelerating-standard-c-with-gpus-using-stdpar/ Nvidia Accelerating Standard C++ with GPUs Using stdpar]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Parallel Sorting Example&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::sort(std::execution::par_unseq, sorted.begin(), sorted.end());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::seq&amp;lt;/code&amp;gt; sequential&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::unseq&amp;lt;/code&amp;gt; vectorized only (C++20)&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::par&amp;lt;/code&amp;gt; parallel&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::par_unseq&amp;lt;/code&amp;gt; parallel and vectorized&lt;br /&gt;
&lt;br /&gt;
===Random===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;random&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/header/random cppreference.com]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::random_device rd;  //Will be used to obtain a seed for the random number engine&lt;br /&gt;
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()&lt;br /&gt;
std::uniform_int_distribution&amp;lt;&amp;gt; dis(1, 6);&lt;br /&gt;
 &lt;br /&gt;
for (int n=0; n&amp;lt;10; ++n)&lt;br /&gt;
   //Use dis to transform the random unsigned int generated by gen into an int in [1, 6]&lt;br /&gt;
   std::cout &amp;lt;&amp;lt; dis(gen) &amp;lt;&amp;lt; &#039; &#039;;&lt;br /&gt;
std::cout &amp;lt;&amp;lt; &#039;\n&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===const===&lt;br /&gt;
For variables:&lt;br /&gt;
# Use &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; for values initialized at compile time and won&#039;t change at runtime. Most of the time, this is what you want for hardcoded compile time parameters.&lt;br /&gt;
# Use &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; for values initialized at runtime and won&#039;t change.&lt;br /&gt;
# Use &amp;lt;code&amp;gt;constinit&amp;lt;/code&amp;gt; for values initialized at compile time and may change at runtime. I haven&#039;t found a use case for this yet.&lt;br /&gt;
&lt;br /&gt;
For functions:&lt;br /&gt;
# Add &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; to the end of a method declaration if it won&#039;t change the object.&lt;br /&gt;
# Add &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; if the function can be evaluated at compile time, i.e. can accepts and output &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; variables.&lt;br /&gt;
# Add &amp;lt;code&amp;gt;consteval&amp;lt;/code&amp;gt; if you want to force the function to only be evaluated at compile time.&lt;br /&gt;
&lt;br /&gt;
==STL==&lt;br /&gt;
STL is the Standard Template Library originally implemented in 1994 by Stepanov and Lee from HP.&amp;lt;br&amp;gt;&lt;br /&gt;
STL consists of a general set of algorithms, containers, functions, and iterators.&amp;lt;br&amp;gt;&lt;br /&gt;
Today, STL refers to those containers and algorithms which are now built into the standard library (std) of C++.&lt;br /&gt;
&lt;br /&gt;
===Simple Containers===&lt;br /&gt;
====std::pair====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/utility/pair std::pair]&lt;br /&gt;
&lt;br /&gt;
===Sequences===&lt;br /&gt;
====std::array====&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;array&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This wrapper around C-style arrays gives us size information and allows the array to be passed around by reference while keeping the array on the stack or in a struct.&lt;br /&gt;
Unless you need stack allocation or allocation into a struct, you should probably use a vector.&lt;br /&gt;
&lt;br /&gt;
====std::vector====&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;vector&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
https://en.cppreference.com/w/cpp/container/vector&amp;lt;br&amp;gt;&lt;br /&gt;
This is a dynamically-allocated resizable array, known as an ArrayList in Java.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
// Basics&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; my_vec;&lt;br /&gt;
// Vector with size 5&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; my_vec(5);&lt;br /&gt;
// Vector with size 5 initialized to 1&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; my_vec(5, 1);&lt;br /&gt;
&lt;br /&gt;
// Length of vector&lt;br /&gt;
my_vec.size();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to size()==0&lt;br /&gt;
my_vec.empty();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to my_vec[0];&lt;br /&gt;
// Undefined on empty vectors&lt;br /&gt;
my_vec.front();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to my_vec[my_vec.size()-1];&lt;br /&gt;
// Undefined on empty vectors&lt;br /&gt;
my_vec.back();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that [https://en.cppreference.com/w/cpp/container/vector_bool &amp;lt;code&amp;gt;vector&amp;lt;bool&amp;gt;&amp;lt;/code&amp;gt;] is a special case of bit-packed booleans instead of an array of bools. You should use &amp;lt;code&amp;gt;vector&amp;lt;char&amp;gt;&amp;lt;/code&amp;gt; instead if your code relies on it being contiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::span====&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;span&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://en.cppreference.com/w/cpp/container/span&amp;lt;br&amp;gt;&lt;br /&gt;
This is view of some contiguous amount of memory. If the size is static, this is equivalent to a single pointer, otherwise is it equivalent to two pointers (i.e. begin and end).&lt;br /&gt;
If you use this as the parameter to your function, it will accept both arrays and vectors.&lt;br /&gt;
Additionaly, there is a [https://en.cppreference.com/w/cpp/container/span/subspan subspan] function so you don&#039;t need to pass around indices or pointers to get subvectors.&lt;br /&gt;
&lt;br /&gt;
====std::deque====&lt;br /&gt;
Double-ended queue&lt;br /&gt;
&lt;br /&gt;
====std::list====&lt;br /&gt;
This is a doubly linked list. You can delete elements from the middle of the list if you have an iterator.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::list&amp;lt;int&amp;gt; m_list;&lt;br /&gt;
&lt;br /&gt;
// Insert requires an iterator position&lt;br /&gt;
std::list&amp;lt;int&amp;gt;::iterator m_it = m_list.insert(m_list.begin(), 5);&lt;br /&gt;
&lt;br /&gt;
// Remove the element&lt;br /&gt;
m_list.erase(m_it);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Container adaptors===&lt;br /&gt;
====std::queue====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/queue Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
std::queue&amp;lt;int&amp;gt; my_queue;&lt;br /&gt;
&lt;br /&gt;
my_queue.push(a);&lt;br /&gt;
auto val = my_queue.front();&lt;br /&gt;
my_queue.pop(); // returns void&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::stack====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/stack cppreference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::stack&amp;lt;char&amp;gt; my_stack;&lt;br /&gt;
&lt;br /&gt;
// Push to stack&lt;br /&gt;
// You can also use emplace&lt;br /&gt;
// Returns void&lt;br /&gt;
my_stack.push(&#039;a&#039;);&lt;br /&gt;
&lt;br /&gt;
// Peek&lt;br /&gt;
// Always make sure stack is not empty&lt;br /&gt;
char top = my_stack.top();&lt;br /&gt;
&lt;br /&gt;
// Pop&lt;br /&gt;
// Note: returns void&lt;br /&gt;
// Always make sure stack is not empty&lt;br /&gt;
my_stack.pop();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::priority_queue====&lt;br /&gt;
This is a min/max heap.&lt;br /&gt;
&lt;br /&gt;
===Associative Containers===&lt;br /&gt;
Also known as maps or associative arrays.&lt;br /&gt;
====std::set====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/set reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;set&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a binary tree (likely red-black tree). You can assume &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; operations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====std::map====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/map reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;map&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a binary tree (likely red-black tree). You can assume &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; operations.&lt;br /&gt;
&lt;br /&gt;
====std::unordered_set====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/unordered_set reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;unordered_set&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a hashset. You can assume operations are &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; on average and &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; worst case.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::unordered_set&amp;lt;int&amp;gt; my_set;&lt;br /&gt;
// Add&lt;br /&gt;
my_set.insert(5);&lt;br /&gt;
// Check contains&lt;br /&gt;
my_set.find(5) != my_set.end(); // Before C++20&lt;br /&gt;
my_set.contains(5); // C++20&lt;br /&gt;
// Remove&lt;br /&gt;
my_set.erase(5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::unordered_map====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/unordered_map reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;unordered_map&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a hashmap. You can assume operations are &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; on average and &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; worst case.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::unordered_map&amp;lt;int, std::string&amp;gt; my_map;&lt;br /&gt;
my_map[5] = &amp;quot;hey&amp;quot;; // Fine as long as value type is default-constructible&lt;br /&gt;
my_map.insert({5, &amp;quot;hey&amp;quot;}); &lt;br /&gt;
my_map.find(5) != my_map.end();&lt;br /&gt;
my_map.contains(5); // C++20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;Custom Keys&lt;br /&gt;
How to use a rational number as a key in C++&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
struct Fraction&lt;br /&gt;
{&lt;br /&gt;
    int num;&lt;br /&gt;
    int den;&lt;br /&gt;
&lt;br /&gt;
    bool operator==(const Fraction &amp;amp;other) const { &lt;br /&gt;
        return num*other.den == den * other.num;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Fraction(int a, int b) : num(a), den(b) {}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functional Programming==&lt;br /&gt;
https://medium.com/swlh/doing-it-the-functional-way-in-c-5c392bbdd46a&lt;br /&gt;
&lt;br /&gt;
Many of these can be parallelized with [https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t execution policies] such as &amp;lt;code&amp;gt;std::execution::par&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;std::execution::par_unseq&amp;lt;/code&amp;gt;. Paired with [https://adaptivecpp.github.io/AdaptiveCpp/stdpar/ AdaptiveCPP], some operations can be automatically GPU accelerated as well.&lt;br /&gt;
&lt;br /&gt;
Most of these require C++20.&lt;br /&gt;
&lt;br /&gt;
===Map===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::for_each&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::transform&amp;lt;/code&amp;gt;&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/copy &amp;lt;code&amp;gt;std::copy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::copy_if&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/fill &amp;lt;code&amp;gt;std::fill&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
===Reduce/Fold===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::reduce&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::accumulate&amp;lt;/code&amp;gt;&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/ranges/fold_left &amp;lt;code&amp;gt;std::ranges::fold_left&amp;lt;/code&amp;gt;] (C++23)&lt;br /&gt;
&lt;br /&gt;
===Filter===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::copy_if&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::remove_if&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::find_if&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming Styles==&lt;br /&gt;
===Modern C++===&lt;br /&gt;
[https://github.com/rigtorp/awesome-modern-cpp List of resources]&amp;lt;br&amp;gt;&lt;br /&gt;
* Use RAII principles.&lt;br /&gt;
** I.e. each object should manage its own memory rather than the caller having to manage it.&lt;br /&gt;
** You should never use `malloc` and `free` unless interfacing with C libraries.&lt;br /&gt;
* Avoid the use of new and delete, instead using vector or smart pointers.&lt;br /&gt;
* Use clang-format.&lt;br /&gt;
&lt;br /&gt;
;Resources&lt;br /&gt;
* [https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md CppCoreGuidelines]&lt;br /&gt;
* [https://google.github.io/styleguide/cppguide.html Google C++ Style Guide] - note that some people dislike this since it is focused on interoperability and suggests avoiding exceptions.&lt;br /&gt;
&lt;br /&gt;
==RAII==&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/raii cppreference raii]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/rule_of_three cppreference rule_of_three]&amp;lt;br&amp;gt;&lt;br /&gt;
Resource Acquisition Is Initialization - binds the life cycle of a resource to the lifetime of an object.&amp;lt;br&amp;gt;&lt;br /&gt;
For instance, the resource for a vector is an allocated amount of memory. Once the vector is destroyed and the destructor called, the resource is released.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need any from one of the rules, you need to implement the remainder&lt;br /&gt;
&lt;br /&gt;
;Rule of zero&amp;lt;br&amp;gt;&lt;br /&gt;
Do not use a custom deconstructor, copy constructor, or copy assignment. Push all of these operations into the classes of member variables such as &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unique_ptr&amp;lt;/code&amp;gt;. This is the best and simplest case.&lt;br /&gt;
&lt;br /&gt;
;[[Wikipedia: Rule of three (C++ programming) | Rule of three]]&lt;br /&gt;
* Destructor&lt;br /&gt;
* Copy constructor&lt;br /&gt;
* Copy assignment operator&lt;br /&gt;
&lt;br /&gt;
;[[Wikipedia: Rule of three (C++ programming)#Rule of five | Rule of five]]&lt;br /&gt;
* All from rule of three plus:&lt;br /&gt;
* Move constructor&lt;br /&gt;
* Move operator&lt;br /&gt;
&lt;br /&gt;
;Rule of four and a half:&lt;br /&gt;
* Destructor&lt;br /&gt;
* Copy constructor&lt;br /&gt;
* Copy-and-swap assignment operator&lt;br /&gt;
* Swap function&lt;br /&gt;
&lt;br /&gt;
{{hidden | Example Rule of Four RAII Class |&lt;br /&gt;
Copied from [https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom stack overflow]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt; // std::copy&lt;br /&gt;
#include &amp;lt;cstddef&amp;gt; // std::size_t&lt;br /&gt;
&lt;br /&gt;
class dumb_array&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    // (default) constructor&lt;br /&gt;
    dumb_array(std::size_t size = 0)&lt;br /&gt;
        : mSize(size),&lt;br /&gt;
          mArray(mSize ? new int[mSize]() : nullptr)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // copy-constructor&lt;br /&gt;
    dumb_array(const dumb_array&amp;amp; other)&lt;br /&gt;
        : mSize(other.mSize),&lt;br /&gt;
          mArray(mSize ? new int[mSize] : nullptr)&lt;br /&gt;
    {&lt;br /&gt;
        // note that this is non-throwing, because of the data&lt;br /&gt;
        // types being used; more attention to detail with regards&lt;br /&gt;
        // to exceptions must be given in a more general case, however&lt;br /&gt;
        std::copy(other.mArray, other.mArray + mSize, mArray);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // destructor&lt;br /&gt;
    ~dumb_array()&lt;br /&gt;
    {&lt;br /&gt;
        delete [] mArray;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // assignment operator&lt;br /&gt;
    dumb_array&amp;amp; operator=(dumb_array other) // (1)&lt;br /&gt;
    {&lt;br /&gt;
        swap(*this, other); // (2)&lt;br /&gt;
&lt;br /&gt;
        return *this;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // swap&lt;br /&gt;
    friend void swap(dumb_array&amp;amp; first, dumb_array&amp;amp; second) // nothrow&lt;br /&gt;
    {&lt;br /&gt;
        // enable ADL (not necessary in our case, but good practice)&lt;br /&gt;
        using std::swap;&lt;br /&gt;
&lt;br /&gt;
        // by swapping the members of two objects,&lt;br /&gt;
        // the two objects are effectively swapped&lt;br /&gt;
        swap(first.mSize, second.mSize);&lt;br /&gt;
        swap(first.mArray, second.mArray);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
    std::size_t mSize;&lt;br /&gt;
    int* mArray;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Useful Libraries==&lt;br /&gt;
A list of useful libraries&lt;br /&gt;
&lt;br /&gt;
===Boost===&lt;br /&gt;
{{main | Boost (C++ libraries)}}&lt;br /&gt;
A set of popular C++ libraries. Most are header-only.&lt;br /&gt;
&lt;br /&gt;
===cxxopts===&lt;br /&gt;
[https://github.com/jarro2783/cxxopts Link]&amp;lt;br&amp;gt;&lt;br /&gt;
A header-only C++ argument parser.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that if you already use Boost, you can use &amp;lt;code&amp;gt;Boost::Program_options&amp;lt;/code&amp;gt; instead.&lt;br /&gt;
===Eigen===&lt;br /&gt;
{{main | Eigen (C++ library)}}&lt;br /&gt;
A header-only C++ linear algebra library.&lt;br /&gt;
&lt;br /&gt;
===absl===&lt;br /&gt;
https://github.com/abseil/abseil-cpp is a library used by Google which supplements the standard library.&lt;br /&gt;
&lt;br /&gt;
Useful things:&lt;br /&gt;
# &amp;lt;code&amp;gt;absl::Time&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;absl::Duration&amp;lt;/code&amp;gt;.&lt;br /&gt;
# [https://abseil.io/docs/cpp/guides/strings#abslstrcat absl strings]&lt;br /&gt;
# [https://abseil.io/docs/cpp/guides/logging absl logging]&lt;br /&gt;
&lt;br /&gt;
Many parts of absl now have &amp;lt;code&amp;gt;std::&amp;lt;/code&amp;gt; equivalents such as &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::string_view&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::span&amp;lt;/code&amp;gt;. Unless contributing to Google codebases, you should probably prefer those.&lt;br /&gt;
&lt;br /&gt;
At Google, they prefer absl hash containers over unordered_set and unordered_map:&lt;br /&gt;
# &amp;lt;code&amp;gt;absl::flat_hash_map&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming languages]]&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=C%2B%2B&amp;diff=7192</id>
		<title>C++</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=C%2B%2B&amp;diff=7192"/>
		<updated>2025-11-23T01:18:15Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
C++ is a very popular and powerful language which includes all the low-level features of [[C_(programming_language) | C]] (e.g. pointers, operator overloading) along many high-level features (RAII, STD algorithms, STL containers) thanks to the C++ standard library.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
How to do things using the [https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library C++ standard library (stdlib)].&lt;br /&gt;
===Compilation===&lt;br /&gt;
{{See also|CMake|Makefile}}&lt;br /&gt;
====cmake====&lt;br /&gt;
&lt;br /&gt;
====g++====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
g++ my_driver.cc [-Iincludefolder] -o my_program.out&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Standard optimizations&lt;br /&gt;
* &amp;lt;code&amp;gt;-std=c++17&amp;lt;/code&amp;gt; for C++17 support&lt;br /&gt;
* &amp;lt;code&amp;gt;-O3&amp;lt;/code&amp;gt; for level 3 optimizations&lt;br /&gt;
* &amp;lt;code&amp;gt;-g&amp;lt;/code&amp;gt; to include debugging info&lt;br /&gt;
* &amp;lt;code&amp;gt;-march=native&amp;lt;/code&amp;gt; - use all instructions available on the current CPU&lt;br /&gt;
* &amp;lt;code&amp;gt;-mtune=native&amp;lt;/code&amp;gt; - optimize for the current CPU&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
====Main====&lt;br /&gt;
All C++ programs launch in a &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; function.&lt;br /&gt;
Similar to [[C (programming language) | C]], the arguments are &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;char *argv[]&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
These can be easily converted to a &amp;lt;code&amp;gt;std::vector&amp;lt;std::string&amp;gt;&amp;lt;/code&amp;gt; for convenience.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
  std::vector&amp;lt;std::string&amp;gt; args(argv, argv + argc);&lt;br /&gt;
  // Your code here&lt;br /&gt;
  return EXIT_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Headers====&lt;br /&gt;
[https://stackoverflow.com/questions/10694255/cmath-vs-math-h-and-similar-c-prefixed-vs-h-extension-headers Reference]&lt;br /&gt;
&lt;br /&gt;
C++ includes C-headers such as &amp;lt;code&amp;gt;math.h&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cmath&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The C-style header will place everything in the global namespace while the C++ header will place everything in &amp;lt;code&amp;gt;std&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
You should use &amp;lt;code&amp;gt;cmath&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Lambda Expressions====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/lambda Reference]&lt;br /&gt;
&lt;br /&gt;
====Casting====&lt;br /&gt;
[https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used Types of casts]&lt;br /&gt;
&lt;br /&gt;
C++ has several types of casts including:&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/static_cast &amp;lt;code&amp;gt;static_cast&amp;lt;/code&amp;gt;] - your standard cast with conversion. Does not perform any checks.&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/dynamic_cast &amp;lt;code&amp;gt;dynamic_cast&amp;lt;/code&amp;gt;] - for casting objects with checking, requires a polymorphic base class (with a virtual function). Will return nullptr.&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/reinterpret_cast &amp;lt;code&amp;gt;reinterpret_cast&amp;lt;/code&amp;gt;] - cast without any conversion, for directly dealing with binary data, equivalent to &amp;lt;code&amp;gt;*(T*)&amp;lt;/code&amp;gt; in C.&lt;br /&gt;
&lt;br /&gt;
====References====&lt;br /&gt;
References are accepted or store using &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
void healPerson(Person &amp;amp;person) {&lt;br /&gt;
  person.health = 100;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
References are like pointers since they do not copy the object except they cannot be null and they cannot be reassigned.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that primitives can also be used with references, in which case changes will propagate to the underlying value.&amp;lt;br&amp;gt;&lt;br /&gt;
You can also use them as class attributes, initializing them in the constructor&#039;s initializer list.&amp;lt;br&amp;gt;&lt;br /&gt;
To store references in a vector, you can use &amp;lt;code&amp;gt;std::reference_wrapper&amp;lt;/code&amp;gt; and include the &amp;lt;code&amp;gt;functional&amp;lt;/code&amp;gt; header.&lt;br /&gt;
&lt;br /&gt;
====Types====&lt;br /&gt;
For simple programs, you can use the standard types:&lt;br /&gt;
* &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;size_t&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt;&lt;br /&gt;
See [https://stackoverflow.com/questions/6462439/whats-the-difference-between-long-long-and-long SO] for the standard and guaranteed precision of these built-in types.&lt;br /&gt;
&lt;br /&gt;
C++ also has fixed-width types in &amp;lt;code&amp;gt;#include &amp;lt;cstdint&amp;gt;&amp;lt;/code&amp;gt; (since C++11).&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/header/cstdint cppreference cstdint]&amp;lt;br&amp;gt;&lt;br /&gt;
I recommend using these for anything with specific or high precision requirements.&amp;lt;br&amp;gt;&lt;br /&gt;
Typically, I use:&lt;br /&gt;
* &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;std::byte&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;int64_t&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;long long&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;string&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t need to own the string, prefer to use &amp;lt;code&amp;gt;string_view&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// c-str to string&lt;br /&gt;
char *old_string = &amp;quot;my c-style string&amp;quot;;&lt;br /&gt;
string cpp_string(old_string);&lt;br /&gt;
&lt;br /&gt;
// string to c-str&lt;br /&gt;
cpp_string.c_str();&lt;br /&gt;
&lt;br /&gt;
// char to string&lt;br /&gt;
char my_char = &#039;a&#039;;&lt;br /&gt;
string my_str(1, my_char);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====String Interpolation====&lt;br /&gt;
[https://stackoverflow.com/questions/10410023/string-format-alternative-in-c Reference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    std::string a = &amp;quot;a&amp;quot;, b = &amp;quot;b&amp;quot;, c = &amp;quot;c&amp;quot;;&lt;br /&gt;
    // apply formatting&lt;br /&gt;
    std::stringstream s;&lt;br /&gt;
    s &amp;lt;&amp;lt; a &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; b &amp;lt;&amp;lt; &amp;quot; &amp;gt; &amp;quot; &amp;lt;&amp;lt; c;&lt;br /&gt;
    // assign to std::string&lt;br /&gt;
    std::string str = s.str();&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; str &amp;lt;&amp;lt; &amp;quot;\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Buildings Strings====&lt;br /&gt;
[https://www.fluentcpp.com/2017/12/19/build-strings-from-plain-string-up-to-boost-karma/ The Complete Guide to Building Strings In C++]&amp;lt;br&amp;gt;&lt;br /&gt;
There are multiple ways of buildings strings in C++.&amp;lt;br&amp;gt;&lt;br /&gt;
Strings are mutable in C++.&amp;lt;br&amp;gt;&lt;br /&gt;
I typically use &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ostringstream&amp;lt;/code&amp;gt; to build strings.&lt;br /&gt;
&lt;br /&gt;
====std::basic_string_view====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/string/basic_string_view std::basic_string_view]&lt;br /&gt;
&lt;br /&gt;
This is useful for writing functions which accept anything that looks like a string such as substrings, since typically &amp;lt;code&amp;gt;std::string::substr&amp;lt;/code&amp;gt; performs a copy.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;code&amp;gt;std::string_view&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;std::basic_string_view&amp;lt;char&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Filesystem===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;filesystem&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Convenient functions for filesystem. Added since C++17.&lt;br /&gt;
====Path====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/filesystem/path cppreference]&lt;br /&gt;
&lt;br /&gt;
Note if you use g++ &amp;lt;= version 9, you will need to add the flag &amp;lt;code&amp;gt;-lstdc++fs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
using std::filesystem::path;&lt;br /&gt;
&lt;br /&gt;
// Initialization&lt;br /&gt;
path my_path = &amp;quot;my_dir/my_file&amp;quot;;&lt;br /&gt;
// or my_path = path(&amp;quot;my_dir&amp;quot;) / &amp;quot;my_file&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Append to path&lt;br /&gt;
path(&amp;quot;foo&amp;quot;) / &amp;quot;bar&amp;quot;; // path(&amp;quot;foo/bar&amp;quot;)&lt;br /&gt;
path(&amp;quot;foo&amp;quot;) / &amp;quot;/bar&amp;quot;; // path(&amp;quot;/bar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
// Print&lt;br /&gt;
std::cout &amp;lt;&amp;lt; my_path &amp;lt;&amp;lt; std::endl; // prints &amp;quot;my_dir/my_file&amp;quot; with quotes&lt;br /&gt;
std::cout &amp;lt;&amp;lt; my_path.string() &amp;lt;&amp;lt; std::endl; // prints my_dir/my_file without quotes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* &amp;lt;code&amp;gt;path&amp;lt;/code&amp;gt; supports implicit conversion to &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Directories====&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/filesystem/create_directory &amp;lt;code&amp;gt;create_directory(path)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;create_directories(path)&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/filesystem/directory_iterator &amp;lt;code&amp;gt;directory_iterator(path)&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* &amp;lt;code&amp;gt;create_directory&amp;lt;/code&amp;gt; requires that the parent directory already exists&lt;br /&gt;
** If not, use &amp;lt;code&amp;gt;create_directories&amp;lt;/code&amp;gt; instead&lt;br /&gt;
&lt;br /&gt;
===Fstream===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;fstream&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Used for input/output of files&lt;br /&gt;
&lt;br /&gt;
====Reading and Writing====&lt;br /&gt;
Reading and writing is done using &amp;lt;code&amp;gt;fstream&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
If you don&#039;t need r/w, use &amp;lt;code&amp;gt;istream&amp;lt;/code&amp;gt; for reading or &amp;lt;code&amp;gt;ostream&amp;lt;/code&amp;gt; for writing.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  std::ifstream my_file(&amp;quot;my_file.txt&amp;quot;);&lt;br /&gt;
  std::string line;&lt;br /&gt;
  // Read line by line&lt;br /&gt;
  // You can also read using &amp;lt;&amp;lt;&lt;br /&gt;
  while (getline(my_file, line)) {&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Reading a whole file====&lt;br /&gt;
[https://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html Reference and comparison of different methods]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;cerrno&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;string_view&amp;gt;&lt;br /&gt;
&lt;br /&gt;
std::string get_file_contents(std::string_view filename) {&lt;br /&gt;
  std::ifstream in(filename, std::ios::in | std::ios::binary);&lt;br /&gt;
  if (in.good()) {&lt;br /&gt;
    std::string contents;&lt;br /&gt;
    in.seekg(0, std::ios::end);&lt;br /&gt;
    contents.resize(static_cast&amp;lt;unsigned int&amp;gt;(in.tellg()));&lt;br /&gt;
    in.seekg(0, std::ios::beg);&lt;br /&gt;
    in.read(&amp;amp;contents[0], contents.size());&lt;br /&gt;
    return contents;&lt;br /&gt;
  }&lt;br /&gt;
  std::cerr &amp;lt;&amp;lt; &amp;quot;Failed to open file: &amp;quot; &amp;lt;&amp;lt; filename &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
  throw(errno);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Regular Expressions===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;regex&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://en.cppreference.com/w/cpp/regex Reference]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;regex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  std::regex myRegex(&amp;quot;(\\d+)&amp;quot;);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Thread===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;thread&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/thread/thread std::thread reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic Usage:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::thread my_thread(thread_function);&lt;br /&gt;
// Calling methods&lt;br /&gt;
// You can also pass in parameters as usual&lt;br /&gt;
std::thread my_thread(&amp;amp;Class::method, this);&lt;br /&gt;
// Lambda functions&lt;br /&gt;
std::thread my_thread([&amp;amp;]() {&lt;br /&gt;
 // do something&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Wait for thread to finish&lt;br /&gt;
my_thread.join();&lt;br /&gt;
&lt;br /&gt;
// get id of thread&lt;br /&gt;
std::thread::id my_id = my_thread.get_id();&lt;br /&gt;
&lt;br /&gt;
// get id of this thread&lt;br /&gt;
std::thread::id my_id = std::this_thread::get_id();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Sleep ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::this_thread::sleep_for(std::chrono::milliseconds(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
====Parallel For====&lt;br /&gt;
[https://www.alecjacobson.com/weblog/?p=4544 Reference]&lt;br /&gt;
&lt;br /&gt;
===Memory===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;memory&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
====Smart Pointers====&lt;br /&gt;
[https://www.geeksforgeeks.org/auto_ptr-unique_ptr-shared_ptr-weak_ptr-2/ Smart Pointers]&amp;lt;br&amp;gt;&lt;br /&gt;
Smart pointers were added in C++11.&amp;lt;br&amp;gt;&lt;br /&gt;
There are 3 types of smart pointers:&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/memory/unique_ptr &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt;] - one piece of code &#039;&#039;owns&#039;&#039; the memory at any given time.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::shared_ptr&amp;lt;/code&amp;gt; - the memory has multiple owners.&lt;br /&gt;
* &amp;lt;code&amp;gt;std::weak_ptr&amp;lt;/code&amp;gt; - a non-owning reference to a shared_ptr.&lt;br /&gt;
&lt;br /&gt;
In general, there should be one object owning an object using a &amp;lt;code&amp;gt;unique_ptr&amp;lt;/code&amp;gt;. Whenever you pass the value around, other functions should receive the object as a reference making it clear that they do not have ownership of the object. Smart pointers are nullable and assignable similar to regular pointers.&lt;br /&gt;
&lt;br /&gt;
Prefer to use &amp;lt;code&amp;gt;make_unique&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;make_shared&amp;lt;/code&amp;gt; which will only make one memory allocation for both the object and the pointer rather than two memory allocations.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can call &amp;lt;code&amp;gt;my_ptr.reset(new Car())&amp;lt;/code&amp;gt; to change the pointer or &amp;lt;code&amp;gt;my_ptr.reset()&amp;lt;/code&amp;gt; to deallocate the object referenced by the pointer.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Block-scope car&lt;br /&gt;
Car my_car;&lt;br /&gt;
&lt;br /&gt;
// Old C++&lt;br /&gt;
// Must call delete my_car; to avoid memory leaks.&lt;br /&gt;
Car *my_car = new Car();&lt;br /&gt;
&lt;br /&gt;
// Using unique ptr&lt;br /&gt;
std::unique_ptr&amp;lt;Car&amp;gt; my_car(new Car());&lt;br /&gt;
&lt;br /&gt;
// Or starting from C++14&lt;br /&gt;
auto my_car = std::make_unique&amp;lt;Car&amp;gt;();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* If the object you need is not very large, you can consider just including it as part of your class (or leaving it on the stack) rather than use pointers.&lt;br /&gt;
* If you want to get a copy of the smart pointer to the current object, the object must &#039;&#039;&#039;publically&#039;&#039;&#039; inherit &amp;lt;code&amp;gt;std::enable_shared_from_this&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Then you can call &amp;lt;code&amp;gt;shared_from_this()&amp;lt;/code&amp;gt; from within any method (not the constructor).&lt;br /&gt;
** May throw &amp;lt;code&amp;gt;bad_weak_ptr&amp;lt;/code&amp;gt; if you call &amp;lt;code&amp;gt;shared_from_this()&amp;lt;/code&amp;gt; without &amp;lt;code&amp;gt;make_shared&amp;lt;/code&amp;gt; or if you do not publically inherit &amp;lt;code&amp;gt;std::enable_shared_from_this&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* When writing functions when do not operate on pointers and do not claim ownership of objects, you should just take a reference to the object as the argument.&lt;br /&gt;
* &amp;lt;code&amp;gt;std::auto_ptr&amp;lt;/code&amp;gt; was a predecessor to &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt; which allowed copies. It shouldn&#039;t be used anymore.&lt;br /&gt;
&lt;br /&gt;
====Garbage Collection====&lt;br /&gt;
Starting from C++11, you should use smart pointers such as [https://en.cppreference.com/w/cpp/memory/shared_ptr &amp;lt;code&amp;gt;shared_ptr&amp;lt;/code&amp;gt;] which have automatic garbage collection.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Traditional C++ does not have garbage collection.&amp;lt;br&amp;gt;&lt;br /&gt;
After using &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; to allocate an object, use &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; to deallocate it.  &amp;lt;br&amp;gt;&lt;br /&gt;
You can also use C allocation with &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;alloca&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt;, though it is [https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-and-or-new not recommended] since these are not type-safe.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Custom Deleter====&lt;br /&gt;
[https://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html Custom Deleters]&amp;lt;br&amp;gt;&lt;br /&gt;
When using smart pointers, the default deleter is the &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; function but you can also specify your own deleter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
# Using a functor&lt;br /&gt;
struct AVFrameDeleter {&lt;br /&gt;
  void operator()(AVFrame *p) { av_frame_free(&amp;amp;p); }&lt;br /&gt;
};&lt;br /&gt;
std::unique_ptr&amp;lt;AVFrame, AVFrameDeleter&amp;gt; rgb_frame(av_frame_alloc());&lt;br /&gt;
&lt;br /&gt;
# Using free&lt;br /&gt;
std::unique_ptr&amp;lt;void *, decltype(std::free) *&amp;gt; my_buffer(std::malloc(10), std::free);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Deallocate====&lt;br /&gt;
Normally, containers such as &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; will automatically deallocate memory from the heap when the destructor is called. However, occationally you may want to coerse this deallocation yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
There are a few ways to do this:&lt;br /&gt;
* Use smart pointers&lt;br /&gt;
* Swap&lt;br /&gt;
* Call a clear/shrink/deallocate function&lt;br /&gt;
Example [https://stackoverflow.com/questions/3054567/right-way-to-deallocate-an-stdvector-object Reference]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Using smart pointers&lt;br /&gt;
std::unique_ptr&amp;lt;std::vector&amp;lt;float&amp;gt;&amp;gt; my_vector = make_unique&amp;lt;std::vector&amp;lt;float&amp;gt;&amp;gt;(99);&lt;br /&gt;
my_vector.reset();&lt;br /&gt;
&lt;br /&gt;
// Swap&lt;br /&gt;
std::vector&amp;lt;float&amp;gt; my_vector(99);&lt;br /&gt;
my_vector = std::vector&amp;lt;float&amp;gt;();&lt;br /&gt;
// Or alternatively&lt;br /&gt;
// std::vector&amp;lt;float&amp;gt;().swap(my_vector);&lt;br /&gt;
// std::swap(my_vector, std::vector&amp;lt;float&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Swap for cl::Buffer&lt;br /&gt;
cl::Buffer my_buf(context, CL_MEM_READ_WRITE, size);&lt;br /&gt;
my_buf = cl::Buffer();&lt;br /&gt;
&lt;br /&gt;
// Clear and shrink&lt;br /&gt;
// Specific to std::vector&lt;br /&gt;
std::vector&amp;lt;float&amp;gt; my_vector(99);&lt;br /&gt;
my_vector.clear();&lt;br /&gt;
my_vector.shrink_to_fit();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Limits===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;limits&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/types/numeric_limits Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
C++ has standard macros such as &amp;lt;code&amp;gt;INT_MAX&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The limits header adds these limits for every type.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Equivalent to FLT_MAX&lt;br /&gt;
std::numeric_limits&amp;lt;float&amp;gt;::max();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Utility===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;utility&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
====std::move====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/utility/move Ref]&amp;lt;br&amp;gt;&lt;br /&gt;
Use &amp;lt;code&amp;gt;std::move&amp;lt;/code&amp;gt; to move containers.&lt;br /&gt;
&lt;br /&gt;
===Algorithm===&lt;br /&gt;
====std::find====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/find Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::generate====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/generate cppreference]&amp;lt;br&amp;gt;&lt;br /&gt;
Allows you to fill a container using a function call&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;random&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    std::random_device rd;&lt;br /&gt;
    std::mt19937 gen(rd());&lt;br /&gt;
    # Fill with integers in [0, 10]&lt;br /&gt;
    std::uniform_int_distribution&amp;lt;&amp;gt; dis(0, 10);&lt;br /&gt;
&lt;br /&gt;
    std::vector&amp;lt;int&amp;gt; my_vec(10, 0);&lt;br /&gt;
    std::generate(my_vec.begin(), my_vec.end(), [&amp;amp;](){return dis(gen);});&lt;br /&gt;
    &lt;br /&gt;
    for (int v : my_vec) {&lt;br /&gt;
        std::cout &amp;lt;&amp;lt; v &amp;lt;&amp;lt; &amp;quot; &amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Numeric===&lt;br /&gt;
====std::iota====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/iota Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Fills an array or vector with increasing values. Can pass in a starting number.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; v(60);&lt;br /&gt;
std::iota(v.begin(), v.end(), 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====std::accumulate====&lt;br /&gt;
Adds up numbers. Can pass in a starting number.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; v(60);&lt;br /&gt;
std::iota(v.begin(), v.end(), 0);&lt;br /&gt;
std::accumulate(v.begin(), v.end(), 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Chrono===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;chrono&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I now prefer using &amp;lt;code&amp;gt;absl::Time&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;absl::Duration&amp;lt;/code&amp;gt; over Chrono because they abstract away the underlying type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
auto start = std::chrono::high_resolution_clock::now();&lt;br /&gt;
// do something&lt;br /&gt;
auto end = std::chrono::high_resolution_clock::now();&lt;br /&gt;
std::cout &amp;lt;&amp;lt; &amp;quot;Time elapsed: &amp;quot; &lt;br /&gt;
          &amp;lt;&amp;lt; std::chrono::duration_cast&amp;lt;std::chrono::milliseconds&amp;gt;(end - start).count() &lt;br /&gt;
          &amp;lt;&amp;lt; &amp;quot; ms&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Execution===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;execution&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
The execution header gives you tools for parallel execution (since C++17).&amp;lt;br&amp;gt;&lt;br /&gt;
See [https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t execution_policy_tag].&amp;lt;br&amp;gt;&lt;br /&gt;
[https://devblogs.microsoft.com/cppblog/using-c17-parallel-algorithms-for-better-performance/ C++17 Parallel Algorithms blog].&amp;lt;br&amp;gt;&lt;br /&gt;
[https://developer.nvidia.com/blog/accelerating-standard-c-with-gpus-using-stdpar/ Nvidia Accelerating Standard C++ with GPUs Using stdpar]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Parallel Sorting Example&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::sort(std::execution::par_unseq, sorted.begin(), sorted.end());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::seq&amp;lt;/code&amp;gt; sequential&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::unseq&amp;lt;/code&amp;gt; vectorized only (C++20)&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::par&amp;lt;/code&amp;gt; parallel&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::par_unseq&amp;lt;/code&amp;gt; parallel and vectorized&lt;br /&gt;
&lt;br /&gt;
===Random===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;random&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/header/random cppreference.com]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::random_device rd;  //Will be used to obtain a seed for the random number engine&lt;br /&gt;
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()&lt;br /&gt;
std::uniform_int_distribution&amp;lt;&amp;gt; dis(1, 6);&lt;br /&gt;
 &lt;br /&gt;
for (int n=0; n&amp;lt;10; ++n)&lt;br /&gt;
   //Use dis to transform the random unsigned int generated by gen into an int in [1, 6]&lt;br /&gt;
   std::cout &amp;lt;&amp;lt; dis(gen) &amp;lt;&amp;lt; &#039; &#039;;&lt;br /&gt;
std::cout &amp;lt;&amp;lt; &#039;\n&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===const===&lt;br /&gt;
For variables:&lt;br /&gt;
# Use &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; for values initialized at compile time and won&#039;t change at runtime. Most of the time, this is what you want for hardcoded compile time parameters.&lt;br /&gt;
# Use &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; for values initialized at runtime and won&#039;t change.&lt;br /&gt;
# Use &amp;lt;code&amp;gt;constinit&amp;lt;/code&amp;gt; for values initialized at compile time and may change at runtime. I haven&#039;t found a use case for this yet.&lt;br /&gt;
&lt;br /&gt;
For functions:&lt;br /&gt;
# Add &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; to the end of a method declaration if it won&#039;t change the object.&lt;br /&gt;
# Add &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; if the function can be evaluated at compile time, i.e. can accepts and output &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; variables.&lt;br /&gt;
# Add &amp;lt;code&amp;gt;consteval&amp;lt;/code&amp;gt; if you want to force the function to only be evaluated at compile time.&lt;br /&gt;
&lt;br /&gt;
==STL==&lt;br /&gt;
STL is the Standard Template Library originally implemented in 1994 by Stepanov and Lee from HP.&amp;lt;br&amp;gt;&lt;br /&gt;
STL consists of a general set of algorithms, containers, functions, and iterators.&amp;lt;br&amp;gt;&lt;br /&gt;
Today, STL refers to those containers and algorithms which are now built into the standard library (std) of C++.&lt;br /&gt;
&lt;br /&gt;
===Simple Containers===&lt;br /&gt;
====std::pair====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/utility/pair std::pair]&lt;br /&gt;
&lt;br /&gt;
===Sequences===&lt;br /&gt;
====std::array====&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;array&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This wrapper around C-style arrays gives us size information and allows the array to be passed around by reference while keeping the array on the stack or in a struct.&lt;br /&gt;
Unless you need stack allocation or allocation into a struct, you are should probably use a vector.&lt;br /&gt;
&lt;br /&gt;
====std::vector====&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;vector&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
https://en.cppreference.com/w/cpp/container/vector&amp;lt;br&amp;gt;&lt;br /&gt;
This is a dynamically-allocated resizable array, known as an ArrayList in Java.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
// Basics&lt;br /&gt;
vector my_vec;&lt;br /&gt;
// Vector with size 5&lt;br /&gt;
vector my_vec(5);&lt;br /&gt;
// Vector with size 5 initialized to 1&lt;br /&gt;
vector my_vec(5, 1);&lt;br /&gt;
&lt;br /&gt;
// Length of vector&lt;br /&gt;
my_vec.size();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to size()==0&lt;br /&gt;
my_vec.empty();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to my_vec[0];&lt;br /&gt;
// Undefined on empty vectors&lt;br /&gt;
my_vec.front();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to my_vec[my_vec.size()-1];&lt;br /&gt;
// Undefined on empty vectors&lt;br /&gt;
my_vec.back();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that [https://en.cppreference.com/w/cpp/container/vector_bool &amp;lt;code&amp;gt;vector&amp;lt;bool&amp;gt;&amp;lt;/code&amp;gt;] is a special case of bit-packed booleans instead of an array of bools. You should use &amp;lt;code&amp;gt;vector&amp;lt;char&amp;gt;&amp;lt;/code&amp;gt; instead if your code relies on it being continguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::span====&lt;br /&gt;
&amp;lt;code&amp;gt;#include 	&amp;amp;lt;span&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://en.cppreference.com/w/cpp/container/span&amp;lt;br&amp;gt;&lt;br /&gt;
This is view of some contiguous amount of memory. If the size is static, this is equivalent to a single pointer, otherwise is it equivalent to two pointers (i.e. begin and end).&lt;br /&gt;
If you use this as the parameter to your function, it will accept both arrays and vectors.&lt;br /&gt;
Additionaly, there is a [https://en.cppreference.com/w/cpp/container/span/subspan subspan] function so you don&#039;t need to pass around indices or pointers to get subvectors.&lt;br /&gt;
&lt;br /&gt;
====std::deque====&lt;br /&gt;
Double-ended queue&lt;br /&gt;
&lt;br /&gt;
====std::list====&lt;br /&gt;
This is a doubly linked list. You can delete elements from the middle of the list if you know have an iterator.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
list&amp;lt;int&amp;gt; m_list;&lt;br /&gt;
&lt;br /&gt;
list&amp;lt;int&amp;gt;::iterator m_it = m_list.insert(5);&lt;br /&gt;
&lt;br /&gt;
// Remove the element&lt;br /&gt;
m_list.erase(m_it);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Container adaptors===&lt;br /&gt;
====std::queue====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/queue Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
std::queue&amp;lt;int&amp;gt; my_queue;&lt;br /&gt;
&lt;br /&gt;
my_queue.push(a);&lt;br /&gt;
auto val = my_queue.front();&lt;br /&gt;
my_queue.pop(); // returns void&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::stack====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/stack cppreference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::stack&amp;lt;char&amp;gt; my_stack;&lt;br /&gt;
&lt;br /&gt;
// Push to stack&lt;br /&gt;
// You can also use emplace&lt;br /&gt;
// Returns void&lt;br /&gt;
my_stack.push(&#039;a&#039;);&lt;br /&gt;
&lt;br /&gt;
// Peek&lt;br /&gt;
// Always make sure stack is not empty&lt;br /&gt;
char top = my_stack.top();&lt;br /&gt;
&lt;br /&gt;
// Pop&lt;br /&gt;
// Note: returns void&lt;br /&gt;
// Always make sure stack is not empty&lt;br /&gt;
my_stack.pop();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::priority_queue====&lt;br /&gt;
This is a min/max heap.&lt;br /&gt;
&lt;br /&gt;
===Associative Containers===&lt;br /&gt;
Also known as maps or associative arrays.&lt;br /&gt;
====std::set====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/set reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;set&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a binary tree (likely red-black tree). You can assume &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; operations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====std::map====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/map reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;map&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a binary tree (likely red-black tree). You can assume &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; operations.&lt;br /&gt;
&lt;br /&gt;
====std::unordered_set====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/unordered_set reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;unordered_set&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a hashset. You can assume operations are &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; on average and &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; worst case.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;gt;&lt;br /&gt;
std::unordered_set&amp;lt;int&amp;gt; my_set;&lt;br /&gt;
// Add&lt;br /&gt;
my_set.insert(5);&lt;br /&gt;
// Check contains&lt;br /&gt;
my_set.find(5) != my_set.end(); // Before C++20&lt;br /&gt;
my_set.contains(5); // C++20&lt;br /&gt;
// Remove&lt;br /&gt;
my_set.erase(5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::unordered_map====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/unordered_map reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;unordered_map&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a hashmap. You can assume operations are &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; on average and &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; worst case.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::unordered_map&amp;lt;int, std::string&amp;gt; my_map;&lt;br /&gt;
my_map[5] = &amp;quot;hey&amp;quot;; // Fine as long as value type is not a reference.&lt;br /&gt;
my_map.insert({5, &amp;quot;hey&amp;quot;}); // Necessary if value type is a reference.&lt;br /&gt;
my_map.find(5) != my_map.end();&lt;br /&gt;
my_map.contains(5); // C++20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;Custom Keys&lt;br /&gt;
How to use a rational number as a key in C++&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
struct Fraction&lt;br /&gt;
{&lt;br /&gt;
    int num;&lt;br /&gt;
    int den;&lt;br /&gt;
&lt;br /&gt;
    bool operator==(const Fraction &amp;amp;other) const { &lt;br /&gt;
        return num*other.den == den * other.num;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Fraction(int a, int b) : num(a), den(b) {}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functional Programming==&lt;br /&gt;
https://medium.com/swlh/doing-it-the-functional-way-in-c-5c392bbdd46a&lt;br /&gt;
&lt;br /&gt;
Many of these can be parallelized with [https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t execution policies] such as &amp;lt;code&amp;gt;std::execution::par&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;std::execution::par_unseq&amp;lt;/code&amp;gt;. Paired with [https://adaptivecpp.github.io/AdaptiveCpp/stdpar/ AdaptiveCPP], some operations can be automatically GPU accelerated as well.&lt;br /&gt;
&lt;br /&gt;
Most of these require C++20.&lt;br /&gt;
&lt;br /&gt;
===Map===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::for_each&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::transform&amp;lt;/code&amp;gt;&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/copy &amp;lt;code&amp;gt;std::copy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::copy_if&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/fill &amp;lt;code&amp;gt;std::fill&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
===Reduce/Fold===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::reduce&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::accumulate&amp;lt;/code&amp;gt;&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/ranges/fold_left &amp;lt;code&amp;gt;std::ranges::fold_left&amp;lt;/code&amp;gt;] (C++23)&lt;br /&gt;
&lt;br /&gt;
===Filter===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::copy_if&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::remove_if&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::find_if&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming Styles==&lt;br /&gt;
===Modern C++===&lt;br /&gt;
[https://github.com/rigtorp/awesome-modern-cpp List of resources]&amp;lt;br&amp;gt;&lt;br /&gt;
* Use RAII principles.&lt;br /&gt;
** I.e. each object should manage it&#039;s own memory rather than the caller having to manage it.&lt;br /&gt;
** You should never use `malloc` and `free` unless interfacing with C libraries.&lt;br /&gt;
* Avoid the use of new and delete, instead using vector or smart pointers.&lt;br /&gt;
* Use clang-format.&lt;br /&gt;
&lt;br /&gt;
;Resources&lt;br /&gt;
* [https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md CppCoreGuidelines]&lt;br /&gt;
* [https://google.github.io/styleguide/cppguide.html Google C++ Style Guide] - note that some people dislike this since it is focused on interoperability and suggests avoiding exceptions.&lt;br /&gt;
&lt;br /&gt;
==RAII==&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/raii cppreference raii]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/rule_of_three cppreference rule_of_three]&amp;lt;br&amp;gt;&lt;br /&gt;
Resource Acquisition Is Initialization - binds the life cycle of a resource to the lifetime of an object.&amp;lt;br&amp;gt;&lt;br /&gt;
For instance, the resource for a vector is an allocated amount of memory. Once the vector is destroyed and the destructor called, the resource is released.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need any from one of the rules, you need to implement the remainder&lt;br /&gt;
&lt;br /&gt;
;Rule of zero&amp;lt;br&amp;gt;&lt;br /&gt;
Do not use a custom deconstructor, copy constructor, or copy assignment. Push all of these operations into the classes of member variables such as &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unique_ptr&amp;lt;/code&amp;gt;. This is the best and simplest case.&lt;br /&gt;
&lt;br /&gt;
;[[Wikipedia: Rule of three (C++ programming) | Rule of three]]&lt;br /&gt;
* Destructor&lt;br /&gt;
* Copy constructor&lt;br /&gt;
* Copy assignment operator&lt;br /&gt;
&lt;br /&gt;
;[[Wikipedia: Rule of three (C++ programming)#Rule of five | Rule of five]]&lt;br /&gt;
* All from rule of three plus:&lt;br /&gt;
* Move constructor&lt;br /&gt;
* Move operator&lt;br /&gt;
&lt;br /&gt;
;Rule of four and a half:&lt;br /&gt;
* Destructor&lt;br /&gt;
* Copy constructor&lt;br /&gt;
* Copy-and-swap assignment operator&lt;br /&gt;
* Swap function&lt;br /&gt;
&lt;br /&gt;
{{hidden | Example Rule of Four RAII Class |&lt;br /&gt;
Copied from [https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom stack overflow]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt; // std::copy&lt;br /&gt;
#include &amp;lt;cstddef&amp;gt; // std::size_t&lt;br /&gt;
&lt;br /&gt;
class dumb_array&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    // (default) constructor&lt;br /&gt;
    dumb_array(std::size_t size = 0)&lt;br /&gt;
        : mSize(size),&lt;br /&gt;
          mArray(mSize ? new int[mSize]() : nullptr)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // copy-constructor&lt;br /&gt;
    dumb_array(const dumb_array&amp;amp; other)&lt;br /&gt;
        : mSize(other.mSize),&lt;br /&gt;
          mArray(mSize ? new int[mSize] : nullptr)&lt;br /&gt;
    {&lt;br /&gt;
        // note that this is non-throwing, because of the data&lt;br /&gt;
        // types being used; more attention to detail with regards&lt;br /&gt;
        // to exceptions must be given in a more general case, however&lt;br /&gt;
        std::copy(other.mArray, other.mArray + mSize, mArray);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // destructor&lt;br /&gt;
    ~dumb_array()&lt;br /&gt;
    {&lt;br /&gt;
        delete [] mArray;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // assignment operator&lt;br /&gt;
    dumb_array&amp;amp; operator=(dumb_array other) // (1)&lt;br /&gt;
    {&lt;br /&gt;
        swap(*this, other); // (2)&lt;br /&gt;
&lt;br /&gt;
        return *this;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // swap&lt;br /&gt;
    friend void swap(dumb_array&amp;amp; first, dumb_array&amp;amp; second) // nothrow&lt;br /&gt;
    {&lt;br /&gt;
        // enable ADL (not necessary in our case, but good practice)&lt;br /&gt;
        using std::swap;&lt;br /&gt;
&lt;br /&gt;
        // by swapping the members of two objects,&lt;br /&gt;
        // the two objects are effectively swapped&lt;br /&gt;
        swap(first.mSize, second.mSize);&lt;br /&gt;
        swap(first.mArray, second.mArray);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
    std::size_t mSize;&lt;br /&gt;
    int* mArray;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Useful Libraries==&lt;br /&gt;
A list of useful libraries&lt;br /&gt;
&lt;br /&gt;
===Boost===&lt;br /&gt;
{{main | Boost (C++ libraries)}}&lt;br /&gt;
A set of popular C++ libraries. Most are header-only.&lt;br /&gt;
&lt;br /&gt;
===cxxopts===&lt;br /&gt;
[https://github.com/jarro2783/cxxopts Link]&amp;lt;br&amp;gt;&lt;br /&gt;
A header-only C++ argument parser.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that if you already use Boost, you can use &amp;lt;code&amp;gt;Boost::Program_options&amp;lt;/code&amp;gt; instead.&lt;br /&gt;
===Eigen===&lt;br /&gt;
{{main | Eigen (C++ library)}}&lt;br /&gt;
A header-only C++ linear algebra library.&lt;br /&gt;
&lt;br /&gt;
===absl===&lt;br /&gt;
https://github.com/abseil/abseil-cpp is a library used by Google which supplements the standard library.&lt;br /&gt;
&lt;br /&gt;
Useful things:&lt;br /&gt;
# &amp;lt;code&amp;gt;absl::Time&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;absl::Duration&amp;lt;/code&amp;gt;.&lt;br /&gt;
# [https://abseil.io/docs/cpp/guides/strings#abslstrcat absl strings]&lt;br /&gt;
# [https://abseil.io/docs/cpp/guides/logging absl logging]&lt;br /&gt;
&lt;br /&gt;
Many parts of absl now have &amp;lt;code&amp;gt;std::&amp;lt;/code&amp;gt; equivalents such as &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::string_view&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::span&amp;lt;/code&amp;gt;. Unless contributing to Google codebases, you should probably prefer those.&lt;br /&gt;
&lt;br /&gt;
At Google, they prefer absl hash containers over unordered_set and unordered_map:&lt;br /&gt;
# &amp;lt;code&amp;gt;absl::flat_hash_map&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming languages]]&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=C%2B%2B&amp;diff=7191</id>
		<title>C++</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=C%2B%2B&amp;diff=7191"/>
		<updated>2025-11-23T01:17:55Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
C++ is a very popular and powerful language which includes all the low-level features of [[C_(programming_language) | C]] (e.g. pointers, operator overloading) along many high-level features (RAII, STD algorithms, STL containers) thanks to the C++ standard library.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
How to do things using the [https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library C++ standard library (stdlib)].&lt;br /&gt;
===Compilation===&lt;br /&gt;
{{See also|CMake|Makefile}}&lt;br /&gt;
====cmake====&lt;br /&gt;
&lt;br /&gt;
====g++====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
g++ my_driver.c [-Iincludefolder] -o my_program.out&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Standard optimizations&lt;br /&gt;
* &amp;lt;code&amp;gt;-std=c++17&amp;lt;/code&amp;gt; for C++17 support&lt;br /&gt;
* &amp;lt;code&amp;gt;-O3&amp;lt;/code&amp;gt; for level 3 optimizations&lt;br /&gt;
* &amp;lt;code&amp;gt;-g&amp;lt;/code&amp;gt; to include debugging info&lt;br /&gt;
* &amp;lt;code&amp;gt;-march=native&amp;lt;/code&amp;gt; - use all instructions available on the current CPU&lt;br /&gt;
* &amp;lt;code&amp;gt;-mtune=native&amp;lt;/code&amp;gt; - optimize for the current CPU&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
====Main====&lt;br /&gt;
All C++ programs launch in a &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; function.&lt;br /&gt;
Similar to [[C (programming language) | C]], the arguments are &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;char *argv[]&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
These can be easily converted to a &amp;lt;code&amp;gt;std::vector&amp;lt;std::string&amp;gt;&amp;lt;/code&amp;gt; for convenience.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
  std::vector&amp;lt;std::string&amp;gt; args(argv, argv + argc);&lt;br /&gt;
  // Your code here&lt;br /&gt;
  return EXIT_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Headers====&lt;br /&gt;
[https://stackoverflow.com/questions/10694255/cmath-vs-math-h-and-similar-c-prefixed-vs-h-extension-headers Reference]&lt;br /&gt;
&lt;br /&gt;
C++ includes C-headers such as &amp;lt;code&amp;gt;math.h&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cmath&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The C-style header will place everything in the global namespace while the C++ header will place everything in &amp;lt;code&amp;gt;std&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
You should use &amp;lt;code&amp;gt;cmath&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Lambda Expressions====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/lambda Reference]&lt;br /&gt;
&lt;br /&gt;
====Casting====&lt;br /&gt;
[https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used Types of casts]&lt;br /&gt;
&lt;br /&gt;
C++ has several types of casts including:&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/static_cast &amp;lt;code&amp;gt;static_cast&amp;lt;/code&amp;gt;] - your standard cast with conversion. Does not perform any checks.&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/dynamic_cast &amp;lt;code&amp;gt;dynamic_cast&amp;lt;/code&amp;gt;] - for casting objects with checking, requires a polymorphic base class (with a virtual function). Will return nullptr.&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/language/reinterpret_cast &amp;lt;code&amp;gt;reinterpret_cast&amp;lt;/code&amp;gt;] - cast without any conversion, for directly dealing with binary data, equivalent to &amp;lt;code&amp;gt;*(T*)&amp;lt;/code&amp;gt; in C.&lt;br /&gt;
&lt;br /&gt;
====References====&lt;br /&gt;
References are accepted or store using &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
void healPerson(Person &amp;amp;person) {&lt;br /&gt;
  person.health = 100;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
References are like pointers since they do not copy the object except they cannot be null and they cannot be reassigned.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that primitives can also be used with references, in which case changes will propagate to the underlying value.&amp;lt;br&amp;gt;&lt;br /&gt;
You can also use them as class attributes, initializing them in the constructor&#039;s initializer list.&amp;lt;br&amp;gt;&lt;br /&gt;
To store references in a vector, you can use &amp;lt;code&amp;gt;std::reference_wrapper&amp;lt;/code&amp;gt; and include the &amp;lt;code&amp;gt;functional&amp;lt;/code&amp;gt; header.&lt;br /&gt;
&lt;br /&gt;
====Types====&lt;br /&gt;
For simple programs, you can use the standard types:&lt;br /&gt;
* &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;size_t&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt;&lt;br /&gt;
See [https://stackoverflow.com/questions/6462439/whats-the-difference-between-long-long-and-long SO] for the standard and guaranteed precision of these built-in types.&lt;br /&gt;
&lt;br /&gt;
C++ also has fixed-width types in &amp;lt;code&amp;gt;#include &amp;lt;cstdint&amp;gt;&amp;lt;/code&amp;gt; (since C++11).&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/header/cstdint cppreference cstdint]&amp;lt;br&amp;gt;&lt;br /&gt;
I recommend using these for anything with specific or high precision requirements.&amp;lt;br&amp;gt;&lt;br /&gt;
Typically, I use:&lt;br /&gt;
* &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;std::byte&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;int64_t&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;long long&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;string&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t need to own the string, prefer to use &amp;lt;code&amp;gt;string_view&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// c-str to string&lt;br /&gt;
char *old_string = &amp;quot;my c-style string&amp;quot;;&lt;br /&gt;
string cpp_string(old_string);&lt;br /&gt;
&lt;br /&gt;
// string to c-str&lt;br /&gt;
cpp_string.c_str();&lt;br /&gt;
&lt;br /&gt;
// char to string&lt;br /&gt;
char my_char = &#039;a&#039;;&lt;br /&gt;
string my_str(1, my_char);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====String Interpolation====&lt;br /&gt;
[https://stackoverflow.com/questions/10410023/string-format-alternative-in-c Reference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    std::string a = &amp;quot;a&amp;quot;, b = &amp;quot;b&amp;quot;, c = &amp;quot;c&amp;quot;;&lt;br /&gt;
    // apply formatting&lt;br /&gt;
    std::stringstream s;&lt;br /&gt;
    s &amp;lt;&amp;lt; a &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; b &amp;lt;&amp;lt; &amp;quot; &amp;gt; &amp;quot; &amp;lt;&amp;lt; c;&lt;br /&gt;
    // assign to std::string&lt;br /&gt;
    std::string str = s.str();&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; str &amp;lt;&amp;lt; &amp;quot;\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Buildings Strings====&lt;br /&gt;
[https://www.fluentcpp.com/2017/12/19/build-strings-from-plain-string-up-to-boost-karma/ The Complete Guide to Building Strings In C++]&amp;lt;br&amp;gt;&lt;br /&gt;
There are multiple ways of buildings strings in C++.&amp;lt;br&amp;gt;&lt;br /&gt;
Strings are mutable in C++.&amp;lt;br&amp;gt;&lt;br /&gt;
I typically use &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ostringstream&amp;lt;/code&amp;gt; to build strings.&lt;br /&gt;
&lt;br /&gt;
====std::basic_string_view====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/string/basic_string_view std::basic_string_view]&lt;br /&gt;
&lt;br /&gt;
This is useful for writing functions which accept anything that looks like a string such as substrings, since typically &amp;lt;code&amp;gt;std::string::substr&amp;lt;/code&amp;gt; performs a copy.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;code&amp;gt;std::string_view&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;std::basic_string_view&amp;lt;char&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Filesystem===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;filesystem&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Convenient functions for filesystem. Added since C++17.&lt;br /&gt;
====Path====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/filesystem/path cppreference]&lt;br /&gt;
&lt;br /&gt;
Note if you use g++ &amp;lt;= version 9, you will need to add the flag &amp;lt;code&amp;gt;-lstdc++fs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
using std::filesystem::path;&lt;br /&gt;
&lt;br /&gt;
// Initialization&lt;br /&gt;
path my_path = &amp;quot;my_dir/my_file&amp;quot;;&lt;br /&gt;
// or my_path = path(&amp;quot;my_dir&amp;quot;) / &amp;quot;my_file&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Append to path&lt;br /&gt;
path(&amp;quot;foo&amp;quot;) / &amp;quot;bar&amp;quot;; // path(&amp;quot;foo/bar&amp;quot;)&lt;br /&gt;
path(&amp;quot;foo&amp;quot;) / &amp;quot;/bar&amp;quot;; // path(&amp;quot;/bar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
// Print&lt;br /&gt;
std::cout &amp;lt;&amp;lt; my_path &amp;lt;&amp;lt; std::endl; // prints &amp;quot;my_dir/my_file&amp;quot; with quotes&lt;br /&gt;
std::cout &amp;lt;&amp;lt; my_path.string() &amp;lt;&amp;lt; std::endl; // prints my_dir/my_file without quotes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* &amp;lt;code&amp;gt;path&amp;lt;/code&amp;gt; supports implicit conversion to &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Directories====&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/filesystem/create_directory &amp;lt;code&amp;gt;create_directory(path)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;create_directories(path)&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/filesystem/directory_iterator &amp;lt;code&amp;gt;directory_iterator(path)&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* &amp;lt;code&amp;gt;create_directory&amp;lt;/code&amp;gt; requires that the parent directory already exists&lt;br /&gt;
** If not, use &amp;lt;code&amp;gt;create_directories&amp;lt;/code&amp;gt; instead&lt;br /&gt;
&lt;br /&gt;
===Fstream===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;fstream&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Used for input/output of files&lt;br /&gt;
&lt;br /&gt;
====Reading and Writing====&lt;br /&gt;
Reading and writing is done using &amp;lt;code&amp;gt;fstream&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
If you don&#039;t need r/w, use &amp;lt;code&amp;gt;istream&amp;lt;/code&amp;gt; for reading or &amp;lt;code&amp;gt;ostream&amp;lt;/code&amp;gt; for writing.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  std::ifstream my_file(&amp;quot;my_file.txt&amp;quot;);&lt;br /&gt;
  std::string line;&lt;br /&gt;
  // Read line by line&lt;br /&gt;
  // You can also read using &amp;lt;&amp;lt;&lt;br /&gt;
  while (getline(my_file, line)) {&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Reading a whole file====&lt;br /&gt;
[https://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html Reference and comparison of different methods]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;cerrno&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;string_view&amp;gt;&lt;br /&gt;
&lt;br /&gt;
std::string get_file_contents(std::string_view filename) {&lt;br /&gt;
  std::ifstream in(filename, std::ios::in | std::ios::binary);&lt;br /&gt;
  if (in.good()) {&lt;br /&gt;
    std::string contents;&lt;br /&gt;
    in.seekg(0, std::ios::end);&lt;br /&gt;
    contents.resize(static_cast&amp;lt;unsigned int&amp;gt;(in.tellg()));&lt;br /&gt;
    in.seekg(0, std::ios::beg);&lt;br /&gt;
    in.read(&amp;amp;contents[0], contents.size());&lt;br /&gt;
    return contents;&lt;br /&gt;
  }&lt;br /&gt;
  std::cerr &amp;lt;&amp;lt; &amp;quot;Failed to open file: &amp;quot; &amp;lt;&amp;lt; filename &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
  throw(errno);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Regular Expressions===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;regex&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://en.cppreference.com/w/cpp/regex Reference]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;regex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  std::regex myRegex(&amp;quot;(\\d+)&amp;quot;);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Thread===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;thread&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/thread/thread std::thread reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basic Usage:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::thread my_thread(thread_function);&lt;br /&gt;
// Calling methods&lt;br /&gt;
// You can also pass in parameters as usual&lt;br /&gt;
std::thread my_thread(&amp;amp;Class::method, this);&lt;br /&gt;
// Lambda functions&lt;br /&gt;
std::thread my_thread([&amp;amp;]() {&lt;br /&gt;
 // do something&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Wait for thread to finish&lt;br /&gt;
my_thread.join();&lt;br /&gt;
&lt;br /&gt;
// get id of thread&lt;br /&gt;
std::thread::id my_id = my_thread.get_id();&lt;br /&gt;
&lt;br /&gt;
// get id of this thread&lt;br /&gt;
std::thread::id my_id = std::this_thread::get_id();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Sleep ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::this_thread::sleep_for(std::chrono::milliseconds(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
====Parallel For====&lt;br /&gt;
[https://www.alecjacobson.com/weblog/?p=4544 Reference]&lt;br /&gt;
&lt;br /&gt;
===Memory===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;memory&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
====Smart Pointers====&lt;br /&gt;
[https://www.geeksforgeeks.org/auto_ptr-unique_ptr-shared_ptr-weak_ptr-2/ Smart Pointers]&amp;lt;br&amp;gt;&lt;br /&gt;
Smart pointers were added in C++11.&amp;lt;br&amp;gt;&lt;br /&gt;
There are 3 types of smart pointers:&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/memory/unique_ptr &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt;] - one piece of code &#039;&#039;owns&#039;&#039; the memory at any given time.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::shared_ptr&amp;lt;/code&amp;gt; - the memory has multiple owners.&lt;br /&gt;
* &amp;lt;code&amp;gt;std::weak_ptr&amp;lt;/code&amp;gt; - a non-owning reference to a shared_ptr.&lt;br /&gt;
&lt;br /&gt;
In general, there should be one object owning an object using a &amp;lt;code&amp;gt;unique_ptr&amp;lt;/code&amp;gt;. Whenever you pass the value around, other functions should receive the object as a reference making it clear that they do not have ownership of the object. Smart pointers are nullable and assignable similar to regular pointers.&lt;br /&gt;
&lt;br /&gt;
Prefer to use &amp;lt;code&amp;gt;make_unique&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;make_shared&amp;lt;/code&amp;gt; which will only make one memory allocation for both the object and the pointer rather than two memory allocations.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can call &amp;lt;code&amp;gt;my_ptr.reset(new Car())&amp;lt;/code&amp;gt; to change the pointer or &amp;lt;code&amp;gt;my_ptr.reset()&amp;lt;/code&amp;gt; to deallocate the object referenced by the pointer.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Block-scope car&lt;br /&gt;
Car my_car;&lt;br /&gt;
&lt;br /&gt;
// Old C++&lt;br /&gt;
// Must call delete my_car; to avoid memory leaks.&lt;br /&gt;
Car *my_car = new Car();&lt;br /&gt;
&lt;br /&gt;
// Using unique ptr&lt;br /&gt;
std::unique_ptr&amp;lt;Car&amp;gt; my_car(new Car());&lt;br /&gt;
&lt;br /&gt;
// Or starting from C++14&lt;br /&gt;
auto my_car = std::make_unique&amp;lt;Car&amp;gt;();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* If the object you need is not very large, you can consider just including it as part of your class (or leaving it on the stack) rather than use pointers.&lt;br /&gt;
* If you want to get a copy of the smart pointer to the current object, the object must &#039;&#039;&#039;publically&#039;&#039;&#039; inherit &amp;lt;code&amp;gt;std::enable_shared_from_this&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Then you can call &amp;lt;code&amp;gt;shared_from_this()&amp;lt;/code&amp;gt; from within any method (not the constructor).&lt;br /&gt;
** May throw &amp;lt;code&amp;gt;bad_weak_ptr&amp;lt;/code&amp;gt; if you call &amp;lt;code&amp;gt;shared_from_this()&amp;lt;/code&amp;gt; without &amp;lt;code&amp;gt;make_shared&amp;lt;/code&amp;gt; or if you do not publically inherit &amp;lt;code&amp;gt;std::enable_shared_from_this&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* When writing functions when do not operate on pointers and do not claim ownership of objects, you should just take a reference to the object as the argument.&lt;br /&gt;
* &amp;lt;code&amp;gt;std::auto_ptr&amp;lt;/code&amp;gt; was a predecessor to &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt; which allowed copies. It shouldn&#039;t be used anymore.&lt;br /&gt;
&lt;br /&gt;
====Garbage Collection====&lt;br /&gt;
Starting from C++11, you should use smart pointers such as [https://en.cppreference.com/w/cpp/memory/shared_ptr &amp;lt;code&amp;gt;shared_ptr&amp;lt;/code&amp;gt;] which have automatic garbage collection.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Traditional C++ does not have garbage collection.&amp;lt;br&amp;gt;&lt;br /&gt;
After using &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; to allocate an object, use &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; to deallocate it.  &amp;lt;br&amp;gt;&lt;br /&gt;
You can also use C allocation with &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;alloca&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt;, though it is [https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-and-or-new not recommended] since these are not type-safe.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Custom Deleter====&lt;br /&gt;
[https://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html Custom Deleters]&amp;lt;br&amp;gt;&lt;br /&gt;
When using smart pointers, the default deleter is the &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; function but you can also specify your own deleter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
# Using a functor&lt;br /&gt;
struct AVFrameDeleter {&lt;br /&gt;
  void operator()(AVFrame *p) { av_frame_free(&amp;amp;p); }&lt;br /&gt;
};&lt;br /&gt;
std::unique_ptr&amp;lt;AVFrame, AVFrameDeleter&amp;gt; rgb_frame(av_frame_alloc());&lt;br /&gt;
&lt;br /&gt;
# Using free&lt;br /&gt;
std::unique_ptr&amp;lt;void *, decltype(std::free) *&amp;gt; my_buffer(std::malloc(10), std::free);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Deallocate====&lt;br /&gt;
Normally, containers such as &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; will automatically deallocate memory from the heap when the destructor is called. However, occationally you may want to coerse this deallocation yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
There are a few ways to do this:&lt;br /&gt;
* Use smart pointers&lt;br /&gt;
* Swap&lt;br /&gt;
* Call a clear/shrink/deallocate function&lt;br /&gt;
Example [https://stackoverflow.com/questions/3054567/right-way-to-deallocate-an-stdvector-object Reference]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Using smart pointers&lt;br /&gt;
std::unique_ptr&amp;lt;std::vector&amp;lt;float&amp;gt;&amp;gt; my_vector = make_unique&amp;lt;std::vector&amp;lt;float&amp;gt;&amp;gt;(99);&lt;br /&gt;
my_vector.reset();&lt;br /&gt;
&lt;br /&gt;
// Swap&lt;br /&gt;
std::vector&amp;lt;float&amp;gt; my_vector(99);&lt;br /&gt;
my_vector = std::vector&amp;lt;float&amp;gt;();&lt;br /&gt;
// Or alternatively&lt;br /&gt;
// std::vector&amp;lt;float&amp;gt;().swap(my_vector);&lt;br /&gt;
// std::swap(my_vector, std::vector&amp;lt;float&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Swap for cl::Buffer&lt;br /&gt;
cl::Buffer my_buf(context, CL_MEM_READ_WRITE, size);&lt;br /&gt;
my_buf = cl::Buffer();&lt;br /&gt;
&lt;br /&gt;
// Clear and shrink&lt;br /&gt;
// Specific to std::vector&lt;br /&gt;
std::vector&amp;lt;float&amp;gt; my_vector(99);&lt;br /&gt;
my_vector.clear();&lt;br /&gt;
my_vector.shrink_to_fit();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Limits===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;limits&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/types/numeric_limits Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
C++ has standard macros such as &amp;lt;code&amp;gt;INT_MAX&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The limits header adds these limits for every type.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Equivalent to FLT_MAX&lt;br /&gt;
std::numeric_limits&amp;lt;float&amp;gt;::max();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Utility===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;utility&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
====std::move====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/utility/move Ref]&amp;lt;br&amp;gt;&lt;br /&gt;
Use &amp;lt;code&amp;gt;std::move&amp;lt;/code&amp;gt; to move containers.&lt;br /&gt;
&lt;br /&gt;
===Algorithm===&lt;br /&gt;
====std::find====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/find Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::generate====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/generate cppreference]&amp;lt;br&amp;gt;&lt;br /&gt;
Allows you to fill a container using a function call&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;random&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    std::random_device rd;&lt;br /&gt;
    std::mt19937 gen(rd());&lt;br /&gt;
    # Fill with integers in [0, 10]&lt;br /&gt;
    std::uniform_int_distribution&amp;lt;&amp;gt; dis(0, 10);&lt;br /&gt;
&lt;br /&gt;
    std::vector&amp;lt;int&amp;gt; my_vec(10, 0);&lt;br /&gt;
    std::generate(my_vec.begin(), my_vec.end(), [&amp;amp;](){return dis(gen);});&lt;br /&gt;
    &lt;br /&gt;
    for (int v : my_vec) {&lt;br /&gt;
        std::cout &amp;lt;&amp;lt; v &amp;lt;&amp;lt; &amp;quot; &amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Numeric===&lt;br /&gt;
====std::iota====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/algorithm/iota Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Fills an array or vector with increasing values. Can pass in a starting number.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; v(60);&lt;br /&gt;
std::iota(v.begin(), v.end(), 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====std::accumulate====&lt;br /&gt;
Adds up numbers. Can pass in a starting number.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;int&amp;gt; v(60);&lt;br /&gt;
std::iota(v.begin(), v.end(), 0);&lt;br /&gt;
std::accumulate(v.begin(), v.end(), 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Chrono===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;chrono&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I now prefer using &amp;lt;code&amp;gt;absl::Time&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;absl::Duration&amp;lt;/code&amp;gt; over Chrono because they abstract away the underlying type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
auto start = std::chrono::high_resolution_clock::now();&lt;br /&gt;
// do something&lt;br /&gt;
auto end = std::chrono::high_resolution_clock::now();&lt;br /&gt;
std::cout &amp;lt;&amp;lt; &amp;quot;Time elapsed: &amp;quot; &lt;br /&gt;
          &amp;lt;&amp;lt; std::chrono::duration_cast&amp;lt;std::chrono::milliseconds&amp;gt;(end - start).count() &lt;br /&gt;
          &amp;lt;&amp;lt; &amp;quot; ms&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Execution===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;execution&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
The execution header gives you tools for parallel execution (since C++17).&amp;lt;br&amp;gt;&lt;br /&gt;
See [https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t execution_policy_tag].&amp;lt;br&amp;gt;&lt;br /&gt;
[https://devblogs.microsoft.com/cppblog/using-c17-parallel-algorithms-for-better-performance/ C++17 Parallel Algorithms blog].&amp;lt;br&amp;gt;&lt;br /&gt;
[https://developer.nvidia.com/blog/accelerating-standard-c-with-gpus-using-stdpar/ Nvidia Accelerating Standard C++ with GPUs Using stdpar]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Parallel Sorting Example&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::sort(std::execution::par_unseq, sorted.begin(), sorted.end());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::seq&amp;lt;/code&amp;gt; sequential&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::unseq&amp;lt;/code&amp;gt; vectorized only (C++20)&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::par&amp;lt;/code&amp;gt; parallel&lt;br /&gt;
* &amp;lt;code&amp;gt;std::execution::par_unseq&amp;lt;/code&amp;gt; parallel and vectorized&lt;br /&gt;
&lt;br /&gt;
===Random===&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;random&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/header/random cppreference.com]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::random_device rd;  //Will be used to obtain a seed for the random number engine&lt;br /&gt;
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()&lt;br /&gt;
std::uniform_int_distribution&amp;lt;&amp;gt; dis(1, 6);&lt;br /&gt;
 &lt;br /&gt;
for (int n=0; n&amp;lt;10; ++n)&lt;br /&gt;
   //Use dis to transform the random unsigned int generated by gen into an int in [1, 6]&lt;br /&gt;
   std::cout &amp;lt;&amp;lt; dis(gen) &amp;lt;&amp;lt; &#039; &#039;;&lt;br /&gt;
std::cout &amp;lt;&amp;lt; &#039;\n&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===const===&lt;br /&gt;
For variables:&lt;br /&gt;
# Use &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; for values initialized at compile time and won&#039;t change at runtime. Most of the time, this is what you want for hardcoded compile time parameters.&lt;br /&gt;
# Use &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; for values initialized at runtime and won&#039;t change.&lt;br /&gt;
# Use &amp;lt;code&amp;gt;constinit&amp;lt;/code&amp;gt; for values initialized at compile time and may change at runtime. I haven&#039;t found a use case for this yet.&lt;br /&gt;
&lt;br /&gt;
For functions:&lt;br /&gt;
# Add &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; to the end of a method declaration if it won&#039;t change the object.&lt;br /&gt;
# Add &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; if the function can be evaluated at compile time, i.e. can accepts and output &amp;lt;code&amp;gt;constexpr&amp;lt;/code&amp;gt; variables.&lt;br /&gt;
# Add &amp;lt;code&amp;gt;consteval&amp;lt;/code&amp;gt; if you want to force the function to only be evaluated at compile time.&lt;br /&gt;
&lt;br /&gt;
==STL==&lt;br /&gt;
STL is the Standard Template Library originally implemented in 1994 by Stepanov and Lee from HP.&amp;lt;br&amp;gt;&lt;br /&gt;
STL consists of a general set of algorithms, containers, functions, and iterators.&amp;lt;br&amp;gt;&lt;br /&gt;
Today, STL refers to those containers and algorithms which are now built into the standard library (std) of C++.&lt;br /&gt;
&lt;br /&gt;
===Simple Containers===&lt;br /&gt;
====std::pair====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/utility/pair std::pair]&lt;br /&gt;
&lt;br /&gt;
===Sequences===&lt;br /&gt;
====std::array====&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;array&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This wrapper around C-style arrays gives us size information and allows the array to be passed around by reference while keeping the array on the stack or in a struct.&lt;br /&gt;
Unless you need stack allocation or allocation into a struct, you are should probably use a vector.&lt;br /&gt;
&lt;br /&gt;
====std::vector====&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;vector&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
https://en.cppreference.com/w/cpp/container/vector&amp;lt;br&amp;gt;&lt;br /&gt;
This is a dynamically-allocated resizable array, known as an ArrayList in Java.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
// Basics&lt;br /&gt;
vector my_vec;&lt;br /&gt;
// Vector with size 5&lt;br /&gt;
vector my_vec(5);&lt;br /&gt;
// Vector with size 5 initialized to 1&lt;br /&gt;
vector my_vec(5, 1);&lt;br /&gt;
&lt;br /&gt;
// Length of vector&lt;br /&gt;
my_vec.size();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to size()==0&lt;br /&gt;
my_vec.empty();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to my_vec[0];&lt;br /&gt;
// Undefined on empty vectors&lt;br /&gt;
my_vec.front();&lt;br /&gt;
&lt;br /&gt;
// Equivalent to my_vec[my_vec.size()-1];&lt;br /&gt;
// Undefined on empty vectors&lt;br /&gt;
my_vec.back();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that [https://en.cppreference.com/w/cpp/container/vector_bool &amp;lt;code&amp;gt;vector&amp;lt;bool&amp;gt;&amp;lt;/code&amp;gt;] is a special case of bit-packed booleans instead of an array of bools. You should use &amp;lt;code&amp;gt;vector&amp;lt;char&amp;gt;&amp;lt;/code&amp;gt; instead if your code relies on it being continguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::span====&lt;br /&gt;
&amp;lt;code&amp;gt;#include 	&amp;amp;lt;span&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://en.cppreference.com/w/cpp/container/span&amp;lt;br&amp;gt;&lt;br /&gt;
This is view of some contiguous amount of memory. If the size is static, this is equivalent to a single pointer, otherwise is it equivalent to two pointers (i.e. begin and end).&lt;br /&gt;
If you use this as the parameter to your function, it will accept both arrays and vectors.&lt;br /&gt;
Additionaly, there is a [https://en.cppreference.com/w/cpp/container/span/subspan subspan] function so you don&#039;t need to pass around indices or pointers to get subvectors.&lt;br /&gt;
&lt;br /&gt;
====std::deque====&lt;br /&gt;
Double-ended queue&lt;br /&gt;
&lt;br /&gt;
====std::list====&lt;br /&gt;
This is a doubly linked list. You can delete elements from the middle of the list if you know have an iterator.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
list&amp;lt;int&amp;gt; m_list;&lt;br /&gt;
&lt;br /&gt;
list&amp;lt;int&amp;gt;::iterator m_it = m_list.insert(5);&lt;br /&gt;
&lt;br /&gt;
// Remove the element&lt;br /&gt;
m_list.erase(m_it);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Container adaptors===&lt;br /&gt;
====std::queue====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/queue Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
std::queue&amp;lt;int&amp;gt; my_queue;&lt;br /&gt;
&lt;br /&gt;
my_queue.push(a);&lt;br /&gt;
auto val = my_queue.front();&lt;br /&gt;
my_queue.pop(); // returns void&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::stack====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/stack cppreference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::stack&amp;lt;char&amp;gt; my_stack;&lt;br /&gt;
&lt;br /&gt;
// Push to stack&lt;br /&gt;
// You can also use emplace&lt;br /&gt;
// Returns void&lt;br /&gt;
my_stack.push(&#039;a&#039;);&lt;br /&gt;
&lt;br /&gt;
// Peek&lt;br /&gt;
// Always make sure stack is not empty&lt;br /&gt;
char top = my_stack.top();&lt;br /&gt;
&lt;br /&gt;
// Pop&lt;br /&gt;
// Note: returns void&lt;br /&gt;
// Always make sure stack is not empty&lt;br /&gt;
my_stack.pop();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::priority_queue====&lt;br /&gt;
This is a min/max heap.&lt;br /&gt;
&lt;br /&gt;
===Associative Containers===&lt;br /&gt;
Also known as maps or associative arrays.&lt;br /&gt;
====std::set====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/set reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;set&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a binary tree (likely red-black tree). You can assume &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; operations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====std::map====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/map reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;map&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a binary tree (likely red-black tree). You can assume &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; operations.&lt;br /&gt;
&lt;br /&gt;
====std::unordered_set====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/unordered_set reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include &amp;lt;unordered_set&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a hashset. You can assume operations are &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; on average and &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; worst case.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;gt;&lt;br /&gt;
std::unordered_set&amp;lt;int&amp;gt; my_set;&lt;br /&gt;
// Add&lt;br /&gt;
my_set.insert(5);&lt;br /&gt;
// Check contains&lt;br /&gt;
my_set.find(5) != my_set.end(); // Before C++20&lt;br /&gt;
my_set.contains(5); // C++20&lt;br /&gt;
// Remove&lt;br /&gt;
my_set.erase(5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====std::unordered_map====&lt;br /&gt;
[https://en.cppreference.com/w/cpp/container/unordered_map reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#include&amp;lt;unordered_map&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
This is a hashmap. You can assume operations are &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; on average and &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; worst case.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
std::unordered_map&amp;lt;int, std::string&amp;gt; my_map;&lt;br /&gt;
my_map[5] = &amp;quot;hey&amp;quot;; // Fine as long as value type is not a reference.&lt;br /&gt;
my_map.insert({5, &amp;quot;hey&amp;quot;}); // Necessary if value type is a reference.&lt;br /&gt;
my_map.find(5) != my_map.end();&lt;br /&gt;
my_map.contains(5); // C++20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;Custom Keys&lt;br /&gt;
How to use a rational number as a key in C++&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
struct Fraction&lt;br /&gt;
{&lt;br /&gt;
    int num;&lt;br /&gt;
    int den;&lt;br /&gt;
&lt;br /&gt;
    bool operator==(const Fraction &amp;amp;other) const { &lt;br /&gt;
        return num*other.den == den * other.num;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Fraction(int a, int b) : num(a), den(b) {}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functional Programming==&lt;br /&gt;
https://medium.com/swlh/doing-it-the-functional-way-in-c-5c392bbdd46a&lt;br /&gt;
&lt;br /&gt;
Many of these can be parallelized with [https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t execution policies] such as &amp;lt;code&amp;gt;std::execution::par&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;std::execution::par_unseq&amp;lt;/code&amp;gt;. Paired with [https://adaptivecpp.github.io/AdaptiveCpp/stdpar/ AdaptiveCPP], some operations can be automatically GPU accelerated as well.&lt;br /&gt;
&lt;br /&gt;
Most of these require C++20.&lt;br /&gt;
&lt;br /&gt;
===Map===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::for_each&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::transform&amp;lt;/code&amp;gt;&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/copy &amp;lt;code&amp;gt;std::copy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::copy_if&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/fill &amp;lt;code&amp;gt;std::fill&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
===Reduce/Fold===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::reduce&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::accumulate&amp;lt;/code&amp;gt;&lt;br /&gt;
* [https://en.cppreference.com/w/cpp/algorithm/ranges/fold_left &amp;lt;code&amp;gt;std::ranges::fold_left&amp;lt;/code&amp;gt;] (C++23)&lt;br /&gt;
&lt;br /&gt;
===Filter===&lt;br /&gt;
* &amp;lt;code&amp;gt;std::copy_if&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::remove_if&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;std::find_if&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming Styles==&lt;br /&gt;
===Modern C++===&lt;br /&gt;
[https://github.com/rigtorp/awesome-modern-cpp List of resources]&amp;lt;br&amp;gt;&lt;br /&gt;
* Use RAII principles.&lt;br /&gt;
** I.e. each object should manage it&#039;s own memory rather than the caller having to manage it.&lt;br /&gt;
** You should never use `malloc` and `free` unless interfacing with C libraries.&lt;br /&gt;
* Avoid the use of new and delete, instead using vector or smart pointers.&lt;br /&gt;
* Use clang-format.&lt;br /&gt;
&lt;br /&gt;
;Resources&lt;br /&gt;
* [https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md CppCoreGuidelines]&lt;br /&gt;
* [https://google.github.io/styleguide/cppguide.html Google C++ Style Guide] - note that some people dislike this since it is focused on interoperability and suggests avoiding exceptions.&lt;br /&gt;
&lt;br /&gt;
==RAII==&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/raii cppreference raii]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://en.cppreference.com/w/cpp/language/rule_of_three cppreference rule_of_three]&amp;lt;br&amp;gt;&lt;br /&gt;
Resource Acquisition Is Initialization - binds the life cycle of a resource to the lifetime of an object.&amp;lt;br&amp;gt;&lt;br /&gt;
For instance, the resource for a vector is an allocated amount of memory. Once the vector is destroyed and the destructor called, the resource is released.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need any from one of the rules, you need to implement the remainder&lt;br /&gt;
&lt;br /&gt;
;Rule of zero&amp;lt;br&amp;gt;&lt;br /&gt;
Do not use a custom deconstructor, copy constructor, or copy assignment. Push all of these operations into the classes of member variables such as &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unique_ptr&amp;lt;/code&amp;gt;. This is the best and simplest case.&lt;br /&gt;
&lt;br /&gt;
;[[Wikipedia: Rule of three (C++ programming) | Rule of three]]&lt;br /&gt;
* Destructor&lt;br /&gt;
* Copy constructor&lt;br /&gt;
* Copy assignment operator&lt;br /&gt;
&lt;br /&gt;
;[[Wikipedia: Rule of three (C++ programming)#Rule of five | Rule of five]]&lt;br /&gt;
* All from rule of three plus:&lt;br /&gt;
* Move constructor&lt;br /&gt;
* Move operator&lt;br /&gt;
&lt;br /&gt;
;Rule of four and a half:&lt;br /&gt;
* Destructor&lt;br /&gt;
* Copy constructor&lt;br /&gt;
* Copy-and-swap assignment operator&lt;br /&gt;
* Swap function&lt;br /&gt;
&lt;br /&gt;
{{hidden | Example Rule of Four RAII Class |&lt;br /&gt;
Copied from [https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom stack overflow]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt; // std::copy&lt;br /&gt;
#include &amp;lt;cstddef&amp;gt; // std::size_t&lt;br /&gt;
&lt;br /&gt;
class dumb_array&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    // (default) constructor&lt;br /&gt;
    dumb_array(std::size_t size = 0)&lt;br /&gt;
        : mSize(size),&lt;br /&gt;
          mArray(mSize ? new int[mSize]() : nullptr)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // copy-constructor&lt;br /&gt;
    dumb_array(const dumb_array&amp;amp; other)&lt;br /&gt;
        : mSize(other.mSize),&lt;br /&gt;
          mArray(mSize ? new int[mSize] : nullptr)&lt;br /&gt;
    {&lt;br /&gt;
        // note that this is non-throwing, because of the data&lt;br /&gt;
        // types being used; more attention to detail with regards&lt;br /&gt;
        // to exceptions must be given in a more general case, however&lt;br /&gt;
        std::copy(other.mArray, other.mArray + mSize, mArray);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // destructor&lt;br /&gt;
    ~dumb_array()&lt;br /&gt;
    {&lt;br /&gt;
        delete [] mArray;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // assignment operator&lt;br /&gt;
    dumb_array&amp;amp; operator=(dumb_array other) // (1)&lt;br /&gt;
    {&lt;br /&gt;
        swap(*this, other); // (2)&lt;br /&gt;
&lt;br /&gt;
        return *this;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // swap&lt;br /&gt;
    friend void swap(dumb_array&amp;amp; first, dumb_array&amp;amp; second) // nothrow&lt;br /&gt;
    {&lt;br /&gt;
        // enable ADL (not necessary in our case, but good practice)&lt;br /&gt;
        using std::swap;&lt;br /&gt;
&lt;br /&gt;
        // by swapping the members of two objects,&lt;br /&gt;
        // the two objects are effectively swapped&lt;br /&gt;
        swap(first.mSize, second.mSize);&lt;br /&gt;
        swap(first.mArray, second.mArray);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
    std::size_t mSize;&lt;br /&gt;
    int* mArray;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Useful Libraries==&lt;br /&gt;
A list of useful libraries&lt;br /&gt;
&lt;br /&gt;
===Boost===&lt;br /&gt;
{{main | Boost (C++ libraries)}}&lt;br /&gt;
A set of popular C++ libraries. Most are header-only.&lt;br /&gt;
&lt;br /&gt;
===cxxopts===&lt;br /&gt;
[https://github.com/jarro2783/cxxopts Link]&amp;lt;br&amp;gt;&lt;br /&gt;
A header-only C++ argument parser.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that if you already use Boost, you can use &amp;lt;code&amp;gt;Boost::Program_options&amp;lt;/code&amp;gt; instead.&lt;br /&gt;
===Eigen===&lt;br /&gt;
{{main | Eigen (C++ library)}}&lt;br /&gt;
A header-only C++ linear algebra library.&lt;br /&gt;
&lt;br /&gt;
===absl===&lt;br /&gt;
https://github.com/abseil/abseil-cpp is a library used by Google which supplements the standard library.&lt;br /&gt;
&lt;br /&gt;
Useful things:&lt;br /&gt;
# &amp;lt;code&amp;gt;absl::Time&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;absl::Duration&amp;lt;/code&amp;gt;.&lt;br /&gt;
# [https://abseil.io/docs/cpp/guides/strings#abslstrcat absl strings]&lt;br /&gt;
# [https://abseil.io/docs/cpp/guides/logging absl logging]&lt;br /&gt;
&lt;br /&gt;
Many parts of absl now have &amp;lt;code&amp;gt;std::&amp;lt;/code&amp;gt; equivalents such as &amp;lt;code&amp;gt;std::unique_ptr&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::string_view&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;std::span&amp;lt;/code&amp;gt;. Unless contributing to Google codebases, you should probably prefer those.&lt;br /&gt;
&lt;br /&gt;
At Google, they prefer absl hash containers over unordered_set and unordered_map:&lt;br /&gt;
# &amp;lt;code&amp;gt;absl::flat_hash_map&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming languages]]&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Three.js&amp;diff=7190</id>
		<title>Three.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Three.js&amp;diff=7190"/>
		<updated>2025-10-30T19:21:59Z</updated>

		<summary type="html">&lt;p&gt;David: /* Color Spaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
A very useful JavaScript graphics library which uses WebGL build by Mr. Doob (Ricardo Cabello, Google).&lt;br /&gt;
&lt;br /&gt;
* [http://threejs.org threejs.org]&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
# Install &amp;lt;code&amp;gt;three&amp;lt;/code&amp;gt; using npm:&lt;br /&gt;
#:&amp;lt;pre&amp;gt;&lt;br /&gt;
#::npm i three&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Import into your main JS script&lt;br /&gt;
#:&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
import * as THREE from &#039;three&#039;;&lt;br /&gt;
// or const THREE = require(&#039;three&#039;);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can import specific components from examples as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
import {OrbitControls} from &#039;three/examples/jsm/controls/OrbitControls.js&#039;;&lt;br /&gt;
import {Stats} from &#039;three/examples/jsm/libs/stats.module.js&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Instancing==&lt;br /&gt;
See [https://threejs.org/examples/?q=instancing#webgl_instancing_performance instancing example].&lt;br /&gt;
&lt;br /&gt;
There are two main ways of instancing in three.js:&lt;br /&gt;
* Using an [https://threejs.org/docs/#api/en/objects/InstancedMesh InstancedMesh]&lt;br /&gt;
* Merging geometries (since we don&#039;t have a geometry shader)&lt;br /&gt;
&lt;br /&gt;
==Shaders==&lt;br /&gt;
See [https://threejs.org/docs/#api/en/materials/ShaderMaterial ShaderMaterial].&lt;br /&gt;
&lt;br /&gt;
==Color Spaces==&lt;br /&gt;
By default, three.js works in Linear color space. This means that input colors are converted from SRGB to linear before rendering, most color calculations happen in linear color space, the final color is converted to SRGB for display.&lt;br /&gt;
&lt;br /&gt;
# THREE.Color values are converted from SRGB to Linear color space on CPU at https://github.com/mrdoob/three.js/blob/0af9729d0c143a86a1d725d6e2c3ad83301f3f34/src/math/Color.js#L211&lt;br /&gt;
# Textures are converted from their source color space to linear. This is done by https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/unpackColorSpace.&lt;br /&gt;
# When rendering directly to canvas or XR, shaders output in SRGB. When rendering to a rendertarget, shaders output in linear. See https://github.com/mrdoob/three.js/blob/e04b9f7bd7f5b17103339d343168bfab2d6e0ace/src/renderers/WebGLRenderer.js#L2198 for the CPU side and https://github.com/mrdoob/three.js/blob/e04b9f7bd7f5b17103339d343168bfab2d6e0ace/src/renderers/shaders/ShaderChunk/colorspace_fragment.glsl.js for the GPU side.&lt;br /&gt;
# If using postprocessing, make sure to use an Output pass to convert the linear render target into SRGB.&lt;br /&gt;
&lt;br /&gt;
See https://discourse.threejs.org/t/updates-to-color-management-in-three-js-r152/50791&lt;br /&gt;
&lt;br /&gt;
==References==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Three.js&amp;diff=7189</id>
		<title>Three.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Three.js&amp;diff=7189"/>
		<updated>2025-10-30T19:21:43Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
A very useful JavaScript graphics library which uses WebGL build by Mr. Doob (Ricardo Cabello, Google).&lt;br /&gt;
&lt;br /&gt;
* [http://threejs.org threejs.org]&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
# Install &amp;lt;code&amp;gt;three&amp;lt;/code&amp;gt; using npm:&lt;br /&gt;
#:&amp;lt;pre&amp;gt;&lt;br /&gt;
#::npm i three&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Import into your main JS script&lt;br /&gt;
#:&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
import * as THREE from &#039;three&#039;;&lt;br /&gt;
// or const THREE = require(&#039;three&#039;);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can import specific components from examples as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
import {OrbitControls} from &#039;three/examples/jsm/controls/OrbitControls.js&#039;;&lt;br /&gt;
import {Stats} from &#039;three/examples/jsm/libs/stats.module.js&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Instancing==&lt;br /&gt;
See [https://threejs.org/examples/?q=instancing#webgl_instancing_performance instancing example].&lt;br /&gt;
&lt;br /&gt;
There are two main ways of instancing in three.js:&lt;br /&gt;
* Using an [https://threejs.org/docs/#api/en/objects/InstancedMesh InstancedMesh]&lt;br /&gt;
* Merging geometries (since we don&#039;t have a geometry shader)&lt;br /&gt;
&lt;br /&gt;
==Shaders==&lt;br /&gt;
See [https://threejs.org/docs/#api/en/materials/ShaderMaterial ShaderMaterial].&lt;br /&gt;
&lt;br /&gt;
==Color Spaces==&lt;br /&gt;
By default, three.js works in Linear color space. This means that input colors are converted from SRGB to linear before rendering, most color calculations happen in linear color space, the final color is converted to SRGB for display.&lt;br /&gt;
&lt;br /&gt;
1. THREE.Color values are converted from SRGB to Linear color space on CPU at https://github.com/mrdoob/three.js/blob/0af9729d0c143a86a1d725d6e2c3ad83301f3f34/src/math/Color.js#L211&lt;br /&gt;
2. Textures are converted from their source color space to linear. This is done by https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/unpackColorSpace.&lt;br /&gt;
3. When rendering directly to canvas or XR, shaders output in SRGB. When rendering to a rendertarget, shaders output in linear. See https://github.com/mrdoob/three.js/blob/e04b9f7bd7f5b17103339d343168bfab2d6e0ace/src/renderers/WebGLRenderer.js#L2198 for the CPU side and https://github.com/mrdoob/three.js/blob/e04b9f7bd7f5b17103339d343168bfab2d6e0ace/src/renderers/shaders/ShaderChunk/colorspace_fragment.glsl.js for the GPU side.&lt;br /&gt;
4. If using postprocessing, make sure to use an Output pass to convert the linear render target into SRGB.&lt;br /&gt;
&lt;br /&gt;
See https://discourse.threejs.org/t/updates-to-color-management-in-three-js-r152/50791&lt;br /&gt;
&lt;br /&gt;
==References==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Meta_Quest_ADB_Commands&amp;diff=7188</id>
		<title>Meta Quest ADB Commands</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Meta_Quest_ADB_Commands&amp;diff=7188"/>
		<updated>2025-10-15T05:39:41Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Disable proximity sensor&lt;br /&gt;
adb shell am broadcast -a com.oculus.vrpowermanager.prox_close&lt;br /&gt;
&lt;br /&gt;
# Restore proximity sensor&lt;br /&gt;
adb shell am broadcast -a com.oculus.vrpowermanager.automation_disable&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Meta_Quest_ADB_Commands&amp;diff=7187</id>
		<title>Meta Quest ADB Commands</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Meta_Quest_ADB_Commands&amp;diff=7187"/>
		<updated>2025-10-15T05:39:29Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Disable proximity sensor&lt;br /&gt;
adb shell am broadcast -a com.oculus.vrpowermanager.prox_close&lt;br /&gt;
&lt;br /&gt;
# Restore proximity sensor&lt;br /&gt;
adb shell am broadcast -a com.oculus.vrpowermanager.automation_disable&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Meta_Quest_ADB_Commands&amp;diff=7186</id>
		<title>Meta Quest ADB Commands</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Meta_Quest_ADB_Commands&amp;diff=7186"/>
		<updated>2025-10-15T05:39:07Z</updated>

		<summary type="html">&lt;p&gt;David: Created page with &amp;quot;  &amp;lt;p&amp;gt; # Disable proximity sensor adb shell am broadcast -a com.oculus.vrpowermanager.prox_close  # Restore proximity sensor adb shell am broadcast -a com.oculus.vrpowermanager.automation_disable  &amp;lt;/p&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
# Disable proximity sensor&lt;br /&gt;
adb shell am broadcast -a com.oculus.vrpowermanager.prox_close&lt;br /&gt;
&lt;br /&gt;
# Restore proximity sensor&lt;br /&gt;
adb shell am broadcast -a com.oculus.vrpowermanager.automation_disable&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7185</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7185"/>
		<updated>2025-10-08T21:47:56Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Transparent objects need to be rendered from back to front. This is simple to do each frame on CPU when you have a limited number of convex meshes which are small relative to their distance to each other.&lt;br /&gt;
&lt;br /&gt;
However, when parts of a mesh overlap each other, you have large meshes which overlap each other, or you have a huge number of transparent objects, it may be necessary to switch to an order-independent transparency.&lt;br /&gt;
&lt;br /&gt;
The main idea of order-independent transparency is to either:&lt;br /&gt;
# Approximate transparency using a commutative operation, i.e. addition.&lt;br /&gt;
# Render fragments (per-pixel colors) from back to front.&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Depth Peeling==&lt;br /&gt;
Do several render passes. In each render pass, set a range of z values from back to front and render only z values within the threshold for each render pass.&lt;br /&gt;
&lt;br /&gt;
===Dual Depth Peeling===&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
This is a performance optimization over depth peeling which allows using half the number of passes.&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
The idea is to apply dithering, rendering objects as opaque.&lt;br /&gt;
When objects overlap, the depth test prevents objects behind from rendering over objects in front.&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;br /&gt;
This method requires an atomic counter or storage buffers with atomic operations, available in OpenGL 4.2+, Vulkan, and WebGPU. It also requires a small amount of overdraw since sorting needs to happen per pixel.&lt;br /&gt;
&lt;br /&gt;
The idea is to have each pixel build a linked list of each fragment being drawn. Then the linked list will be sorted and rendered back to front.&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7184</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7184"/>
		<updated>2025-10-08T21:45:46Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Transparent objects need to be rendered from back to front. This is simple to do each frame on CPU when you have a limited number of convex meshes which are small relative to their distance to each other.&lt;br /&gt;
&lt;br /&gt;
However, when parts of a mesh overlap each other, you have large meshes which overlap each other, or you have a huge number of transparent objects, it may be necessary to switch to an order-independent transparency.&lt;br /&gt;
&lt;br /&gt;
The main idea of order-independent transparency is to either:&lt;br /&gt;
1. Approximate transparency using a commutative operation, i.e. addition.&lt;br /&gt;
2. Render fragments (per-pixel colors) from back to front.&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Depth Peeling==&lt;br /&gt;
Do several render passes. In each render pass, set a range of z values from back to front and render only z values within the threshold for each render pass.&lt;br /&gt;
&lt;br /&gt;
===Dual Depth Peeling===&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
This is a performance optimization over depth peeling which allows using half the number of passes.&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
The idea is to apply dithering, rendering objects as opaque.&lt;br /&gt;
When objects overlap, the depth test prevents objects behind from rendering over objects in front.&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;br /&gt;
This method requires an atomic counter or storage buffers with atomic operations, available in OpenGL 4.2+, Vulkan, and WebGPU. It also requires a small amount of overdraw since sorting needs to happen per pixel.&lt;br /&gt;
&lt;br /&gt;
The idea is to have each pixel build a linked list of each fragment being drawn. Then the linked list will be sorted and rendered back to front.&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7183</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7183"/>
		<updated>2025-10-08T21:39:10Z</updated>

		<summary type="html">&lt;p&gt;David: /* Per-Pixel Linked Lists */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Depth Peeling==&lt;br /&gt;
Do several render passes. In each render pass, set a range of z values from back to front and render only z values within the threshold for each render pass.&lt;br /&gt;
&lt;br /&gt;
===Dual Depth Peeling===&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
This is a performance optimization over depth peeling which allows using half the number of passes.&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
The idea is to apply dithering, rendering objects as opaque.&lt;br /&gt;
When objects overlap, the depth test prevents objects behind from rendering over objects in front.&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;br /&gt;
This method requires an atomic counter or storage buffers with atomic operations, available in OpenGL 4.2+, Vulkan, and WebGPU. It also requires a small amount of overdraw since sorting needs to happen per pixel.&lt;br /&gt;
&lt;br /&gt;
The idea is to have each pixel build a linked list of each fragment being drawn. Then the linked list will be sorted and rendered back to front.&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7182</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7182"/>
		<updated>2025-10-08T21:30:34Z</updated>

		<summary type="html">&lt;p&gt;David: /* Dual Depth Peeling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Depth Peeling==&lt;br /&gt;
Do several render passes. In each render pass, set a range of z values from back to front and render only z values within the threshold for each render pass.&lt;br /&gt;
&lt;br /&gt;
===Dual Depth Peeling===&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
This is a performance optimization over depth peeling which allows using half the number of passes.&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
The idea is to apply dithering, rendering objects as opaque.&lt;br /&gt;
When objects overlap, the depth test prevents objects behind from rendering over objects in front.&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7181</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7181"/>
		<updated>2025-10-08T21:27:27Z</updated>

		<summary type="html">&lt;p&gt;David: /* Stochastic Transparency */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Depth Peeling==&lt;br /&gt;
Do several render passes. In each render pass, set a range of z values from back to front and render only z values within the threshold for each render pass.&lt;br /&gt;
&lt;br /&gt;
==Dual Depth Peeling==&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
The idea is to apply dithering, rendering objects as opaque.&lt;br /&gt;
When objects overlap, the depth test prevents objects behind from rendering over objects in front.&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7180</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7180"/>
		<updated>2025-10-08T21:27:15Z</updated>

		<summary type="html">&lt;p&gt;David: /* Stochastic Transparency */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Depth Peeling==&lt;br /&gt;
Do several render passes. In each render pass, set a range of z values from back to front and render only z values within the threshold for each render pass.&lt;br /&gt;
&lt;br /&gt;
==Dual Depth Peeling==&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
The idea is to apply dithering, rendering objects as opaque.&lt;br /&gt;
When objects overlap, the depth test prevents objects in front from rendering over objects behind.&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7179</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7179"/>
		<updated>2025-10-08T21:22:26Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Depth Peeling==&lt;br /&gt;
Do several render passes. In each render pass, set a range of z values from back to front and render only z values within the threshold for each render pass.&lt;br /&gt;
&lt;br /&gt;
==Dual Depth Peeling==&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7178</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7178"/>
		<updated>2025-10-08T21:21:11Z</updated>

		<summary type="html">&lt;p&gt;David: /* Weighted Blended Order Independent Transparency */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
# Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
# Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Dual Depth Peeling==&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7177</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7177"/>
		<updated>2025-10-08T21:21:03Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Additive Transparency==&lt;br /&gt;
Take all the transparent colors and add them up. Addition is commutative so the order doesn&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
This builds upon additive transparency with two buffers:&lt;br /&gt;
1. Accum buffer: weighted average of all premultiplied-alpha RGB colors.&lt;br /&gt;
2. Revealage buffer: buffer representing how much of the opaque background is visible through the transparent layers.&lt;br /&gt;
&lt;br /&gt;
==Dual Depth Peeling==&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7176</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7176"/>
		<updated>2025-10-08T21:06:49Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
==Dual Depth Peeling==&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Per-Pixel Linked Lists==&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7175</id>
		<title>Order independent transparency</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Order_independent_transparency&amp;diff=7175"/>
		<updated>2025-10-08T21:06:36Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Methods for order independent transparency&lt;br /&gt;
&lt;br /&gt;
==Weighted Blended Order Independent Transparency==&lt;br /&gt;
See http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html&lt;br /&gt;
&lt;br /&gt;
==Dual Depth Peeling==&lt;br /&gt;
https://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf&lt;br /&gt;
&lt;br /&gt;
==Stochastic Transparency==&lt;br /&gt;
https://research.nvidia.com/publication/2011-08_stochastic-transparency&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Dyson_Cordless_Vacuum&amp;diff=7174</id>
		<title>Dyson Cordless Vacuum</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Dyson_Cordless_Vacuum&amp;diff=7174"/>
		<updated>2025-09-14T18:55:31Z</updated>

		<summary type="html">&lt;p&gt;David: Created page with &amp;quot;https://www.techradar.com/home/vacuums/dyson-vacuum-tools-guide&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://www.techradar.com/home/vacuums/dyson-vacuum-tools-guide&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7173</id>
		<title>Tesla Model Y Sounds</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7173"/>
		<updated>2025-09-06T20:05:52Z</updated>

		<summary type="html">&lt;p&gt;David: /* Rear seat rattle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
List of resources to deal with rattle and creaking sounds in the Tesla Model Y.&lt;br /&gt;
&lt;br /&gt;
===Seat belt adjuster rattle===&lt;br /&gt;
&lt;br /&gt;
See https://www.youtube.com/watch?v=KctTaFCZhWE for the fix.&amp;lt;br&amp;gt;&lt;br /&gt;
This one works for me.&lt;br /&gt;
&lt;br /&gt;
===Rear seat rattle===&lt;br /&gt;
See https://www.youtube.com/watch?v=nn2mBrJVefo&lt;br /&gt;
&lt;br /&gt;
See https://www.reddit.com/r/ModelY/comments/1l1yhib/backseat_rattle_found/?share_id=GL0NVJwcQksqU9wUtxDnN&amp;amp;utm_medium=android_app&amp;amp;utm_name=androidcss&amp;amp;utm_source=share&amp;amp;utm_term=1&lt;br /&gt;
&lt;br /&gt;
===Hatch creaking===&lt;br /&gt;
&lt;br /&gt;
# Adjust the rubber bumpers&lt;br /&gt;
# https://www.youtube.com/watch?v=OBPwmvFn-5c&lt;br /&gt;
# For non-US cars, see https://teslamotorsclub.com/tmc/threads/creaking-tailgate-mobile-technician-visit.306684/page-2&lt;br /&gt;
&lt;br /&gt;
;Hatch rattle&lt;br /&gt;
In the hatch, there is a place where two metal pieces join along the bottom of the window. You can insert popsicle sticks there to prevent metal creaking.&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7172</id>
		<title>Tesla Model Y Sounds</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7172"/>
		<updated>2025-09-06T20:05:46Z</updated>

		<summary type="html">&lt;p&gt;David: /* Hatch creaking */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
List of resources to deal with rattle and creaking sounds in the Tesla Model Y.&lt;br /&gt;
&lt;br /&gt;
===Seat belt adjuster rattle===&lt;br /&gt;
&lt;br /&gt;
See https://www.youtube.com/watch?v=KctTaFCZhWE for the fix.&amp;lt;br&amp;gt;&lt;br /&gt;
This one works for me.&lt;br /&gt;
&lt;br /&gt;
===Rear seat rattle===&lt;br /&gt;
See https://www.youtube.com/watch?v=nn2mBrJVefo&lt;br /&gt;
See https://www.reddit.com/r/ModelY/comments/1l1yhib/backseat_rattle_found/?share_id=GL0NVJwcQksqU9wUtxDnN&amp;amp;utm_medium=android_app&amp;amp;utm_name=androidcss&amp;amp;utm_source=share&amp;amp;utm_term=1&lt;br /&gt;
&lt;br /&gt;
===Hatch creaking===&lt;br /&gt;
&lt;br /&gt;
# Adjust the rubber bumpers&lt;br /&gt;
# https://www.youtube.com/watch?v=OBPwmvFn-5c&lt;br /&gt;
# For non-US cars, see https://teslamotorsclub.com/tmc/threads/creaking-tailgate-mobile-technician-visit.306684/page-2&lt;br /&gt;
&lt;br /&gt;
;Hatch rattle&lt;br /&gt;
In the hatch, there is a place where two metal pieces join along the bottom of the window. You can insert popsicle sticks there to prevent metal creaking.&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7171</id>
		<title>Tesla Model Y Sounds</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7171"/>
		<updated>2025-09-06T20:05:37Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
List of resources to deal with rattle and creaking sounds in the Tesla Model Y.&lt;br /&gt;
&lt;br /&gt;
===Seat belt adjuster rattle===&lt;br /&gt;
&lt;br /&gt;
See https://www.youtube.com/watch?v=KctTaFCZhWE for the fix.&amp;lt;br&amp;gt;&lt;br /&gt;
This one works for me.&lt;br /&gt;
&lt;br /&gt;
===Rear seat rattle===&lt;br /&gt;
See https://www.youtube.com/watch?v=nn2mBrJVefo&lt;br /&gt;
See https://www.reddit.com/r/ModelY/comments/1l1yhib/backseat_rattle_found/?share_id=GL0NVJwcQksqU9wUtxDnN&amp;amp;utm_medium=android_app&amp;amp;utm_name=androidcss&amp;amp;utm_source=share&amp;amp;utm_term=1&lt;br /&gt;
&lt;br /&gt;
===Hatch creaking===&lt;br /&gt;
&lt;br /&gt;
# Adjust the rubber bumpers&lt;br /&gt;
# https://www.youtube.com/watch?v=OBPwmvFn-5c&lt;br /&gt;
# For non-US cars, see https://teslamotorsclub.com/tmc/threads/creaking-tailgate-mobile-technician-visit.306684/page-2&lt;br /&gt;
&lt;br /&gt;
# Hatch rattle&lt;br /&gt;
In the hatch, there is a place where two metal pieces join along the bottom of the window. You can insert popsicle sticks there to prevent metal creaking.&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7170</id>
		<title>Tesla Model Y Sounds</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Tesla_Model_Y_Sounds&amp;diff=7170"/>
		<updated>2025-09-06T20:04:35Z</updated>

		<summary type="html">&lt;p&gt;David: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
List of resources to deal with rattle and creaking sounds in the Tesla Model Y.&lt;br /&gt;
&lt;br /&gt;
===Seat belt adjuster rattle===&lt;br /&gt;
&lt;br /&gt;
See https://www.youtube.com/watch?v=KctTaFCZhWE for the fix.&amp;lt;br&amp;gt;&lt;br /&gt;
This one works for me.&lt;br /&gt;
&lt;br /&gt;
===Rear seat rattle===&lt;br /&gt;
https://www.youtube.com/watch?v=nn2mBrJVefo&lt;br /&gt;
&lt;br /&gt;
===Hatch creaking===&lt;br /&gt;
&lt;br /&gt;
# Adjust the rubber bumpers&lt;br /&gt;
# https://www.youtube.com/watch?v=OBPwmvFn-5c&lt;br /&gt;
# For non-US cars, see https://teslamotorsclub.com/tmc/threads/creaking-tailgate-mobile-technician-visit.306684/page-2&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=JavaScript&amp;diff=7169</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=JavaScript&amp;diff=7169"/>
		<updated>2025-07-16T20:06:42Z</updated>

		<summary type="html">&lt;p&gt;David: /* Useful Packages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;JavaScript is a single-threaded programming language. In the browser, JS is event-driven, meaning that after initialization, the JS engine is idle until an event occurs such as a button being pressed in the DOM.&lt;br /&gt;
&lt;br /&gt;
This page is a mostly about browser-based JavaScript or ECMAScript usage and interaction with the HTML DOM (window).&lt;br /&gt;
For server and desktop application JavaScript usage, please see the [[NodeJS]] page.&lt;br /&gt;
&lt;br /&gt;
==Language Syntax==&lt;br /&gt;
General Ecmascript syntax. Parts of this section applies to browser-side JS and server-side JS (Node.js, Deno), though details may vary between runtimes.&lt;br /&gt;
&lt;br /&gt;
===Regular Expressions (Regex)===&lt;br /&gt;
[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions MDN Guide]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const myRegex = /(\d+),(\d+)/;&lt;br /&gt;
const myStr = &amp;quot;124,52&amp;quot;;&lt;br /&gt;
const match = myStr.match(myRegex);&lt;br /&gt;
// Captures&lt;br /&gt;
console.log(match[1], match[2]);&lt;br /&gt;
console.table(match);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Classes===&lt;br /&gt;
Traditionally, classes are done using functions in JavaScript.&amp;lt;br&amp;gt;&lt;br /&gt;
{{hidden | Traditional JS Classes |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function Rectangle(height, width) {&lt;br /&gt;
  this.height = height;&lt;br /&gt;
  this.width = width;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// To extend some Shape class&lt;br /&gt;
Rectangle.prototype = Object.create(Shape.prototype);&lt;br /&gt;
// To add to the prototype&lt;br /&gt;
Object.assign(Rectangle.prototype, {&lt;br /&gt;
  constructor: Rectangle,&lt;br /&gt;
  getSize: function() {&lt;br /&gt;
    return this.height * this.width;&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes Mozilla Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
ES2015 adds syntax for classes in JavaScript.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
class Rectangle extends Shape {&lt;br /&gt;
  constructor(height, width) {&lt;br /&gt;
    this.height = height;&lt;br /&gt;
    this.width = width;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  getSize() {&lt;br /&gt;
    return this.height * this.width;  &lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Promises===&lt;br /&gt;
Added in ES2015 (ES6)&amp;lt;br&amp;gt;&lt;br /&gt;
See [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises]&amp;lt;br&amp;gt;&lt;br /&gt;
In general, a function returns a promise if it needs to perform asyncronous tasks.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function myFunc() {&lt;br /&gt;
  // Do syncronous things here&lt;br /&gt;
  return new Promise((resolve, reject) =&amp;gt; {&lt;br /&gt;
    // Do asyncronous things here&lt;br /&gt;
    // Return data&lt;br /&gt;
    resolve(myData);&lt;br /&gt;
    // Or if we have an error&lt;br /&gt;
    reject(myError);&lt;br /&gt;
  });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
myFunc()&lt;br /&gt;
  .then(data =&amp;gt; {&lt;br /&gt;
     console.log(data);&lt;br /&gt;
  }).catch(err =&amp;gt; {&lt;br /&gt;
     console.error(err);&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Async-await===&lt;br /&gt;
Added in ES2017&lt;br /&gt;
&lt;br /&gt;
See [https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await Async_await]&amp;lt;br&amp;gt;&lt;br /&gt;
Async functions return implicit promises. They allow you to use keyword &amp;lt;code&amp;gt;await&amp;lt;/code&amp;gt; to get results from other promises or functions.&lt;br /&gt;
&lt;br /&gt;
===Enums===&lt;br /&gt;
See [https://stackoverflow.com/questions/287903/what-is-the-preferred-syntax-for-defining-enums-in-javascript Stack overflow]&lt;br /&gt;
&lt;br /&gt;
Ecmascript doesn&#039;t have a built-in way to define ENUMS. One way is to use &amp;lt;code&amp;gt;Object.freeze&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
const WORKERSTATUS = Object.freeze({&lt;br /&gt;
  ACTIVE: &amp;quot;ACTIVE&amp;quot;,&lt;br /&gt;
  DISABLED: &amp;quot;DISABLED&amp;quot;,&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Notes&lt;br /&gt;
* This does not enforce any kind of type. If you need that, use [https://www.typescriptlang.org/docs/handbook/enums.html typescript enums].&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt;===&lt;br /&gt;
* &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; is the old way of declaring variables. It has function-scope rather than block-scope. Note that &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; can also be redefined which can hide errors.&lt;br /&gt;
* &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; are post-ES6 ways which have block-scope.&lt;br /&gt;
&lt;br /&gt;
These days you should never use &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt;.  &lt;br /&gt;
The Google [https://google.github.io/styleguide/jsguide.html JS Style Guide] and [https://google.github.io/styleguide/tsguide.html TS Style Guide] suggest using &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; by default.&lt;br /&gt;
&lt;br /&gt;
==Browser Usage==&lt;br /&gt;
For basic dom manipulation, see [https://htmldom.dev/ https://htmldom.dev/].&lt;br /&gt;
&lt;br /&gt;
===Inputs===&lt;br /&gt;
&lt;br /&gt;
====Showing an input image====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const myInput = document.getElementById(&amp;quot;myInput&amp;quot;);&lt;br /&gt;
const myImage = document.getElementById(&amp;quot;myImage&amp;quot;);&lt;br /&gt;
myInput.addEventListener(&#039;change&#039;, function() {&lt;br /&gt;
    if (myInput.files.length !== 1) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    let image = myInput.files[0];&lt;br /&gt;
    const reader = new FileReader();&lt;br /&gt;
    reader.onload = function(e) {&lt;br /&gt;
        myImage.src = e.target.result;&lt;br /&gt;
    };&lt;br /&gt;
    reader.readAsDataURL(image);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Canvas===&lt;br /&gt;
&lt;br /&gt;
===Picture===&lt;br /&gt;
&lt;br /&gt;
===Video===&lt;br /&gt;
Your HTML:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;video id=&amp;quot;myVideoElt&amp;quot; controls&amp;gt;&lt;br /&gt;
&amp;lt;/video&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Your JS:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const myVideo = document.getElementById(&amp;quot;myVideoElt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Create a new source&lt;br /&gt;
const newSource = document.createElement(&amp;quot;source&amp;quot;);&lt;br /&gt;
const myVideoUrl = &amp;quot;https://interactive-examples.mdn.mozilla.net/media/examples/flower.webm&amp;quot;;&lt;br /&gt;
newSource.setAttribute(&amp;quot;src&amp;quot;, myVideoUrl);&lt;br /&gt;
myVideo.appendChild(newSource);&lt;br /&gt;
myVideo.play();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Compilation==&lt;br /&gt;
===Webpack===&lt;br /&gt;
===Babel===&lt;br /&gt;
&lt;br /&gt;
==Websockets==&lt;br /&gt;
How to use Websockets&lt;br /&gt;
===Getting Started===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
let ws = new WebSocket(this.SERVER_URL);&lt;br /&gt;
ws.onopen = function(event) {&lt;br /&gt;
   console.log(&amp;quot;Websocket opened&amp;quot;);&lt;br /&gt;
   ws.send(&amp;quot;Hi&amp;quot;);&lt;br /&gt;
};&lt;br /&gt;
ws.onmessage = function(event) {&lt;br /&gt;
   console.log(&amp;quot;message received&amp;quot;);&lt;br /&gt;
   console.log(event.data);&lt;br /&gt;
};&lt;br /&gt;
ws.onclose = function() {&lt;br /&gt;
   console.log(&amp;quot;WS Closed&amp;quot;);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Data Structures==&lt;br /&gt;
JavaScript traditionally has arrays and objects (hashmap) data structures.&amp;lt;br&amp;gt;&lt;br /&gt;
ES2015 (ES6) adds several collections including: Map, Set, WeakMap, WeakSet&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.sitepoint.com/es6-collections-map-set-weakmap-weakset/ ES6 Collections]&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
let arr = [1,2,3];&lt;br /&gt;
&lt;br /&gt;
// Map&lt;br /&gt;
arr.map(x =&amp;gt; x &amp;gt; 2); // [false, false, true]&lt;br /&gt;
&lt;br /&gt;
// Reduce or Fold&lt;br /&gt;
// Note that if you do not provide an initial accumulator,&lt;br /&gt;
// then the first element will be your accumulator&lt;br /&gt;
// I.e. the first call to your function will be (arr[0], arr[1])&lt;br /&gt;
arr.reduce((acc, x) =&amp;gt; acc + x, 0); // 6&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Objects===&lt;br /&gt;
Objects are maps in JavaScript. They are typically implemented as hashmaps by the JS engine.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that you can only use numbers and strings as keys.&amp;lt;br&amp;gt;&lt;br /&gt;
Learn more about the implementation at [https://v8.dev/blog/hash-code https://v8.dev/blog/hash-code]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
let my_map = {};&lt;br /&gt;
// or my_map[&amp;quot;my_key&amp;quot;]&lt;br /&gt;
my_map.my_key = &amp;quot;my_value&amp;quot;;&lt;br /&gt;
&amp;quot;my_key&amp;quot; in my_map;&lt;br /&gt;
&lt;br /&gt;
// Loop over keys&lt;br /&gt;
for (let key in a) {&lt;br /&gt;
  console.log(&amp;quot;Key:&amp;quot;, key);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Map===&lt;br /&gt;
[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map MDN Map]  &lt;br /&gt;
[https://www.ecma-international.org/ecma-262/10.0/index.html#sec-map-objects ES2019 (ES10) Map Specification]  &lt;br /&gt;
This is your typical hashmap.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
let myMap = new Map();&lt;br /&gt;
&lt;br /&gt;
let keyObj = {};&lt;br /&gt;
&lt;br /&gt;
// Set value&lt;br /&gt;
myMap.set(keyObj, &#039;value associated with keyObj&#039;);&lt;br /&gt;
&lt;br /&gt;
// Get size&lt;br /&gt;
myMap.size;&lt;br /&gt;
&lt;br /&gt;
// Get value&lt;br /&gt;
myMap.get(keyObj);&lt;br /&gt;
&lt;br /&gt;
// Check if key is in the map&lt;br /&gt;
myMap.has(keyObj);&lt;br /&gt;
&lt;br /&gt;
// Delete&lt;br /&gt;
myMap.delete(keyObj);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* You can mix and match types of keys&lt;br /&gt;
* The hash for objects are randomly generated under the hood&lt;br /&gt;
* Do not use &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; to get or set from the map&lt;br /&gt;
* Iterating over a Map will be in order of insertion&lt;br /&gt;
&lt;br /&gt;
;Saving as json&lt;br /&gt;
See [https://2ality.com/2015/08/es6-map-json.html es6 map json]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const data = JSON.stringify([...myMap]);&lt;br /&gt;
myMap = new Map(JSON.parse(data));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set===&lt;br /&gt;
[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set MDN Set]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
let my_set = new Set();&lt;br /&gt;
&lt;br /&gt;
// Returns the set itself&lt;br /&gt;
my_set.add(key);&lt;br /&gt;
&lt;br /&gt;
my_set.has(key);&lt;br /&gt;
&lt;br /&gt;
my_set.clear();&lt;br /&gt;
&lt;br /&gt;
// Returns true if key was in the set&lt;br /&gt;
my_set.delete(key);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===WeakMap===&lt;br /&gt;
Unlike map, weakmap holds weak references to its keys. This allows keys to be garbage collected when no reference to it remains.&lt;br /&gt;
Note that once keys are garbage collected, they are also removed from the weakmap since you can no longer access them.&lt;br /&gt;
You can not iterate through a weakmap.&lt;br /&gt;
&lt;br /&gt;
===WeakSet===&lt;br /&gt;
&lt;br /&gt;
==WebXR==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Check for VR support&lt;br /&gt;
if (&amp;quot;xr&amp;quot; in navigator &amp;amp;&amp;amp; &amp;quot;isSessionSupported&amp;quot; in navigator.xr) {&lt;br /&gt;
  navigator.xr.isSessionSupported(&#039;immersive-vr&#039;).then((supported) =&amp;gt; {&lt;br /&gt;
    console.log(&amp;quot;immersive-vr supported:&amp;quot;, supported);&lt;br /&gt;
  });&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Modules==&lt;br /&gt;
These days, we can use modules for everything.  &lt;br /&gt;
Note that in most instances, you should compile these using Webpack, browserify or similar.  &lt;br /&gt;
For Node.js, you will need to transpile using Babel.  &lt;br /&gt;
&lt;br /&gt;
However some modern browsers now support importing modules directly using script tags.  &lt;br /&gt;
&lt;br /&gt;
* [[Caniuse: Modules]]&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules MDN Guide to Modules]&lt;br /&gt;
&lt;br /&gt;
Example Module&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Import three.js as a module. webpack will resolve this.&lt;br /&gt;
import * as THREE from &#039;three&#039;;&lt;br /&gt;
// Import MyClass as a module. webpack will resolve this.&lt;br /&gt;
import {MyClass} from &amp;quot;./MyClass.js&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Pretend we&#039;re writing another class&lt;br /&gt;
export class MyOtherClass {&lt;br /&gt;
  constructor() {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* The Google style guide suggests always using named exports rather than using &amp;lt;code&amp;gt;export default&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Web Workers==&lt;br /&gt;
By default, JavaScript is a single-threaded language. For things that take a long time, people usually use asynchronous JS through promises and callbacks. However, if you have a heavy calculation that needs to be performed, you can use spawn web workers which will run in background threads. NodeJS also has a similar concept called [https://nodejs.org/api/worker_threads.html Worker Threads].&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
&lt;br /&gt;
;Your main JS file:&lt;br /&gt;
&lt;br /&gt;
;Your worker JS file:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Resources&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers MDN: Using web workers]&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API Web Workers API]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Documentation==&lt;br /&gt;
Use [https://jsdoc.app/ JSDoc] for documentation.  &lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
Frameworks for testing JS:&lt;br /&gt;
* [https://jestjs.io/ https://jestjs.io/]&lt;br /&gt;
&lt;br /&gt;
==Useful Packages==&lt;br /&gt;
Packages which run in the browser and may be useful for developing web applications.&lt;br /&gt;
Note that some of these may overlap with the NodeJS page.&lt;br /&gt;
&lt;br /&gt;
===lerp, clamp===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm i lerp clamp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
Math.lerp = require(&amp;quot;lerp&amp;quot;);&lt;br /&gt;
Math.clamp = require(&amp;quot;clamp&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===pako===&lt;br /&gt;
[https://github.com/nodeca/pako pako github]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;zlib port to javascript, very fast!&amp;quot;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm install pako&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===url-join===&lt;br /&gt;
Basically &amp;lt;code&amp;gt;path.join&amp;lt;/code&amp;gt; for the browser.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm install url-join&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===mathjs===&lt;br /&gt;
[https://mathjs.org/ https://mathjs.org/]&amp;lt;br&amp;gt;&lt;br /&gt;
Some useful math things for JavaScript in the browser and in NodeJS&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm install mathjs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming languages]]&lt;br /&gt;
&lt;br /&gt;
==Misc==&lt;br /&gt;
* [[Javascript CDNs]]&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Javascript_CDNs&amp;diff=7168</id>
		<title>Javascript CDNs</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Javascript_CDNs&amp;diff=7168"/>
		<updated>2025-07-16T20:03:33Z</updated>

		<summary type="html">&lt;p&gt;David: Created page with &amp;quot; List of free CDNs for open source JS libraries:  ==NPM CDNs== * https://www.jsdelivr.com/ * https://unpkg.com/ * https://www.skypack.dev/  ==Github CDNs== * https://statically.io/ * https://www.jsdelivr.com/github * https://raw.githack.com/&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
List of free CDNs for open source JS libraries:&lt;br /&gt;
&lt;br /&gt;
==NPM CDNs==&lt;br /&gt;
* https://www.jsdelivr.com/&lt;br /&gt;
* https://unpkg.com/&lt;br /&gt;
* https://www.skypack.dev/&lt;br /&gt;
&lt;br /&gt;
==Github CDNs==&lt;br /&gt;
* https://statically.io/&lt;br /&gt;
* https://www.jsdelivr.com/github&lt;br /&gt;
* https://raw.githack.com/&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Email_Routing&amp;diff=7167</id>
		<title>Email Routing</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Email_Routing&amp;diff=7167"/>
		<updated>2025-07-16T04:07:43Z</updated>

		<summary type="html">&lt;p&gt;David: /* Sending */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Two services for email routing.&lt;br /&gt;
&lt;br /&gt;
==Cloudflare Email Routing==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://forwardemail.net forwardemail.net]==&lt;br /&gt;
If you don&#039;t use cloudflare, you can use https://forwardemail.com instead.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that their free plan requires you to put all the emails into a txt dns entry.&lt;br /&gt;
&lt;br /&gt;
==Sending==&lt;br /&gt;
&lt;br /&gt;
===Setting up send from===&lt;br /&gt;
You can send from your gmail by doing the following:&lt;br /&gt;
# Update your TXT dns record to&lt;br /&gt;
#: &amp;lt;pre&amp;gt;v=spf1 include:_spf.mx.cloudflare.net include:_spf.google.com ~all&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Follow https://gist.github.com/irazasyed/a5ca450f1b1b8a01e092b74866e9b2f1&lt;br /&gt;
&lt;br /&gt;
This drawback is that this requies an app password on your Google account and the email does not pass DKIM.&lt;br /&gt;
&lt;br /&gt;
===Mailjet===&lt;br /&gt;
See https://mailjet.com.&lt;br /&gt;
Mailjet&#039;s free plan allows sending 200 emails per day or 6000 per month.&lt;br /&gt;
&lt;br /&gt;
===Purelymail===&lt;br /&gt;
[https://purelymail.com Purelymail] is a $10 per year email service.&lt;br /&gt;
&lt;br /&gt;
===Validation===&lt;br /&gt;
Use https://www.mail-tester.com/&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Email_Routing&amp;diff=7166</id>
		<title>Email Routing</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Email_Routing&amp;diff=7166"/>
		<updated>2025-07-16T03:53:31Z</updated>

		<summary type="html">&lt;p&gt;David: /* Sending */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Two services for email routing.&lt;br /&gt;
&lt;br /&gt;
==Cloudflare Email Routing==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://forwardemail.net forwardemail.net]==&lt;br /&gt;
If you don&#039;t use cloudflare, you can use https://forwardemail.com instead.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that their free plan requires you to put all the emails into a txt dns entry.&lt;br /&gt;
&lt;br /&gt;
==Sending==&lt;br /&gt;
&lt;br /&gt;
===Setting up send from===&lt;br /&gt;
You can send from your gmail by doing the following:&lt;br /&gt;
# Update your TXT dns record to&lt;br /&gt;
#: &amp;lt;pre&amp;gt;v=spf1 include:_spf.mx.cloudflare.net include:_spf.google.com ~all&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Follow https://gist.github.com/irazasyed/a5ca450f1b1b8a01e092b74866e9b2f1&lt;br /&gt;
&lt;br /&gt;
This drawback is that this requies an app password on your Google account and the email does not pass DKIM.&lt;br /&gt;
&lt;br /&gt;
===Mailjet===&lt;br /&gt;
See https://mailjet.com&lt;br /&gt;
&lt;br /&gt;
===Purelymail===&lt;br /&gt;
[https://purelymail.com Purelymail] is a $10 per year email service.&lt;br /&gt;
&lt;br /&gt;
===Validation===&lt;br /&gt;
Use https://www.mail-tester.com/&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Email_Routing&amp;diff=7165</id>
		<title>Email Routing</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Email_Routing&amp;diff=7165"/>
		<updated>2025-07-16T02:41:18Z</updated>

		<summary type="html">&lt;p&gt;David: /* Sending */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Two services for email routing.&lt;br /&gt;
&lt;br /&gt;
==Cloudflare Email Routing==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://forwardemail.net forwardemail.net]==&lt;br /&gt;
If you don&#039;t use cloudflare, you can use https://forwardemail.com instead.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that their free plan requires you to put all the emails into a txt dns entry.&lt;br /&gt;
&lt;br /&gt;
==Sending==&lt;br /&gt;
&lt;br /&gt;
===Setting up send from===&lt;br /&gt;
You can send from your gmail by doing the following:&lt;br /&gt;
# Update your TXT dns record to&lt;br /&gt;
#: &amp;lt;pre&amp;gt;v=spf1 include:_spf.mx.cloudflare.net include:_spf.google.com ~all&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Follow https://gist.github.com/irazasyed/a5ca450f1b1b8a01e092b74866e9b2f1&lt;br /&gt;
&lt;br /&gt;
This drawback is that this requies an app password on your Google account and the email does not pass DKIM.&lt;br /&gt;
&lt;br /&gt;
===Purelymail===&lt;br /&gt;
[https://purelymail.com Purelymail] is a $10 per year email service.&lt;br /&gt;
&lt;br /&gt;
===Validation===&lt;br /&gt;
Use https://www.mail-tester.com/&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Linux&amp;diff=7164</id>
		<title>Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Linux&amp;diff=7164"/>
		<updated>2025-06-25T06:59:25Z</updated>

		<summary type="html">&lt;p&gt;David: /* Fix time difference between Windows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A collection of notes on using Linux systems.&lt;br /&gt;
Notes here are for Ubuntu but should work on similar debian derivative distros.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Basic Terminal Commands==&lt;br /&gt;
{{see also | Bash (Unix shell)}}&lt;br /&gt;
===List===&lt;br /&gt;
&amp;lt;code&amp;gt;ls&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;-l&amp;lt;/code&amp;gt; shows long format&lt;br /&gt;
* &amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt; shows all files including hidden files, current directory &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;, and parent directory &amp;lt;code&amp;gt;..&amp;lt;/code&amp;gt;.&lt;br /&gt;
** &amp;lt;code&amp;gt;-A&amp;lt;/code&amp;gt; omits &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;..&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt; human readable file sizes&lt;br /&gt;
* &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; shows blocks taken up by the file (i.e. size on disk)&lt;br /&gt;
&lt;br /&gt;
There are also other commands like &amp;lt;code&amp;gt;lsblk&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;lscpu&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;lshw&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Disk Space===&lt;br /&gt;
* &amp;lt;code&amp;gt;du&amp;lt;/code&amp;gt; Disk Usage&lt;br /&gt;
** &amp;lt;code&amp;gt;du -sh&amp;lt;/code&amp;gt; Show size of current directory&lt;br /&gt;
** &amp;lt;code&amp;gt;du -h --max-depth=1&amp;lt;/code&amp;gt; Show size of files and folders in current directory. I have &amp;lt;code&amp;gt;du&amp;lt;/code&amp;gt; aliased to this.&lt;br /&gt;
** Flags:&lt;br /&gt;
*** &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt; human readable (adds M or G)&lt;br /&gt;
*** &amp;lt;code&amp;gt;--max-depth&amp;lt;/code&amp;gt; depth to recurse. Default is &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;df&amp;lt;/code&amp;gt; Disk Filesystems&lt;br /&gt;
** Shows usage, total space available, and mount position&lt;br /&gt;
** &amp;lt;code&amp;gt; df -Ph .&amp;lt;/code&amp;gt; See free space in current directory&lt;br /&gt;
&lt;br /&gt;
If looking to free up space, I recommend installing &amp;lt;code&amp;gt;ncdu&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Monitoring===&lt;br /&gt;
* &amp;lt;code&amp;gt;htop&amp;lt;/code&amp;gt; - basic terminal system monitor, enhanced version of &amp;lt;code&amp;gt;top&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;watch -n 0.5 &amp;lt;program&amp;gt;&amp;lt;/code&amp;gt; - repeatedly call &amp;lt;program&amp;gt; every 0.5 seconds&lt;br /&gt;
&lt;br /&gt;
===Standard Streams===&lt;br /&gt;
* &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; will pipe stdout to the stdin of another process&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; will redirect stdout to a file&lt;br /&gt;
* &amp;lt;code&amp;gt;2&amp;gt;&amp;amp;1&amp;lt;/code&amp;gt; will redirect stderr (2) to stdout (1)&lt;br /&gt;
* [https://www.gnu.org/software/coreutils/manual/html_node/tee-invocation.html &amp;lt;code&amp;gt;tee&amp;lt;/code&amp;gt;] will redirect stdout to multiple files and show it in the terminal&lt;br /&gt;
&lt;br /&gt;
===Shutdown===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
shutdown -h [now | -t &amp;lt;time&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt; poweroff, the default&lt;br /&gt;
* &amp;lt;code&amp;gt;-t time&amp;lt;/code&amp;gt; schedule a shutdown in &#039;&#039;time&#039;&#039; seconds&lt;br /&gt;
* &amp;lt;code&amp;gt;-r&amp;lt;/code&amp;gt; restart&lt;br /&gt;
* &amp;lt;code&amp;gt;-c&amp;lt;/code&amp;gt; cancel pending shutdown&lt;br /&gt;
&lt;br /&gt;
==Package Management==&lt;br /&gt;
See [https://www.digitalocean.com/community/tutorials/package-management-basics-apt-yum-dnf-pkg DigitalOcean: Package management basics]&lt;br /&gt;
&lt;br /&gt;
===apt===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# List all installed packages&lt;br /&gt;
apt list --installed&lt;br /&gt;
&lt;br /&gt;
# Search repos for package&lt;br /&gt;
apt search libdpkg-dev&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Repositories&lt;br /&gt;
Repository sources are saved in&lt;br /&gt;
* A line in &amp;lt;code&amp;gt;/etc/apt/sources.list&amp;lt;/code&amp;gt;&lt;br /&gt;
* A file in &amp;lt;code&amp;gt;/etc/apt/sources.list.d/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Application desktop icons are stored in &amp;lt;code&amp;gt;/usr/share/applications/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The update notifications are in &amp;lt;code&amp;gt;/etc/apt/apt.conf.d/99update-notifier&amp;lt;/code&amp;gt;. Comment these out to disable them.&amp;lt;br&amp;gt;&lt;br /&gt;
Unattended-updates are in &amp;lt;code&amp;gt;/etc/apt/apt.conf.d/50unattended-upgrades&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{hidden | dpkg |&lt;br /&gt;
===dpkg===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# List everything&lt;br /&gt;
sudo dpkg -l&lt;br /&gt;
&lt;br /&gt;
# List things with apache in the name&lt;br /&gt;
sudo dpkg -l | grep apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{hidden | yum |&lt;br /&gt;
===yum===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Update package lists, typically not necessary&lt;br /&gt;
yum check-update&lt;br /&gt;
&lt;br /&gt;
# Upgrade packages&lt;br /&gt;
yum update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==SSH==&lt;br /&gt;
===SSH Keys===&lt;br /&gt;
Generate an ssh-key for every client&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -t ed25519 [-C &amp;quot;comment your client name&amp;quot;] [-f output_path]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some older software such as Solid file explorer require RSA keys in PEM key format&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -t rsa -b 4096 -m PEM [-C &amp;quot;comment your client name&amp;quot;] [-f output_path]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also convert existing keys to PEM format&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -p -m PEM [-C &amp;quot;comment your client name&amp;quot;] [-f output_path]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to change the comment on your key&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -c -C &amp;quot;New comment&amp;quot; -f path_to_key&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manage ssh keys&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# On the client&lt;br /&gt;
ssh-copy-id &amp;lt;host&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# On the server&lt;br /&gt;
vim ~/.ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
* According to [https://security.stackexchange.com/questions/143442/what-are-ssh-keygen-best-practices this] you should avoid using ECDSA and DSA keys.&lt;br /&gt;
&lt;br /&gt;
===Disable password authentication===&lt;br /&gt;
# Edit &amp;lt;code&amp;gt;/etc/ssh/sshd_config&amp;lt;/code&amp;gt;&lt;br /&gt;
# Set &amp;lt;code&amp;gt;PasswordAuthentication&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;&lt;br /&gt;
# Set &amp;lt;code&amp;gt;ChallengeResponseAuthentication&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;&lt;br /&gt;
# Test by ssh&#039;ing into the machine using &amp;lt;code&amp;gt;-o PreferredAuthentications=password -o PubkeyAuthentication=no&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Port Forwarding===&lt;br /&gt;
Also known as: SSH Tunneling, SSH Proxy, SSH Reverse Proxy&lt;br /&gt;
&lt;br /&gt;
If you need to access a port on the remote computer, you can use the &amp;lt;code&amp;gt;-L&amp;lt;/code&amp;gt; option to forward ports from the remote to the local machine.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -L &amp;lt;localport&amp;gt;:localhost:&amp;lt;remoteport&amp;gt; &amp;lt;remoteurl&amp;gt;&lt;br /&gt;
# E.g. ssh -L 8080:localhost:80 david@davidl.me&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the reverse, giving the remote access to a local port using &amp;lt;code&amp;gt;-R&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -R &amp;lt;localport&amp;gt;:host:&amp;lt;remoteport&amp;gt; &amp;lt;remoteurl&amp;gt;&lt;br /&gt;
# E.g. ssh -R 8080:localhost:80 david@davidl.me&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* You can also run this without creating a shell using &amp;lt;code&amp;gt;-N&amp;lt;/code&amp;gt;. This will block your shell. See [https://unix.stackexchange.com/questions/100859/ssh-tunnel-without-shell-on-ssh-server SE Answer].&lt;br /&gt;
* Adding &amp;lt;code&amp;gt;-f&amp;lt;/code&amp;gt; pushes ssh to the background.&lt;br /&gt;
** This will implicitly add &amp;lt;code&amp;gt;-n&amp;lt;/code&amp;gt; which redirects &amp;lt;code&amp;gt;stdin&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;/dev/null&amp;lt;/code&amp;gt;.&lt;br /&gt;
** If you want to be able to foreground this again, the use &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt; or &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt;+&amp;lt;kbd&amp;gt;z&amp;lt;/kbd&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
===alias===&lt;br /&gt;
You can create aliases in your &amp;lt;code&amp;gt;.ssh/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host my_alias&lt;br /&gt;
  User my_username&lt;br /&gt;
  Hostname my_server@my_domain.com&lt;br /&gt;
  Port 52&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==VNC==&lt;br /&gt;
===x11vnc===&lt;br /&gt;
[https://askubuntu.com/questions/1033274/ubuntu-18-04-connect-to-login-screen-over-vnc Reference]&lt;br /&gt;
&lt;br /&gt;
I recommend not exposing VNC. Set it to localhost only and use ssh port forwarding.&lt;br /&gt;
&lt;br /&gt;
===Remmina===&lt;br /&gt;
If using a wired connection, you can save a preset to &amp;lt;code&amp;gt;localhost:5901&amp;lt;/code&amp;gt; or similar.&lt;br /&gt;
&lt;br /&gt;
Note that the Remmina which ships with Ubuntu 18.04 is outdated and buggy.&lt;br /&gt;
You can upgrade it by adding the Remmina PPA.&lt;br /&gt;
See [https://remmina.org/how-to-install-remmina/ https://remmina.org/how-to-install-remmina/] for details.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-add-repository ppa:remmina-ppa-team/remmina-next&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install remmina remmina-plugin-rdp remmina-plugin-secret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Nvidia==&lt;br /&gt;
&lt;br /&gt;
===Driver Installation===&lt;br /&gt;
# Run &amp;lt;code&amp;gt;ubuntu-drivers list&amp;lt;/code&amp;gt; to get a list of drivers&lt;br /&gt;
# Install the latest driver&lt;br /&gt;
#* E.g. &amp;lt;code&amp;gt;sudo apt install nvidia-driver-460&amp;lt;/code&amp;gt;&lt;br /&gt;
# If you have secure boot enabled, you will be asked for a password during installation&lt;br /&gt;
#* This is because the driver is a DKMS module.&lt;br /&gt;
#* After installation, reboot your computer and select &amp;quot;Enroll MOK&amp;quot; and enter that password in.&lt;br /&gt;
#* &#039;&#039;&#039;Note&#039;&#039;&#039; Failure to do this will result in the driver not working&lt;br /&gt;
# Validate your installation by running &amp;lt;code&amp;gt;nvidia-smi&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* &amp;lt;code&amp;gt;nvidia-smi&amp;lt;/code&amp;gt; shows the latest cuda version supported by the driver, not the cuda version installed.&lt;br /&gt;
&lt;br /&gt;
===Cuda Installation===&lt;br /&gt;
Download cuda from the nvidia website or add the cuda repo to your apt sources.&lt;br /&gt;
&lt;br /&gt;
===Switching between Nvidia and Intel===&lt;br /&gt;
[https://www.linuxbabe.com/desktop-linux/switch-intel-nvidia-graphics-card-ubuntu Reference]&lt;br /&gt;
&lt;br /&gt;
Make sure the Nvidia graphics drivers are installed. Then you can select between Nvidia and Intel GPUs using the Nvidia X Server Settings application &amp;lt;code&amp;gt;nvidia-settings&amp;lt;/code&amp;gt;. Alternatively, you can use the following commands in the terminal.&amp;lt;br&amp;gt;&lt;br /&gt;
To switch to the Nvidia GPU:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo prime-select nvidia&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
To switch back to the Intel GPU:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo prime-select intel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;prime-select query&amp;lt;/code&amp;gt; will print either &amp;lt;code&amp;gt;nvidia&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;intel&amp;lt;/code&amp;gt; to stdout.&lt;br /&gt;
&lt;br /&gt;
===Fix tearing on laptops===&lt;br /&gt;
[https://ubuntuhandbook.org/index.php/2018/07/fix-screen-tearing-ubuntu-18-04-optimus-laptops/ Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
# Add &amp;lt;code&amp;gt;options nvidia-drm modeset=1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;/etc/modprobe.d/nvidia-drm-nomodeset.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
# Run &amp;lt;code&amp;gt;sudo update-initramfs -u&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Environment Variables==&lt;br /&gt;
[https://help.ubuntu.com/community/EnvironmentVariables Ubuntu Help Reference]&lt;br /&gt;
&lt;br /&gt;
==Tmux==&lt;br /&gt;
[https://tmuxcheatsheet.com/ Tmux cheat sheet]&lt;br /&gt;
&lt;br /&gt;
Tmux, or Terminal Multiplexer is an alternative to screen.&amp;lt;br&amp;gt;&lt;br /&gt;
Use it to keep terminals open and tasks running after you disconnect your SSH connection.&amp;lt;br&amp;gt;&lt;br /&gt;
Getting Started:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make a new session&lt;br /&gt;
tmux&lt;br /&gt;
# Make a new named session&lt;br /&gt;
tmux new -s my_session&lt;br /&gt;
# Rename a session&lt;br /&gt;
# Keybinding: Ctrl + b, $&lt;br /&gt;
tmux rename-session [-t current-name] [new-name]&lt;br /&gt;
# Detach from a session&lt;br /&gt;
# Keybinding: Ctrl + b, d&lt;br /&gt;
tmux detach&lt;br /&gt;
# List windows&lt;br /&gt;
tmux ls&lt;br /&gt;
# Attach to a session&lt;br /&gt;
tmux attach -t my_session&lt;br /&gt;
# Renumber windows&lt;br /&gt;
:movew&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mouse scrolling===&lt;br /&gt;
Set &amp;lt;code&amp;gt;set -g mouse on&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;~/.tmux.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Manager==&lt;br /&gt;
The default file manager in Ubuntu is Nautilus&lt;br /&gt;
&lt;br /&gt;
===Add to context menu===&lt;br /&gt;
[https://askubuntu.com/questions/1030940/nautilus-actions-in-18-04 AskUbuntu]&lt;br /&gt;
&lt;br /&gt;
;22.04&lt;br /&gt;
See [https://github.com/harry-cpp/code-nautilus https://github.com/harry-cpp/code-nautilus]&lt;br /&gt;
&lt;br /&gt;
;20.04&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo add-apt-repository universe&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install filemanager-actions nautilus-actions nautilus-extension-fma&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Etcher==&lt;br /&gt;
[https://github.com/balena-io/etcher Github]&amp;lt;br&amp;gt;&lt;br /&gt;
Installing etcher&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;deb https://deb.etcher.io stable etcher&amp;quot; | sudo tee /etc/apt/sources.list.d/balena-etcher.list&lt;br /&gt;
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install balena-etcher-electron&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Logs==&lt;br /&gt;
Logs are stored under &amp;lt;code&amp;gt;/var/log&amp;lt;/code&amp;gt;. These can end up taking up a lot of space.&amp;lt;br&amp;gt;&lt;br /&gt;
You can delete logs in the journal folder [https://unix.stackexchange.com/questions/130786/can-i-remove-files-in-var-log-journal-and-var-cache-abrt-di-usr Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Default gcc/g++ version==&lt;br /&gt;
See [https://askubuntu.com/questions/26498/how-to-choose-the-default-gcc-and-g-version https://askubuntu.com/questions/26498/how-to-choose-the-default-gcc-and-g-version].&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Install&lt;br /&gt;
sudo update-alternatives --remove-all gcc &lt;br /&gt;
sudo update-alternatives --remove-all g++&lt;br /&gt;
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 10&lt;br /&gt;
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 20&lt;br /&gt;
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 10&lt;br /&gt;
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 20&lt;br /&gt;
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30&lt;br /&gt;
sudo update-alternatives --set cc /usr/bin/gcc&lt;br /&gt;
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30&lt;br /&gt;
sudo update-alternatives --set c++ /usr/bin/g++&lt;br /&gt;
&lt;br /&gt;
# Select&lt;br /&gt;
sudo update-alternatives --config gcc&lt;br /&gt;
sudo update-alternatives --config g++&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Power Management==&lt;br /&gt;
===tlp===&lt;br /&gt;
[https://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html Website]&amp;lt;br&amp;gt;&lt;br /&gt;
Battery power management&lt;br /&gt;
&lt;br /&gt;
==Virtual Machines (VM)==&lt;br /&gt;
===Guest VMs===&lt;br /&gt;
Using Ubuntu as a guest:&lt;br /&gt;
* Install &amp;lt;code&amp;gt;open-vm-tools-desktop&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===KVM===&lt;br /&gt;
{{main | Archwiki: KVM}}&lt;br /&gt;
&lt;br /&gt;
===Docker===&lt;br /&gt;
{{main | Docker (software)}}&lt;br /&gt;
&lt;br /&gt;
==Services and Scheduling==&lt;br /&gt;
===crontab===&lt;br /&gt;
The following will open a list of cron jobs you have.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
crontab -e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The default editor is nano. You can change it to vim using &amp;lt;code&amp;gt;VISUAL=vim&amp;lt;/code&amp;gt; env variable or with &amp;lt;code&amp;gt;select-editor&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===systemd service===&lt;br /&gt;
See [https://wiki.debian.org/systemd/Services debian/systemd Services]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.freedesktop.org/software/systemd/man/systemd.service.html manual]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
System-wide services are in &amp;lt;code&amp;gt;/etc/systemd/system/&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
User services are in &amp;lt;code&amp;gt;~/.config/systemd/user/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{hidden|A basic systemd service file|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Contents of /etc/systemd/system/myservice.service&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=My Service&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
Restart=always&lt;br /&gt;
WorkingDirectory=/usr/local/bin&lt;br /&gt;
ExecStart=/usr/local/bin/myservice&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable with &amp;lt;code&amp;gt;sudo systemctl enable myservice&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
;Usage&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl enable &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl status &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl start &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl stop &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl restart &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo systemctl disable &amp;lt;my_service&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* Type should be &amp;lt;code&amp;gt;forking&amp;lt;/code&amp;gt; if your service runs and then ends&lt;br /&gt;
* See service log with &amp;lt;code&amp;gt;sudo journalctl myservice&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Management==&lt;br /&gt;
===rsync===&lt;br /&gt;
{{main | rsync}}&lt;br /&gt;
&lt;br /&gt;
[https://linux.die.net/man/1/rsync Documentation]&lt;br /&gt;
&lt;br /&gt;
Use this to sync folders between directories of across networks&lt;br /&gt;
&lt;br /&gt;
;Common Flags&lt;br /&gt;
* &amp;lt;code&amp;gt;-a, --archive&amp;lt;/code&amp;gt; archive mode; equals -rlptgoD&lt;br /&gt;
* &amp;lt;code&amp;gt;--info=progress2&amp;lt;/code&amp;gt; show progress&lt;br /&gt;
&lt;br /&gt;
See [[ArchWiki: rsync]] to learn how to use rclone for incremental backups (a la time machine).&lt;br /&gt;
&lt;br /&gt;
===rclone===&lt;br /&gt;
{{ main | rclone }}&lt;br /&gt;
Similar to rsync but for cloud services such as Dropbox and Google Drive.&amp;lt;br&amp;gt;&lt;br /&gt;
I recommend installing from their website to get the latest version.&lt;br /&gt;
&lt;br /&gt;
===scp===&lt;br /&gt;
Usage&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp [source_machine]:[source_file] [target_machine]:[target_file]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;Flags&lt;br /&gt;
* &amp;lt;code&amp;gt;-r&amp;lt;/code&amp;gt; recursive, needed to scp directories&lt;br /&gt;
* &amp;lt;code&amp;gt;-P [port]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* The machine can be an alias or user@domain&lt;br /&gt;
&lt;br /&gt;
===7z===&lt;br /&gt;
7zip CLI&amp;lt;br&amp;gt;&lt;br /&gt;
Install with &amp;lt;code&amp;gt;sudo apt install p7zip-full&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;gt;&lt;br /&gt;
# Archive&lt;br /&gt;
7z a &amp;lt;output_file&amp;gt; &amp;lt;input_file/folder&amp;gt;&lt;br /&gt;
# Archive with password&lt;br /&gt;
7z a &amp;lt;output_file&amp;gt; &amp;lt;input_file&amp;gt; -p -mhe=on&lt;br /&gt;
&lt;br /&gt;
# Extract &lt;br /&gt;
7z x &amp;lt;file&amp;gt; [-o{dir}]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-mhe=on&amp;lt;/code&amp;gt; hides file stuctures&lt;br /&gt;
&lt;br /&gt;
===zip/unzip===&lt;br /&gt;
Note that p7zip-full also includes the ability to zip/unzip .zip files.&amp;lt;br&amp;gt;&lt;br /&gt;
;Zip a folder&lt;br /&gt;
&amp;lt;code&amp;gt;zip -r file.zip folder&amp;lt;/code&amp;gt;&lt;br /&gt;
;Unzip an archive&lt;br /&gt;
&amp;lt;code&amp;gt;unzip file.zip [-d destination]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===diff===&lt;br /&gt;
[https://www.geeksforgeeks.org/diff-command-linux-examples/ diff examples]&lt;br /&gt;
&lt;br /&gt;
;Important flags&lt;br /&gt;
* &amp;lt;code&amp;gt;--strip-trailing-cr&amp;lt;/code&amp;gt; Ignores &amp;lt;code&amp;gt;\r&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===tar===&lt;br /&gt;
{{ main | tar (computing) }}&lt;br /&gt;
;Extraction&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tar xzvf archive.tar.gz&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Archive&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tar czpvf archive.tar.gz files&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===find===&lt;br /&gt;
Find files by their filename&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find &amp;lt;folder&amp;gt; [args] -name &amp;lt;name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-maxdepth &amp;lt;num&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===grep===&lt;br /&gt;
Find files containing a pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
grep -r &amp;lt;pattern&amp;gt; *&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dual Booting==&lt;br /&gt;
===Fix time difference between Windows===&lt;br /&gt;
By default, Windows stores the local time in the hardware clock while Ubuntu stores UTC time.&lt;br /&gt;
&lt;br /&gt;
Set ubuntu to store UTC time:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
timedatectl set-local-rtc 0 --adjust-system-clock&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set Windows to store UTC time:&lt;br /&gt;
https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows&lt;br /&gt;
&lt;br /&gt;
===Recover GRUB after installing Windows===&lt;br /&gt;
[https://help.ubuntu.com/community/RecoveringUbuntuAfterInstallingWindows Ubuntu Help]&amp;lt;br&amp;gt;&lt;br /&gt;
If you install windows after installing Ubuntu&lt;br /&gt;
&lt;br /&gt;
===GrubReboot===&lt;br /&gt;
[https://wiki.debian.org/GrubReboot GrubReboot]&amp;lt;br&amp;gt;&lt;br /&gt;
Allows you to reboot into an OS one time.&amp;lt;br&amp;gt;&lt;br /&gt;
i.e. If you are ssh&#039;d into linux and want to boot into Windows one time.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Encryption===&lt;br /&gt;
[https://www.mikekasberg.com/blog/2020/04/08/dual-boot-ubuntu-and-windows-with-encryption.html https://www.mikekasberg.com/blog/2020/04/08/dual-boot-ubuntu-and-windows-with-encryption.html]&lt;br /&gt;
&lt;br /&gt;
==Users and Groups==&lt;br /&gt;
===Users===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make a new user&lt;br /&gt;
adduser &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Add user to admins&lt;br /&gt;
usermod -aG sudo &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Change the password of a user&lt;br /&gt;
passwd&lt;br /&gt;
passwd &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete a user&lt;br /&gt;
# -r will also delete their home directory&lt;br /&gt;
userdel -r &amp;lt;user&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make a group&lt;br /&gt;
groupadd &amp;lt;group&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete a group&lt;br /&gt;
groupdel &amp;lt;group&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# List members in groups&lt;br /&gt;
getent group &amp;lt;group&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Add user to group&lt;br /&gt;
usermod -a -G &amp;lt;group&amp;gt; &amp;lt;user&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Remove user from group&lt;br /&gt;
gpasswd -d &amp;lt;user&amp;gt; &amp;lt;group&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Permissions==&lt;br /&gt;
In unix filesystems, files and folders have individual permissions.&amp;lt;br&amp;gt;&lt;br /&gt;
You can set permissions for each file/folder independently and for the following sets of users:&lt;br /&gt;
* User/Owner &amp;lt;code&amp;gt;u&amp;lt;/code&amp;gt;&lt;br /&gt;
* Group &amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt;&lt;br /&gt;
* Other &amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt;&lt;br /&gt;
You can also set permissions for all of the above with:&lt;br /&gt;
* All &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;&lt;br /&gt;
Each file and folder can have the following permission for each set of user:&lt;br /&gt;
* Read &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;&lt;br /&gt;
* Write &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&lt;br /&gt;
* Execute &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;&lt;br /&gt;
The above totals 9 bits (3 sets of users times 3 permissions).&lt;br /&gt;
&lt;br /&gt;
In addition to the above, there are 3 special bits:&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sticky_bit Sticky bit &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt;] - only allow the owners of subfiles/subfolders to modify them&lt;br /&gt;
** Useful for shared folders such as /tmp&lt;br /&gt;
* Setuid - automatically elevate execution of this file to the owner&#039;s priviledges&lt;br /&gt;
* Setgid - automatically elevate execution of this file to the group&#039;s priviledges&lt;br /&gt;
&lt;br /&gt;
In total, permissions for each file and folder can be stored in 16 bits or 2 bytes.&lt;br /&gt;
&lt;br /&gt;
===chmod===&lt;br /&gt;
change mode&lt;br /&gt;
&lt;br /&gt;
===chown===&lt;br /&gt;
change owner&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chown [-r] &amp;lt;user&amp;gt;[:&amp;lt;group&amp;gt;] &amp;lt;item&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===chgrp===&lt;br /&gt;
&lt;br /&gt;
===Access Control Lists (ACL)===&lt;br /&gt;
&lt;br /&gt;
==Display Scaling (HiDPI)==&lt;br /&gt;
See [https://wiki.archlinux.org/index.php/HiDPI Arch Wiki HiDPI]  &lt;br /&gt;
&lt;br /&gt;
Fractional scaling is natively available in Ubuntu 20.04+.&lt;br /&gt;
&lt;br /&gt;
{{hidden | Ubuntu 18.04 |&lt;br /&gt;
;Xorg&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Find your display&lt;br /&gt;
xrandr&lt;br /&gt;
xrandr --output &amp;lt;display&amp;gt; --scale 1.25x1.25&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Wayland&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gsettings set org.gnome.mutter experimental-features &amp;quot;[&#039;scale-monitor-framebuffer&#039;]&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I have the following script run at startup&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
gsettings set org.gnome.desktop.interface scaling-factor 2&lt;br /&gt;
gsettings set org.gnome.settings-daemon.plugins.xsettings overrides &amp;quot;{&#039;Gdk/WindowScalingFactor&#039;: &amp;lt;2&amp;gt;}&amp;quot;&lt;br /&gt;
xrandr --output DP-2 --scale 1.3x1.3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Clock==&lt;br /&gt;
See [https://help.ubuntu.com/lts/serverguide/NTP.html Ubuntu Time Synchronization]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Install chrony&lt;br /&gt;
sudo apt install chrony&lt;br /&gt;
# Synchronize time&lt;br /&gt;
sudo chronyd -q&lt;br /&gt;
# Check time synchronization&lt;br /&gt;
sudo chronyd -Q&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes&lt;br /&gt;
* Syncing over the internet will be off by a few milliseconds (e.g. 0.003 seconds).&lt;br /&gt;
* Syncing with another computer over lan&lt;br /&gt;
&lt;br /&gt;
===Syncing with another computer===&lt;br /&gt;
See [https://askubuntu.com/questions/787855/how-to-use-chrony-to-synchronize-timestamp-on-two-computers/1018204 askubuntu]&amp;lt;br&amp;gt;&lt;br /&gt;
;On the server&lt;br /&gt;
Add the following to &amp;lt;code&amp;gt;/etc/chrony.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# make it serve time even if it is not synced (as it can&#039;t reach out)&lt;br /&gt;
local stratum 8&lt;br /&gt;
# allow the IP of your peer to connect (192.168 subnet)&lt;br /&gt;
allow 192.168&lt;br /&gt;
# Or&lt;br /&gt;
# allow all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;On the client&lt;br /&gt;
Add the following to &amp;lt;code&amp;gt;/etc/chrony.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set the servers IP here to sync to it&lt;br /&gt;
server &amp;lt;Server_IP&amp;gt; iburst&lt;br /&gt;
# remove the default servers in the config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;code&amp;gt;/dev/&amp;lt;/code&amp;gt;==&lt;br /&gt;
See [[Wikipedia: Device file#Pseudo-devices]]&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;===&lt;br /&gt;
Discards all input.  &lt;br /&gt;
Produces EOF.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;random&amp;lt;/code&amp;gt;===&lt;br /&gt;
See [https://security.stackexchange.com/questions/3936/is-a-rand-from-dev-urandom-secure-for-a-login-key/3939#3939 stackexchange]&amp;lt;br&amp;gt;&lt;br /&gt;
See [https://www.2uo.de/myths-about-urandom/ Myths about urandom]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;TLDR&amp;amp;#58; Use &amp;lt;code&amp;gt;/dev/urandom&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;/dev/random&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt;urandom&amp;lt;/code&amp;gt;===&lt;br /&gt;
Produces random numbers.&lt;br /&gt;
&lt;br /&gt;
On my system, it&#039;s limited to about 60 MB/s. If you need faster randomness, you can encrypt from &amp;lt;code&amp;gt;/dev/zero&amp;lt;/code&amp;gt; to get 2.7 GB/s.  &lt;br /&gt;
See [https://serverfault.com/questions/6440/is-there-an-alternative-to-dev-urandom/415962#415962 reference].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Using urandom&lt;br /&gt;
pv &amp;lt; /dev/urandom &amp;gt; /dev/ull&lt;br /&gt;
&lt;br /&gt;
# Using encryption&lt;br /&gt;
openssl enc -pbkdf2 -iter 100000 -aes-256-ctr -pass pass:&amp;quot;$(dd if=/dev/urandom bs=128 count=1 2&amp;gt;/dev/null | base64)&amp;quot; -nosalt &amp;lt; /dev/zero | pv &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
# Create a 4 GB file.&lt;br /&gt;
dd if=/dev/zero bs=4M count=1024 | openssl enc -pbkdf2 -iter 100000 -aes-256-ctr -pass pass:&amp;quot;$(dd if=/dev/urandom bs=128 count=1 2&amp;gt;/dev/null | base64)&amp;quot; -nosalt | pv &amp;gt; random.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gnome==&lt;br /&gt;
===Tweaks===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install gnome-tweaks&lt;br /&gt;
sudo apt install chrome-gnome-shell&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Auto Reboot==&lt;br /&gt;
[https://unix.stackexchange.com/questions/141095/automatically-reboot-if-no-wifi-connection-for-a-certain-time reference]&lt;br /&gt;
&lt;br /&gt;
{{hidden | Auto Reboot Script |&lt;br /&gt;
Auto reboot if no internet is detected:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
TMP_FILE=/tmp/inet_up&lt;br /&gt;
&lt;br /&gt;
# Edit this function if you want to do something besides reboot&lt;br /&gt;
no_inet_action() {&lt;br /&gt;
    if [ &amp;quot;$1&amp;quot; -eq 1 ]; then&lt;br /&gt;
        systemctl restart network-manager&lt;br /&gt;
    elif [ &amp;quot;$1&amp;quot; -ge 2 ]; then&lt;br /&gt;
        rm -f $TMP_FILE&lt;br /&gt;
        shutdown -r now &amp;quot;No Internet&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
increment_tmp_file() {&lt;br /&gt;
    if [ ! -f $TMP_FILE ]; then&lt;br /&gt;
       echo 0 &amp;gt; $TMP_FILE&lt;br /&gt;
    fi&lt;br /&gt;
    oldnum=$(cut -d &#039;,&#039; -f2 $TMP_FILE)&lt;br /&gt;
    newnum=$((&amp;quot;$oldnum&amp;quot; + 1))&lt;br /&gt;
    sed -i &amp;quot;s/$oldnum\$/$newnum/g&amp;quot; $TMP_FILE&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if ping -c5 google.com; then&lt;br /&gt;
    echo 0 &amp;gt; $TMP_FILE&lt;br /&gt;
    date &amp;gt; /tmp/inet_up_last_check&lt;br /&gt;
else&lt;br /&gt;
    increment_tmp_file&lt;br /&gt;
    oldnum=$(cut -d &#039;,&#039; -f2 $TMP_FILE)&lt;br /&gt;
    no_inet_action &amp;quot;$oldnum&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add to sudo&#039;s crontab to run every 10 minutes&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*/10 * * * * /home/david/bin/check_inet.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Encryption==&lt;br /&gt;
For encrypting entire drives, I recommend LUKS.&amp;lt;br&amp;gt;&lt;br /&gt;
If you want encrypt a directly, you can use fscrypt (ext4 only).&lt;br /&gt;
&lt;br /&gt;
Note that ecryptfs is deprecated and shouldn&#039;t be used.&lt;br /&gt;
&lt;br /&gt;
===Encrypt Home After Install===&lt;br /&gt;
See [[Archwiki: Fscrypt#Encrypt_a_home_directory]].  &lt;br /&gt;
See [https://tlbdk.github.io/ubuntu/2018/10/22/fscrypt.html https://tlbdk.github.io/ubuntu/2018/10/22/fscrypt.html].&lt;br /&gt;
&lt;br /&gt;
This uses the newer fscrypt and requires Ubuntu 18.10+.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Install fscrypt and do setup&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install fscrypt libpam-fscrypt&lt;br /&gt;
sudo fscrypt setup&lt;br /&gt;
sudo fscrypt setup /&lt;br /&gt;
sudo tune2fs -O encrypt /dev/&amp;lt;yourdevice&amp;gt;&lt;br /&gt;
# E.g. sudo tune2fs -O encrypt /dev/sda5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Create a new temp sudo user and login to it&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Create the encrypted home folder&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
export USERNAME=david&lt;br /&gt;
# Move old home folder&lt;br /&gt;
sudo mv /home/$USERNAME /home/$USERNAME.bak&lt;br /&gt;
&lt;br /&gt;
# Create a new home folder and encrypt it&lt;br /&gt;
mkdir /home/$USERNAME&lt;br /&gt;
chown $USERNAME:$USERNAME /home/$USERNAME&lt;br /&gt;
fscrypt encrypt /home/$USERNAME --user=$USERNAME&lt;br /&gt;
&lt;br /&gt;
# Copy files to the new home folder using cp or rsync&lt;br /&gt;
# cp -a -T /home/$USERNAME.bak /home&lt;br /&gt;
rsync -aHX --info=progress2 /home/$USERNAME.bak/ /home/$USERNAME/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Test the encrypted home folder by logging into your user&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Cleanup by removing the temporary user and deleting the old home folder&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
shred /home/$USERNAME.bak/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes and Caveats&lt;br /&gt;
* &amp;lt;code&amp;gt;systemd&amp;lt;/code&amp;gt; will no longer have access to your home so all startup apps should be placed elsewhere&lt;br /&gt;
** E.g. Move all startup scripts in your &amp;lt;code&amp;gt;~/.local/bin&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;/usr/local/bin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; will not work until home has been decrypted since the authorized keys are in &amp;lt;code&amp;gt;~/.ssh/authorized_keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{hidden | SSH Workaround |&lt;br /&gt;
Getting SSH to work with an encrypted home dir is a giant pain.  &lt;br /&gt;
Also things like tmux still won&#039;t work.  &lt;br /&gt;
Overall I do not recommend doing this on a server.&lt;br /&gt;
&lt;br /&gt;
# Move ssh keys elsewhere such as &amp;lt;code&amp;gt;/etc/ssh/authorized_keys/&amp;lt;user&amp;gt;&amp;lt;/code&amp;gt;. &lt;br /&gt;
#* Add &amp;lt;code&amp;gt;/etc/ssh/authorized_keys/%u&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;AuthorizedKeysFile&amp;lt;/code&amp;gt; line in &amp;lt;code&amp;gt;/etc/ssh/sshd_config&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Create a sudo user with and unencrypted home directory.&lt;br /&gt;
# After every restart, ssh into the unencrypted sudo user and decrypt your home directory: &lt;br /&gt;
#* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sudo fscrypt unlock /home/david --user=david&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Then ssh into your account.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==SFTP==&lt;br /&gt;
You can create a specific user with a chroot to limit SFTP to specific folders.  &lt;br /&gt;
See [[Archwiki: SFTP chroot]] for details.&lt;br /&gt;
/etc/ssh/sshd_config&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Subsystem sftp /usr/lib/ssh/sftp-server&lt;br /&gt;
&lt;br /&gt;
Match Group sftponly&lt;br /&gt;
  ChrootDirectory %h&lt;br /&gt;
  ForceCommand internal-sftp&lt;br /&gt;
  AllowTcpForwarding no&lt;br /&gt;
  X11Forwarding no&lt;br /&gt;
  PasswordAuthentication no&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hardware Info==&lt;br /&gt;
&lt;br /&gt;
;Benchmarking&lt;br /&gt;
Basic CPU benchmark&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sysbench cpu --threads=2 run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==MOTD==&lt;br /&gt;
Message of the day is the text you see when you login via SSH.  &lt;br /&gt;
Ubuntu stores its MOTD in &amp;lt;code&amp;gt;/etc/update-motd.d/&amp;lt;/code&amp;gt;. Other distros use &amp;lt;code&amp;gt;/etc/motd/&amp;lt;/code&amp;gt;.  &lt;br /&gt;
You can disable the Ubuntu news motd in &amp;lt;code&amp;gt;/etc/default/motd-news&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==System Administration==&lt;br /&gt;
{{main | Linux Administration}}&lt;br /&gt;
&lt;br /&gt;
==Installing Binaries==&lt;br /&gt;
# Copy your binary to &amp;lt;code&amp;gt;/usr/local/bin/&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;~/.local/bin/&amp;lt;/code&amp;gt;&lt;br /&gt;
# Copy your man page to &amp;lt;code&amp;gt;/usr/local/share/man/man1/&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;~/.local/share/man/man1/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Network Troubleshooting==&lt;br /&gt;
On one of my OptiPlex 5060 servers, the network adapter would reset on git ssh clones.&amp;lt;br&amp;gt;&lt;br /&gt;
This would appear in &amp;lt;code&amp;gt;/var/log/syslog&amp;lt;/code&amp;gt; as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Feb  8 22:22:01 optiplex5060-2 kernel: [ 4378.992607] e1000e 0000:00:1f.6 eno1: Reset adapter unexpectedly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This was resolved by disabling TCP Segmentation Offload:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo ethtool -K eno1 tso off&lt;br /&gt;
&lt;br /&gt;
# Verify tso is disabled&lt;br /&gt;
ethtool -k eno1 | grep tcp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make this persist across reboots:&lt;br /&gt;
{{hidden | Script |&lt;br /&gt;
If you&#039;re using netplan (default for Ubuntu):&amp;lt;br&amp;gt;&lt;br /&gt;
[https://michael.mulqueen.me.uk/2018/08/disable-offloading-netplan-ubuntu/ Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
output_path=/usr/lib/networkd-dispatcher/routable.d/10-disable-offloading&lt;br /&gt;
sudo tee $output_path &amp;lt;&amp;lt;EOF&amp;gt; /dev/null&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
ethtool -K eno1 tso off&lt;br /&gt;
EOF&lt;br /&gt;
sudo chmod +x $output_path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If using ifupdown:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
output_path=/etc/network/if-up.d/disable-tso&lt;br /&gt;
sudo tee $output_path &amp;lt;&amp;lt;EOF&amp;gt; /dev/null&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
ethtool -K eno1 tso off&lt;br /&gt;
EOF&lt;br /&gt;
sudo chmod +x $output_path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Cloning to a new disk==&lt;br /&gt;
The easiest way is to use gparted.&lt;br /&gt;
&lt;br /&gt;
{{hidden | Terminal Guide |&lt;br /&gt;
To do this in the terminal:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
OLD_DRIVE=/dev/sda&lt;br /&gt;
NEW_DRIVE=/dev/sdb&lt;br /&gt;
&lt;br /&gt;
# Show old drive partitions in sectors&lt;br /&gt;
parted $OLD_DRIVE unit s print free&lt;br /&gt;
&lt;br /&gt;
# Apply GPT&lt;br /&gt;
parted $NEW_DRIVE mklabel gpt&lt;br /&gt;
# Copy new EFI partition with start 1024s and end 1050623s&lt;br /&gt;
parted $NEW_DRIVE mkpart primary fat32 2048s 1050623s&lt;br /&gt;
# Apply boot and esp flags.&lt;br /&gt;
parted $NEW_DRIVE set 1 boot on&lt;br /&gt;
parted $NEW_DRIVE set 1 esp on&lt;br /&gt;
parted $NEW_DRIVE name 1 &#039;EFI System Partition&#039;&lt;br /&gt;
# dd the old to the new&lt;br /&gt;
dd if=${OLD_DRIVE}1 of=${NEW_DRIVE}1 bs=4k&lt;br /&gt;
&lt;br /&gt;
# Make a new partition. Make sure start and end sectors are aligned.&lt;br /&gt;
# i.e. start % 8 == 0 and end % 8 == 7 if your physical sector size is 4096 bytes, typical for new HDDs and SSDs.&lt;br /&gt;
parted $NEW_DRIVE mkpart primary btrfs 1050624s 488396791s&lt;br /&gt;
parted $NEW_DRIVE align-check opt 2&lt;br /&gt;
&lt;br /&gt;
# Copy the filesystem&lt;br /&gt;
mkfs.btrfs ${NEW_DRIVE}2&lt;br /&gt;
mkdir /media/${NEW_DRIVE}&lt;br /&gt;
mount -t btrfs -o compress=zstd /media/${NEW_DRIVE}2&lt;br /&gt;
rsync -axHAWXS --numeric-ids --info=progress2 /media/${NEW_DRIVE}2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://superuser.com/questions/307541/copy-entire-file-system-hierarchy-from-one-drive-to-another rsync reference]&lt;br /&gt;
&lt;br /&gt;
;rsync options&lt;br /&gt;
* -a     archive mode&lt;br /&gt;
* -x     one file system&lt;br /&gt;
* -H     preserve hard links&lt;br /&gt;
* -A     preserve ACLs&lt;br /&gt;
* -W     copy whole files instead of deltas&lt;br /&gt;
* -X     preserve extended attributes&lt;br /&gt;
* -S     handle sparse files efficiently&lt;br /&gt;
* --numeric-ids    use id instead of uid/gid&lt;br /&gt;
&lt;br /&gt;
To copy a root partition, make sure you change the following on the new drive:&lt;br /&gt;
* Update the UUID and mount options in &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
* Update the UUID in &amp;lt;code&amp;gt;/boot/grub/grub.cfg&amp;lt;/code&amp;gt; and run &amp;lt;code&amp;gt;update-grub&amp;lt;/code&amp;gt;&lt;br /&gt;
* Update the UUID in &amp;lt;code&amp;gt;/boot/EFI/ubuntu/grub.cfg&amp;lt;/code&amp;gt;&lt;br /&gt;
* Run [https://help.ubuntu.com/community/Boot-Repair boot-repair] from a live disk if you run into any issues.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Ubuntu==&lt;br /&gt;
Ubuntu-specific notes&lt;br /&gt;
&lt;br /&gt;
===Disable ESM message===&lt;br /&gt;
[https://askubuntu.com/questions/1453749/inhibit-esm-messages-at-login Reference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Disable MOTD&lt;br /&gt;
sudo chmod -x /etc/update-motd.d/88-esm-announce&lt;br /&gt;
sudo chmod -x /etc/update-motd.d/91-contract-ua-esm-status&lt;br /&gt;
&lt;br /&gt;
# Disable APT check&lt;br /&gt;
sudo sed -Ezi.orig \&lt;br /&gt;
  -e &#039;s/(def _output_esm_service_status.outstream, have_esm_service, service_type.:\n)/\1    return\n/&#039; \&lt;br /&gt;
  -e &#039;s/(def _output_esm_package_alert.*?\n.*?\n.:\n)/\1    return\n/&#039; \&lt;br /&gt;
  /usr/lib/update-notifier/apt_check.py&lt;br /&gt;
sudo /usr/lib/update-notifier/update-motd-updates-available --force&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Jujutsu_(VCS)&amp;diff=7163</id>
		<title>Jujutsu (VCS)</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Jujutsu_(VCS)&amp;diff=7163"/>
		<updated>2025-06-17T23:11:24Z</updated>

		<summary type="html">&lt;p&gt;David: /* Git pull */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Notes on using jj&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Git pull===&lt;br /&gt;
See https://jj-vcs.github.io/jj/latest/github/#updating-the-repository&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jj git pull&lt;br /&gt;
jj rebase -d main@origin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Jujutsu_(VCS)&amp;diff=7162</id>
		<title>Jujutsu (VCS)</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Jujutsu_(VCS)&amp;diff=7162"/>
		<updated>2025-06-17T23:10:49Z</updated>

		<summary type="html">&lt;p&gt;David: Created page with &amp;quot;Notes on using jj   ===Git pull=== See https://jj-vcs.github.io/jj/latest/github/#updating-the-repository &amp;lt;pre&amp;gt; jj git pull jj rebase -d $main_bookmark &amp;lt;/pre&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Notes on using jj&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Git pull===&lt;br /&gt;
See https://jj-vcs.github.io/jj/latest/github/#updating-the-repository&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jj git pull&lt;br /&gt;
jj rebase -d $main_bookmark&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=Computer_Graphics&amp;diff=7161</id>
		<title>Computer Graphics</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=Computer_Graphics&amp;diff=7161"/>
		<updated>2025-06-07T06:40:40Z</updated>

		<summary type="html">&lt;p&gt;David: /* Homogeneous Coordinates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Basics of Computer Graphics&lt;br /&gt;
&lt;br /&gt;
==Homogeneous Coordinates==&lt;br /&gt;
[http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/ http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/]&lt;br /&gt;
&lt;br /&gt;
Points and vectors are represented using homogeneous coordinates in computer graphics.  &lt;br /&gt;
This allows affine transformations in 3D (i.e. rotation and translation) to be represented as a matrix multiplication.  &lt;br /&gt;
While rotations can typically be represented in a 3x3 matrix multiplication, a translation requires a [[wikipedia:Shear mapping | &#039;&#039;shear&#039;&#039;]] in 4D.&lt;br /&gt;
&lt;br /&gt;
Points are &amp;lt;math&amp;gt;(x,y,z,1)&amp;lt;/math&amp;gt; and vectors are &amp;lt;math&amp;gt;(x,y,z,0)&amp;lt;/math&amp;gt;.  &lt;br /&gt;
The last coordinate in points allow for translations to be represented as matrix multiplications.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* The point &amp;lt;math&amp;gt;(kx, ky, kz, k)&amp;lt;/math&amp;gt; is equivalent to &amp;lt;math&amp;gt;(x, y, z, 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Affine transformations consist of translations, rotations, and scaling&lt;br /&gt;
&lt;br /&gt;
===Translation Matrix===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
T =&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; X\\&lt;br /&gt;
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; Y\\&lt;br /&gt;
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; Z\\&lt;br /&gt;
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rotation Matrix===&lt;br /&gt;
Rotations can be about the X, Y, and Z axis.&amp;lt;br&amp;gt;&lt;br /&gt;
Below is a rotation about the Z axis by angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
R = \begin{bmatrix}&lt;br /&gt;
\cos(\theta) &amp;amp; -\sin(\theta) &amp;amp; 0 &amp;amp; 0\\&lt;br /&gt;
\sin(\theta) &amp;amp; \cos(\theta) &amp;amp; 0 &amp;amp; 0\\&lt;br /&gt;
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0\\&lt;br /&gt;
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To formulate a rotation about a specific axis, we use [[Wikipedia:Rodrigues&#039; rotation formula]].&amp;lt;br&amp;gt;&lt;br /&gt;
Suppose we want to rotate by angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; around axis &amp;lt;math&amp;gt;\mathbf{k}=(k_x, k_y, k_z)&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Let &amp;lt;math&amp;gt;&lt;br /&gt;
\mathbf{K} = [\mathbf{k}]_{\times} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
0 &amp;amp; -k_z &amp;amp; k_y\\&lt;br /&gt;
k_z &amp;amp; 0 &amp;amp; -k_x\\&lt;br /&gt;
-k_y &amp;amp; k_x &amp;amp; 0&lt;br /&gt;
\end{bmatrix}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Then the rotation matrix is &amp;lt;math&amp;gt;\mathbf{R} = \mathbf{I}_{3} + (\sin \theta)\mathbf{K} + (1 - \cos \theta)\mathbf{K}^2&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Here the 4x4 form is: &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
R = \begin{bmatrix}&lt;br /&gt;
\mathbf{R} &amp;amp; \mathbf{0}\\&lt;br /&gt;
\mathbf{0}^T &amp;amp; 1&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Scaling Matrix===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
S = \begin{bmatrix}&lt;br /&gt;
X &amp;amp; 0 &amp;amp; 0 &amp;amp; 0\\&lt;br /&gt;
0 &amp;amp; Y &amp;amp; 0 &amp;amp; 0\\&lt;br /&gt;
0 &amp;amp; 0 &amp;amp; Z &amp;amp; 0\\&lt;br /&gt;
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Transformation matrix===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = T * R * S&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Depending on implementation, it may be more memory-efficient or compute-efficient to represent affine transformations as their own class rather than 4x4 matrices. For example, a rotation can be represented with 3 floats in angle-axis or 4 floats in quaternion coordinates rather than a 3x3 rotation matrix.&lt;br /&gt;
&lt;br /&gt;
For example, see&lt;br /&gt;
* [https://eigen.tuxfamily.org/dox/classEigen_1_1Transform.html Eigen::Transform]&lt;br /&gt;
&lt;br /&gt;
===Barycentric Coordinates===&lt;br /&gt;
&lt;br /&gt;
==MVP Matrices==&lt;br /&gt;
&lt;br /&gt;
To convert from model coordinates &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; to screen coordinates &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, you do multiply by the MVP matrices &amp;lt;math&amp;gt;w=P*V*M*v&amp;lt;/math&amp;gt;&lt;br /&gt;
* The model matrix &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; applies the transform of your object. This includes the position and rotation. &amp;lt;math&amp;gt;M*v&amp;lt;/math&amp;gt; is in world coordinates.&lt;br /&gt;
* The view matrix &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; applies the inverse transform of your camera. &amp;lt;math&amp;gt;V*M*v&amp;lt;/math&amp;gt; is in camera or view coordinates (i.e. coordinates relative to the camera).&lt;br /&gt;
* The projection matrix &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; applies the projection of your camera, typically an orthographic or a perspective camera. The perspective camera shrinks objects in the distance.&lt;br /&gt;
&lt;br /&gt;
===Model Matrix===&lt;br /&gt;
[https://gamedev.stackexchange.com/questions/16719/what-is-the-correct-order-to-multiply-scale-rotation-and-translation-matrices-f Order of matrices]&amp;lt;br&amp;gt;&lt;br /&gt;
The model matrix is the product of the element&#039;s scale, rotation, and translation matrices.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;M = T * R * S&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===View Matrix===&lt;br /&gt;
[https://webglfactory.blogspot.com/2011/06/how-to-create-view-matrix.html Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/lookat-function Lookat function]&amp;lt;br&amp;gt;&lt;br /&gt;
The view matrix is a 4x4 matrix which encodes the position and rotation of the camera.&amp;lt;br&amp;gt;&lt;br /&gt;
Given a camera at position &amp;lt;math&amp;gt;\mathbf p&amp;lt;/math&amp;gt; looking at target &amp;lt;math&amp;gt;\mathbf t&amp;lt;/math&amp;gt; and up vector &amp;lt;math&amp;gt;\mathbf u&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
We can calculate the forward vector (from target to position) as &amp;lt;math&amp;gt;\mathbf{f}=\mathbf{p} - \mathbf{t}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
We can calculate the right vector as &amp;lt;math&amp;gt;\mathbf u \times \mathbf f&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Then the view matrix is written as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r_x r_y r_z 0&lt;br /&gt;
u_x u_y u_z 0&lt;br /&gt;
f_x f_y f_z 0&lt;br /&gt;
p_x p_y p_z 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Matrix lookAt(camera_pos, target, up) {&lt;br /&gt;
  forward = normalize(camera - target)&lt;br /&gt;
  up_normalized = normalize(up)&lt;br /&gt;
  right = normalize(cross(up, forward)&lt;br /&gt;
  // Make sure up is perpendicular to forward&lt;br /&gt;
  up = normalize(cross(forward, right)&lt;br /&gt;
  m = stack([right, up, forward, camera], 0)&lt;br /&gt;
  return m&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perspective Projection Matrix===&lt;br /&gt;
[https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/building-basic-perspective-projection-matrix https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/building-basic-perspective-projection-matrix]&lt;br /&gt;
&lt;br /&gt;
https://www.songho.ca/opengl/gl_projectionmatrix.html&lt;br /&gt;
&lt;br /&gt;
The projection matrix applies a perspective projection based on the field of view of the camera. This is done dividing the x,y view coordinates by the z-coordinate so that further object appear closer to the center. Note that the output is typically in normalized device coordinates (NDC) &amp;lt;math&amp;gt;[-1, 1]\times[-1, 1]&amp;lt;/math&amp;gt; rather than image coordinates &amp;lt;math&amp;gt;{0, ..., W-1} \times {0, ..., H-1}&amp;lt;/math&amp;gt;. Additionally, in NDC, the y-coordinate typically points upwards unlike image coordinates.&lt;br /&gt;
&lt;br /&gt;
The Z-coordinate in the projection matrix represents a remapped version of the z-depth, i.e. depth along the camera forward axis. In OpenGL, this maps z=-f to 1 and z=-n to -1 where -z is forward.&lt;br /&gt;
&lt;br /&gt;
Notes: In computer vision, this is analogous to the calibration matrix &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt;. &lt;br /&gt;
It contains the intrinsic parameters of your pinhole camera such as field of view and focal length. The focal length determines the resolution of your output.&lt;br /&gt;
&lt;br /&gt;
===Inverting the projection===&lt;br /&gt;
If you have the depth (either z-depth or euclidean depth), you can invert the projection operation.  &lt;br /&gt;
The idea is to construct a ray from the camera to the pixel on a plane of the viewing frustrum and scale the distance accordingly.&lt;br /&gt;
&lt;br /&gt;
See [https://gamedev.stackexchange.com/questions/108856/fast-position-reconstruction-from-depth/111885#111885 stackexchange].&lt;br /&gt;
&lt;br /&gt;
==Shading==&lt;br /&gt;
{{main | Wikipedia:Shading}}&lt;br /&gt;
===Interpolation===&lt;br /&gt;
&lt;br /&gt;
* Flat shading - color is computed for each face/triangle.&lt;br /&gt;
* Gourard shading - color is computed for each vertex and interpolated.&lt;br /&gt;
* Phong shading - color is computed for each pixel with the normal vector interpolated from each vertex.&lt;br /&gt;
&lt;br /&gt;
===Lambert reflectance===&lt;br /&gt;
{{main | Wikipedia: Lambertian reflectance}}&lt;br /&gt;
This is a way to model diffuse (matte) materials.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_D = (\mathbf{L} \cdot \mathbf{N}) * C * I_{L}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\mathbf{N}&amp;lt;/math&amp;gt; is the normal vector.&lt;br /&gt;
* &amp;lt;math&amp;gt;\mathbf{L}&amp;lt;/math&amp;gt; is the vector to the light.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; is the color.&lt;br /&gt;
* &amp;lt;math&amp;gt;I_{L}&amp;lt;/math&amp;gt; is the intensity of light.&lt;br /&gt;
&lt;br /&gt;
===Phong reflection model===&lt;br /&gt;
{{main | Wikipedia: Phong reflection model}}&lt;br /&gt;
See [https://www.scratchapixel.com/lessons/3d-basic-rendering/phong-shader-BRDF scratchapixel phong shader BRDF].  &lt;br /&gt;
This is a way to model specular (shiny) materials.&lt;br /&gt;
&lt;br /&gt;
Here, the image is a linear combination of ambient, diffuse, and specular colors.  &lt;br /&gt;
&lt;br /&gt;
If &amp;lt;math&amp;gt;\mathbf{N}&amp;lt;/math&amp;gt; is the normal vector, &amp;lt;math&amp;gt;\mathbf{V}&amp;lt;/math&amp;gt; is a vector from the vertex to the viewer, &amp;lt;math&amp;gt;\mathbf{L}&amp;lt;/math&amp;gt; from the light to the vertex, and &amp;lt;math&amp;gt;\mathbf{R}&amp;lt;/math&amp;gt; the incident vector (i.e. &amp;lt;math&amp;gt;\mathbf{L}&amp;lt;/math&amp;gt; rotated 180 around &amp;lt;math&amp;gt;\mathbf{N}&amp;lt;/math&amp;gt;) then&lt;br /&gt;
* Ambient is a constant color for every pixel.&lt;br /&gt;
* The diffuse coefficient is &amp;lt;math&amp;gt;\mathbf{N} \cdot \mathbf{L}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* The specular coefficient is &amp;lt;math&amp;gt;(\mathbf{R} \cdot \mathbf{V})^n&amp;lt;/math&amp;gt; where &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; is the &#039;&#039;shininess&#039;&#039;.&lt;br /&gt;
The final color is &amp;lt;math&amp;gt;k_{ambient} * ambientColor + k_{diffuse} * (\mathbf{N} \cdot \mathbf{L}) * diffuseColor + k_{specular} * (\mathbf{R} \cdot \mathbf{V})^n * specularColor&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* The diffuse and specular components need to be computed for every visible light source.&lt;br /&gt;
&lt;br /&gt;
===Physically Based===&lt;br /&gt;
See [https://static1.squarespace.com/static/58586fa5ebbd1a60e7d76d3e/t/593a3afa46c3c4a376d779f6/1496988449807/s2012_pbs_disney_brdf_notes_v2.pdf pbs disney brdf notes] and the [http://www.pbr-book.org/ pbr-book]  &lt;br /&gt;
In frameworks and libraries, these are often refered to as &#039;&#039;standard materials&#039;&#039; or in Blender, &#039;&#039;Principled BSDF&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Blending and Pixel Formats==&lt;br /&gt;
&lt;br /&gt;
===Pixel Formats===&lt;br /&gt;
&lt;br /&gt;
===Blending===&lt;br /&gt;
&lt;br /&gt;
To output transparent images, i.e. images with alpha, you&#039;ll generally want to blend using [[Premultiplied Alpha]]. Rendering in premultiplied alpha prevents your RGB color values from getting mixed with the background color empty pixels.&lt;br /&gt;
&lt;br /&gt;
===Rendering===&lt;br /&gt;
&lt;br /&gt;
For rasterization, the render loop typically consists of:&lt;br /&gt;
# Render the shadow map.&lt;br /&gt;
# Render all opaque objects front-to-back.&lt;br /&gt;
## Opaque objects write to the depth buffer.&lt;br /&gt;
# Render all transparent objects back-to-front&lt;br /&gt;
## Transparent objects do not write to the depth buffer.&lt;br /&gt;
&lt;br /&gt;
Rendering opaque objects front to back minimizes overdraw, where a pixel gets drawn to multiple times in a single frame.&lt;br /&gt;
Rendering transparent objects back to front is needed for proper blending of transparent materials.&lt;br /&gt;
&lt;br /&gt;
==Anti-aliasing==&lt;br /&gt;
For a high-quality anti-aliasing, you&#039;ll generally want to multiple multi-sampling (MSAA).&lt;br /&gt;
This causes the GPU to render the depth buffer at a higher resolution to determine the contribution of your fragment shader&#039;s color to the final image.&lt;br /&gt;
&lt;br /&gt;
See https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing#:~:text=How%20MSAA%20really%20works%20is,buffer%20to%20determine%20subsample%20coverage for more details.&lt;br /&gt;
&lt;br /&gt;
==More Terms==&lt;br /&gt;
* [[Wikipedia: Diffuse reflection | Diffuse reflection]] - reflection scattered in many directions (i.e. matte)&lt;br /&gt;
* [[Wikipedia: Specular reflection | Specular reflection]] - mirror reflection&lt;br /&gt;
* [[Wikipedia: Refraction | Refraction]] - change in direction of light as it passes through a material&lt;br /&gt;
&lt;br /&gt;
==Resources==&lt;br /&gt;
* [https://www.udacity.com/course/interactive-3d-graphics--cs291 Udacity Interactive 3D Graphics]&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=FFmpeg&amp;diff=7160</id>
		<title>FFmpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=FFmpeg&amp;diff=7160"/>
		<updated>2025-06-05T06:01:23Z</updated>

		<summary type="html">&lt;p&gt;David: /* My Preferences */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://ffmpeg.org/ FFmpeg] (Fast Forward MPEG) is a library for encoding and decoding multimedia.&lt;br /&gt;
&lt;br /&gt;
You can interact with FFmpeg using their command-line interface or using their [https://ffmpeg.org/doxygen/trunk/index.html C API].  &lt;br /&gt;
Note that a lot of things involving just decoding or encoding can be done by calling their CLI application and piping things to stdin or from stdout.&lt;br /&gt;
&lt;br /&gt;
==CLI==&lt;br /&gt;
You can download static builds of FFmpeg from&lt;br /&gt;
* Linux: [https://johnvansickle.com/ffmpeg/ https://johnvansickle.com/ffmpeg/]&lt;br /&gt;
* Windows: [https://ffmpeg.zeranoe.com/builds/ https://ffmpeg.zeranoe.com/builds/]&lt;br /&gt;
&lt;br /&gt;
If you need nvenc support, you can build FFmpeg with https://github.com/markus-perl/ffmpeg-build-script.&lt;br /&gt;
&lt;br /&gt;
Basic usage is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg [-ss start_second] -i input_file [-s resolution] [-b bitrate] [-t time] [-r output_framerate] output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-pattern_type glob&amp;lt;/code&amp;gt; for wildcards (e.g. all images in a folder)&lt;br /&gt;
&lt;br /&gt;
===x264===&lt;br /&gt;
x264 is a software h264 decoder and encoder.&amp;lt;br&amp;gt;&lt;br /&gt;
[https://trac.ffmpeg.org/wiki/Encode/H.264]&lt;br /&gt;
&lt;br /&gt;
===Changing Pixel Format===&lt;br /&gt;
Encode to h264 with YUV420p pixel format&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -c:v libx264 -profile:v high -pix_fmt yuv420p output.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Images to Video===&lt;br /&gt;
[https://en.wikibooks.org/wiki/FFMPEG_An_Intermediate_Guide/image_sequence Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Assuming 60 images per second and you want a 30 fps video.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make sure -framerate is before -i&lt;br /&gt;
ffmpeg -framerate 60 -i image-%03d.png -r 30 video.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Video to Images===&lt;br /&gt;
Extracting frames from a video&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i video.mp4 frames/%d.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-ss H:M:S&amp;lt;/code&amp;gt; to specify where to start before you input the video&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-vframes 1&amp;lt;/code&amp;gt; to extract one frames&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-vf &amp;quot;select=not(mod(n\,10))&amp;quot;&amp;lt;/code&amp;gt; to select every 10th frame&lt;br /&gt;
&lt;br /&gt;
===Get a list of encoders/decoders===&lt;br /&gt;
[https://superuser.com/questions/1236275/how-can-i-use-crf-encoding-with-nvenc-in-ffmpeg Reference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for i in encoders decoders filters; do&lt;br /&gt;
    echo $i:; ffmpeg -hide_banner -${i} | egrep -i &amp;quot;npp|cuvid|nvenc|cuda&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===PSNR/SSIM===&lt;br /&gt;
[https://github.com/stoyanovgeorge/ffmpeg/wiki/How-to-Compare-Video Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
FFmpeg can compare two videos and output the psnr or ssim numbers for each of the y, u, and v channels.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i distorted.mp4 -i reference.mp4 \&lt;br /&gt;
       -lavfi &amp;quot;ssim;[0:v][1:v]psnr&amp;quot; -f null –&lt;br /&gt;
&lt;br /&gt;
ffmpeg -i distorted.mp4 -i reference.mp4 -lavfi  psnr -f null -&lt;br /&gt;
ffmpeg -i distorted.mp4 -i reference.mp4 -lavfi  ssim -f null -&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generate Thumbnails===&lt;br /&gt;
[https://superuser.com/questions/1099491/batch-extract-thumbnails-with-ffmpeg Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Below is a bash script to generate all thumbnails in a folder&lt;br /&gt;
{{hidden|Script|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
&lt;br /&gt;
OUTPUT_FOLDER=&amp;quot;thumbnails&amp;quot;&lt;br /&gt;
&lt;br /&gt;
mkdir -p $OUTPUT_FOLDER&lt;br /&gt;
for file in *.mp4;&lt;br /&gt;
  do ffmpeg -i &amp;quot;$file&amp;quot; -vf &amp;quot;select=gte(n\,300)&amp;quot; -vframes 1 &amp;quot;$OUTPUT_FOLDER/${file%.mp4}.png&amp;quot;;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===MP4 to GIF===&lt;br /&gt;
Normally you can just do&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i my_video.mp4 my_video.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want better quality, you can use the following filter_complex:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[0]split=2[v1][v2];[v1]palettegen=stats_mode=full[palette];[v2][palette]paletteuse=dither=sierra2_4a&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is another script from [https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality]&lt;br /&gt;
{{hidden | mp4 to gif script |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
ffmpeg -i $1 -vf &amp;quot;fps=15,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse&amp;quot; -loop 0 $2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Pipe to stdout===&lt;br /&gt;
Below is an example of piping the video only to stdout:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i video.webm -pix_fmt rgb24 -f rawvideo -&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python, you can read it as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
video_width = 1920&lt;br /&gt;
video_height = 1080&lt;br /&gt;
ffmpeg_process = subprocess.Popen(ffmpeg_command,&lt;br /&gt;
                                  stdout=subprocess.PIPE,&lt;br /&gt;
                                  stderr=subprocess.PIPE)&lt;br /&gt;
raw_image = ffmpeg_process.stdout.read(&lt;br /&gt;
              video_width * video_height * 3)&lt;br /&gt;
image = (np.frombuffer(raw_image, dtype=np.uint8)&lt;br /&gt;
           .reshape(video_height, video_width, 3))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Filters==&lt;br /&gt;
Filters are part of the CLI&amp;lt;br&amp;gt;&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html https://ffmpeg.org/ffmpeg-filters.html]&lt;br /&gt;
&lt;br /&gt;
===Crop===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input_filename -vf  &amp;quot;crop=w:h:x:y&amp;quot; output_filename&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Here &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; are the top left corners of your crop. &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; are the height and width of the final image or video.&lt;br /&gt;
&lt;br /&gt;
===Resizing/Scaling===&lt;br /&gt;
[https://trac.ffmpeg.org/wiki/Scaling FFMpeg Scaling]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html#scale scale filter]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.avi -vf scale=320:240 output.avi&lt;br /&gt;
&lt;br /&gt;
ffmpeg -i input.jpg -vf scale=iw*2:ih input_double_width.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If the aspect ratio is not what you expect, try using the &amp;lt;code&amp;gt;setdar&amp;lt;/code&amp;gt; filter.&lt;br /&gt;
** E.g. &amp;lt;code&amp;gt;setdar=ratio=2/1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Resizing with transparent padding&lt;br /&gt;
Useful for generating logos&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i icon.svg -vf &amp;quot;scale=h=128:w=128:force_original_aspect_ratio=decrease,pad=128:128:(ow-iw)/2:(oh-ih)/2:color=0x00000000&amp;quot; -y icon.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{hidden | More sizes |&lt;br /&gt;
&lt;br /&gt;
;256&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i icon.svg -vf &amp;quot;scale=h=256:w=256:force_original_aspect_ratio=decrease,pad=256:256:(ow-iw)/2:(oh-ih)/2:color=0x00000000&amp;quot; -y icon.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;512&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i icon.svg -vf &amp;quot;scale=h=512:w=512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=0x00000000&amp;quot; -y icon.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Rotation===&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html#transpose transpose filter]&lt;br /&gt;
&lt;br /&gt;
To rotate 180 degrees&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;transpose=1,transpose=1&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 0 – Rotate by 90 degrees counter-clockwise and flip vertically.&lt;br /&gt;
* 1 – Rotate by 90 degrees clockwise.&lt;br /&gt;
* 2 – Rotate by 90 degrees counter-clockwise.&lt;br /&gt;
* 3 – Rotate by 90 degrees clockwise and flip vertically.&lt;br /&gt;
&lt;br /&gt;
===360 Video===&lt;br /&gt;
See [https://ffmpeg.org/ffmpeg-filters.html#v360 v360 filter]&lt;br /&gt;
&lt;br /&gt;
=====Converting EAC to equirectangular=====&lt;br /&gt;
Youtube sometimes uses an EAC format. You can convert this to the traditional equirectangular format as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;v360=eac:e&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes you may run into errors where height or width is not divisible by 2.&amp;lt;br&amp;gt;&lt;br /&gt;
Apply a scale filter to fix this issue.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;v360=eac:e,scale=iw:-2&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Converting to rectilinear====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;v360=e:rectilinear:h_fov=90:v_fov=90&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Metadata====&lt;br /&gt;
To add 360 video metadata, you should use [https://github.com/google/spatial-media Google&#039;s spatial-media].&lt;br /&gt;
This will add the following sidedata which you can see using &amp;lt;code&amp;gt;ffprobe&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Side data:&lt;br /&gt;
 spherical: equirectangular (0.000000/0.000000/0.000000) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Removing Duplicate Frames===&lt;br /&gt;
[https://stackoverflow.com/questions/37088517/remove-sequentially-duplicate-frames-when-using-ffmpeg Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html#mpdecimate mpdecimate filter]&lt;br /&gt;
&lt;br /&gt;
Useful for extracting frames from timelapses.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf mpdecimate,setpts=N/FRAME_RATE/TB out.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Stack and Unstack===&lt;br /&gt;
To stack, see [https://ffmpeg.org/ffmpeg-all.html#hstack &amp;lt;code&amp;gt;hstack&amp;lt;/code&amp;gt;], [https://ffmpeg.org/ffmpeg-all.html#vstack &amp;lt;code&amp;gt;vstack&amp;lt;/code&amp;gt;].  &lt;br /&gt;
To unstack, see &amp;lt;code&amp;gt;crop&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Filter-Complex===&lt;br /&gt;
Filter complex allows you to create a graph of filters.&lt;br /&gt;
&lt;br /&gt;
Suppose you have 3 inputs: $1, $2, $3.  &lt;br /&gt;
Then you can access them as streams [0], [1], [3].  &lt;br /&gt;
The filter syntax allows you to chain multiple filters where each filter is an edge.  &lt;br /&gt;
For example, &amp;lt;code&amp;gt;[0]split[t1][t2]&amp;lt;/code&amp;gt; creates two vertices t1 and t2 from input 0.&lt;br /&gt;
The last statement in your edge will be the output of your command:  &lt;br /&gt;
E.g. &amp;lt;code&amp;gt;[t1][t2]vstack&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i $1 -i $2 -i $3 -filter_complex &amp;quot;[0]split[t1][t2];[t1][t2]vstack&amp;quot; output.mkv -y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Concatenate Videos===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i part_1.mp4 \&lt;br /&gt;
    -i part_2.mp4 \&lt;br /&gt;
    -i part_3.mp4 \&lt;br /&gt;
    -filter_complex \&lt;br /&gt;
    &amp;quot;[0]scale=1920:1080[0s];\&lt;br /&gt;
     [1]scale=1920:1080[1s];\&lt;br /&gt;
     [2]scale=1920:1080[2s];\&lt;br /&gt;
     [0s][0:a][1s][1:a][2s][2:a]concat=n=3:v=1:a=1[v][a]&amp;quot; \&lt;br /&gt;
    -map &amp;quot;[v]&amp;quot; -map &amp;quot;[a]&amp;quot; \&lt;br /&gt;
    -vsync 2 \&lt;br /&gt;
    all_parts.mp4 -y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Replace transparency===&lt;br /&gt;
[https://superuser.com/questions/1341674/ffmpeg-convert-transparency-to-a-certain-color Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Add a background to transparent images.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i in.mov -filter_complex &amp;quot;[0]format=pix_fmts=yuva420p,split=2[bg][fg];[bg]drawbox=c=white@1:replace=1:t=fill[bg];[bg][fg]overlay=format=auto&amp;quot; -c:a copy new.mov&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Draw Text===&lt;br /&gt;
https://stackoverflow.com/questions/15364861/frame-number-overlay-with-ffmpeg&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input -vf &amp;quot;drawtext=fontfile=Arial.ttf: text=&#039;%{frame_num}&#039;: start_number=1: x=(w-tw)/2: y=h-(2*lh): fontcolor=black: fontsize=20: box=1: boxcolor=white: boxborderw=5&amp;quot; -c:a copy output&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==C API==&lt;br /&gt;
A doxygen reference manual for their C api is available at [https://ffmpeg.org/doxygen/trunk/index.html].&amp;lt;br&amp;gt;&lt;br /&gt;
Note that FFmpeg is licensed under GPL.&amp;lt;br&amp;gt;&lt;br /&gt;
If you only need to do encoding and decoding, you can simply pipe the inputs and outputs of the FFmpeg CLI to your program [https://batchloaf.wordpress.com/2017/02/12/a-simple-way-to-read-and-write-audio-and-video-files-in-c-using-ffmpeg-part-2-video/].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
Best way to get started is to look at the [https://ffmpeg.org/doxygen/trunk/examples.html official examples].&lt;br /&gt;
&lt;br /&gt;
====Structs====&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVInputFormat.html &amp;lt;code&amp;gt;AVInputFormat&amp;lt;/code&amp;gt;]/[https://www.ffmpeg.org/doxygen/trunk/structAVOutputFormat.html &amp;lt;code&amp;gt;AVOutputFormat&amp;lt;/code&amp;gt;] Represents a container type.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVFormatContext.html &amp;lt;code&amp;gt;AVFormatContext&amp;lt;/code&amp;gt;] Represents your specific container.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVStream.html &amp;lt;code&amp;gt;AVStream&amp;lt;/code&amp;gt;] Represents a single audio, video, or data stream in your container.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVCodec.html &amp;lt;code&amp;gt;AVCodec&amp;lt;/code&amp;gt;] Represents a single codec (e.g. H.264)&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVCodecContext.html &amp;lt;code&amp;gt;AVCodecContext&amp;lt;/code&amp;gt;] Represents your specific codec and contains all associated paramters (e.g. resolution, bitrate, fps).&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVPacket.html &amp;lt;code&amp;gt;AVPacket&amp;lt;/code&amp;gt;] Compressed Data.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVFrame.html &amp;lt;code&amp;gt;AVFrame&amp;lt;/code&amp;gt;] Decoded audio or video data.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structSwsContext.html &amp;lt;code&amp;gt;SwsContext&amp;lt;/code&amp;gt;] Used for image scaling and colorspace and pixel format conversion operations.&lt;br /&gt;
&lt;br /&gt;
====Pixel Formats====&lt;br /&gt;
[https://www.ffmpeg.org/doxygen/4.0/pixfmt_8h.html Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Pixel formats are stored as &amp;lt;code&amp;gt;AVPixelFormat&amp;lt;/code&amp;gt; enums.&amp;lt;br&amp;gt;&lt;br /&gt;
Below are descriptions for a few common pixel formats.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that the exact sizes of buffers may vary depending on alignment.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;AV_PIX_FMT_RGB24&lt;br /&gt;
* This is your standard 24 bits per pixel RGB.&amp;lt;br&amp;gt;&lt;br /&gt;
* In your AVFrame, data[0] will contain your single buffer RGBRGBRGB.&amp;lt;br&amp;gt;&lt;br /&gt;
* Where the linesize is typically &amp;lt;math&amp;gt;3 * width&amp;lt;/math&amp;gt; bytes per row and &amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; bytes per pixel.&lt;br /&gt;
&lt;br /&gt;
;AV_PIX_FMT_YUV420P&lt;br /&gt;
* This is a planar YUV pixel format with chroma subsampling.&amp;lt;br&amp;gt;&lt;br /&gt;
* Each pixel will have its own luma component (Y) but each &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; block of pixels will share chrominance components (U, V)&amp;lt;br&amp;gt;&lt;br /&gt;
* In your AVFrame, data[0] will contain your Y image, data[1] will contain your .&amp;lt;br&amp;gt;&lt;br /&gt;
* Data[0] will typically be &amp;lt;math&amp;gt;width * height&amp;lt;/math&amp;gt; bytes.&amp;lt;br&amp;gt;&lt;br /&gt;
* Data[1] and data[2] will typically be &amp;lt;math&amp;gt;width * height / 4&amp;lt;/math&amp;gt; bytes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Muxing to memory===&lt;br /&gt;
You can specify a custom &amp;lt;code&amp;gt;AVIOContext&amp;lt;/code&amp;gt; and attach it to your &amp;lt;code&amp;gt;AVFormatContext-&amp;gt;pb&amp;lt;/code&amp;gt; to mux directly to memory or to implement your own buffering.&lt;br /&gt;
&lt;br /&gt;
===NVENC===&lt;br /&gt;
[https://superuser.com/questions/1296374/best-settings-for-ffmpeg-with-nvenc Options Reference]&lt;br /&gt;
&lt;br /&gt;
When encoding using NVENC, your &amp;lt;code&amp;gt;codec_ctx-&amp;gt;priv_data&amp;lt;/code&amp;gt; is a pointer to a &amp;lt;code&amp;gt;NvencContext&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To list all of the things you can set in the private data, you can type the following in bash&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -hide_banner -h encoder=h264_nvenc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{ hidden | NVENC Codec Ctx |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
  if ((ret = av_hwdevice_ctx_create(&amp;amp;hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, NULL,&lt;br /&gt;
                                    NULL, 0)) &amp;lt; 0) {&lt;br /&gt;
    cerr &amp;lt;&amp;lt; &amp;quot;[VideoEncoder::VideoEncoder] Failed to create hw context&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (!(codec = avcodec_find_encoder_by_name(&amp;quot;h264_nvenc&amp;quot;))) {&lt;br /&gt;
    cerr &amp;lt;&amp;lt; &amp;quot;[VideoEncoder::VideoEncoder] Failed to find h264_nvenc encoder&amp;quot;&lt;br /&gt;
         &amp;lt;&amp;lt; endl;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  codec_ctx = avcodec_alloc_context3(codec);&lt;br /&gt;
  codec_ctx-&amp;gt;bit_rate = 2500000;&lt;br /&gt;
  codec_ctx-&amp;gt;width = source_codec_ctx-&amp;gt;width;&lt;br /&gt;
  codec_ctx-&amp;gt;height = source_codec_ctx-&amp;gt;height;&lt;br /&gt;
  codec_ctx-&amp;gt;codec_type = AVMEDIA_TYPE_VIDEO;&lt;br /&gt;
  codec_ctx-&amp;gt;time_base = source_codec_ctx-&amp;gt;time_base;&lt;br /&gt;
  input_timebase = source_codec_ctx-&amp;gt;time_base;&lt;br /&gt;
  codec_ctx-&amp;gt;framerate = source_codec_ctx-&amp;gt;framerate;&lt;br /&gt;
  codec_ctx-&amp;gt;pix_fmt = AV_PIX_FMT_CUDA;&lt;br /&gt;
  codec_ctx-&amp;gt;profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;&lt;br /&gt;
  codec_ctx-&amp;gt;max_b_frames = 0;&lt;br /&gt;
  codec_ctx-&amp;gt;delay = 0;&lt;br /&gt;
  codec_ctx-&amp;gt;gop_size = 0;&lt;br /&gt;
// Todo: figure out which ones of these do nothing&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;cq&amp;quot;, &amp;quot;23&amp;quot;, AV_OPT_SEARCH_CHILDREN);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;preset&amp;quot;, &amp;quot;llhp&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;tune&amp;quot;, &amp;quot;zerolatency&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;look_ahead&amp;quot;, &amp;quot;0&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;zerolatency&amp;quot;, &amp;quot;1&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;nb_surfaces&amp;quot;, &amp;quot;0&amp;quot;, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==C++ API==&lt;br /&gt;
FFmpeg does not have an official C++ API.&amp;lt;br&amp;gt;&lt;br /&gt;
There are wrappers such as [https://github.com/Raveler/ffmpeg-cpp Raveler/ffmpeg-cpp] which you can use.&amp;lt;br&amp;gt;&lt;br /&gt;
However, I recommend just using the C API and wrapping things in smart pointers.&lt;br /&gt;
&lt;br /&gt;
==Python API==&lt;br /&gt;
You can try [https://github.com/PyAV-Org/PyAV pyav] which contains bindings for the library. However I haven&#039;t tried it.  &lt;br /&gt;
If you just need to call the CLI, you can use [https://github.com/kkroening/ffmpeg-python ffmpeg-python] to help build calls.&lt;br /&gt;
&lt;br /&gt;
==JavaScript API==&lt;br /&gt;
To use FFmpeg in a browser, see [https://ffmpegwasm.netlify.app/ ffmpegwasm].  &lt;br /&gt;
This is used in https://davidl.me/apps/media/index.html.&lt;br /&gt;
&lt;br /&gt;
==My Preferences==&lt;br /&gt;
My preferences for encoding video&lt;br /&gt;
&lt;br /&gt;
===AV1===&lt;br /&gt;
Prefer AV1 for encoding video on on modern devices.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===H265/HEVC===&lt;br /&gt;
H264/HEVC is now a good tradeoff between size, quality, and compatibility.&lt;br /&gt;
This has been supported on devices since Android 5.0 (2014).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i $1 -c:v libx265 -crf 23 -preset slow -pix_fmt yuv444p10le -c:a libopus -b:a 128K $2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* The pixel format &amp;lt;code&amp;gt;yuv444p10le&amp;lt;/code&amp;gt; is 10 bit color without chroma subsampling. If your source is lower, you can use &amp;lt;code&amp;gt;yuv420p&amp;lt;/code&amp;gt; instead for 8-bit color and 4:2:0 chroma subsampling.&lt;br /&gt;
&lt;br /&gt;
===H264===&lt;br /&gt;
If you need compatability with very old and low end devices.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i $1 -c:v libx264 -crf 28 -preset medium -pix_fmt yuv420p -c:a libfdk_aac -b:a 128K $2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Opus===&lt;br /&gt;
&lt;br /&gt;
For streaming:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.wav -c:a libopus -b:a 96k output.opus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See https://wiki.xiph.org/Opus_Recommended_Settings&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
	<entry>
		<id>https://wiki.davidl.me/index.php?title=FFmpeg&amp;diff=7159</id>
		<title>FFmpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.davidl.me/index.php?title=FFmpeg&amp;diff=7159"/>
		<updated>2025-06-05T01:33:15Z</updated>

		<summary type="html">&lt;p&gt;David: /* Opus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://ffmpeg.org/ FFmpeg] (Fast Forward MPEG) is a library for encoding and decoding multimedia.&lt;br /&gt;
&lt;br /&gt;
You can interact with FFmpeg using their command-line interface or using their [https://ffmpeg.org/doxygen/trunk/index.html C API].  &lt;br /&gt;
Note that a lot of things involving just decoding or encoding can be done by calling their CLI application and piping things to stdin or from stdout.&lt;br /&gt;
&lt;br /&gt;
==CLI==&lt;br /&gt;
You can download static builds of FFmpeg from&lt;br /&gt;
* Linux: [https://johnvansickle.com/ffmpeg/ https://johnvansickle.com/ffmpeg/]&lt;br /&gt;
* Windows: [https://ffmpeg.zeranoe.com/builds/ https://ffmpeg.zeranoe.com/builds/]&lt;br /&gt;
&lt;br /&gt;
If you need nvenc support, you can build FFmpeg with https://github.com/markus-perl/ffmpeg-build-script.&lt;br /&gt;
&lt;br /&gt;
Basic usage is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg [-ss start_second] -i input_file [-s resolution] [-b bitrate] [-t time] [-r output_framerate] output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-pattern_type glob&amp;lt;/code&amp;gt; for wildcards (e.g. all images in a folder)&lt;br /&gt;
&lt;br /&gt;
===x264===&lt;br /&gt;
x264 is a software h264 decoder and encoder.&amp;lt;br&amp;gt;&lt;br /&gt;
[https://trac.ffmpeg.org/wiki/Encode/H.264]&lt;br /&gt;
&lt;br /&gt;
===Changing Pixel Format===&lt;br /&gt;
Encode to h264 with YUV420p pixel format&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -c:v libx264 -profile:v high -pix_fmt yuv420p output.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Images to Video===&lt;br /&gt;
[https://en.wikibooks.org/wiki/FFMPEG_An_Intermediate_Guide/image_sequence Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Assuming 60 images per second and you want a 30 fps video.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Make sure -framerate is before -i&lt;br /&gt;
ffmpeg -framerate 60 -i image-%03d.png -r 30 video.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Video to Images===&lt;br /&gt;
Extracting frames from a video&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i video.mp4 frames/%d.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-ss H:M:S&amp;lt;/code&amp;gt; to specify where to start before you input the video&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-vframes 1&amp;lt;/code&amp;gt; to extract one frames&lt;br /&gt;
* Use &amp;lt;code&amp;gt;-vf &amp;quot;select=not(mod(n\,10))&amp;quot;&amp;lt;/code&amp;gt; to select every 10th frame&lt;br /&gt;
&lt;br /&gt;
===Get a list of encoders/decoders===&lt;br /&gt;
[https://superuser.com/questions/1236275/how-can-i-use-crf-encoding-with-nvenc-in-ffmpeg Reference]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for i in encoders decoders filters; do&lt;br /&gt;
    echo $i:; ffmpeg -hide_banner -${i} | egrep -i &amp;quot;npp|cuvid|nvenc|cuda&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===PSNR/SSIM===&lt;br /&gt;
[https://github.com/stoyanovgeorge/ffmpeg/wiki/How-to-Compare-Video Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
FFmpeg can compare two videos and output the psnr or ssim numbers for each of the y, u, and v channels.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i distorted.mp4 -i reference.mp4 \&lt;br /&gt;
       -lavfi &amp;quot;ssim;[0:v][1:v]psnr&amp;quot; -f null –&lt;br /&gt;
&lt;br /&gt;
ffmpeg -i distorted.mp4 -i reference.mp4 -lavfi  psnr -f null -&lt;br /&gt;
ffmpeg -i distorted.mp4 -i reference.mp4 -lavfi  ssim -f null -&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generate Thumbnails===&lt;br /&gt;
[https://superuser.com/questions/1099491/batch-extract-thumbnails-with-ffmpeg Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Below is a bash script to generate all thumbnails in a folder&lt;br /&gt;
{{hidden|Script|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
&lt;br /&gt;
OUTPUT_FOLDER=&amp;quot;thumbnails&amp;quot;&lt;br /&gt;
&lt;br /&gt;
mkdir -p $OUTPUT_FOLDER&lt;br /&gt;
for file in *.mp4;&lt;br /&gt;
  do ffmpeg -i &amp;quot;$file&amp;quot; -vf &amp;quot;select=gte(n\,300)&amp;quot; -vframes 1 &amp;quot;$OUTPUT_FOLDER/${file%.mp4}.png&amp;quot;;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===MP4 to GIF===&lt;br /&gt;
Normally you can just do&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i my_video.mp4 my_video.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want better quality, you can use the following filter_complex:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[0]split=2[v1][v2];[v1]palettegen=stats_mode=full[palette];[v2][palette]paletteuse=dither=sierra2_4a&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is another script from [https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality]&lt;br /&gt;
{{hidden | mp4 to gif script |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
ffmpeg -i $1 -vf &amp;quot;fps=15,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse&amp;quot; -loop 0 $2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Pipe to stdout===&lt;br /&gt;
Below is an example of piping the video only to stdout:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i video.webm -pix_fmt rgb24 -f rawvideo -&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python, you can read it as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
video_width = 1920&lt;br /&gt;
video_height = 1080&lt;br /&gt;
ffmpeg_process = subprocess.Popen(ffmpeg_command,&lt;br /&gt;
                                  stdout=subprocess.PIPE,&lt;br /&gt;
                                  stderr=subprocess.PIPE)&lt;br /&gt;
raw_image = ffmpeg_process.stdout.read(&lt;br /&gt;
              video_width * video_height * 3)&lt;br /&gt;
image = (np.frombuffer(raw_image, dtype=np.uint8)&lt;br /&gt;
           .reshape(video_height, video_width, 3))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Filters==&lt;br /&gt;
Filters are part of the CLI&amp;lt;br&amp;gt;&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html https://ffmpeg.org/ffmpeg-filters.html]&lt;br /&gt;
&lt;br /&gt;
===Crop===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input_filename -vf  &amp;quot;crop=w:h:x:y&amp;quot; output_filename&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Here &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; are the top left corners of your crop. &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; are the height and width of the final image or video.&lt;br /&gt;
&lt;br /&gt;
===Resizing/Scaling===&lt;br /&gt;
[https://trac.ffmpeg.org/wiki/Scaling FFMpeg Scaling]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html#scale scale filter]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.avi -vf scale=320:240 output.avi&lt;br /&gt;
&lt;br /&gt;
ffmpeg -i input.jpg -vf scale=iw*2:ih input_double_width.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If the aspect ratio is not what you expect, try using the &amp;lt;code&amp;gt;setdar&amp;lt;/code&amp;gt; filter.&lt;br /&gt;
** E.g. &amp;lt;code&amp;gt;setdar=ratio=2/1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Resizing with transparent padding&lt;br /&gt;
Useful for generating logos&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i icon.svg -vf &amp;quot;scale=h=128:w=128:force_original_aspect_ratio=decrease,pad=128:128:(ow-iw)/2:(oh-ih)/2:color=0x00000000&amp;quot; -y icon.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{hidden | More sizes |&lt;br /&gt;
&lt;br /&gt;
;256&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i icon.svg -vf &amp;quot;scale=h=256:w=256:force_original_aspect_ratio=decrease,pad=256:256:(ow-iw)/2:(oh-ih)/2:color=0x00000000&amp;quot; -y icon.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;512&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i icon.svg -vf &amp;quot;scale=h=512:w=512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=0x00000000&amp;quot; -y icon.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Rotation===&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html#transpose transpose filter]&lt;br /&gt;
&lt;br /&gt;
To rotate 180 degrees&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;transpose=1,transpose=1&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 0 – Rotate by 90 degrees counter-clockwise and flip vertically.&lt;br /&gt;
* 1 – Rotate by 90 degrees clockwise.&lt;br /&gt;
* 2 – Rotate by 90 degrees counter-clockwise.&lt;br /&gt;
* 3 – Rotate by 90 degrees clockwise and flip vertically.&lt;br /&gt;
&lt;br /&gt;
===360 Video===&lt;br /&gt;
See [https://ffmpeg.org/ffmpeg-filters.html#v360 v360 filter]&lt;br /&gt;
&lt;br /&gt;
=====Converting EAC to equirectangular=====&lt;br /&gt;
Youtube sometimes uses an EAC format. You can convert this to the traditional equirectangular format as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;v360=eac:e&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes you may run into errors where height or width is not divisible by 2.&amp;lt;br&amp;gt;&lt;br /&gt;
Apply a scale filter to fix this issue.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;v360=eac:e,scale=iw:-2&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Converting to rectilinear====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf &amp;quot;v360=e:rectilinear:h_fov=90:v_fov=90&amp;quot; output.mp4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Metadata====&lt;br /&gt;
To add 360 video metadata, you should use [https://github.com/google/spatial-media Google&#039;s spatial-media].&lt;br /&gt;
This will add the following sidedata which you can see using &amp;lt;code&amp;gt;ffprobe&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Side data:&lt;br /&gt;
 spherical: equirectangular (0.000000/0.000000/0.000000) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Removing Duplicate Frames===&lt;br /&gt;
[https://stackoverflow.com/questions/37088517/remove-sequentially-duplicate-frames-when-using-ffmpeg Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://ffmpeg.org/ffmpeg-filters.html#mpdecimate mpdecimate filter]&lt;br /&gt;
&lt;br /&gt;
Useful for extracting frames from timelapses.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.mp4 -vf mpdecimate,setpts=N/FRAME_RATE/TB out.mp4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Stack and Unstack===&lt;br /&gt;
To stack, see [https://ffmpeg.org/ffmpeg-all.html#hstack &amp;lt;code&amp;gt;hstack&amp;lt;/code&amp;gt;], [https://ffmpeg.org/ffmpeg-all.html#vstack &amp;lt;code&amp;gt;vstack&amp;lt;/code&amp;gt;].  &lt;br /&gt;
To unstack, see &amp;lt;code&amp;gt;crop&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Filter-Complex===&lt;br /&gt;
Filter complex allows you to create a graph of filters.&lt;br /&gt;
&lt;br /&gt;
Suppose you have 3 inputs: $1, $2, $3.  &lt;br /&gt;
Then you can access them as streams [0], [1], [3].  &lt;br /&gt;
The filter syntax allows you to chain multiple filters where each filter is an edge.  &lt;br /&gt;
For example, &amp;lt;code&amp;gt;[0]split[t1][t2]&amp;lt;/code&amp;gt; creates two vertices t1 and t2 from input 0.&lt;br /&gt;
The last statement in your edge will be the output of your command:  &lt;br /&gt;
E.g. &amp;lt;code&amp;gt;[t1][t2]vstack&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i $1 -i $2 -i $3 -filter_complex &amp;quot;[0]split[t1][t2];[t1][t2]vstack&amp;quot; output.mkv -y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Concatenate Videos===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i part_1.mp4 \&lt;br /&gt;
    -i part_2.mp4 \&lt;br /&gt;
    -i part_3.mp4 \&lt;br /&gt;
    -filter_complex \&lt;br /&gt;
    &amp;quot;[0]scale=1920:1080[0s];\&lt;br /&gt;
     [1]scale=1920:1080[1s];\&lt;br /&gt;
     [2]scale=1920:1080[2s];\&lt;br /&gt;
     [0s][0:a][1s][1:a][2s][2:a]concat=n=3:v=1:a=1[v][a]&amp;quot; \&lt;br /&gt;
    -map &amp;quot;[v]&amp;quot; -map &amp;quot;[a]&amp;quot; \&lt;br /&gt;
    -vsync 2 \&lt;br /&gt;
    all_parts.mp4 -y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Replace transparency===&lt;br /&gt;
[https://superuser.com/questions/1341674/ffmpeg-convert-transparency-to-a-certain-color Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Add a background to transparent images.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i in.mov -filter_complex &amp;quot;[0]format=pix_fmts=yuva420p,split=2[bg][fg];[bg]drawbox=c=white@1:replace=1:t=fill[bg];[bg][fg]overlay=format=auto&amp;quot; -c:a copy new.mov&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Draw Text===&lt;br /&gt;
https://stackoverflow.com/questions/15364861/frame-number-overlay-with-ffmpeg&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ffmpeg -i input -vf &amp;quot;drawtext=fontfile=Arial.ttf: text=&#039;%{frame_num}&#039;: start_number=1: x=(w-tw)/2: y=h-(2*lh): fontcolor=black: fontsize=20: box=1: boxcolor=white: boxborderw=5&amp;quot; -c:a copy output&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==C API==&lt;br /&gt;
A doxygen reference manual for their C api is available at [https://ffmpeg.org/doxygen/trunk/index.html].&amp;lt;br&amp;gt;&lt;br /&gt;
Note that FFmpeg is licensed under GPL.&amp;lt;br&amp;gt;&lt;br /&gt;
If you only need to do encoding and decoding, you can simply pipe the inputs and outputs of the FFmpeg CLI to your program [https://batchloaf.wordpress.com/2017/02/12/a-simple-way-to-read-and-write-audio-and-video-files-in-c-using-ffmpeg-part-2-video/].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
Best way to get started is to look at the [https://ffmpeg.org/doxygen/trunk/examples.html official examples].&lt;br /&gt;
&lt;br /&gt;
====Structs====&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVInputFormat.html &amp;lt;code&amp;gt;AVInputFormat&amp;lt;/code&amp;gt;]/[https://www.ffmpeg.org/doxygen/trunk/structAVOutputFormat.html &amp;lt;code&amp;gt;AVOutputFormat&amp;lt;/code&amp;gt;] Represents a container type.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVFormatContext.html &amp;lt;code&amp;gt;AVFormatContext&amp;lt;/code&amp;gt;] Represents your specific container.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVStream.html &amp;lt;code&amp;gt;AVStream&amp;lt;/code&amp;gt;] Represents a single audio, video, or data stream in your container.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVCodec.html &amp;lt;code&amp;gt;AVCodec&amp;lt;/code&amp;gt;] Represents a single codec (e.g. H.264)&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVCodecContext.html &amp;lt;code&amp;gt;AVCodecContext&amp;lt;/code&amp;gt;] Represents your specific codec and contains all associated paramters (e.g. resolution, bitrate, fps).&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVPacket.html &amp;lt;code&amp;gt;AVPacket&amp;lt;/code&amp;gt;] Compressed Data.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structAVFrame.html &amp;lt;code&amp;gt;AVFrame&amp;lt;/code&amp;gt;] Decoded audio or video data.&lt;br /&gt;
* [https://www.ffmpeg.org/doxygen/trunk/structSwsContext.html &amp;lt;code&amp;gt;SwsContext&amp;lt;/code&amp;gt;] Used for image scaling and colorspace and pixel format conversion operations.&lt;br /&gt;
&lt;br /&gt;
====Pixel Formats====&lt;br /&gt;
[https://www.ffmpeg.org/doxygen/4.0/pixfmt_8h.html Reference]&amp;lt;br&amp;gt;&lt;br /&gt;
Pixel formats are stored as &amp;lt;code&amp;gt;AVPixelFormat&amp;lt;/code&amp;gt; enums.&amp;lt;br&amp;gt;&lt;br /&gt;
Below are descriptions for a few common pixel formats.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that the exact sizes of buffers may vary depending on alignment.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;AV_PIX_FMT_RGB24&lt;br /&gt;
* This is your standard 24 bits per pixel RGB.&amp;lt;br&amp;gt;&lt;br /&gt;
* In your AVFrame, data[0] will contain your single buffer RGBRGBRGB.&amp;lt;br&amp;gt;&lt;br /&gt;
* Where the linesize is typically &amp;lt;math&amp;gt;3 * width&amp;lt;/math&amp;gt; bytes per row and &amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; bytes per pixel.&lt;br /&gt;
&lt;br /&gt;
;AV_PIX_FMT_YUV420P&lt;br /&gt;
* This is a planar YUV pixel format with chroma subsampling.&amp;lt;br&amp;gt;&lt;br /&gt;
* Each pixel will have its own luma component (Y) but each &amp;lt;math&amp;gt;2 \times 2&amp;lt;/math&amp;gt; block of pixels will share chrominance components (U, V)&amp;lt;br&amp;gt;&lt;br /&gt;
* In your AVFrame, data[0] will contain your Y image, data[1] will contain your .&amp;lt;br&amp;gt;&lt;br /&gt;
* Data[0] will typically be &amp;lt;math&amp;gt;width * height&amp;lt;/math&amp;gt; bytes.&amp;lt;br&amp;gt;&lt;br /&gt;
* Data[1] and data[2] will typically be &amp;lt;math&amp;gt;width * height / 4&amp;lt;/math&amp;gt; bytes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Muxing to memory===&lt;br /&gt;
You can specify a custom &amp;lt;code&amp;gt;AVIOContext&amp;lt;/code&amp;gt; and attach it to your &amp;lt;code&amp;gt;AVFormatContext-&amp;gt;pb&amp;lt;/code&amp;gt; to mux directly to memory or to implement your own buffering.&lt;br /&gt;
&lt;br /&gt;
===NVENC===&lt;br /&gt;
[https://superuser.com/questions/1296374/best-settings-for-ffmpeg-with-nvenc Options Reference]&lt;br /&gt;
&lt;br /&gt;
When encoding using NVENC, your &amp;lt;code&amp;gt;codec_ctx-&amp;gt;priv_data&amp;lt;/code&amp;gt; is a pointer to a &amp;lt;code&amp;gt;NvencContext&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To list all of the things you can set in the private data, you can type the following in bash&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -hide_banner -h encoder=h264_nvenc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{ hidden | NVENC Codec Ctx |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
  if ((ret = av_hwdevice_ctx_create(&amp;amp;hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, NULL,&lt;br /&gt;
                                    NULL, 0)) &amp;lt; 0) {&lt;br /&gt;
    cerr &amp;lt;&amp;lt; &amp;quot;[VideoEncoder::VideoEncoder] Failed to create hw context&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (!(codec = avcodec_find_encoder_by_name(&amp;quot;h264_nvenc&amp;quot;))) {&lt;br /&gt;
    cerr &amp;lt;&amp;lt; &amp;quot;[VideoEncoder::VideoEncoder] Failed to find h264_nvenc encoder&amp;quot;&lt;br /&gt;
         &amp;lt;&amp;lt; endl;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  codec_ctx = avcodec_alloc_context3(codec);&lt;br /&gt;
  codec_ctx-&amp;gt;bit_rate = 2500000;&lt;br /&gt;
  codec_ctx-&amp;gt;width = source_codec_ctx-&amp;gt;width;&lt;br /&gt;
  codec_ctx-&amp;gt;height = source_codec_ctx-&amp;gt;height;&lt;br /&gt;
  codec_ctx-&amp;gt;codec_type = AVMEDIA_TYPE_VIDEO;&lt;br /&gt;
  codec_ctx-&amp;gt;time_base = source_codec_ctx-&amp;gt;time_base;&lt;br /&gt;
  input_timebase = source_codec_ctx-&amp;gt;time_base;&lt;br /&gt;
  codec_ctx-&amp;gt;framerate = source_codec_ctx-&amp;gt;framerate;&lt;br /&gt;
  codec_ctx-&amp;gt;pix_fmt = AV_PIX_FMT_CUDA;&lt;br /&gt;
  codec_ctx-&amp;gt;profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;&lt;br /&gt;
  codec_ctx-&amp;gt;max_b_frames = 0;&lt;br /&gt;
  codec_ctx-&amp;gt;delay = 0;&lt;br /&gt;
  codec_ctx-&amp;gt;gop_size = 0;&lt;br /&gt;
// Todo: figure out which ones of these do nothing&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;cq&amp;quot;, &amp;quot;23&amp;quot;, AV_OPT_SEARCH_CHILDREN);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;preset&amp;quot;, &amp;quot;llhp&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;tune&amp;quot;, &amp;quot;zerolatency&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;look_ahead&amp;quot;, &amp;quot;0&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;zerolatency&amp;quot;, &amp;quot;1&amp;quot;, 0);&lt;br /&gt;
  av_opt_set(codec_ctx-&amp;gt;priv_data, &amp;quot;nb_surfaces&amp;quot;, &amp;quot;0&amp;quot;, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==C++ API==&lt;br /&gt;
FFmpeg does not have an official C++ API.&amp;lt;br&amp;gt;&lt;br /&gt;
There are wrappers such as [https://github.com/Raveler/ffmpeg-cpp Raveler/ffmpeg-cpp] which you can use.&amp;lt;br&amp;gt;&lt;br /&gt;
However, I recommend just using the C API and wrapping things in smart pointers.&lt;br /&gt;
&lt;br /&gt;
==Python API==&lt;br /&gt;
You can try [https://github.com/PyAV-Org/PyAV pyav] which contains bindings for the library. However I haven&#039;t tried it.  &lt;br /&gt;
If you just need to call the CLI, you can use [https://github.com/kkroening/ffmpeg-python ffmpeg-python] to help build calls.&lt;br /&gt;
&lt;br /&gt;
==JavaScript API==&lt;br /&gt;
To use FFmpeg in a browser, see [https://ffmpegwasm.netlify.app/ ffmpegwasm].  &lt;br /&gt;
This is used in https://davidl.me/apps/media/index.html.&lt;br /&gt;
&lt;br /&gt;
==My Preferences==&lt;br /&gt;
My preferences for encoding video&lt;br /&gt;
===H264===&lt;br /&gt;
H264 is best when you need the most compatability, especially with older or low end devices.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
!#/bin/bash&lt;br /&gt;
&lt;br /&gt;
ffmpeg -i $1 -c:v libx264 -crf 28 -preset medium -pix_fmt yuv420p -c:a libfdk_aac -b:a 128K $2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* MP4 is ok&lt;br /&gt;
&lt;br /&gt;
===H265/HEVC===&lt;br /&gt;
H264/HEVC is now a good tradeoff between size, quality, and compatability.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
!#/bin/bash&lt;br /&gt;
&lt;br /&gt;
ffmpeg -i $1 -c:v libx265 -crf 23 -preset slow -pix_fmt yuv444p10le -c:a libopus -b:a 128K $2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Notes&lt;br /&gt;
* You need to output to a MKV file&lt;br /&gt;
* The pixel format &amp;lt;code&amp;gt;yuv444p10le&amp;lt;/code&amp;gt; is 10 bit color without chroma subsampling. If your source is lower, you can use &amp;lt;code&amp;gt;yuv420p&amp;lt;/code&amp;gt; instead for 8-bit color and 4:2:0 chroma subsampling.&lt;br /&gt;
&lt;br /&gt;
===AV1===&lt;br /&gt;
&lt;br /&gt;
===Opus===&lt;br /&gt;
&lt;br /&gt;
For streaming:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ffmpeg -i input.wav -c:a libopus -b:a 96k output.opus&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See https://wiki.xiph.org/Opus_Recommended_Settings&lt;/div&gt;</summary>
		<author><name>David</name></author>
	</entry>
</feed>