13460 lines
No EOL
972 KiB
HTML
13460 lines
No EOL
972 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html class="no-js" lang="en">
|
|
<head>
|
|
<meta charset="utf-8"/>
|
|
<meta content="width=device-width,initial-scale=1" name="viewport"/>
|
|
<meta content="Electromagnetic simulation tools" name="description"/>
|
|
<link href="https://mpxd.net/docs/meanas/print_page/" rel="canonical"/>
|
|
<link href="../assets/images/favicon.png" rel="icon"/>
|
|
<meta content="mkdocs-1.6.1, mkdocs-material-9.7.6" name="generator"/>
|
|
<title>Print Site - meanas</title>
|
|
<link href="data:text/css,%40charset%20%22UTF-8%22%3Bhtml%7B-webkit-text-size-adjust%3Anone%3B-moz-text-size-adjust%3Anone%3Btext-size-adjust%3Anone%3Bbox-sizing%3Aborder-box%7D%2A%2C%3Aafter%2C%3Abefore%7Bbox-sizing%3Ainherit%7D%40media%20%28prefers-reduced-motion%29%7B%2A%2C%3Aafter%2C%3Abefore%7Btransition%3Anone%21important%7D%7Dbody%7Bmargin%3A0%7Da%2Cbutton%2Cinput%2Clabel%7B-webkit-tap-highlight-color%3Atransparent%7Da%7Bcolor%3Ainherit%3Btext-decoration%3Anone%7Dhr%7Bborder%3A0%3Bbox-sizing%3Ainitial%3Bdisplay%3Ablock%3Bheight%3A.05rem%3Boverflow%3Avisible%3Bpadding%3A0%7Dsmall%7Bfont-size%3A80%25%7Dsub%2Csup%7Bline-height%3A1em%7Dimg%7Bborder-style%3Anone%7Dtable%7Bborder-collapse%3Ainitial%3Bborder-spacing%3A0%7Dtd%2Cth%7Bfont-weight%3A400%3Bvertical-align%3Atop%7Dbutton%7Bbackground%3A%230000%3Bborder%3A0%3Bfont-family%3Ainherit%3Bfont-size%3Ainherit%3Bmargin%3A0%3Bpadding%3A0%7Dinput%7Bborder%3A0%3Boutline%3Anone%7D%3Aroot%7B--md-primary-fg-color%3A%234051b5%3B--md-primary-fg-color--light%3A%235d6cc0%3B--md-primary-fg-color--dark%3A%23303fa1%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%3B--md-accent-fg-color%3A%23526cfe%3B--md-accent-fg-color--transparent%3A%23526cfe1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-scheme%3Ddefault%5D%7Bcolor-scheme%3Alight%7D%5Bdata-md-color-scheme%3Ddefault%5D%20img%5Bsrc%24%3D%22%23gh-dark-mode-only%22%5D%2C%5Bdata-md-color-scheme%3Ddefault%5D%20img%5Bsrc%24%3D%22%23only-dark%22%5D%7Bdisplay%3Anone%7D%3Aroot%2C%5Bdata-md-color-scheme%3Ddefault%5D%7B--md-hue%3A225deg%3B--md-default-fg-color%3A%23000000de%3B--md-default-fg-color--light%3A%230000008a%3B--md-default-fg-color--lighter%3A%2300000052%3B--md-default-fg-color--lightest%3A%2300000012%3B--md-default-bg-color%3A%23fff%3B--md-default-bg-color--light%3A%23ffffffb3%3B--md-default-bg-color--lighter%3A%23ffffff4d%3B--md-default-bg-color--lightest%3A%23ffffff1f%3B--md-code-fg-color%3A%2336464e%3B--md-code-bg-color%3A%23f5f5f5%3B--md-code-bg-color--light%3A%23f5f5f5b3%3B--md-code-bg-color--lighter%3A%23f5f5f54d%3B--md-code-hl-color%3A%234287ff%3B--md-code-hl-color--light%3A%234287ff1a%3B--md-code-hl-number-color%3A%23d52a2a%3B--md-code-hl-special-color%3A%23db1457%3B--md-code-hl-function-color%3A%23a846b9%3B--md-code-hl-constant-color%3A%236e59d9%3B--md-code-hl-keyword-color%3A%233f6ec6%3B--md-code-hl-string-color%3A%231c7d4d%3B--md-code-hl-name-color%3Avar%28--md-code-fg-color%29%3B--md-code-hl-operator-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-punctuation-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-comment-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-generic-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-variable-color%3Avar%28--md-default-fg-color--light%29%3B--md-typeset-color%3Avar%28--md-default-fg-color%29%3B--md-typeset-a-color%3Avar%28--md-primary-fg-color%29%3B--md-typeset-del-color%3A%23f5503d26%3B--md-typeset-ins-color%3A%230bd57026%3B--md-typeset-kbd-color%3A%23fafafa%3B--md-typeset-kbd-accent-color%3A%23fff%3B--md-typeset-kbd-border-color%3A%23b8b8b8%3B--md-typeset-mark-color%3A%23ffff0080%3B--md-typeset-table-color%3A%230000001f%3B--md-typeset-table-color--light%3Argba%280%2C0%2C0%2C.035%29%3B--md-admonition-fg-color%3Avar%28--md-default-fg-color%29%3B--md-admonition-bg-color%3Avar%28--md-default-bg-color%29%3B--md-warning-fg-color%3A%23000000de%3B--md-warning-bg-color%3A%23ff9%3B--md-footer-fg-color%3A%23fff%3B--md-footer-fg-color--light%3A%23ffffffb3%3B--md-footer-fg-color--lighter%3A%23ffffff73%3B--md-footer-bg-color%3A%23000000de%3B--md-footer-bg-color--dark%3A%2300000052%3B--md-shadow-z1%3A0%200.2rem%200.5rem%20%230000000d%2C0%200%200.05rem%20%230000001a%3B--md-shadow-z2%3A0%200.2rem%200.5rem%20%230000001a%2C0%200%200.05rem%20%2300000040%3B--md-shadow-z3%3A0%200.2rem%200.5rem%20%230003%2C0%200%200.05rem%20%2300000059%7D.md-icon%20svg%7Bfill%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A1.2rem%3Bwidth%3A1.2rem%7Dbody%7B-webkit-font-smoothing%3Aantialiased%3B-moz-osx-font-smoothing%3Agrayscale%3B--md-text-font-family%3Avar%28--md-text-font%2C_%29%2C-apple-system%2CBlinkMacSystemFont%2CHelvetica%2CArial%2Csans-serif%3B--md-code-font-family%3Avar%28--md-code-font%2C_%29%2CSFMono-Regular%2CConsolas%2CMenlo%2Cmonospace%7Daside%2Cbody%2Cinput%7Bfont-feature-settings%3A%22kern%22%2C%22liga%22%3Bcolor%3Avar%28--md-typeset-color%29%3Bfont-family%3Avar%28--md-text-font-family%29%7Dcode%2Ckbd%2Cpre%7Bfont-feature-settings%3A%22kern%22%3Bfont-family%3Avar%28--md-code-font-family%29%7D%3Aroot%7B--md-typeset-table-sort-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m18%2021-4-4h3V7h-3l4-4%204%204h-3v10h3M2%2019v-2h10v2M2%2013v-2h7v2M2%207V5h4v2z%22/%3E%3C/svg%3E%27%29%3B--md-typeset-table-sort-icon--asc%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2017h3l-4%204-4-4h3V3h2M2%2017h10v2H2M6%205v2H2V5m0%206h7v2H2z%22/%3E%3C/svg%3E%27%29%3B--md-typeset-table-sort-icon--desc%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%207h3l-4-4-4%204h3v14h2M2%2017h10v2H2M6%205v2H2V5m0%206h7v2H2z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%7B-webkit-print-color-adjust%3Aexact%3Bcolor-adjust%3Aexact%3Bfont-size%3A.8rem%3Bline-height%3A1.6%3Boverflow-wrap%3Abreak-word%7D%40media%20print%7B.md-typeset%7Bfont-size%3A.68rem%7D%7D.md-typeset%20blockquote%2C.md-typeset%20dl%2C.md-typeset%20figure%2C.md-typeset%20ol%2C.md-typeset%20pre%2C.md-typeset%20ul%7Bmargin-bottom%3A1em%3Bmargin-top%3A1em%7D.md-typeset%20h1%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A2em%3Bline-height%3A1.3%3Bmargin%3A0%200%201.25em%7D.md-typeset%20h1%2C.md-typeset%20h2%7Bfont-weight%3A300%3Bletter-spacing%3A-.01em%7D.md-typeset%20h2%7Bfont-size%3A1.5625em%3Bline-height%3A1.4%3Bmargin%3A1.6em%200%20.64em%7D.md-typeset%20h3%7Bfont-size%3A1.25em%3Bfont-weight%3A400%3Bletter-spacing%3A-.01em%3Bline-height%3A1.5%3Bmargin%3A1.6em%200%20.8em%7D.md-typeset%20h2%2Bh3%7Bmargin-top%3A.8em%7D.md-typeset%20h4%7Bfont-weight%3A700%3Bletter-spacing%3A-.01em%3Bmargin%3A1em%200%7D.md-typeset%20h5%2C.md-typeset%20h6%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.8em%3Bfont-weight%3A700%3Bletter-spacing%3A-.01em%3Bmargin%3A1.25em%200%7D.md-typeset%20h5%7Btext-transform%3Auppercase%7D.md-typeset%20h5%20code%7Btext-transform%3Anone%7D.md-typeset%20hr%7Bborder-bottom%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bdisplay%3Aflow-root%3Bmargin%3A1.5em%200%7D.md-typeset%20a%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bword-break%3Abreak-word%7D.md-typeset%20a%2C.md-typeset%20a%3Abefore%7Btransition%3Acolor%20125ms%7D.md-typeset%20a%3Afocus%2C.md-typeset%20a%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20a%3Afocus%20code%2C.md-typeset%20a%3Ahover%20code%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20a%20code%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-typeset%20a.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-typeset%20code%2C.md-typeset%20kbd%2C.md-typeset%20pre%7Bcolor%3Avar%28--md-code-fg-color%29%3Bdirection%3Altr%3Bfont-variant-ligatures%3Anone%3Btransition%3Abackground-color%20125ms%7D%40media%20print%7B.md-typeset%20code%2C.md-typeset%20kbd%2C.md-typeset%20pre%7Bwhite-space%3Apre-wrap%7D%7D.md-typeset%20code%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bborder-radius%3A.1rem%3B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%3Bfont-size%3A.85em%3Bpadding%3A0%20.2941176471em%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%3Bword-break%3Abreak-word%7D.md-typeset%20code%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D.md-typeset%20pre%7Bdisplay%3Aflow-root%3Bline-height%3A1.4%3Bposition%3Arelative%7D.md-typeset%20pre%3Ecode%7B-webkit-box-decoration-break%3Aslice%3Bbox-decoration-break%3Aslice%3Bbox-shadow%3Anone%3Bdisplay%3Ablock%3Bmargin%3A0%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boverflow%3Aauto%3Bpadding%3A.7720588235em%201.1764705882em%3Bscrollbar-color%3Avar%28--md-default-fg-color--lighter%29%20%230000%3Bscrollbar-width%3Athin%3Btouch-action%3Aauto%3Bword-break%3Anormal%7D.md-typeset%20pre%3Ecode%3Ahover%7Bscrollbar-color%3Avar%28--md-accent-fg-color%29%20%230000%7D.md-typeset%20pre%3Ecode%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-typeset%20pre%3Ecode%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-typeset%20pre%3Ecode%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20kbd%7Bbackground-color%3Avar%28--md-typeset-kbd-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3A0%20.1rem%200%20.05rem%20var%28--md-typeset-kbd-border-color%29%2C0%20.1rem%200%20var%28--md-typeset-kbd-border-color%29%2C0%20-.1rem%20.2rem%20var%28--md-typeset-kbd-accent-color%29%20inset%3Bcolor%3Avar%28--md-default-fg-color%29%3Bdisplay%3Ainline-block%3Bfont-size%3A.75em%3Bpadding%3A0%20.6666666667em%3Bvertical-align%3Atext-top%3Bword-break%3Abreak-word%7D.md-typeset%20mark%7Bbackground-color%3Avar%28--md-typeset-mark-color%29%3B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%3Bcolor%3Ainherit%3Bword-break%3Abreak-word%7D.md-typeset%20abbr%7Bcursor%3Ahelp%3Btext-decoration%3Anone%7D.md-typeset%20%5Bdata-preview%5D%2C.md-typeset%20abbr%7Bborder-bottom%3A.05rem%20dotted%20var%28--md-default-fg-color--light%29%7D.md-typeset%20small%7Bopacity%3A.75%7D%5Bdir%3Dltr%5D%20.md-typeset%20sub%2C%5Bdir%3Dltr%5D%20.md-typeset%20sup%7Bmargin-left%3A.078125em%7D%5Bdir%3Drtl%5D%20.md-typeset%20sub%2C%5Bdir%3Drtl%5D%20.md-typeset%20sup%7Bmargin-right%3A.078125em%7D%5Bdir%3Dltr%5D%20.md-typeset%20blockquote%7Bpadding-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20blockquote%7Bpadding-right%3A.6rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20blockquote%7Bborder-left%3A.2rem%20solid%20var%28--md-default-fg-color--lighter%29%7D%5Bdir%3Drtl%5D%20.md-typeset%20blockquote%7Bborder-right%3A.2rem%20solid%20var%28--md-default-fg-color--lighter%29%7D.md-typeset%20blockquote%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bmargin-left%3A0%3Bmargin-right%3A0%7D.md-typeset%20ul%7Blist-style-type%3Adisc%7D.md-typeset%20ul%5Btype%5D%7Blist-style-type%3Arevert-layer%7D%5Bdir%3Dltr%5D%20.md-typeset%20ol%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%7Bmargin-left%3A.625em%7D%5Bdir%3Drtl%5D%20.md-typeset%20ol%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%7Bmargin-right%3A.625em%7D.md-typeset%20ol%2C.md-typeset%20ul%7Bpadding%3A0%7D.md-typeset%20ol%3Anot%28%5Bhidden%5D%29%2C.md-typeset%20ul%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Aflow-root%7D.md-typeset%20ol%20ol%2C.md-typeset%20ul%20ol%7Blist-style-type%3Alower-alpha%7D.md-typeset%20ol%20ol%20ol%2C.md-typeset%20ul%20ol%20ol%7Blist-style-type%3Alower-roman%7D.md-typeset%20ol%20ol%20ol%20ol%2C.md-typeset%20ul%20ol%20ol%20ol%7Blist-style-type%3Aupper-alpha%7D.md-typeset%20ol%20ol%20ol%20ol%20ol%2C.md-typeset%20ul%20ol%20ol%20ol%20ol%7Blist-style-type%3Aupper-roman%7D.md-typeset%20ol%5Btype%5D%2C.md-typeset%20ul%5Btype%5D%7Blist-style-type%3Arevert-layer%7D%5Bdir%3Dltr%5D%20.md-typeset%20ol%20li%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%20li%7Bmargin-left%3A1.25em%7D%5Bdir%3Drtl%5D%20.md-typeset%20ol%20li%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%20li%7Bmargin-right%3A1.25em%7D.md-typeset%20ol%20li%2C.md-typeset%20ul%20li%7Bmargin-bottom%3A.5em%7D.md-typeset%20ol%20li%20blockquote%2C.md-typeset%20ol%20li%20p%2C.md-typeset%20ul%20li%20blockquote%2C.md-typeset%20ul%20li%20p%7Bmargin%3A.5em%200%7D.md-typeset%20ol%20li%3Alast-child%2C.md-typeset%20ul%20li%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-typeset%20ol%20li%20ol%2C%5Bdir%3Dltr%5D%20.md-typeset%20ol%20li%20ul%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%20li%20ol%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%20li%20ul%7Bmargin-left%3A.625em%7D%5Bdir%3Drtl%5D%20.md-typeset%20ol%20li%20ol%2C%5Bdir%3Drtl%5D%20.md-typeset%20ol%20li%20ul%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%20li%20ol%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%20li%20ul%7Bmargin-right%3A.625em%7D.md-typeset%20ol%20li%20ol%2C.md-typeset%20ol%20li%20ul%2C.md-typeset%20ul%20li%20ol%2C.md-typeset%20ul%20li%20ul%7Bmargin-bottom%3A.5em%3Bmargin-top%3A.5em%7D%5Bdir%3Dltr%5D%20.md-typeset%20dd%7Bmargin-left%3A1.875em%7D%5Bdir%3Drtl%5D%20.md-typeset%20dd%7Bmargin-right%3A1.875em%7D.md-typeset%20dd%7Bmargin-bottom%3A1.5em%3Bmargin-top%3A1em%7D.md-typeset%20img%2C.md-typeset%20svg%2C.md-typeset%20video%7Bheight%3Aauto%3Bmax-width%3A100%25%7D.md-typeset%20img%5Balign%3Dleft%5D%7Bmargin%3A1em%201em%201em%200%7D.md-typeset%20img%5Balign%3Dright%5D%7Bmargin%3A1em%200%201em%201em%7D.md-typeset%20img%5Balign%5D%3Aonly-child%7Bmargin-top%3A0%7D.md-typeset%20figure%7Bdisplay%3Aflow-root%3Bmargin%3A1em%20auto%3Bmax-width%3A100%25%3Btext-align%3Acenter%3Bwidth%3Afit-content%7D.md-typeset%20figure%20img%7Bdisplay%3Ablock%3Bmargin%3A0%20auto%7D.md-typeset%20figcaption%7Bfont-style%3Aitalic%3Bmargin%3A1em%20auto%3Bmax-width%3A24rem%7D.md-typeset%20iframe%7Bmax-width%3A100%25%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder%3A.05rem%20solid%20var%28--md-typeset-table-color%29%3Bborder-radius%3A.1rem%3Bdisplay%3Ainline-block%3Bfont-size%3A.64rem%3Bmax-width%3A100%25%3Boverflow%3Aauto%3Btouch-action%3Aauto%7D%40media%20print%7B.md-typeset%20table%3Anot%28%5Bclass%5D%29%7Bdisplay%3Atable%7D%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%2B%2A%7Bmargin-top%3A1.5em%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3E%3Afirst-child%2C.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3E%3Alast-child%2C.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3E%3Alast-child%7Bmargin-bottom%3A0%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3Anot%28%5Balign%5D%29%2C.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3Anot%28%5Balign%5D%29%7Btext-align%3Aleft%7D%5Bdir%3Drtl%5D%20.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3Anot%28%5Balign%5D%29%2C%5Bdir%3Drtl%5D%20.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3Anot%28%5Balign%5D%29%7Btext-align%3Aright%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%7Bfont-weight%3A700%3Bmin-width%3A5rem%3Bpadding%3A.9375em%201.25em%3Bvertical-align%3Atop%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%7Bborder-top%3A.05rem%20solid%20var%28--md-typeset-table-color%29%3Bpadding%3A.9375em%201.25em%3Bvertical-align%3Atop%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20tbody%20tr%7Btransition%3Abackground-color%20125ms%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20tbody%20tr%3Ahover%7Bbackground-color%3Avar%28--md-typeset-table-color--light%29%3Bbox-shadow%3A0%20.05rem%200%20var%28--md-default-bg-color%29%20inset%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20a%7Bword-break%3Anormal%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%7Bcursor%3Apointer%7D%5Bdir%3Dltr%5D%20.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Aafter%7Bmargin-left%3A.5em%7D%5Bdir%3Drtl%5D%20.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Aafter%7Bmargin-right%3A.5em%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Aafter%7Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A1.2em%3B-webkit-mask-image%3Avar%28--md-typeset-table-sort-icon%29%3Bmask-image%3Avar%28--md-typeset-table-sort-icon%29%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Abackground-color%20125ms%3Bvertical-align%3Atext-bottom%3Bwidth%3A1.2em%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Ahover%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%5Baria-sort%3Dascending%5D%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--light%29%3B-webkit-mask-image%3Avar%28--md-typeset-table-sort-icon--asc%29%3Bmask-image%3Avar%28--md-typeset-table-sort-icon--asc%29%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%5Baria-sort%3Ddescending%5D%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--light%29%3B-webkit-mask-image%3Avar%28--md-typeset-table-sort-icon--desc%29%3Bmask-image%3Avar%28--md-typeset-table-sort-icon--desc%29%7D.md-typeset__scrollwrap%7Bmargin%3A1em%20-.8rem%3Boverflow-x%3Aauto%3Btouch-action%3Aauto%7D.md-typeset__table%7Bdisplay%3Ainline-block%3Bmargin-bottom%3A.5em%3Bpadding%3A0%20.8rem%7D%40media%20print%7B.md-typeset__table%7Bdisplay%3Ablock%7D%7Dhtml%20.md-typeset__table%20table%7Bdisplay%3Atable%3Bmargin%3A0%3Boverflow%3Ahidden%3Bwidth%3A100%25%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-content__inner%3Epre%7Bmargin%3A1em%20-.8rem%7D.md-content__inner%3Epre%20code%7Bborder-radius%3A0%7D%7D.md-typeset%20.md-author%7Bborder-radius%3A100%25%3Bdisplay%3Ablock%3Bflex-shrink%3A0%3Bheight%3A1.6rem%3Boverflow%3Ahidden%3Bposition%3Arelative%3Btransition%3Acolor%20125ms%2Ctransform%20125ms%3Bwidth%3A1.6rem%7D.md-typeset%20.md-author%20img%7Bdisplay%3Ablock%7D.md-typeset%20.md-author--more%7Bbackground%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bfont-size%3A.6rem%3Bfont-weight%3A700%3Bline-height%3A1.6rem%3Btext-align%3Acenter%7D.md-typeset%20.md-author--long%7Bheight%3A2.4rem%3Bwidth%3A2.4rem%7D.md-typeset%20a.md-author%7Btransform%3Ascale%281%29%7D.md-typeset%20a.md-author%20img%7Bborder-radius%3A100%25%3Bfilter%3Agrayscale%28100%25%29%20opacity%2875%25%29%3Btransition%3Afilter%20125ms%7D.md-typeset%20a.md-author%3Afocus%2C.md-typeset%20a.md-author%3Ahover%7Btransform%3Ascale%281.1%29%3Bz-index%3A1%7D.md-typeset%20a.md-author%3Afocus%20img%2C.md-typeset%20a.md-author%3Ahover%20img%7Bfilter%3Agrayscale%280%29%7D.md-banner%7Bbackground-color%3Avar%28--md-footer-bg-color%29%3Bcolor%3Avar%28--md-footer-fg-color%29%3Boverflow%3Aauto%7D%40media%20print%7B.md-banner%7Bdisplay%3Anone%7D%7D.md-banner--warning%7Bbackground-color%3Avar%28--md-warning-bg-color%29%3Bcolor%3Avar%28--md-warning-fg-color%29%7D.md-banner__inner%7Bfont-size%3A.7rem%3Bmargin%3A.6rem%20auto%3Bpadding%3A0%20.8rem%7D%5Bdir%3Dltr%5D%20.md-banner__button%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-banner__button%7Bfloat%3Aleft%7D.md-banner__button%7Bcolor%3Ainherit%3Bcursor%3Apointer%3Btransition%3Aopacity%20.25s%7D.no-js%20.md-banner__button%7Bdisplay%3Anone%7D.md-banner__button%3Ahover%7Bopacity%3A.7%7Dhtml%7Bfont-size%3A125%25%3Bheight%3A100%25%3Boverflow-x%3Ahidden%7D%40media%20screen%20and%20%28min-width%3A100em%29%7Bhtml%7Bfont-size%3A137.5%25%7D%7D%40media%20screen%20and%20%28min-width%3A125em%29%7Bhtml%7Bfont-size%3A150%25%7D%7Dbody%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bfont-size%3A.5rem%3Bmin-height%3A100%25%3Bposition%3Arelative%3Bwidth%3A100%25%7D%40media%20print%7Bbody%7Bdisplay%3Ablock%7D%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7Bbody%5Bdata-md-scrolllock%5D%7Bposition%3Afixed%7D%7D.md-grid%7Bmargin-left%3Aauto%3Bmargin-right%3Aauto%3Bmax-width%3A61rem%7D.md-container%7Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bflex-grow%3A1%7D%40media%20print%7B.md-container%7Bdisplay%3Ablock%7D%7D.md-main%7Bflex-grow%3A1%7D.md-main__inner%7Bdisplay%3Aflex%3Bheight%3A100%25%3Bmargin-top%3A1.5rem%7D.md-ellipsis%7Boverflow%3Ahidden%3Btext-overflow%3Aellipsis%7D.md-toggle%7Bdisplay%3Anone%7D.md-option%7Bheight%3A0%3Bopacity%3A0%3Bposition%3Aabsolute%3Bwidth%3A0%7D.md-option%3Achecked%2Blabel%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ablock%7D.md-option.focus-visible%2Blabel%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-style%3Aauto%7D.md-skip%7Bbackground-color%3Avar%28--md-default-fg-color%29%3Bborder-radius%3A.1rem%3Bcolor%3Avar%28--md-default-bg-color%29%3Bfont-size%3A.64rem%3Bmargin%3A.5rem%3Bopacity%3A0%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Bpadding%3A.3rem%20.5rem%3Bposition%3Afixed%3Btransform%3AtranslateY%28.4rem%29%3Bz-index%3A-1%7D.md-skip%3Afocus%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Copacity%20175ms%2075ms%3Bz-index%3A10%7D%40page%7Bmargin%3A25mm%7D%3Aroot%7B--md-clipboard-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2021H8V7h11m0-2H8a2%202%200%200%200-2%202v14a2%202%200%200%200%202%202h11a2%202%200%200%200%202-2V7a2%202%200%200%200-2-2m-3-4H4a2%202%200%200%200-2%202v14h2V3h12z%22/%3E%3C/svg%3E%27%29%7D.md-clipboard%7Bborder-radius%3A.1rem%3Bcolor%3Avar%28--md-default-fg-color--lightest%29%3Bcursor%3Apointer%3Bheight%3A1.5em%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.1rem%3Btransition%3Acolor%20.25s%3Bwidth%3A1.5em%3Bz-index%3A1%7D%40media%20print%7B.md-clipboard%7Bdisplay%3Anone%7D%7D.md-clipboard%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D%3Ahover%3E.md-clipboard%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-clipboard%3Afocus%2C.md-clipboard%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-clipboard%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A1.125em%3Bmargin%3A0%20auto%3B-webkit-mask-image%3Avar%28--md-clipboard-icon%29%3Bmask-image%3Avar%28--md-clipboard-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A1.125em%7D.md-clipboard--inline%7Bcursor%3Apointer%7D.md-clipboard--inline%20code%7Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%7D.md-clipboard--inline%3Afocus%20code%2C.md-clipboard--inline%3Ahover%20code%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D%3Aroot%7B--md-code-select-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2019h-4v2h4c1.1%200%202-.9%202-2v-4h-2m0-12h-4v2h4v4h2V5c0-1.1-.9-2-2-2M5%205h4V3H5c-1.1%200-2%20.9-2%202v4h2m0%206H3v4c0%201.1.9%202%202%202h4v-2H5zm2-4h2v2H7zm4%200h2v2h-2zm4%200h2v2h-2zM7%207h2v2H7zm4%200h2v2h-2zm4%200h2v2h-2zm-8%208h2v2H7zm4%200h2v2h-2zm4%200h2v2h-2z%22/%3E%3C/svg%3E%27%29%3B--md-code-copy-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2021H8V7h11m0-2H8a2%202%200%200%200-2%202v14a2%202%200%200%200%202%202h11a2%202%200%200%200%202-2V7a2%202%200%200%200-2-2m-3-4H4a2%202%200%200%200-2%202v14h2V3h12z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.md-code__content%7Bdisplay%3Agrid%7D.md-code__nav%7Bbackground-color%3Avar%28--md-code-bg-color--lighter%29%3Bborder-radius%3A.1rem%3Bdisplay%3Aflex%3Bgap%3A.2rem%3Bpadding%3A.2rem%3Bposition%3Aabsolute%3Bright%3A.25em%3Btop%3A.25em%3Btransition%3Abackground-color%20.25s%3Bz-index%3A1%7D%3Ahover%3E.md-code__nav%7Bbackground-color%3Avar%28--md-code-bg-color--light%29%7D.md-code__button%7Bcolor%3Avar%28--md-default-fg-color--lightest%29%3Bcursor%3Apointer%3Bdisplay%3Ablock%3Bheight%3A1.5em%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.1rem%3Btransition%3Acolor%20.25s%3Bwidth%3A1.5em%7D%3Ahover%3E%2A%3E.md-code__button%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-code__button.focus-visible%2C.md-code__button%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-code__button--active%7Bcolor%3Avar%28--md-default-fg-color%29%21important%7D.md-code__button%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A1.125em%3Bmargin%3A0%20auto%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A1.125em%7D.md-code__button%5Bdata-md-type%3Dselect%5D%3Aafter%7B-webkit-mask-image%3Avar%28--md-code-select-icon%29%3Bmask-image%3Avar%28--md-code-select-icon%29%7D.md-code__button%5Bdata-md-type%3Dcopy%5D%3Aafter%7B-webkit-mask-image%3Avar%28--md-code-copy-icon%29%3Bmask-image%3Avar%28--md-code-copy-icon%29%7D%40keyframes%20consent%7B0%25%7Bopacity%3A0%3Btransform%3AtranslateY%28100%25%29%7Dto%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%7D%7D%40keyframes%20overlay%7B0%25%7Bopacity%3A0%7Dto%7Bopacity%3A1%7D%7D.md-consent__overlay%7Banimation%3Aoverlay%20.25s%20both%3B-webkit-backdrop-filter%3Ablur%28.1rem%29%3Bbackdrop-filter%3Ablur%28.1rem%29%3Bbackground-color%3A%230000008a%3Bheight%3A100%25%3Bopacity%3A1%3Bposition%3Afixed%3Btop%3A0%3Bwidth%3A100%25%3Bz-index%3A5%7D.md-consent__inner%7Banimation%3Aconsent%20.5s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%20both%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder%3A0%3Bborder-radius%3A.1rem%3Bbottom%3A0%3Bbox-shadow%3A0%200%20.2rem%20%230000001a%2C0%20.2rem%20.4rem%20%230003%3Bmax-height%3A100%25%3Boverflow%3Aauto%3Bpadding%3A0%3Bposition%3Afixed%3Bwidth%3A100%25%3Bz-index%3A5%7D.md-consent__form%7Bpadding%3A.8rem%7D.md-consent__settings%7Bdisplay%3Anone%3Bmargin%3A1em%200%7Dinput%3Achecked%2B.md-consent__settings%7Bdisplay%3Ablock%7D.md-consent__controls%7Bmargin-bottom%3A.8rem%7D.md-typeset%20.md-consent__controls%20.md-button%7Bdisplay%3Ainline%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-typeset%20.md-consent__controls%20.md-button%7Bdisplay%3Ablock%3Bmargin-top%3A.4rem%3Btext-align%3Acenter%3Bwidth%3A100%25%7D%7D.md-consent%20label%7Bcursor%3Apointer%7D.md-content%7Bflex-grow%3A1%3Bmin-width%3A0%7D.md-content__inner%7Bmargin%3A0%20.8rem%201.2rem%3Bpadding-top%3A.6rem%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdir%3Dltr%5D%20.md-sidebar--primary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%7Bmargin-left%3A1.2rem%7D%5Bdir%3Dltr%5D%20.md-sidebar--secondary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%2C%5Bdir%3Drtl%5D%20.md-sidebar--primary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%7Bmargin-right%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-sidebar--secondary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%7Bmargin-left%3A1.2rem%7D%7D.md-content__inner%3Abefore%7Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A.4rem%7D.md-content__inner%3E%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-content__button%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-content__button%7Bfloat%3Aleft%7D%5Bdir%3Dltr%5D%20.md-content__button%7Bmargin-left%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-content__button%7Bmargin-right%3A.4rem%7D.md-content__button%7Bmargin%3A.4rem%200%3Bpadding%3A0%7D%40media%20print%7B.md-content__button%7Bdisplay%3Anone%7D%7D.md-typeset%20.md-content__button%7Bcolor%3Avar%28--md-default-fg-color--lighter%29%7D.md-content__button%20svg%7Bdisplay%3Ainline%3Bvertical-align%3Atop%7D%5Bdir%3Drtl%5D%20.md-content__button%20svg%7Btransform%3AscaleX%28-1%29%7D%5Bdir%3Dltr%5D%20.md-dialog%7Bright%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-dialog%7Bleft%3A.8rem%7D.md-dialog%7Bbackground-color%3Avar%28--md-default-fg-color%29%3Bborder-radius%3A.1rem%3Bbottom%3A.8rem%3Bbox-shadow%3Avar%28--md-shadow-z3%29%3Bmin-width%3A11.1rem%3Bopacity%3A0%3Bpadding%3A.4rem%20.6rem%3Bpointer-events%3Anone%3Bposition%3Afixed%3Btransform%3AtranslateY%28100%25%29%3Btransition%3Atransform%200ms%20.4s%2Copacity%20.4s%3Bz-index%3A4%7D%40media%20print%7B.md-dialog%7Bdisplay%3Anone%7D%7D.md-dialog--active%7Bopacity%3A1%3Bpointer-events%3Aauto%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.4s%20cubic-bezier%28.075%2C.85%2C.175%2C1%29%2Copacity%20.4s%7D.md-dialog__inner%7Bcolor%3Avar%28--md-default-bg-color%29%3Bfont-size%3A.7rem%7D.md-feedback%7Bmargin%3A2em%200%201em%3Btext-align%3Acenter%7D.md-feedback%20fieldset%7Bborder%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-feedback__title%7Bfont-weight%3A700%3Bmargin%3A1em%20auto%7D.md-feedback__inner%7Bposition%3Arelative%7D.md-feedback__list%7Bdisplay%3Aflex%3Bflex-wrap%3Awrap%3Bplace-content%3Abaseline%20center%3Bposition%3Arelative%7D.md-feedback__list%3Ahover%20.md-icon%3Anot%28%3Adisabled%29%7Bcolor%3Avar%28--md-default-fg-color--lighter%29%7D%3Adisabled%20.md-feedback__list%7Bmin-height%3A1.8rem%7D.md-feedback__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bflex-shrink%3A0%3Bmargin%3A0%20.1rem%3Btransition%3Acolor%20125ms%7D.md-feedback__icon%3Anot%28%3Adisabled%29.md-icon%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-feedback__icon%3Adisabled%7Bcolor%3Avar%28--md-default-fg-color--lightest%29%3Bpointer-events%3Anone%7D.md-feedback__note%7Bopacity%3A0%3Bposition%3Arelative%3Btransform%3AtranslateY%28.4rem%29%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%7D.md-feedback__note%3E%2A%7Bmargin%3A0%20auto%3Bmax-width%3A16rem%7D%3Adisabled%20.md-feedback__note%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%7D%40media%20print%7B.md-feedback%7Bdisplay%3Anone%7D%7D.md-footer%7Bbackground-color%3Avar%28--md-footer-bg-color%29%3Bcolor%3Avar%28--md-footer-fg-color%29%7D%40media%20print%7B.md-footer%7Bdisplay%3Anone%7D%7D.md-footer__inner%7Bjustify-content%3Aspace-between%3Boverflow%3Aauto%3Bpadding%3A.2rem%7D.md-footer__inner%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Aflex%7D.md-footer__link%7Balign-items%3Aend%3Bdisplay%3Aflex%3Bflex-grow%3A0.01%3Bmargin-bottom%3A.4rem%3Bmargin-top%3A1rem%3Bmax-width%3A100%25%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boverflow%3Ahidden%3Btransition%3Aopacity%20.25s%7D.md-footer__link%3Afocus%2C.md-footer__link%3Ahover%7Bopacity%3A.7%7D%5Bdir%3Drtl%5D%20.md-footer__link%20svg%7Btransform%3AscaleX%28-1%29%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-footer__link--prev%7Bflex-shrink%3A0%7D.md-footer__link--prev%20.md-footer__title%7Bdisplay%3Anone%7D%7D%5Bdir%3Dltr%5D%20.md-footer__link--next%7Bmargin-left%3Aauto%7D%5Bdir%3Drtl%5D%20.md-footer__link--next%7Bmargin-right%3Aauto%7D.md-footer__link--next%7Btext-align%3Aright%7D%5Bdir%3Drtl%5D%20.md-footer__link--next%7Btext-align%3Aleft%7D.md-footer__title%7Bflex-grow%3A1%3Bfont-size%3A.9rem%3Bmargin-bottom%3A.7rem%3Bmax-width%3Acalc%28100%25%20-%202.4rem%29%3Bpadding%3A0%201rem%3Bwhite-space%3Anowrap%7D.md-footer__button%7Bmargin%3A.2rem%3Bpadding%3A.4rem%7D.md-footer__direction%7Bfont-size%3A.64rem%3Bopacity%3A.7%7D.md-footer-meta%7Bbackground-color%3Avar%28--md-footer-bg-color--dark%29%7D.md-footer-meta__inner%7Bdisplay%3Aflex%3Bflex-wrap%3Awrap%3Bjustify-content%3Aspace-between%3Bpadding%3A.2rem%7Dhtml%20.md-footer-meta.md-typeset%20a%7Bcolor%3Avar%28--md-footer-fg-color--light%29%7Dhtml%20.md-footer-meta.md-typeset%20a%3Afocus%2Chtml%20.md-footer-meta.md-typeset%20a%3Ahover%7Bcolor%3Avar%28--md-footer-fg-color%29%7D.md-copyright%7Bcolor%3Avar%28--md-footer-fg-color--lighter%29%3Bfont-size%3A.64rem%3Bmargin%3Aauto%20.6rem%3Bpadding%3A.4rem%200%3Bwidth%3A100%25%7D%40media%20screen%20and%20%28min-width%3A45em%29%7B.md-copyright%7Bwidth%3Aauto%7D%7D.md-copyright__highlight%7Bcolor%3Avar%28--md-footer-fg-color--light%29%7D.md-social%7Bdisplay%3Ainline-flex%3Bgap%3A.2rem%3Bmargin%3A0%20.4rem%3Bpadding%3A.2rem%200%20.6rem%7D%40media%20screen%20and%20%28min-width%3A45em%29%7B.md-social%7Bpadding%3A.6rem%200%7D%7D.md-social__link%7Bdisplay%3Ainline-block%3Bheight%3A1.6rem%3Btext-align%3Acenter%3Bwidth%3A1.6rem%7D.md-social__link%3Abefore%7Bline-height%3A1.9%7D.md-social__link%20svg%7Bfill%3Acurrentcolor%3Bmax-height%3A.8rem%3Bvertical-align%3A-25%25%7D.md-typeset%20.md-button%7Bborder%3A.1rem%20solid%3Bborder-radius%3A.1rem%3Bcolor%3Avar%28--md-primary-fg-color%29%3Bcursor%3Apointer%3Bdisplay%3Ainline-block%3Bfont-weight%3A700%3Bpadding%3A.625em%202em%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%2Cborder-color%20125ms%7D.md-typeset%20.md-button--primary%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bborder-color%3Avar%28--md-primary-fg-color%29%3Bcolor%3Avar%28--md-primary-bg-color%29%7D.md-typeset%20.md-button%3Afocus%2C.md-typeset%20.md-button%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%3Bborder-color%3Avar%28--md-accent-fg-color%29%3Bcolor%3Avar%28--md-accent-bg-color%29%7D%5Bdir%3Dltr%5D%20.md-typeset%20.md-input%7Bborder-top-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.md-input%2C%5Bdir%3Drtl%5D%20.md-typeset%20.md-input%7Bborder-top-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.md-input%7Bborder-top-left-radius%3A.1rem%7D.md-typeset%20.md-input%7Bborder-bottom%3A.1rem%20solid%20var%28--md-default-fg-color--lighter%29%3Bbox-shadow%3Avar%28--md-shadow-z1%29%3Bfont-size%3A.8rem%3Bheight%3A1.8rem%3Bpadding%3A0%20.6rem%3Btransition%3Aborder%20.25s%2Cbox-shadow%20.25s%7D.md-typeset%20.md-input%3Afocus%2C.md-typeset%20.md-input%3Ahover%7Bborder-bottom-color%3Avar%28--md-accent-fg-color%29%3Bbox-shadow%3Avar%28--md-shadow-z2%29%7D.md-typeset%20.md-input--stretch%7Bwidth%3A100%25%7D.md-header%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bbox-shadow%3A0%200%20.2rem%20%230000%2C0%20.2rem%20.4rem%20%230000%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bdisplay%3Ablock%3Bleft%3A0%3Bposition%3Asticky%3Bright%3A0%3Btop%3A0%3Bz-index%3A4%7D%40media%20print%7B.md-header%7Bdisplay%3Anone%7D%7D.md-header%5Bhidden%5D%7Btransform%3AtranslateY%28-100%25%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.8%2C0%2C.6%2C1%29%2Cbox-shadow%20.25s%7D.md-header--shadow%7Bbox-shadow%3A0%200%20.2rem%20%230000001a%2C0%20.2rem%20.4rem%20%230003%3Btransition%3Atransform%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Cbox-shadow%20.25s%7D.md-header__inner%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bpadding%3A0%20.2rem%7D.md-header__button%7Bcolor%3Acurrentcolor%3Bcursor%3Apointer%3Bmargin%3A.2rem%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Bpadding%3A.4rem%3Bposition%3Arelative%3Btransition%3Aopacity%20.25s%3Bvertical-align%3Amiddle%3Bz-index%3A1%7D.md-header__button%3Ahover%7Bopacity%3A.7%7D.md-header__button%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ainline-block%7D.md-header__button%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D.md-header__button.md-logo%7Bmargin%3A.2rem%3Bpadding%3A.4rem%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-header__button.md-logo%7Bdisplay%3Anone%7D%7D.md-header__button.md-logo%20img%2C.md-header__button.md-logo%20svg%7Bfill%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A1.2rem%3Bwidth%3Aauto%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-header__button%5Bfor%3D__search%5D%7Bdisplay%3Anone%7D%7D.no-js%20.md-header__button%5Bfor%3D__search%5D%7Bdisplay%3Anone%7D%5Bdir%3Drtl%5D%20.md-header__button%5Bfor%3D__search%5D%20svg%7Btransform%3AscaleX%28-1%29%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-header__button%5Bfor%3D__drawer%5D%7Bdisplay%3Anone%7D%7D.md-header__topic%7Bdisplay%3Aflex%3Bmax-width%3A100%25%3Bposition%3Aabsolute%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%3Bwhite-space%3Anowrap%7D.md-header__topic%2B.md-header__topic%7Bopacity%3A0%3Bpointer-events%3Anone%3Btransform%3AtranslateX%281.25rem%29%3Btransition%3Atransform%20.4s%20cubic-bezier%281%2C.7%2C.1%2C.1%29%2Copacity%20.15s%3Bz-index%3A-1%7D%5Bdir%3Drtl%5D%20.md-header__topic%2B.md-header__topic%7Btransform%3AtranslateX%28-1.25rem%29%7D.md-header__topic%3Afirst-child%7Bfont-weight%3A700%7D%5Bdir%3Dltr%5D%20.md-header__title%7Bmargin-left%3A1rem%3Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-header__title%7Bmargin-left%3A.4rem%3Bmargin-right%3A1rem%7D.md-header__title%7Bflex-grow%3A1%3Bfont-size%3A.9rem%3Bheight%3A2.4rem%3Bline-height%3A2.4rem%7D.md-header__title--active%20.md-header__topic%7Bopacity%3A0%3Bpointer-events%3Anone%3Btransform%3AtranslateX%28-1.25rem%29%3Btransition%3Atransform%20.4s%20cubic-bezier%281%2C.7%2C.1%2C.1%29%2Copacity%20.15s%3Bz-index%3A-1%7D%5Bdir%3Drtl%5D%20.md-header__title--active%20.md-header__topic%7Btransform%3AtranslateX%281.25rem%29%7D.md-header__title--active%20.md-header__topic%2B.md-header__topic%7Bopacity%3A1%3Bpointer-events%3Aauto%3Btransform%3AtranslateX%280%29%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%3Bz-index%3A0%7D.md-header__title%3E.md-header__ellipsis%7Bheight%3A100%25%3Bposition%3Arelative%3Bwidth%3A100%25%7D.md-header__option%7Bdisplay%3Aflex%3Bflex-shrink%3A0%3Bmax-width%3A100%25%3Btransition%3Amax-width%200ms%20.25s%2Copacity%20.25s%20.25s%3Bwhite-space%3Anowrap%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-header__option%7Bmax-width%3A0%3Bopacity%3A0%3Btransition%3Amax-width%200ms%2Copacity%200ms%7D.md-header__option%3Einput%7Bbottom%3A0%7D.md-header__source%7Bdisplay%3Anone%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-header__source%7Bmargin-left%3A1rem%7D%5Bdir%3Drtl%5D%20.md-header__source%7Bmargin-right%3A1rem%7D.md-header__source%7Bdisplay%3Ablock%3Bmax-width%3A11.7rem%3Bwidth%3A11.7rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdir%3Dltr%5D%20.md-header__source%7Bmargin-left%3A1.4rem%7D%5Bdir%3Drtl%5D%20.md-header__source%7Bmargin-right%3A1.4rem%7D%7D.md-meta%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.7rem%3Bline-height%3A1.3%7D.md-meta__list%7Bdisplay%3Ainline-flex%3Bflex-wrap%3Awrap%3Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-meta__item%3Anot%28%3Alast-child%29%3Aafter%7Bcontent%3A%22%C2%B7%22%3Bmargin-left%3A.2rem%3Bmargin-right%3A.2rem%7D.md-meta__link%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-meta__link%3Afocus%2C.md-meta__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-draft%7Bbackground-color%3A%23ff1744%3Bborder-radius%3A.125em%3Bcolor%3A%23fff%3Bdisplay%3Ainline-block%3Bfont-weight%3A700%3Bpadding-left%3A.5714285714em%3Bpadding-right%3A.5714285714em%7D%3Aroot%7B--md-nav-icon--prev%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M20%2011v2H8l5.5%205.5-1.42%201.42L4.16%2012l7.92-7.92L13.5%205.5%208%2011z%22/%3E%3C/svg%3E%27%29%3B--md-nav-icon--next%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%3B--md-toc-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M3%209h14V7H3zm0%204h14v-2H3zm0%204h14v-2H3zm16%200h2v-2h-2zm0-10v2h2V7zm0%206h2v-2h-2z%22/%3E%3C/svg%3E%27%29%7D.md-nav%7Bfont-size%3A.7rem%3Bline-height%3A1.3%7D.md-nav__title%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bdisplay%3Ablock%3Bfont-weight%3A700%3Boverflow%3Ahidden%3Bpadding%3A0%20.6rem%3Btext-overflow%3Aellipsis%7D.md-nav__title%20.md-nav__button%7Bdisplay%3Anone%7D.md-nav__title%20.md-nav__button%20img%7Bheight%3A100%25%3Bwidth%3Aauto%7D.md-nav__title%20.md-nav__button.md-logo%20img%2C.md-nav__title%20.md-nav__button.md-logo%20svg%7Bfill%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A2.4rem%3Bmax-width%3A100%25%3Bobject-fit%3Acontain%3Bwidth%3Aauto%7D.md-nav__list%7Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-nav__link%7Balign-items%3Aflex-start%3Bdisplay%3Aflex%3Bgap%3A.4rem%3Bmargin-top%3A.625em%3Bscroll-snap-align%3Astart%3Btransition%3Acolor%20125ms%7D.md-nav__link--passed%2C.md-nav__link--passed%20code%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-nav__item%20.md-nav__link--active%2C.md-nav__item%20.md-nav__link--active%20code%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-nav__link%20.md-ellipsis%7Bposition%3Arelative%7D.md-nav__link%20.md-ellipsis%20code%7Bword-break%3Anormal%7D%5Bdir%3Dltr%5D%20.md-nav__link%20.md-icon%3Alast-child%7Bmargin-left%3Aauto%7D%5Bdir%3Drtl%5D%20.md-nav__link%20.md-icon%3Alast-child%7Bmargin-right%3Aauto%7D.md-nav__link%20.md-typeset%7Bfont-size%3A.7rem%3Bline-height%3A1.3%7D.md-nav__link%20svg%7Bfill%3Acurrentcolor%3Bflex-shrink%3A0%3Bheight%3A1.3em%3Bposition%3Arelative%7D.md-nav__link%5Bfor%5D%3Afocus%2C.md-nav__link%5Bfor%5D%3Ahover%2C.md-nav__link%5Bhref%5D%3Afocus%2C.md-nav__link%5Bhref%5D%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%3Bcursor%3Apointer%7D.md-nav__link%5Bfor%5D%3Afocus%20code%2C.md-nav__link%5Bfor%5D%3Ahover%20code%2C.md-nav__link%5Bhref%5D%3Afocus%20code%2C.md-nav__link%5Bhref%5D%3Ahover%20code%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-nav__link.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%7Bdisplay%3Anone%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%20.md-icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-toc-icon%29%3Bmask-image%3Avar%28--md-toc-icon%29%3Bwidth%3A100%25%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D~.md-nav%7Bdisplay%3Anone%7D.md-nav__container%3E.md-nav__link%7Bmargin-top%3A0%7D.md-nav__container%3E.md-nav__link%3Afirst-child%7Bflex-grow%3A1%3Bmin-width%3A0%7D.md-nav__icon%7Bflex-shrink%3A0%7D.md-nav__source%7Bdisplay%3Anone%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-nav--primary%2C.md-nav--primary%20.md-nav%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bheight%3A100%25%3Bleft%3A0%3Bposition%3Aabsolute%3Bright%3A0%3Btop%3A0%3Bz-index%3A1%7D.md-nav--primary%20.md-nav__item%2C.md-nav--primary%20.md-nav__title%7Bfont-size%3A.8rem%3Bline-height%3A1.5%7D.md-nav--primary%20.md-nav__title%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bheight%3A5.6rem%3Bline-height%3A2.4rem%3Bpadding%3A3rem%20.8rem%20.2rem%3Bposition%3Arelative%3Bwhite-space%3Anowrap%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bleft%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bright%3A.4rem%7D.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bdisplay%3Ablock%3Bheight%3A1.2rem%3Bmargin%3A.2rem%3Bposition%3Aabsolute%3Btop%3A.4rem%3Bwidth%3A1.2rem%7D.md-nav--primary%20.md-nav__title%20.md-nav__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-nav-icon--prev%29%3Bmask-image%3Avar%28--md-nav-icon--prev%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A100%25%7D.md-nav--primary%20.md-nav__title~.md-nav__list%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%20.05rem%200%20var%28--md-default-fg-color--lightest%29%20inset%3Boverflow-y%3Aauto%3Bscroll-snap-type%3Ay%20mandatory%3Btouch-action%3Apan-y%7D.md-nav--primary%20.md-nav__title~.md-nav__list%3E%3Afirst-child%7Bborder-top%3A0%7D.md-nav--primary%20.md-nav__title%5Bfor%3D__drawer%5D%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bfont-weight%3A700%7D.md-nav--primary%20.md-nav__title%20.md-logo%7Bdisplay%3Ablock%3Bleft%3A.2rem%3Bmargin%3A.2rem%3Bpadding%3A.4rem%3Bposition%3Aabsolute%3Bright%3A.2rem%3Btop%3A.2rem%7D.md-nav--primary%20.md-nav__list%7Bflex%3A1%7D.md-nav--primary%20.md-nav__item%7Bborder-top%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%7D.md-nav--primary%20.md-nav__item--active%3E.md-nav__link%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-nav--primary%20.md-nav__item--active%3E.md-nav__link%3Afocus%2C.md-nav--primary%20.md-nav__item--active%3E.md-nav__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-nav--primary%20.md-nav__link%7Bmargin-top%3A0%3Bpadding%3A.6rem%20.8rem%7D.md-nav--primary%20.md-nav__link%20svg%7Bmargin-top%3A.1em%7D.md-nav--primary%20.md-nav__link%3E.md-nav__link%7Bpadding%3A0%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__link%20.md-nav__icon%7Bmargin-right%3A-.2rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__link%20.md-nav__icon%7Bmargin-left%3A-.2rem%7D.md-nav--primary%20.md-nav__link%20.md-nav__icon%7Bfont-size%3A1.2rem%3Bheight%3A1.2rem%3Bwidth%3A1.2rem%7D.md-nav--primary%20.md-nav__link%20.md-nav__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-nav-icon--next%29%3Bmask-image%3Avar%28--md-nav-icon--next%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A100%25%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__icon%3Aafter%7Btransform%3Ascale%28-1%29%7D.md-nav--primary%20.md-nav--secondary%20.md-nav%7Bbackground-color%3Ainitial%3Bposition%3Astatic%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav__link%7Bpadding-left%3A1.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav__link%7Bpadding-right%3A1.4rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-left%3A2rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-right%3A2rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-left%3A2.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-right%3A2.6rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-left%3A3.2rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-right%3A3.2rem%7D.md-nav--secondary%7Bbackground-color%3Ainitial%7D.md-nav__toggle~.md-nav%7Bdisplay%3Aflex%3Bopacity%3A0%3Btransform%3AtranslateX%28100%25%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.8%2C0%2C.6%2C1%29%2Copacity%20125ms%2050ms%7D%5Bdir%3Drtl%5D%20.md-nav__toggle~.md-nav%7Btransform%3AtranslateX%28-100%25%29%7D.md-nav__toggle%3Achecked~.md-nav%7Bopacity%3A1%3Btransform%3AtranslateX%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Copacity%20125ms%20125ms%7D.md-nav__toggle%3Achecked~.md-nav%3E.md-nav__list%7Bbackface-visibility%3Ahidden%7D%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%7Bdisplay%3Aflex%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%20.md-icon%3Aafter%7Bcontent%3A%22%22%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%2B.md-nav__link%7Bdisplay%3Anone%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D~.md-nav%7Bdisplay%3Aflex%7D.md-nav__source%7Bbackground-color%3Avar%28--md-primary-fg-color--dark%29%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bdisplay%3Ablock%3Bpadding%3A0%20.2rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%20and%20%28max-width%3A76.234375em%29%7B.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D%7Bdisplay%3Aflex%7D.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D%20.md-icon%3Aafter%7Bcontent%3A%22%22%7D.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D%2B.md-nav__link%7Bdisplay%3Anone%7D.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D~.md-nav%7Bdisplay%3Aflex%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-nav%7Bmargin-bottom%3A-.4rem%7D.md-nav--secondary%20.md-nav__title%7Bbackground%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.4rem%20.4rem%20var%28--md-default-bg-color%29%3Bposition%3Asticky%3Btop%3A0%3Bz-index%3A1%7D.md-nav--secondary%20.md-nav__title%5Bfor%3D__toc%5D%7Bscroll-snap-align%3Astart%7D.md-nav--secondary%20.md-nav__title%20.md-nav__icon%7Bdisplay%3Anone%7D%5Bdir%3Dltr%5D%20.md-nav--secondary%20.md-nav__list%7Bpadding-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--secondary%20.md-nav__list%7Bpadding-right%3A.6rem%7D.md-nav--secondary%20.md-nav__list%7Bpadding-bottom%3A.4rem%7D%5Bdir%3Dltr%5D%20.md-nav--secondary%20.md-nav__item%3E.md-nav__link%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--secondary%20.md-nav__item%3E.md-nav__link%7Bmargin-left%3A.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-nav%7Bmargin-bottom%3A-.4rem%3Btransition%3Amax-height%20.25s%20cubic-bezier%28.86%2C0%2C.07%2C1%29%7D.md-nav--primary%20.md-nav__title%7Bbackground%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.4rem%20.4rem%20var%28--md-default-bg-color%29%3Bposition%3Asticky%3Btop%3A0%3Bz-index%3A1%7D.md-nav--primary%20.md-nav__title%5Bfor%3D__drawer%5D%7Bscroll-snap-align%3Astart%7D.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bdisplay%3Anone%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__list%7Bpadding-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__list%7Bpadding-right%3A.6rem%7D.md-nav--primary%20.md-nav__list%7Bpadding-bottom%3A.4rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__item%3E.md-nav__link%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__item%3E.md-nav__link%7Bmargin-left%3A.4rem%7D.md-nav__toggle~.md-nav%7Bdisplay%3Agrid%3Bgrid-template-rows%3Aminmax%28.4rem%2C0fr%29%3Bopacity%3A0%3Btransition%3Agrid-template-rows%20.25s%20cubic-bezier%28.86%2C0%2C.07%2C1%29%2Copacity%20.25s%2Cvisibility%200ms%20.25s%3Bvisibility%3Acollapse%7D.md-nav__toggle~.md-nav%3E.md-nav__list%7Boverflow%3Ahidden%7D.md-nav__toggle.md-toggle--indeterminate~.md-nav%2C.md-nav__toggle%3Achecked~.md-nav%7Bgrid-template-rows%3Aminmax%28.4rem%2C1fr%29%3Bopacity%3A1%3Btransition%3Agrid-template-rows%20.25s%20cubic-bezier%28.86%2C0%2C.07%2C1%29%2Copacity%20.15s%20.1s%2Cvisibility%200ms%3Bvisibility%3Avisible%7D.md-nav__toggle.md-toggle--indeterminate~.md-nav%7Btransition%3Anone%7D.md-nav__item--nested%3E.md-nav%3E.md-nav__title%7Bdisplay%3Anone%7D.md-nav__item--section%7Bdisplay%3Ablock%3Bmargin%3A1.25em%200%7D.md-nav__item--section%3Alast-child%7Bmargin-bottom%3A0%7D.md-nav__item--section%3E.md-nav__link%7Bfont-weight%3A700%7D.md-nav__item--section%3E.md-nav__link%5Bfor%5D%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-nav__item--section%3E.md-nav__link%3Anot%28.md-nav__container%29%7Bpointer-events%3Anone%7D.md-nav__item--section%3E.md-nav__link%20.md-icon%2C.md-nav__item--section%3E.md-nav__link%3E%5Bfor%5D%7Bdisplay%3Anone%7D%5Bdir%3Dltr%5D%20.md-nav__item--section%3E.md-nav%7Bmargin-left%3A-.6rem%7D%5Bdir%3Drtl%5D%20.md-nav__item--section%3E.md-nav%7Bmargin-right%3A-.6rem%7D.md-nav__item--section%3E.md-nav%7Bdisplay%3Ablock%3Bopacity%3A1%3Bvisibility%3Avisible%7D.md-nav__item--section%3E.md-nav%3E.md-nav__list%3E.md-nav__item%7Bpadding%3A0%7D.md-nav__icon%7Bborder-radius%3A100%25%3Bheight%3A.9rem%3Btransition%3Abackground-color%20.25s%3Bwidth%3A.9rem%7D.md-nav__icon%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%7D.md-nav__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bborder-radius%3A100%25%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-nav-icon--next%29%3Bmask-image%3Avar%28--md-nav-icon--next%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Atransform%20.25s%3Bvertical-align%3A-.1rem%3Bwidth%3A100%25%7D%5Bdir%3Drtl%5D%20.md-nav__icon%3Aafter%7Btransform%3Arotate%28180deg%29%7D.md-nav__item--nested%20.md-nav__toggle%3Achecked~.md-nav__link%20.md-nav__icon%3Aafter%2C.md-nav__item--nested%20.md-toggle--indeterminate~.md-nav__link%20.md-nav__icon%3Aafter%7Btransform%3Arotate%2890deg%29%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%2C.md-nav--lifted%3E.md-nav__title%7Bdisplay%3Anone%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active%7Bdisplay%3Ablock%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active%3E.md-nav__link%7Bbackground%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.4rem%20.4rem%20var%28--md-default-bg-color%29%3Bmargin-top%3A0%3Bposition%3Asticky%3Btop%3A0%3Bz-index%3A1%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active%3E.md-nav__link%3Anot%28.md-nav__container%29%7Bpointer-events%3Anone%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active.md-nav__item--section%7Bmargin%3A0%7D%5Bdir%3Dltr%5D%20.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%3E.md-nav%3Anot%28.md-nav--secondary%29%7Bmargin-left%3A-.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%3E.md-nav%3Anot%28.md-nav--secondary%29%7Bmargin-right%3A-.6rem%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%3E%5Bfor%5D%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-nav--lifted%20.md-nav%5Bdata-md-level%3D%221%22%5D%7Bgrid-template-rows%3Aminmax%28.4rem%2C1fr%29%3Bopacity%3A1%3Bvisibility%3Avisible%7D%5Bdir%3Dltr%5D%20.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%7Bborder-left%3A.05rem%20solid%20var%28--md-primary-fg-color%29%7D%5Bdir%3Drtl%5D%20.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%7Bborder-right%3A.05rem%20solid%20var%28--md-primary-fg-color%29%7D.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%7Bdisplay%3Ablock%3Bmargin-bottom%3A1.25em%3Bopacity%3A1%3Bvisibility%3Avisible%7D.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%3E.md-nav__list%7Boverflow%3Avisible%3Bpadding-bottom%3A0%7D.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%3E.md-nav__title%7Bdisplay%3Anone%7D%7D.md-pagination%7Bfont-size%3A.8rem%3Bfont-weight%3A700%3Bgap%3A.4rem%7D.md-pagination%2C.md-pagination%3E%2A%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bjustify-content%3Acenter%7D.md-pagination%3E%2A%7Bborder-radius%3A.2rem%3Bheight%3A1.8rem%3Bmin-width%3A1.8rem%3Btext-align%3Acenter%7D.md-pagination__current%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-pagination__link%7Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%7D.md-pagination__link%3Afocus%2C.md-pagination__link%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-pagination__link%3Afocus%20svg%2C.md-pagination__link%3Ahover%20svg%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-pagination__link.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-pagination__link%20svg%7Bfill%3Acurrentcolor%3Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bdisplay%3Ablock%3Bmax-height%3A100%25%3Bwidth%3A1.2rem%7D%3Aroot%7B--md-path-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%7D.md-path%7Bfont-size%3A.7rem%3Bmargin%3A0%20.8rem%3Boverflow%3Aauto%3Bpadding-top%3A1.2rem%7D.md-path%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ablock%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-path%7Bmargin%3A0%201.2rem%7D%7D.md-path__list%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bgap%3A.2rem%3Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-path__item%3Anot%28%3Afirst-child%29%7Bdisplay%3Ainline-flex%3Bgap%3A.2rem%3Bwhite-space%3Anowrap%7D.md-path__item%3Anot%28%3Afirst-child%29%3Abefore%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%3Bcontent%3A%22%22%3Bdisplay%3Ainline%3Bheight%3A.8rem%3B-webkit-mask-image%3Avar%28--md-path-icon%29%3Bmask-image%3Avar%28--md-path-icon%29%3Bwidth%3A.8rem%7D.md-path__link%7Balign-items%3Acenter%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bdisplay%3Aflex%7D.md-path__link%3Afocus%2C.md-path__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D%3Aroot%7B--md-post-pin-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M16%2012V4h1V2H7v2h1v8l-2%202v2h5.2v6h1.6v-6H18v-2z%22/%3E%3C/svg%3E%27%29%7D.md-post__back%7Bborder-bottom%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bmargin-bottom%3A1.2rem%3Bpadding-bottom%3A1.2rem%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-post__back%7Bdisplay%3Anone%7D%7D%5Bdir%3Drtl%5D%20.md-post__back%20svg%7Btransform%3AscaleX%28-1%29%7D.md-post__authors%7Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bgap%3A.6rem%3Bmargin%3A0%20.6rem%201.2rem%7D.md-post%20.md-post__meta%20a%7Btransition%3Acolor%20125ms%7D.md-post%20.md-post__meta%20a%3Afocus%2C.md-post%20.md-post__meta%20a%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-post__title%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-weight%3A700%7D.md-post--excerpt%7Bmargin-bottom%3A3.2rem%7D.md-post--excerpt%20.md-post__header%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bgap%3A.6rem%3Bmin-height%3A1.6rem%7D.md-post--excerpt%20.md-post__authors%7Balign-items%3Acenter%3Bdisplay%3Ainline-flex%3Bflex-direction%3Arow%3Bgap%3A.2rem%3Bmargin%3A0%3Bmin-height%3A2.4rem%7D%5Bdir%3Dltr%5D%20.md-post--excerpt%20.md-post__meta%20.md-meta__list%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-post--excerpt%20.md-post__meta%20.md-meta__list%7Bmargin-left%3A.4rem%7D.md-post--excerpt%20.md-post__content%3E%3Afirst-child%7B--md-scroll-margin%3A6rem%3Bmargin-top%3A0%7D.md-post%3E.md-nav--secondary%7Bmargin%3A1em%200%7D.md-pin%7Bbackground%3Avar%28--md-default-fg-color--lightest%29%3Bborder-radius%3A1rem%3Bmargin-top%3A-.05rem%3Bpadding%3A.2rem%7D.md-pin%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A.6rem%3Bmargin%3A0%20auto%3B-webkit-mask-image%3Avar%28--md-post-pin-icon%29%3Bmask-image%3Avar%28--md-post-pin-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A.6rem%7D.md-profile%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bfont-size%3A.7rem%3Bgap%3A.6rem%3Bline-height%3A1.4%3Bwidth%3A100%25%7D.md-profile__description%7Bflex-grow%3A1%7D.md-content--post%7Bdisplay%3Aflex%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-content--post%7Bflex-flow%3Acolumn-reverse%7D%7D.md-content--post%3E.md-content__inner%7Bflex-grow%3A1%3Bmin-width%3A0%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdir%3Dltr%5D%20.md-content--post%3E.md-content__inner%7Bmargin-left%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-content--post%3E.md-content__inner%7Bmargin-right%3A1.2rem%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-sidebar.md-sidebar--post%7Bpadding%3A0%3Bposition%3Astatic%3Bwidth%3A100%25%7D.md-sidebar.md-sidebar--post%20.md-sidebar__scrollwrap%7Boverflow%3Avisible%7D.md-sidebar.md-sidebar--post%20.md-sidebar__inner%7Bpadding%3A0%7D.md-sidebar.md-sidebar--post%20.md-post__meta%7Bmargin-left%3A.6rem%3Bmargin-right%3A.6rem%7D.md-sidebar.md-sidebar--post%20.md-nav__item%7Bborder%3Anone%3Bdisplay%3Ainline%7D.md-sidebar.md-sidebar--post%20.md-nav__list%7Bdisplay%3Ainline-flex%3Bflex-wrap%3Awrap%3Bgap%3A.6rem%3Bpadding-bottom%3A.6rem%3Bpadding-top%3A.6rem%7D.md-sidebar.md-sidebar--post%20.md-nav__link%7Bpadding%3A0%7D.md-sidebar.md-sidebar--post%20.md-nav%7Bheight%3Aauto%3Bmargin-bottom%3A0%3Bposition%3Astatic%7D%7D%3Aroot%7B--md-progress-value%3A0%3B--md-progress-delay%3A400ms%7D.md-progress%7Bbackground%3Avar%28--md-primary-bg-color%29%3Bheight%3A.075rem%3Bopacity%3Amin%28clamp%280%2Cvar%28--md-progress-value%29%2C1%29%2Cclamp%280%2C100%20-%20var%28--md-progress-value%29%2C1%29%29%3Bposition%3Afixed%3Btop%3A0%3Btransform%3AscaleX%28calc%28var%28--md-progress-value%29%2A1%25%29%29%3Btransform-origin%3Aleft%3Btransition%3Atransform%20.5s%20cubic-bezier%28.19%2C1%2C.22%2C1%29%2Copacity%20.25s%20var%28--md-progress-delay%29%3Bwidth%3A100%25%3Bz-index%3A4%7D%3Aroot%7B--md-search-result-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M14%202H6a2%202%200%200%200-2%202v16a2%202%200%200%200%202%202h7c-.41-.25-.8-.56-1.14-.9-.33-.33-.61-.7-.86-1.1H6V4h7v5h5v1.18c.71.16%201.39.43%202%20.82V8zm6.31%2016.9c1.33-2.11.69-4.9-1.4-6.22-2.11-1.33-4.91-.68-6.22%201.4-1.34%202.11-.69%204.89%201.4%206.22%201.46.93%203.32.93%204.79.02L22%2023.39%2023.39%2022zm-3.81.1a2.5%202.5%200%200%201-2.5-2.5%202.5%202.5%200%200%201%202.5-2.5%202.5%202.5%200%200%201%202.5%202.5%202.5%202.5%200%200%201-2.5%202.5%22/%3E%3C/svg%3E%27%29%7D.md-search%7Bposition%3Arelative%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search%7Bpadding%3A.2rem%200%7D%7D.no-js%20.md-search%7Bdisplay%3Anone%7D.md-search__overlay%7Bopacity%3A0%3Bz-index%3A1%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__overlay%7Bleft%3A-2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__overlay%7Bright%3A-2.2rem%7D.md-search__overlay%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A1rem%3Bheight%3A2rem%3Boverflow%3Ahidden%3Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btop%3A-1rem%3Btransform-origin%3Acenter%3Btransition%3Atransform%20.3s%20.1s%2Copacity%20.2s%20.2s%3Bwidth%3A2rem%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Bopacity%3A1%3Btransition%3Atransform%20.4s%2Copacity%20.1s%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__overlay%7Bleft%3A0%7D%5Bdir%3Drtl%5D%20.md-search__overlay%7Bright%3A0%7D.md-search__overlay%7Bbackground-color%3A%230000008a%3Bcursor%3Apointer%3Bheight%3A0%3Bposition%3Afixed%3Btop%3A0%3Btransition%3Awidth%200ms%20.25s%2Cheight%200ms%20.25s%2Copacity%20.25s%3Bwidth%3A0%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Bheight%3A200vh%3Bopacity%3A1%3Btransition%3Awidth%200ms%2Cheight%200ms%2Copacity%20.25s%3Bwidth%3A100%25%7D%7D%40media%20screen%20and%20%28max-width%3A29.984375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Btransform%3Ascale%2845%29%7D%7D%40media%20screen%20and%20%28min-width%3A30em%29%20and%20%28max-width%3A44.984375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Btransform%3Ascale%2860%29%7D%7D%40media%20screen%20and%20%28min-width%3A45em%29%20and%20%28max-width%3A59.984375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Btransform%3Ascale%2875%29%7D%7D.md-search__inner%7Bbackface-visibility%3Ahidden%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__inner%7Bleft%3A0%7D%5Bdir%3Drtl%5D%20.md-search__inner%7Bright%3A0%7D.md-search__inner%7Bheight%3A0%3Bopacity%3A0%3Boverflow%3Ahidden%3Bposition%3Afixed%3Btop%3A0%3Btransform%3AtranslateX%285%25%29%3Btransition%3Awidth%200ms%20.3s%2Cheight%200ms%20.3s%2Ctransform%20.15s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%20.15s%2Copacity%20.15s%20.15s%3Bwidth%3A0%3Bz-index%3A2%7D%5Bdir%3Drtl%5D%20.md-search__inner%7Btransform%3AtranslateX%28-5%25%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__inner%7Bheight%3A100%25%3Bopacity%3A1%3Btransform%3AtranslateX%280%29%3Btransition%3Awidth%200ms%200ms%2Cheight%200ms%200ms%2Ctransform%20.15s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%20.15s%2Copacity%20.15s%20.15s%3Bwidth%3A100%25%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__inner%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-search__inner%7Bfloat%3Aleft%7D.md-search__inner%7Bpadding%3A.1rem%200%3Bposition%3Arelative%3Btransition%3Awidth%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%3Bwidth%3A11.7rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%20and%20%28max-width%3A76.234375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__inner%7Bwidth%3A23.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__inner%7Bwidth%3A34.4rem%7D%7D.md-search__form%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.6rem%20%230000%3Bheight%3A2.4rem%3Bposition%3Arelative%3Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%3Bz-index%3A2%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__form%7Bbackground-color%3A%2300000042%3Bborder-radius%3A.1rem%3Bheight%3A1.8rem%7D.md-search__form%3Ahover%7Bbackground-color%3A%23ffffff1f%7D%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__form%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%20.1rem%200%200%3Bbox-shadow%3A0%200%20.6rem%20%2300000012%3Bcolor%3Avar%28--md-default-fg-color%29%7D%5Bdir%3Dltr%5D%20.md-search__input%7Bpadding-left%3A3.6rem%3Bpadding-right%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__input%7Bpadding-left%3A2.2rem%3Bpadding-right%3A3.6rem%7D.md-search__input%7Bbackground%3A%230000%3Bfont-size%3A.9rem%3Bheight%3A100%25%3Bposition%3Arelative%3Btext-overflow%3Aellipsis%3Bwidth%3A100%25%3Bz-index%3A2%7D.md-search__input%3A%3Aplaceholder%7Btransition%3Acolor%20.25s%7D.md-search__input%3A%3Aplaceholder%2C.md-search__input~.md-search__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-search__input%3A%3A-ms-clear%7Bdisplay%3Anone%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-search__input%7Bfont-size%3A.9rem%3Bheight%3A2.4rem%3Bwidth%3A100%25%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__input%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__input%7Bpadding-right%3A2.2rem%7D.md-search__input%7Bcolor%3Ainherit%3Bfont-size%3A.8rem%7D.md-search__input%3A%3Aplaceholder%7Bcolor%3Avar%28--md-primary-bg-color--light%29%7D.md-search__input%2B.md-search__icon%7Bcolor%3Avar%28--md-primary-bg-color%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%7Btext-overflow%3Aclip%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%2B.md-search__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%3A%3Aplaceholder%7Bcolor%3A%230000%7D%7D.md-search__icon%7Bcursor%3Apointer%3Bdisplay%3Ainline-block%3Bheight%3A1.2rem%3Btransition%3Acolor%20.25s%2Copacity%20.25s%3Bwidth%3A1.2rem%7D.md-search__icon%3Ahover%7Bopacity%3A.7%7D%5Bdir%3Dltr%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bleft%3A.5rem%7D%5Bdir%3Drtl%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bright%3A.5rem%7D.md-search__icon%5Bfor%3D__search%5D%7Bposition%3Aabsolute%3Btop%3A.3rem%3Bz-index%3A2%7D%5Bdir%3Drtl%5D%20.md-search__icon%5Bfor%3D__search%5D%20svg%7Btransform%3AscaleX%28-1%29%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bleft%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bright%3A.8rem%7D.md-search__icon%5Bfor%3D__search%5D%7Btop%3A.6rem%7D.md-search__icon%5Bfor%3D__search%5D%20svg%3Afirst-child%7Bdisplay%3Anone%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__icon%5Bfor%3D__search%5D%7Bpointer-events%3Anone%7D.md-search__icon%5Bfor%3D__search%5D%20svg%3Alast-child%7Bdisplay%3Anone%7D%7D%5Bdir%3Dltr%5D%20.md-search__options%7Bright%3A.5rem%7D%5Bdir%3Drtl%5D%20.md-search__options%7Bleft%3A.5rem%7D.md-search__options%7Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btop%3A.3rem%3Bz-index%3A2%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__options%7Bright%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-search__options%7Bleft%3A.8rem%7D.md-search__options%7Btop%3A.6rem%7D%7D%5Bdir%3Dltr%5D%20.md-search__options%3E.md-icon%7Bmargin-left%3A.2rem%7D%5Bdir%3Drtl%5D%20.md-search__options%3E.md-icon%7Bmargin-right%3A.2rem%7D.md-search__options%3E.md-icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bopacity%3A0%3Btransform%3Ascale%28.75%29%3Btransition%3Atransform%20.15s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%7D.md-search__options%3E.md-icon%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%3Avalid~.md-search__options%3E.md-icon%7Bopacity%3A1%3Bpointer-events%3Aauto%3Btransform%3Ascale%281%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%3Avalid~.md-search__options%3E.md-icon%3Ahover%7Bopacity%3A.7%7D%5Bdir%3Dltr%5D%20.md-search__suggest%7Bpadding-left%3A3.6rem%3Bpadding-right%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__suggest%7Bpadding-left%3A2.2rem%3Bpadding-right%3A3.6rem%7D.md-search__suggest%7Balign-items%3Acenter%3Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bdisplay%3Aflex%3Bfont-size%3A.9rem%3Bheight%3A100%25%3Bopacity%3A0%3Bposition%3Aabsolute%3Btop%3A0%3Btransition%3Aopacity%2050ms%3Bwhite-space%3Anowrap%3Bwidth%3A100%25%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__suggest%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__suggest%7Bpadding-right%3A2.2rem%7D.md-search__suggest%7Bfont-size%3A.8rem%7D%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__suggest%7Bopacity%3A1%3Btransition%3Aopacity%20.3s%20.1s%7D%5Bdir%3Dltr%5D%20.md-search__output%7Bborder-bottom-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-search__output%2C%5Bdir%3Drtl%5D%20.md-search__output%7Bborder-bottom-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-search__output%7Bborder-bottom-left-radius%3A.1rem%7D.md-search__output%7Boverflow%3Ahidden%3Bposition%3Aabsolute%3Bwidth%3A100%25%3Bz-index%3A1%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-search__output%7Bbottom%3A0%3Btop%3A2.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__output%7Bopacity%3A0%3Btop%3A1.9rem%3Btransition%3Aopacity%20.4s%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__output%7Bbox-shadow%3Avar%28--md-shadow-z3%29%3Bopacity%3A1%7D%7D.md-search__scrollwrap%7Bbackface-visibility%3Ahidden%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bheight%3A100%25%3Boverflow-y%3Aauto%3Btouch-action%3Apan-y%7D%40media%20%28-webkit-max-device-pixel-ratio%3A1%29%2C%28max-resolution%3A1dppx%29%7B.md-search__scrollwrap%7Btransform%3AtranslateZ%280%29%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%20and%20%28max-width%3A76.234375em%29%7B.md-search__scrollwrap%7Bwidth%3A23.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-search__scrollwrap%7Bwidth%3A34.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__scrollwrap%7Bmax-height%3A0%3Bscrollbar-color%3Avar%28--md-default-fg-color--lighter%29%20%230000%3Bscrollbar-width%3Athin%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__scrollwrap%7Bmax-height%3A75vh%7D.md-search__scrollwrap%3Ahover%7Bscrollbar-color%3Avar%28--md-accent-fg-color%29%20%230000%7D.md-search__scrollwrap%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-search__scrollwrap%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-search__scrollwrap%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%7D.md-search-result%7Bcolor%3Avar%28--md-default-fg-color%29%3Bword-break%3Abreak-word%7D.md-search-result__meta%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.64rem%3Bline-height%3A1.8rem%3Bpadding%3A0%20.8rem%3Bscroll-snap-align%3Astart%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search-result__meta%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search-result__meta%7Bpadding-right%3A2.2rem%7D%7D.md-search-result__list%7Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%3B-webkit-user-select%3Anone%3Buser-select%3Anone%7D.md-search-result__item%7Bbox-shadow%3A0%20-.05rem%20var%28--md-default-fg-color--lightest%29%7D.md-search-result__item%3Afirst-child%7Bbox-shadow%3Anone%7D.md-search-result__link%7Bdisplay%3Ablock%3Boutline%3Anone%3Bscroll-snap-align%3Astart%3Btransition%3Abackground-color%20.25s%7D.md-search-result__link%3Afocus%2C.md-search-result__link%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%7D.md-search-result__link%3Alast-child%20p%3Alast-child%7Bmargin-bottom%3A.6rem%7D.md-search-result__more%3Esummary%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Boutline%3Anone%3Bposition%3Asticky%3Bscroll-snap-align%3Astart%3Btop%3A0%3Bz-index%3A1%7D.md-search-result__more%3Esummary%3A%3Amarker%7Bdisplay%3Anone%7D.md-search-result__more%3Esummary%3A%3A-webkit-details-marker%7Bdisplay%3Anone%7D.md-search-result__more%3Esummary%3Ediv%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bfont-size%3A.64rem%3Bpadding%3A.75em%20.8rem%3Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search-result__more%3Esummary%3Ediv%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search-result__more%3Esummary%3Ediv%7Bpadding-right%3A2.2rem%7D%7D.md-search-result__more%3Esummary%3Afocus%3Ediv%2C.md-search-result__more%3Esummary%3Ahover%3Ediv%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-search-result__more%5Bopen%5D%3Esummary%7Bbackground-color%3Avar%28--md-default-bg-color%29%7D.md-search-result__article%7Boverflow%3Ahidden%3Bpadding%3A0%20.8rem%3Bposition%3Arelative%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search-result__article%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search-result__article%7Bpadding-right%3A2.2rem%7D%7D%5Bdir%3Dltr%5D%20.md-search-result__icon%7Bleft%3A0%7D%5Bdir%3Drtl%5D%20.md-search-result__icon%7Bright%3A0%7D.md-search-result__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bheight%3A1.2rem%3Bmargin%3A.5rem%3Bposition%3Aabsolute%3Bwidth%3A1.2rem%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-search-result__icon%7Bdisplay%3Anone%7D%7D.md-search-result__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-search-result-icon%29%3Bmask-image%3Avar%28--md-search-result-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A100%25%7D%5Bdir%3Drtl%5D%20.md-search-result__icon%3Aafter%7Btransform%3AscaleX%28-1%29%7D.md-search-result%20.md-typeset%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.64rem%3Bline-height%3A1.6%7D.md-search-result%20.md-typeset%20h1%7Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-size%3A.8rem%3Bfont-weight%3A400%3Bline-height%3A1.4%3Bmargin%3A.55rem%200%7D.md-search-result%20.md-typeset%20h1%20mark%7Btext-decoration%3Anone%7D.md-search-result%20.md-typeset%20h2%7Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-size%3A.64rem%3Bfont-weight%3A700%3Bline-height%3A1.6%3Bmargin%3A.5em%200%7D.md-search-result%20.md-typeset%20h2%20mark%7Btext-decoration%3Anone%7D.md-search-result__terms%7Bcolor%3Avar%28--md-default-fg-color%29%3Bdisplay%3Ablock%3Bfont-size%3A.64rem%3Bfont-style%3Aitalic%3Bmargin%3A.5em%200%7D.md-search-result%20mark%7Bbackground-color%3Ainitial%3Bcolor%3Avar%28--md-accent-fg-color%29%3Btext-decoration%3Aunderline%7D.md-select%7Bposition%3Arelative%3Bz-index%3A1%7D.md-select__inner%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color%29%3Bleft%3A50%25%3Bmargin-top%3A.2rem%3Bmax-height%3A0%3Bopacity%3A0%3Bposition%3Aabsolute%3Btop%3Acalc%28100%25%20-%20.2rem%29%3Btransform%3Atranslate3d%28-50%25%2C.3rem%2C0%29%3Btransition%3Atransform%20.25s%20375ms%2Copacity%20.25s%20.25s%2Cmax-height%200ms%20.5s%7D.md-select%3Afocus-within%20.md-select__inner%2C.md-select%3Ahover%20.md-select__inner%7Bmax-height%3A10rem%3Bopacity%3A1%3Btransform%3Atranslate3d%28-50%25%2C0%2C0%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.25s%2Cmax-height%200ms%7D.md-select__inner%3Aafter%7Bborder-bottom%3A.2rem%20solid%20%230000%3Bborder-bottom-color%3Avar%28--md-default-bg-color%29%3Bborder-left%3A.2rem%20solid%20%230000%3Bborder-right%3A.2rem%20solid%20%230000%3Bborder-top%3A0%3Bcontent%3A%22%22%3Bheight%3A0%3Bleft%3A50%25%3Bmargin-left%3A-.2rem%3Bmargin-top%3A-.2rem%3Bposition%3Aabsolute%3Btop%3A0%3Bwidth%3A0%7D.md-select__list%7Bborder-radius%3A.1rem%3Bfont-size%3A.8rem%3Blist-style-type%3Anone%3Bmargin%3A0%3Bmax-height%3Ainherit%3Boverflow%3Aauto%3Bpadding%3A0%7D.md-select__item%7Bline-height%3A1.8rem%7D%5Bdir%3Dltr%5D%20.md-select__link%7Bpadding-left%3A.6rem%3Bpadding-right%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-select__link%7Bpadding-left%3A1.2rem%3Bpadding-right%3A.6rem%7D.md-select__link%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Boutline%3Anone%3Bscroll-snap-align%3Astart%3Btransition%3Abackground-color%20.25s%2Ccolor%20.25s%3Bwidth%3A100%25%7D.md-select__link%3Afocus%2C.md-select__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-select__link%3Afocus%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%7D.md-sidebar%7Balign-self%3Aflex-start%3Bflex-shrink%3A0%3Bpadding%3A1.2rem%200%3Bposition%3Asticky%3Btop%3A2.4rem%3Bwidth%3A12.1rem%7D%40media%20print%7B.md-sidebar%7Bdisplay%3Anone%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B%5Bdir%3Dltr%5D%20.md-sidebar--primary%7Bleft%3A-12.1rem%7D%5Bdir%3Drtl%5D%20.md-sidebar--primary%7Bright%3A-12.1rem%7D.md-sidebar--primary%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bdisplay%3Ablock%3Bheight%3A100%25%3Bposition%3Afixed%3Btop%3A0%3Btransform%3AtranslateX%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Cbox-shadow%20.25s%3Bwidth%3A12.1rem%3Bz-index%3A5%7D%5Bdata-md-toggle%3Ddrawer%5D%3Achecked~.md-container%20.md-sidebar--primary%7Bbox-shadow%3Avar%28--md-shadow-z3%29%3Btransform%3AtranslateX%2812.1rem%29%7D%5Bdir%3Drtl%5D%20%5Bdata-md-toggle%3Ddrawer%5D%3Achecked~.md-container%20.md-sidebar--primary%7Btransform%3AtranslateX%28-12.1rem%29%7D.md-sidebar--primary%20.md-sidebar__scrollwrap%7Bbottom%3A0%3Bleft%3A0%3Bmargin%3A0%3Boverflow%3Ahidden%3Bposition%3Aabsolute%3Bright%3A0%3Bscroll-snap-type%3Anone%3Btop%3A0%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-sidebar%7Bheight%3A0%7D.no-js%20.md-sidebar%7Bheight%3Aauto%7D.md-header--lifted~.md-container%20.md-sidebar%7Btop%3A4.8rem%7D%7D.md-sidebar--secondary%7Bdisplay%3Anone%3Border%3A2%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-sidebar--secondary%7Bheight%3A0%7D.no-js%20.md-sidebar--secondary%7Bheight%3Aauto%7D.md-sidebar--secondary%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ablock%7D.md-sidebar--secondary%20.md-sidebar__scrollwrap%7Btouch-action%3Apan-y%7D%7D.md-sidebar__scrollwrap%7Bbackface-visibility%3Ahidden%3Bmargin%3A0%20.2rem%3Boverflow-y%3Aauto%3Bscrollbar-color%3Avar%28--md-default-fg-color--lighter%29%20%230000%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-sidebar__scrollwrap%7Bscrollbar-gutter%3Astable%3Bscrollbar-width%3Athin%7D%7D.md-sidebar__scrollwrap%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-sidebar__scrollwrap%3Afocus-within%2C.md-sidebar__scrollwrap%3Ahover%7Bscrollbar-color%3Avar%28--md-accent-fg-color%29%20%230000%7D.md-sidebar__scrollwrap%3Afocus-within%3A%3A-webkit-scrollbar-thumb%2C.md-sidebar__scrollwrap%3Ahover%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-sidebar__scrollwrap%3Afocus-within%3A%3A-webkit-scrollbar-thumb%3Ahover%2C.md-sidebar__scrollwrap%3Ahover%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%40supports%20selector%28%3A%3A-webkit-scrollbar%29%7B.md-sidebar__scrollwrap%7Bscrollbar-gutter%3Aauto%7D%5Bdir%3Dltr%5D%20.md-sidebar__inner%7Bpadding-right%3Acalc%28100%25%20-%2011.5rem%29%7D%5Bdir%3Drtl%5D%20.md-sidebar__inner%7Bpadding-left%3Acalc%28100%25%20-%2011.5rem%29%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-overlay%7Bbackground-color%3A%230000008a%3Bheight%3A0%3Bopacity%3A0%3Bposition%3Afixed%3Btop%3A0%3Btransition%3Awidth%200ms%20.25s%2Cheight%200ms%20.25s%2Copacity%20.25s%3Bwidth%3A0%3Bz-index%3A5%7D%5Bdata-md-toggle%3Ddrawer%5D%3Achecked~.md-overlay%7Bheight%3A100%25%3Bopacity%3A1%3Btransition%3Awidth%200ms%2Cheight%200ms%2Copacity%20.25s%3Bwidth%3A100%25%7D%7D%40keyframes%20facts%7B0%25%7Bheight%3A0%7Dto%7Bheight%3A.65rem%7D%7D%40keyframes%20fact%7B0%25%7Bopacity%3A0%3Btransform%3AtranslateY%28100%25%29%7D50%25%7Bopacity%3A0%7Dto%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%7D%7D%3Aroot%7B--md-source-forks-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M5%205.372v.878c0%20.414.336.75.75.75h4.5a.75.75%200%200%200%20.75-.75v-.878a2.25%202.25%200%201%201%201.5%200v.878a2.25%202.25%200%200%201-2.25%202.25h-1.5v2.128a2.251%202.251%200%201%201-1.5%200V8.5h-1.5A2.25%202.25%200%200%201%203.5%206.25v-.878a2.25%202.25%200%201%201%201.5%200M5%203.25a.75.75%200%201%200-1.5%200%20.75.75%200%200%200%201.5%200m6.75.75a.75.75%200%201%200%200-1.5.75.75%200%200%200%200%201.5m-3%208.75a.75.75%200%201%200-1.5%200%20.75.75%200%200%200%201.5%200%22/%3E%3C/svg%3E%27%29%3B--md-source-repositories-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M2%202.5A2.5%202.5%200%200%201%204.5%200h8.75a.75.75%200%200%201%20.75.75v12.5a.75.75%200%200%201-.75.75h-2.5a.75.75%200%200%201%200-1.5h1.75v-2h-8a1%201%200%200%200-.714%201.7.75.75%200%201%201-1.072%201.05A2.5%202.5%200%200%201%202%2011.5Zm10.5-1h-8a1%201%200%200%200-1%201v6.708A2.5%202.5%200%200%201%204.5%209h8ZM5%2012.25a.25.25%200%200%201%20.25-.25h3.5a.25.25%200%200%201%20.25.25v3.25a.25.25%200%200%201-.4.2l-1.45-1.087a.25.25%200%200%200-.3%200L5.4%2015.7a.25.25%200%200%201-.4-.2Z%22/%3E%3C/svg%3E%27%29%3B--md-source-stars-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M8%20.25a.75.75%200%200%201%20.673.418l1.882%203.815%204.21.612a.75.75%200%200%201%20.416%201.279l-3.046%202.97.719%204.192a.751.751%200%200%201-1.088.791L8%2012.347l-3.766%201.98a.75.75%200%200%201-1.088-.79l.72-4.194L.818%206.374a.75.75%200%200%201%20.416-1.28l4.21-.611L7.327.668A.75.75%200%200%201%208%20.25m0%202.445L6.615%205.5a.75.75%200%200%201-.564.41l-3.097.45%202.24%202.184a.75.75%200%200%201%20.216.664l-.528%203.084%202.769-1.456a.75.75%200%200%201%20.698%200l2.77%201.456-.53-3.084a.75.75%200%200%201%20.216-.664l2.24-2.183-3.096-.45a.75.75%200%200%201-.564-.41z%22/%3E%3C/svg%3E%27%29%3B--md-source-version-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M1%207.775V2.75C1%201.784%201.784%201%202.75%201h5.025c.464%200%20.91.184%201.238.513l6.25%206.25a1.75%201.75%200%200%201%200%202.474l-5.026%205.026a1.75%201.75%200%200%201-2.474%200l-6.25-6.25A1.75%201.75%200%200%201%201%207.775m1.5%200c0%20.066.026.13.073.177l6.25%206.25a.25.25%200%200%200%20.354%200l5.025-5.025a.25.25%200%200%200%200-.354l-6.25-6.25a.25.25%200%200%200-.177-.073H2.75a.25.25%200%200%200-.25.25ZM6%205a1%201%200%201%201%200%202%201%201%200%200%201%200-2%22/%3E%3C/svg%3E%27%29%7D.md-source%7Bbackface-visibility%3Ahidden%3Bdisplay%3Ablock%3Bfont-size%3A.65rem%3Bline-height%3A1.2%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Btransition%3Aopacity%20.25s%3Bwhite-space%3Anowrap%7D.md-source%3Ahover%7Bopacity%3A.7%7D.md-source__icon%7Bdisplay%3Ainline-block%3Bheight%3A2.4rem%3Bvertical-align%3Amiddle%3Bwidth%3A2rem%7D%5Bdir%3Dltr%5D%20.md-source__icon%20svg%7Bmargin-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-source__icon%20svg%7Bmargin-right%3A.6rem%7D.md-source__icon%20svg%7Bmargin-top%3A.6rem%7D%5Bdir%3Dltr%5D%20.md-source__icon%2B.md-source__repository%7Bpadding-left%3A2rem%7D%5Bdir%3Drtl%5D%20.md-source__icon%2B.md-source__repository%7Bpadding-right%3A2rem%7D%5Bdir%3Dltr%5D%20.md-source__icon%2B.md-source__repository%7Bmargin-left%3A-2rem%7D%5Bdir%3Drtl%5D%20.md-source__icon%2B.md-source__repository%7Bmargin-right%3A-2rem%7D%5Bdir%3Dltr%5D%20.md-source__repository%7Bmargin-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-source__repository%7Bmargin-right%3A.6rem%7D.md-source__repository%7Bdisplay%3Ainline-block%3Bmax-width%3Acalc%28100%25%20-%201.2rem%29%3Boverflow%3Ahidden%3Btext-overflow%3Aellipsis%3Bvertical-align%3Amiddle%7D.md-source__facts%7Bdisplay%3Aflex%3Bfont-size%3A.55rem%3Bgap%3A.4rem%3Blist-style-type%3Anone%3Bmargin%3A.1rem%200%200%3Bopacity%3A.75%3Boverflow%3Ahidden%3Bpadding%3A0%3Bwidth%3A100%25%7D.md-source__repository--active%20.md-source__facts%7Banimation%3Afacts%20.25s%20ease-in%7D.md-source__fact%7Boverflow%3Ahidden%3Btext-overflow%3Aellipsis%7D.md-source__repository--active%20.md-source__fact%7Banimation%3Afact%20.4s%20ease-out%7D%5Bdir%3Dltr%5D%20.md-source__fact%3Abefore%7Bmargin-right%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-source__fact%3Abefore%7Bmargin-left%3A.1rem%7D.md-source__fact%3Abefore%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A.6rem%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bvertical-align%3Atext-top%3Bwidth%3A.6rem%7D.md-source__fact%3Anth-child%281n%2B2%29%7Bflex-shrink%3A0%7D.md-source__fact--version%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-version-icon%29%3Bmask-image%3Avar%28--md-source-version-icon%29%7D.md-source__fact--stars%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-stars-icon%29%3Bmask-image%3Avar%28--md-source-stars-icon%29%7D.md-source__fact--forks%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-forks-icon%29%3Bmask-image%3Avar%28--md-source-forks-icon%29%7D.md-source__fact--repositories%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-repositories-icon%29%3Bmask-image%3Avar%28--md-source-repositories-icon%29%7D.md-source-file%7Bmargin%3A1em%200%7D%5Bdir%3Dltr%5D%20.md-source-file__fact%7Bmargin-right%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-source-file__fact%7Bmargin-left%3A.6rem%7D.md-source-file__fact%7Balign-items%3Acenter%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bdisplay%3Ainline-flex%3Bfont-size%3A.68rem%3Bgap%3A.3rem%7D.md-source-file__fact%20.md-icon%7Bflex-shrink%3A0%3Bmargin-bottom%3A.05rem%7D%5Bdir%3Dltr%5D%20.md-source-file__fact%20.md-author%7Bfloat%3Aleft%7D%5Bdir%3Drtl%5D%20.md-source-file__fact%20.md-author%7Bfloat%3Aright%7D.md-source-file__fact%20.md-author%7Bmargin-right%3A.2rem%7D.md-source-file__fact%20svg%7Bwidth%3A.9rem%7D%3Aroot%7B--md-status%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M11%209h2V7h-2m1%2013c-4.41%200-8-3.59-8-8s3.59-8%208-8%208%203.59%208%208-3.59%208-8%208m0-18A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202m-1%2015h2v-6h-2z%22/%3E%3C/svg%3E%27%29%3B--md-status--new%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m23%2012-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12%203%208.6%201.54%206.71%204.72l-3.61.81.34%203.68L1%2012l2.44%202.78-.34%203.69%203.61.82%201.89%203.18L12%2021l3.4%201.46%201.89-3.18%203.61-.82-.34-3.68zm-10%205h-2v-2h2zm0-4h-2V7h2z%22/%3E%3C/svg%3E%27%29%3B--md-status--deprecated%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M9%203v1H4v2h1v13a2%202%200%200%200%202%202h10a2%202%200%200%200%202-2V6h1V4h-5V3zm0%205h2v9H9zm4%200h2v9h-2z%22/%3E%3C/svg%3E%27%29%3B--md-status--encrypted%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M12%201%203%205v6c0%205.55%203.84%2010.74%209%2012%205.16-1.26%209-6.45%209-12V5zm0%206c1.4%200%202.8%201.1%202.8%202.5V11c.6%200%201.2.6%201.2%201.3v3.5c0%20.6-.6%201.2-1.3%201.2H9.2c-.6%200-1.2-.6-1.2-1.3v-3.5c0-.6.6-1.2%201.2-1.2V9.5C9.2%208.1%2010.6%207%2012%207m0%201.2c-.8%200-1.5.5-1.5%201.3V11h3V9.5c0-.8-.7-1.3-1.5-1.3%22/%3E%3C/svg%3E%27%29%7D.md-status%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--light%29%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A1.125em%3B-webkit-mask-image%3Avar%28--md-status%29%3Bmask-image%3Avar%28--md-status%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bvertical-align%3Atext-bottom%3Bwidth%3A1.125em%7D.md-status%3Ahover%3Aafter%7Bbackground-color%3Acurrentcolor%7D.md-status--new%3Aafter%7B-webkit-mask-image%3Avar%28--md-status--new%29%3Bmask-image%3Avar%28--md-status--new%29%7D.md-status--deprecated%3Aafter%7B-webkit-mask-image%3Avar%28--md-status--deprecated%29%3Bmask-image%3Avar%28--md-status--deprecated%29%7D.md-status--encrypted%3Aafter%7B-webkit-mask-image%3Avar%28--md-status--encrypted%29%3Bmask-image%3Avar%28--md-status--encrypted%29%7D.md-tabs%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bdisplay%3Ablock%3Bline-height%3A1.3%3Boverflow%3Aauto%3Bwidth%3A100%25%3Bz-index%3A3%7D%40media%20print%7B.md-tabs%7Bdisplay%3Anone%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-tabs%7Bdisplay%3Anone%7D%7D.md-tabs%5Bhidden%5D%7Bpointer-events%3Anone%7D%5Bdir%3Dltr%5D%20.md-tabs__list%7Bmargin-left%3A.2rem%7D%5Bdir%3Drtl%5D%20.md-tabs__list%7Bmargin-right%3A.2rem%7D.md-tabs__list%7Bcontain%3Acontent%3Bdisplay%3Aflex%3Blist-style%3Anone%3Bmargin%3A0%3Boverflow%3Aauto%3Bpadding%3A0%3Bscrollbar-width%3Anone%3Bwhite-space%3Anowrap%7D.md-tabs__list%3A%3A-webkit-scrollbar%7Bdisplay%3Anone%7D.md-tabs__item%7Bheight%3A2.4rem%3Bpadding-left%3A.6rem%3Bpadding-right%3A.6rem%7D.md-tabs__item--active%20.md-tabs__link%7Bcolor%3Ainherit%3Bopacity%3A1%7D.md-tabs__link%7Bbackface-visibility%3Ahidden%3Bdisplay%3Aflex%3Bfont-size%3A.7rem%3Bmargin-top%3A.8rem%3Bopacity%3A.7%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.25s%7D.md-tabs__link%3Afocus%2C.md-tabs__link%3Ahover%7Bcolor%3Ainherit%3Bopacity%3A1%7D%5Bdir%3Dltr%5D%20.md-tabs__link%20svg%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-tabs__link%20svg%7Bmargin-left%3A.4rem%7D.md-tabs__link%20svg%7Bfill%3Acurrentcolor%3Bheight%3A1.3em%7D.md-tabs__item%3Anth-child%282%29%20.md-tabs__link%7Btransition-delay%3A20ms%7D.md-tabs__item%3Anth-child%283%29%20.md-tabs__link%7Btransition-delay%3A40ms%7D.md-tabs__item%3Anth-child%284%29%20.md-tabs__link%7Btransition-delay%3A60ms%7D.md-tabs__item%3Anth-child%285%29%20.md-tabs__link%7Btransition-delay%3A80ms%7D.md-tabs__item%3Anth-child%286%29%20.md-tabs__link%7Btransition-delay%3A.1s%7D.md-tabs__item%3Anth-child%287%29%20.md-tabs__link%7Btransition-delay%3A.12s%7D.md-tabs__item%3Anth-child%288%29%20.md-tabs__link%7Btransition-delay%3A.14s%7D.md-tabs__item%3Anth-child%289%29%20.md-tabs__link%7Btransition-delay%3A.16s%7D.md-tabs__item%3Anth-child%2810%29%20.md-tabs__link%7Btransition-delay%3A.18s%7D.md-tabs__item%3Anth-child%2811%29%20.md-tabs__link%7Btransition-delay%3A.2s%7D.md-tabs__item%3Anth-child%2812%29%20.md-tabs__link%7Btransition-delay%3A.22s%7D.md-tabs__item%3Anth-child%2813%29%20.md-tabs__link%7Btransition-delay%3A.24s%7D.md-tabs__item%3Anth-child%2814%29%20.md-tabs__link%7Btransition-delay%3A.26s%7D.md-tabs__item%3Anth-child%2815%29%20.md-tabs__link%7Btransition-delay%3A.28s%7D.md-tabs__item%3Anth-child%2816%29%20.md-tabs__link%7Btransition-delay%3A.3s%7D.md-tabs%5Bhidden%5D%20.md-tabs__link%7Bopacity%3A0%3Btransform%3AtranslateY%2850%25%29%3Btransition%3Atransform%200ms%20.1s%2Copacity%20.1s%7D%3Aroot%7B--md-tag-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m5.41%2021%20.71-4h-4l.35-2h4l1.06-6h-4l.35-2h4l.71-4h2l-.71%204h6l.71-4h2l-.71%204h4l-.35%202h-4l-1.06%206h4l-.35%202h-4l-.71%204h-2l.71-4h-6l-.71%204zM9.53%209l-1.06%206h6l1.06-6z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.md-tags%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ainline-flex%3Bflex-wrap%3Awrap%3Bgap%3A.5em%3Bmargin-bottom%3A.75em%3Bmargin-top%3A-.125em%7D.md-typeset%20.md-tag%7Balign-items%3Acenter%3Bbackground%3Avar%28--md-default-fg-color--lightest%29%3Bborder-radius%3A2.4rem%3Bdisplay%3Ainline-flex%3Bfont-size%3A.64rem%3Bfont-size%3Amin%28.8em%2C.64rem%29%3Bfont-weight%3A700%3Bgap%3A.5em%3Bletter-spacing%3Anormal%3Bline-height%3A1.6%3Bpadding%3A.3125em%20.78125em%7D.md-typeset%20.md-tag%5Bhref%5D%7B-webkit-tap-highlight-color%3Atransparent%3Bcolor%3Ainherit%3Boutline%3Anone%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%7D.md-typeset%20.md-tag%5Bhref%5D%3Afocus%2C.md-typeset%20.md-tag%5Bhref%5D%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%3Bcolor%3Avar%28--md-accent-bg-color%29%7D%5Bid%5D%3E.md-typeset%20.md-tag%7Bvertical-align%3Atext-top%7D.md-typeset%20.md-tag-shadow%7Bopacity%3A.5%7D.md-typeset%20.md-tag-icon%3Abefore%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A1.2em%3B-webkit-mask-image%3Avar%28--md-tag-icon%29%3Bmask-image%3Avar%28--md-tag-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Abackground-color%20125ms%3Bvertical-align%3Atext-bottom%3Bwidth%3A1.2em%7D.md-typeset%20.md-tag-icon%5Bhref%5D%3Afocus%3Abefore%2C.md-typeset%20.md-tag-icon%5Bhref%5D%3Ahover%3Abefore%7Bbackground-color%3Avar%28--md-accent-bg-color%29%7D%40keyframes%20pulse%7B0%25%7Btransform%3Ascale%28.95%29%7D75%25%7Btransform%3Ascale%281%29%7Dto%7Btransform%3Ascale%28.95%29%7D%7D%3Aroot%7B--md-annotation-bg-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M12%202A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202%22/%3E%3C/svg%3E%27%29%3B--md-annotation-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M17%2013h-4v4h-2v-4H7v-2h4V7h2v4h4m-5-9A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202%22/%3E%3C/svg%3E%27%29%7D.md-tooltip%7Bbackface-visibility%3Ahidden%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-family%3Avar%28--md-text-font-family%29%3Bleft%3Aclamp%28var%28--md-tooltip-0%2C0rem%29%20%2B%20.8rem%2Cvar%28--md-tooltip-x%29%2C100vw%20%2B%20var%28--md-tooltip-0%2C0rem%29%20%2B%20.8rem%20-%20var%28--md-tooltip-width%29%20-%202%20%2A%20.8rem%29%3Bmax-width%3Acalc%28100vw%20-%201.6rem%29%3Bopacity%3A0%3Bposition%3Aabsolute%3Btop%3Avar%28--md-tooltip-y%29%3Btransform%3AtranslateY%28-.4rem%29%3Btransition%3Atransform%200ms%20.25s%2Copacity%20.25s%2Cz-index%20.25s%3Bwidth%3Avar%28--md-tooltip-width%29%3Bz-index%3A0%7D.md-tooltip--active%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.25s%2Cz-index%200ms%3Bz-index%3A2%7D.md-tooltip--inline%7Bfont-weight%3A700%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bwidth%3Aauto%7D.md-tooltip--inline%3Anot%28.md-tooltip--active%29%7Btransform%3AtranslateY%28.2rem%29%20scale%28.9%29%7D.md-tooltip--inline%20.md-tooltip__inner%7Bfont-size%3A.5rem%3Bpadding%3A.2rem%20.4rem%7D%5Bhidden%5D%2B.md-tooltip--inline%7Bdisplay%3Anone%7D.focus-visible%3E.md-tooltip%2C.md-tooltip%3Atarget%7Boutline%3Avar%28--md-accent-fg-color%29%20auto%7D.md-tooltip__inner%7Bfont-size%3A.64rem%3Bpadding%3A.8rem%7D.md-tooltip__inner.md-typeset%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-tooltip__inner.md-typeset%3E%3Alast-child%7Bmargin-bottom%3A0%7D.md-annotation%7Bfont-style%3Anormal%3Bfont-weight%3A400%3Boutline%3Anone%3Btext-align%3Ainitial%3Bvertical-align%3Atext-bottom%3Bwhite-space%3Anormal%7D%5Bdir%3Drtl%5D%20.md-annotation%7Bdirection%3Artl%7Dcode%20.md-annotation%7Bfont-family%3Avar%28--md-code-font-family%29%3Bfont-size%3Ainherit%7D.md-annotation%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ainline-block%3Bline-height%3A1.25%7D.md-annotation__index%7Bborder-radius%3A.01px%3Bcursor%3Apointer%3Bdisplay%3Ainline-block%3Bmargin-left%3A.4ch%3Bmargin-right%3A.4ch%3Boutline%3Anone%3Boverflow%3Ahidden%3Bposition%3Arelative%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bvertical-align%3Atext-top%3Bz-index%3A0%7D.md-annotation%20.md-annotation__index%7Btransition%3Az-index%20.25s%7D%40media%20screen%7B.md-annotation__index%7Bwidth%3A2.2ch%7D%5Bdata-md-visible%5D%3E.md-annotation__index%7Banimation%3Apulse%202s%20infinite%7D.md-annotation__index%3Abefore%7Bbackground%3Avar%28--md-default-bg-color%29%3B-webkit-mask-image%3Avar%28--md-annotation-bg-icon%29%3Bmask-image%3Avar%28--md-annotation-bg-icon%29%7D.md-annotation__index%3Aafter%2C.md-annotation__index%3Abefore%7Bcontent%3A%22%22%3Bheight%3A2.2ch%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A-.1ch%3Bwidth%3A2.2ch%3Bz-index%3A-1%7D.md-annotation__index%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%3B-webkit-mask-image%3Avar%28--md-annotation-icon%29%3Bmask-image%3Avar%28--md-annotation-icon%29%3Btransform%3Ascale%281.0001%29%3Btransition%3Abackground-color%20.25s%2Ctransform%20.25s%7D.md-tooltip--active%2B.md-annotation__index%3Aafter%7Btransform%3Arotate%2845deg%29%7D.md-tooltip--active%2B.md-annotation__index%3Aafter%2C%3Ahover%3E.md-annotation__index%3Aafter%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%7D.md-tooltip--active%2B.md-annotation__index%7Banimation-play-state%3Apaused%3Btransition-duration%3A0ms%3Bz-index%3A2%7D.md-annotation__index%20%5Bdata-md-annotation-id%5D%7Bdisplay%3Ainline-block%7D%40media%20print%7B.md-annotation__index%20%5Bdata-md-annotation-id%5D%7Bbackground%3Avar%28--md-default-fg-color--lighter%29%3Bborder-radius%3A2ch%3Bcolor%3Avar%28--md-default-bg-color%29%3Bfont-weight%3A700%3Bpadding%3A0%20.6ch%3Bwhite-space%3Anowrap%7D.md-annotation__index%20%5Bdata-md-annotation-id%5D%3Aafter%7Bcontent%3Aattr%28data-md-annotation-id%29%7D%7D.md-typeset%20.md-annotation-list%7Bcounter-reset%3Aannotation%3Blist-style%3Anone%21important%7D.md-typeset%20.md-annotation-list%20li%7Bposition%3Arelative%7D%5Bdir%3Dltr%5D%20.md-typeset%20.md-annotation-list%20li%3Abefore%7Bleft%3A-2.125em%7D%5Bdir%3Drtl%5D%20.md-typeset%20.md-annotation-list%20li%3Abefore%7Bright%3A-2.125em%7D.md-typeset%20.md-annotation-list%20li%3Abefore%7Bbackground%3Avar%28--md-default-fg-color--lighter%29%3Bborder-radius%3A2ch%3Bcolor%3Avar%28--md-default-bg-color%29%3Bcontent%3Acounter%28annotation%29%3Bcounter-increment%3Aannotation%3Bfont-size%3A.8875em%3Bfont-weight%3A700%3Bheight%3A2ch%3Bline-height%3A1.25%3Bmin-width%3A2ch%3Bpadding%3A0%20.6ch%3Bposition%3Aabsolute%3Btext-align%3Acenter%3Btop%3A.25em%7D%3Aroot%7B--md-tooltip-width%3A20rem%3B--md-tooltip-tail%3A0.3rem%7D.md-tooltip2%7Bbackface-visibility%3Ahidden%3Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-family%3Avar%28--md-text-font-family%29%3Bopacity%3A0%3Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btop%3Acalc%28var%28--md-tooltip-host-y%29%20%2B%20var%28--md-tooltip-y%29%29%3Btransform%3AtranslateY%28-.4rem%29%3Btransform-origin%3Acalc%28var%28--md-tooltip-host-x%29%20%2B%20var%28--md-tooltip-x%29%29%200%3Btransition%3Atransform%200ms%20.25s%2Copacity%20.25s%2Cz-index%20.25s%3Bwidth%3A100%25%3Bz-index%3A0%7D.md-tooltip2%3Abefore%7Bborder-left%3Avar%28--md-tooltip-tail%29%20solid%20%230000%3Bborder-right%3Avar%28--md-tooltip-tail%29%20solid%20%230000%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bleft%3Aclamp%281.5%20%2A%20.8rem%2Cvar%28--md-tooltip-host-x%29%20%2B%20var%28--md-tooltip-x%29%20-%20var%28--md-tooltip-tail%29%2C100vw%20-%202%20%2A%20var%28--md-tooltip-tail%29%20-%201.5%20%2A%20.8rem%29%3Bposition%3Aabsolute%3Bz-index%3A1%7D.md-tooltip2--top%3Abefore%7Bborder-top%3Avar%28--md-tooltip-tail%29%20solid%20var%28--md-default-bg-color%29%3Bbottom%3Acalc%28var%28--md-tooltip-tail%29%2A-1%20%2B%20.025rem%29%3Bfilter%3Adrop-shadow%280%201px%200%20hsla%280%2C0%25%2C0%25%2C.05%29%29%7D.md-tooltip2--bottom%3Abefore%7Bborder-bottom%3Avar%28--md-tooltip-tail%29%20solid%20var%28--md-default-bg-color%29%3Bfilter%3Adrop-shadow%280%20-1px%200%20hsla%280%2C0%25%2C0%25%2C.05%29%29%3Btop%3Acalc%28var%28--md-tooltip-tail%29%2A-1%20%2B%20.025rem%29%7D.md-tooltip2--active%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.4s%20cubic-bezier%280%2C1%2C.5%2C1%29%2Copacity%20.25s%2Cz-index%200ms%3Bz-index%3A2%7D.md-tooltip2__inner%7Bscrollbar-gutter%3Astable%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bleft%3Aclamp%28.8rem%2Cvar%28--md-tooltip-host-x%29%20-%20.8rem%2C100vw%20-%20var%28--md-tooltip-width%29%20-%20.8rem%29%3Bmax-height%3A40vh%3Bmax-width%3Acalc%28100vw%20-%201.6rem%29%3Bposition%3Arelative%3Bscrollbar-width%3Athin%7D.md-tooltip2__inner%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-tooltip2__inner%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-tooltip2__inner%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%7Bfont-size%3A.64rem%3Boverflow%3Aauto%3Bpadding%3A0%20.8rem%3Bpointer-events%3Aauto%3Bwidth%3Avar%28--md-tooltip-width%29%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Aafter%2C%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Abefore%7Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A.8rem%3Bposition%3Asticky%3Bwidth%3A100%25%3Bz-index%3A10%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Abefore%7Bbackground%3Alinear-gradient%28var%28--md-default-bg-color%29%2C%230000%2075%25%29%3Btop%3A0%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Aafter%7Bbackground%3Alinear-gradient%28%230000%2Cvar%28--md-default-bg-color%29%2075%25%29%3Bbottom%3A0%7D%5Brole%3Dtooltip%5D%3E.md-tooltip2__inner%7Bfont-size%3A.5rem%3Bfont-weight%3A700%3Bleft%3Aclamp%28.8rem%2Cvar%28--md-tooltip-host-x%29%20%2B%20var%28--md-tooltip-x%29%20-%20var%28--md-tooltip-width%29/2%2C100vw%20-%20var%28--md-tooltip-width%29%20-%20.8rem%29%3Bmax-width%3Amin%28100vw%20-%202%20%2A%20.8rem%2C400px%29%3Bpadding%3A.2rem%20.4rem%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bwidth%3Afit-content%7D.md-tooltip2__inner.md-typeset%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-tooltip2__inner.md-typeset%3E%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-top%7Bmargin-left%3A50%25%7D%5Bdir%3Drtl%5D%20.md-top%7Bmargin-right%3A50%25%7D.md-top%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A1.6rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bdisplay%3Ablock%3Bfont-size%3A.7rem%3Boutline%3Anone%3Bpadding%3A.4rem%20.8rem%3Bposition%3Afixed%3Btop%3A3.2rem%3Btransform%3Atranslate%28-50%25%29%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%2Ctransform%20125ms%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Copacity%20125ms%3Bz-index%3A2%7D%40media%20print%7B.md-top%7Bdisplay%3Anone%7D%7D%5Bdir%3Drtl%5D%20.md-top%7Btransform%3Atranslate%2850%25%29%7D.md-top%5Bhidden%5D%7Bopacity%3A0%3Bpointer-events%3Anone%3Btransform%3Atranslate%28-50%25%2C.2rem%29%3Btransition-duration%3A0ms%7D%5Bdir%3Drtl%5D%20.md-top%5Bhidden%5D%7Btransform%3Atranslate%2850%25%2C.2rem%29%7D.md-top%3Afocus%2C.md-top%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%3Bcolor%3Avar%28--md-accent-bg-color%29%7D.md-top%20svg%7Bdisplay%3Ainline-block%3Bvertical-align%3A-.5em%7D%40keyframes%20hoverfix%7B0%25%7Bpointer-events%3Anone%7D%7D%3Aroot%7B--md-version-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20320%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M140.3%20376.8c12.6%2010.2%2031.1%209.5%2042.8-2.2l128-128c9.2-9.2%2011.9-22.9%206.9-34.9S301.4%20192%20288.5%20192h-256c-12.9%200-24.6%207.8-29.6%2019.8s-2.2%2025.7%207%2034.8l128%20128z%22/%3E%3C/svg%3E%27%29%7D.md-version%7Bflex-shrink%3A0%3Bfont-size%3A.8rem%3Bheight%3A2.4rem%7D%5Bdir%3Dltr%5D%20.md-version__current%7Bmargin-left%3A1.4rem%3Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-version__current%7Bmargin-left%3A.4rem%3Bmargin-right%3A1.4rem%7D.md-version__current%7Bcolor%3Ainherit%3Bcursor%3Apointer%3Boutline%3Anone%3Bposition%3Arelative%3Btop%3A.05rem%7D%5Bdir%3Dltr%5D%20.md-version__current%3Aafter%7Bmargin-left%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-version__current%3Aafter%7Bmargin-right%3A.4rem%7D.md-version__current%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A.6rem%3B-webkit-mask-image%3Avar%28--md-version-icon%29%3Bmask-image%3Avar%28--md-version-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A.4rem%7D.md-version__alias%7Bmargin-left%3A.3rem%3Bopacity%3A.7%7D.md-version__list%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color%29%3Blist-style-type%3Anone%3Bmargin%3A.2rem%20.8rem%3Bmax-height%3A0%3Bopacity%3A0%3Boverflow%3Aauto%3Bpadding%3A0%3Bposition%3Aabsolute%3Bscroll-snap-type%3Ay%20mandatory%3Btop%3A.15rem%3Btransition%3Amax-height%200ms%20.5s%2Copacity%20.25s%20.25s%3Bz-index%3A3%7D.md-version%3Afocus-within%20.md-version__list%2C.md-version%3Ahover%20.md-version__list%7Bmax-height%3A10rem%3Bopacity%3A1%3Btransition%3Amax-height%200ms%2Copacity%20.25s%7D%40media%20%28hover%3Anone%29%2C%28pointer%3Acoarse%29%7B.md-version%3Ahover%20.md-version__list%7Banimation%3Ahoverfix%20.25s%20forwards%7D.md-version%3Afocus-within%20.md-version__list%7Banimation%3Anone%7D%7D.md-version__item%7Bline-height%3A1.8rem%7D%5Bdir%3Dltr%5D%20.md-version__link%7Bpadding-left%3A.6rem%3Bpadding-right%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-version__link%7Bpadding-left%3A1.2rem%3Bpadding-right%3A.6rem%7D.md-version__link%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Boutline%3Anone%3Bscroll-snap-align%3Astart%3Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%3Bwhite-space%3Anowrap%3Bwidth%3A100%25%7D.md-version__link%3Afocus%2C.md-version__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-version__link%3Afocus%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%7D%3Aroot%7B--md-admonition-icon--note%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M12%202C6.47%202%202%206.47%202%2012s4.47%2010%2010%2010%2010-4.47%2010-10S17.53%202%2012%202m3.1%205.07c.14%200%20.28.05.4.16l1.27%201.27c.23.22.23.57%200%20.78l-1%201-2.05-2.05%201-1c.1-.11.24-.16.38-.16m-1.97%201.74%202.06%202.06-6.06%206.06H7.07v-2.06z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--abstract%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M17%209H7V7h10m0%206H7v-2h10m-3%206H7v-2h7M12%203a1%201%200%200%201%201%201%201%201%200%200%201-1%201%201%201%200%200%201-1-1%201%201%200%200%201%201-1m7%200h-4.18C14.4%201.84%2013.3%201%2012%201s-2.4.84-2.82%202H5a2%202%200%200%200-2%202v14a2%202%200%200%200%202%202h14a2%202%200%200%200%202-2V5a2%202%200%200%200-2-2%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--info%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M13%209h-2V7h2m0%2010h-2v-6h2m-1-9A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--tip%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M17.66%2011.2c-.23-.3-.51-.56-.77-.82-.67-.6-1.43-1.03-2.07-1.66C13.33%207.26%2013%204.85%2013.95%203c-.95.23-1.78.75-2.49%201.32-2.59%202.08-3.61%205.75-2.39%208.9.04.1.08.2.08.33%200%20.22-.15.42-.35.5-.23.1-.47.04-.66-.12a.6.6%200%200%201-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78%2010%204.87%2012.3%205%2014.47c.06.5.12%201%20.29%201.5.14.6.41%201.2.71%201.73%201.08%201.73%202.95%202.97%204.96%203.22%202.14.27%204.43-.12%206.07-1.6%201.83-1.66%202.47-4.32%201.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16%206.3c-.28.24-.74.5-1.1.6-1.12.4-2.24-.16-2.9-.82%201.19-.28%201.9-1.16%202.11-2.05.17-.8-.15-1.46-.28-2.23-.12-.74-.1-1.37.17-2.06.19.38.39.76.63%201.06.77%201%201.98%201.44%202.24%202.8.04.14.06.28.06.43.03.82-.33%201.72-.93%202.27%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--success%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M21%207%209%2019l-5.5-5.5%201.41-1.41L9%2016.17%2019.59%205.59z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--question%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m15.07%2011.25-.9.92C13.45%2012.89%2013%2013.5%2013%2015h-2v-.5c0-1.11.45-2.11%201.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2%202%200%200%200-2-2%202%202%200%200%200-2%202H8a4%204%200%200%201%204-4%204%204%200%200%201%204%204%203.2%203.2%200%200%201-.93%202.25M13%2019h-2v-2h2M12%202A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10c0-5.53-4.5-10-10-10%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--warning%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M13%2014h-2V9h2m0%209h-2v-2h2M1%2021h22L12%202z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--failure%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%206.41%2017.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--danger%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m11.5%2020%204.86-9.73H13V4l-5%209.73h3.5zM12%202c2.75%200%205.1%201%207.05%202.95S22%209.25%2022%2012s-1%205.1-2.95%207.05S14.75%2022%2012%2022s-5.1-1-7.05-2.95S2%2014.75%202%2012s1-5.1%202.95-7.05S9.25%202%2012%202%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--bug%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M11%2013h2v1h-2zm10-8v6c0%205.5-3.8%2010.7-9%2012-5.2-1.3-9-6.5-9-12V5l9-4zm-4%205h-2.2c-.2-.6-.6-1.1-1.1-1.5l1.2-1.2-.7-.7L12.8%208H12c-.2%200-.5%200-.7.1L9.9%206.6l-.8.8%201.2%201.2c-.5.3-.9.8-1.1%201.4H7v1h2v1H7v1h2v1H7v1h2.2c.4%201.2%201.5%202%202.8%202s2.4-.8%202.8-2H17v-1h-2v-1h2v-1h-2v-1h2zm-6%202h2v-1h-2z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--example%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M7%202v2h1v14a4%204%200%200%200%204%204%204%204%200%200%200%204-4V4h1V2zm4%2014c-.6%200-1-.4-1-1s.4-1%201-1%201%20.4%201%201-.4%201-1%201m2-4c-.6%200-1-.4-1-1s.4-1%201-1%201%20.4%201%201-.4%201-1%201m1-5h-4V4h4z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--quote%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M14%2017h3l2-4V7h-6v6h3M6%2017h3l2-4V7H5v6h3z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.admonition%2C.md-typeset%20details%7Bbackground-color%3Avar%28--md-admonition-bg-color%29%3Bborder%3A.075rem%20solid%20%23448aff%3Bborder-radius%3A.2rem%3Bbox-shadow%3Avar%28--md-shadow-z1%29%3Bcolor%3Avar%28--md-admonition-fg-color%29%3Bdisplay%3Aflow-root%3Bfont-size%3A.64rem%3Bmargin%3A1.5625em%200%3Bpadding%3A0%20.6rem%3Bpage-break-inside%3Aavoid%3Btransition%3Abox-shadow%20125ms%7D%40media%20print%7B.md-typeset%20.admonition%2C.md-typeset%20details%7Bbox-shadow%3Anone%7D%7D.md-typeset%20.admonition%3Afocus-within%2C.md-typeset%20details%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23448aff1a%7D.md-typeset%20.admonition%3E%2A%2C.md-typeset%20details%3E%2A%7Bbox-sizing%3Aborder-box%7D.md-typeset%20.admonition%20.admonition%2C.md-typeset%20.admonition%20details%2C.md-typeset%20details%20.admonition%2C.md-typeset%20details%20details%7Bmargin-bottom%3A1em%3Bmargin-top%3A1em%7D.md-typeset%20.admonition%20.md-typeset__scrollwrap%2C.md-typeset%20details%20.md-typeset__scrollwrap%7Bmargin%3A1em%20-.6rem%7D.md-typeset%20.admonition%20.md-typeset__table%2C.md-typeset%20details%20.md-typeset__table%7Bpadding%3A0%20.6rem%7D.md-typeset%20.admonition%3E.tabbed-set%3Aonly-child%2C.md-typeset%20details%3E.tabbed-set%3Aonly-child%7Bmargin-top%3A0%7Dhtml%20.md-typeset%20.admonition%3E%3Alast-child%2Chtml%20.md-typeset%20details%3E%3Alast-child%7Bmargin-bottom%3A.6rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bpadding-left%3A2rem%3Bpadding-right%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bpadding-left%3A.6rem%3Bpadding-right%3A2rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bborder-left-width%3A.2rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-right-width%3A.2rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%2C%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D.md-typeset%20.admonition-title%2C.md-typeset%20summary%7Bbackground-color%3A%23448aff1a%3Bborder%3Anone%3Bfont-weight%3A700%3Bmargin%3A0%20-.6rem%3Bpadding-bottom%3A.4rem%3Bpadding-top%3A.4rem%3Bposition%3Arelative%7Dhtml%20.md-typeset%20.admonition-title%3Alast-child%2Chtml%20.md-typeset%20summary%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%3Abefore%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%3Abefore%7Bleft%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%3Abefore%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%3Abefore%7Bright%3A.6rem%7D.md-typeset%20.admonition-title%3Abefore%2C.md-typeset%20summary%3Abefore%7Bbackground-color%3A%23448aff%3Bcontent%3A%22%22%3Bheight%3A1rem%3B-webkit-mask-image%3Avar%28--md-admonition-icon--note%29%3Bmask-image%3Avar%28--md-admonition-icon--note%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A.625em%3Bwidth%3A1rem%7D.md-typeset%20.admonition-title%20code%2C.md-typeset%20summary%20code%7Bbox-shadow%3A0%200%200%20.05rem%20var%28--md-default-fg-color--lightest%29%7D.md-typeset%20.admonition.note%2C.md-typeset%20details.note%7Bborder-color%3A%23448aff%7D.md-typeset%20.admonition.note%3Afocus-within%2C.md-typeset%20details.note%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23448aff1a%7D.md-typeset%20.note%3E.admonition-title%2C.md-typeset%20.note%3Esummary%7Bbackground-color%3A%23448aff1a%7D.md-typeset%20.note%3E.admonition-title%3Abefore%2C.md-typeset%20.note%3Esummary%3Abefore%7Bbackground-color%3A%23448aff%3B-webkit-mask-image%3Avar%28--md-admonition-icon--note%29%3Bmask-image%3Avar%28--md-admonition-icon--note%29%7D.md-typeset%20.note%3E.admonition-title%3Aafter%2C.md-typeset%20.note%3Esummary%3Aafter%7Bcolor%3A%23448aff%7D.md-typeset%20.admonition.abstract%2C.md-typeset%20details.abstract%7Bborder-color%3A%2300b0ff%7D.md-typeset%20.admonition.abstract%3Afocus-within%2C.md-typeset%20details.abstract%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300b0ff1a%7D.md-typeset%20.abstract%3E.admonition-title%2C.md-typeset%20.abstract%3Esummary%7Bbackground-color%3A%2300b0ff1a%7D.md-typeset%20.abstract%3E.admonition-title%3Abefore%2C.md-typeset%20.abstract%3Esummary%3Abefore%7Bbackground-color%3A%2300b0ff%3B-webkit-mask-image%3Avar%28--md-admonition-icon--abstract%29%3Bmask-image%3Avar%28--md-admonition-icon--abstract%29%7D.md-typeset%20.abstract%3E.admonition-title%3Aafter%2C.md-typeset%20.abstract%3Esummary%3Aafter%7Bcolor%3A%2300b0ff%7D.md-typeset%20.admonition.info%2C.md-typeset%20details.info%7Bborder-color%3A%2300b8d4%7D.md-typeset%20.admonition.info%3Afocus-within%2C.md-typeset%20details.info%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300b8d41a%7D.md-typeset%20.info%3E.admonition-title%2C.md-typeset%20.info%3Esummary%7Bbackground-color%3A%2300b8d41a%7D.md-typeset%20.info%3E.admonition-title%3Abefore%2C.md-typeset%20.info%3Esummary%3Abefore%7Bbackground-color%3A%2300b8d4%3B-webkit-mask-image%3Avar%28--md-admonition-icon--info%29%3Bmask-image%3Avar%28--md-admonition-icon--info%29%7D.md-typeset%20.info%3E.admonition-title%3Aafter%2C.md-typeset%20.info%3Esummary%3Aafter%7Bcolor%3A%2300b8d4%7D.md-typeset%20.admonition.tip%2C.md-typeset%20details.tip%7Bborder-color%3A%2300bfa5%7D.md-typeset%20.admonition.tip%3Afocus-within%2C.md-typeset%20details.tip%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300bfa51a%7D.md-typeset%20.tip%3E.admonition-title%2C.md-typeset%20.tip%3Esummary%7Bbackground-color%3A%2300bfa51a%7D.md-typeset%20.tip%3E.admonition-title%3Abefore%2C.md-typeset%20.tip%3Esummary%3Abefore%7Bbackground-color%3A%2300bfa5%3B-webkit-mask-image%3Avar%28--md-admonition-icon--tip%29%3Bmask-image%3Avar%28--md-admonition-icon--tip%29%7D.md-typeset%20.tip%3E.admonition-title%3Aafter%2C.md-typeset%20.tip%3Esummary%3Aafter%7Bcolor%3A%2300bfa5%7D.md-typeset%20.admonition.success%2C.md-typeset%20details.success%7Bborder-color%3A%2300c853%7D.md-typeset%20.admonition.success%3Afocus-within%2C.md-typeset%20details.success%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300c8531a%7D.md-typeset%20.success%3E.admonition-title%2C.md-typeset%20.success%3Esummary%7Bbackground-color%3A%2300c8531a%7D.md-typeset%20.success%3E.admonition-title%3Abefore%2C.md-typeset%20.success%3Esummary%3Abefore%7Bbackground-color%3A%2300c853%3B-webkit-mask-image%3Avar%28--md-admonition-icon--success%29%3Bmask-image%3Avar%28--md-admonition-icon--success%29%7D.md-typeset%20.success%3E.admonition-title%3Aafter%2C.md-typeset%20.success%3Esummary%3Aafter%7Bcolor%3A%2300c853%7D.md-typeset%20.admonition.question%2C.md-typeset%20details.question%7Bborder-color%3A%2364dd17%7D.md-typeset%20.admonition.question%3Afocus-within%2C.md-typeset%20details.question%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2364dd171a%7D.md-typeset%20.question%3E.admonition-title%2C.md-typeset%20.question%3Esummary%7Bbackground-color%3A%2364dd171a%7D.md-typeset%20.question%3E.admonition-title%3Abefore%2C.md-typeset%20.question%3Esummary%3Abefore%7Bbackground-color%3A%2364dd17%3B-webkit-mask-image%3Avar%28--md-admonition-icon--question%29%3Bmask-image%3Avar%28--md-admonition-icon--question%29%7D.md-typeset%20.question%3E.admonition-title%3Aafter%2C.md-typeset%20.question%3Esummary%3Aafter%7Bcolor%3A%2364dd17%7D.md-typeset%20.admonition.warning%2C.md-typeset%20details.warning%7Bborder-color%3A%23ff9100%7D.md-typeset%20.admonition.warning%3Afocus-within%2C.md-typeset%20details.warning%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23ff91001a%7D.md-typeset%20.warning%3E.admonition-title%2C.md-typeset%20.warning%3Esummary%7Bbackground-color%3A%23ff91001a%7D.md-typeset%20.warning%3E.admonition-title%3Abefore%2C.md-typeset%20.warning%3Esummary%3Abefore%7Bbackground-color%3A%23ff9100%3B-webkit-mask-image%3Avar%28--md-admonition-icon--warning%29%3Bmask-image%3Avar%28--md-admonition-icon--warning%29%7D.md-typeset%20.warning%3E.admonition-title%3Aafter%2C.md-typeset%20.warning%3Esummary%3Aafter%7Bcolor%3A%23ff9100%7D.md-typeset%20.admonition.failure%2C.md-typeset%20details.failure%7Bborder-color%3A%23ff5252%7D.md-typeset%20.admonition.failure%3Afocus-within%2C.md-typeset%20details.failure%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23ff52521a%7D.md-typeset%20.failure%3E.admonition-title%2C.md-typeset%20.failure%3Esummary%7Bbackground-color%3A%23ff52521a%7D.md-typeset%20.failure%3E.admonition-title%3Abefore%2C.md-typeset%20.failure%3Esummary%3Abefore%7Bbackground-color%3A%23ff5252%3B-webkit-mask-image%3Avar%28--md-admonition-icon--failure%29%3Bmask-image%3Avar%28--md-admonition-icon--failure%29%7D.md-typeset%20.failure%3E.admonition-title%3Aafter%2C.md-typeset%20.failure%3Esummary%3Aafter%7Bcolor%3A%23ff5252%7D.md-typeset%20.admonition.danger%2C.md-typeset%20details.danger%7Bborder-color%3A%23ff1744%7D.md-typeset%20.admonition.danger%3Afocus-within%2C.md-typeset%20details.danger%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23ff17441a%7D.md-typeset%20.danger%3E.admonition-title%2C.md-typeset%20.danger%3Esummary%7Bbackground-color%3A%23ff17441a%7D.md-typeset%20.danger%3E.admonition-title%3Abefore%2C.md-typeset%20.danger%3Esummary%3Abefore%7Bbackground-color%3A%23ff1744%3B-webkit-mask-image%3Avar%28--md-admonition-icon--danger%29%3Bmask-image%3Avar%28--md-admonition-icon--danger%29%7D.md-typeset%20.danger%3E.admonition-title%3Aafter%2C.md-typeset%20.danger%3Esummary%3Aafter%7Bcolor%3A%23ff1744%7D.md-typeset%20.admonition.bug%2C.md-typeset%20details.bug%7Bborder-color%3A%23f50057%7D.md-typeset%20.admonition.bug%3Afocus-within%2C.md-typeset%20details.bug%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23f500571a%7D.md-typeset%20.bug%3E.admonition-title%2C.md-typeset%20.bug%3Esummary%7Bbackground-color%3A%23f500571a%7D.md-typeset%20.bug%3E.admonition-title%3Abefore%2C.md-typeset%20.bug%3Esummary%3Abefore%7Bbackground-color%3A%23f50057%3B-webkit-mask-image%3Avar%28--md-admonition-icon--bug%29%3Bmask-image%3Avar%28--md-admonition-icon--bug%29%7D.md-typeset%20.bug%3E.admonition-title%3Aafter%2C.md-typeset%20.bug%3Esummary%3Aafter%7Bcolor%3A%23f50057%7D.md-typeset%20.admonition.example%2C.md-typeset%20details.example%7Bborder-color%3A%237c4dff%7D.md-typeset%20.admonition.example%3Afocus-within%2C.md-typeset%20details.example%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%237c4dff1a%7D.md-typeset%20.example%3E.admonition-title%2C.md-typeset%20.example%3Esummary%7Bbackground-color%3A%237c4dff1a%7D.md-typeset%20.example%3E.admonition-title%3Abefore%2C.md-typeset%20.example%3Esummary%3Abefore%7Bbackground-color%3A%237c4dff%3B-webkit-mask-image%3Avar%28--md-admonition-icon--example%29%3Bmask-image%3Avar%28--md-admonition-icon--example%29%7D.md-typeset%20.example%3E.admonition-title%3Aafter%2C.md-typeset%20.example%3Esummary%3Aafter%7Bcolor%3A%237c4dff%7D.md-typeset%20.admonition.quote%2C.md-typeset%20details.quote%7Bborder-color%3A%239e9e9e%7D.md-typeset%20.admonition.quote%3Afocus-within%2C.md-typeset%20details.quote%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%239e9e9e1a%7D.md-typeset%20.quote%3E.admonition-title%2C.md-typeset%20.quote%3Esummary%7Bbackground-color%3A%239e9e9e1a%7D.md-typeset%20.quote%3E.admonition-title%3Abefore%2C.md-typeset%20.quote%3Esummary%3Abefore%7Bbackground-color%3A%239e9e9e%3B-webkit-mask-image%3Avar%28--md-admonition-icon--quote%29%3Bmask-image%3Avar%28--md-admonition-icon--quote%29%7D.md-typeset%20.quote%3E.admonition-title%3Aafter%2C.md-typeset%20.quote%3Esummary%3Aafter%7Bcolor%3A%239e9e9e%7D%3Aroot%7B--md-footnotes-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%207v4H5.83l3.58-3.59L8%206l-6%206%206%206%201.41-1.42L5.83%2013H21V7z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.footnote%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.64rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.footnote%3Eol%7Bmargin-left%3A0%7D%5Bdir%3Drtl%5D%20.md-typeset%20.footnote%3Eol%7Bmargin-right%3A0%7D.md-typeset%20.footnote%3Eol%3Eli%7Btransition%3Acolor%20125ms%7D.md-typeset%20.footnote%3Eol%3Eli%3Atarget%7Bcolor%3Avar%28--md-default-fg-color%29%7D.md-typeset%20.footnote%3Eol%3Eli%3Afocus-within%20.footnote-backref%7Bopacity%3A1%3Btransform%3AtranslateX%280%29%3Btransition%3Anone%7D.md-typeset%20.footnote%3Eol%3Eli%3Ahover%20.footnote-backref%2C.md-typeset%20.footnote%3Eol%3Eli%3Atarget%20.footnote-backref%7Bopacity%3A1%3Btransform%3AtranslateX%280%29%7D.md-typeset%20.footnote%3Eol%3Eli%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-typeset%20.footnote-ref%7Bfont-size%3A.75em%3Bfont-weight%3A700%7Dhtml%20.md-typeset%20.footnote-ref%7Boutline-offset%3A.1rem%7D.md-typeset%20%5Bid%5E%3D%22fnref%3A%22%5D%3Atarget%3E.footnote-ref%7Boutline%3Aauto%7D.md-typeset%20.footnote-backref%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bdisplay%3Ainline-block%3Bfont-size%3A0%3Bopacity%3A0%3Btransform%3AtranslateX%28.25rem%29%3Btransition%3Acolor%20.25s%2Ctransform%20.25s%20.25s%2Copacity%20125ms%20.25s%3Bvertical-align%3Atext-bottom%7D%40media%20print%7B.md-typeset%20.footnote-backref%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bopacity%3A1%3Btransform%3AtranslateX%280%29%7D%7D%5Bdir%3Drtl%5D%20.md-typeset%20.footnote-backref%7Btransform%3AtranslateX%28-.25rem%29%7D.md-typeset%20.footnote-backref%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.footnote-backref%3Abefore%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A.8rem%3B-webkit-mask-image%3Avar%28--md-footnotes-icon%29%3Bmask-image%3Avar%28--md-footnotes-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.footnote-backref%3Abefore%7Btransform%3AscaleX%28-1%29%7D%5Bdir%3Dltr%5D%20.md-typeset%20.headerlink%7Bmargin-left%3A.5rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.headerlink%7Bmargin-right%3A.5rem%7D.md-typeset%20.headerlink%7Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bdisplay%3Ainline-block%3Bopacity%3A0%3Btransition%3Acolor%20.25s%2Copacity%20125ms%7D%40media%20print%7B.md-typeset%20.headerlink%7Bdisplay%3Anone%7D%7D.md-typeset%20.headerlink%3Afocus%2C.md-typeset%20%3Ahover%3E.headerlink%2C.md-typeset%20%3Atarget%3E.headerlink%7Bopacity%3A1%3Btransition%3Acolor%20.25s%2Copacity%20125ms%7D.md-typeset%20.headerlink%3Afocus%2C.md-typeset%20.headerlink%3Ahover%2C.md-typeset%20%3Atarget%3E.headerlink%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20%3Atarget%7B--md-scroll-margin%3A3.6rem%3B--md-scroll-offset%3A0rem%3Bscroll-margin-top%3Acalc%28var%28--md-scroll-margin%29%20-%20var%28--md-scroll-offset%29%29%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-header--lifted~.md-container%20.md-typeset%20%3Atarget%7B--md-scroll-margin%3A6rem%7D%7D.md-typeset%20h1%3Atarget%2C.md-typeset%20h2%3Atarget%2C.md-typeset%20h3%3Atarget%7B--md-scroll-offset%3A0.2rem%7D.md-typeset%20h4%3Atarget%7B--md-scroll-offset%3A0.15rem%7D.md-typeset%20div.arithmatex%7Boverflow%3Aauto%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-typeset%20div.arithmatex%7Bmargin%3A0%20-.8rem%7D.md-typeset%20div.arithmatex%3E%2A%7Bwidth%3Amin-content%7D%7D.md-typeset%20div.arithmatex%3E%2A%7Bmargin-left%3Aauto%21important%3Bmargin-right%3Aauto%21important%3Bpadding%3A0%20.8rem%3Btouch-action%3Aauto%7D.md-typeset%20div.arithmatex%3E%2A%20mjx-container%7Bmargin%3A0%21important%7D.md-typeset%20div.arithmatex%20mjx-assistive-mml%7Bheight%3A0%7D.md-typeset%20.katex-html%20svg%7Bmax-width%3Arevert%7D.md-typeset%20del.critic%7Bbackground-color%3Avar%28--md-typeset-del-color%29%7D.md-typeset%20del.critic%2C.md-typeset%20ins.critic%7B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%7D.md-typeset%20ins.critic%7Bbackground-color%3Avar%28--md-typeset-ins-color%29%7D.md-typeset%20.critic.comment%7B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%3Bcolor%3Avar%28--md-code-hl-comment-color%29%7D.md-typeset%20.critic.comment%3Abefore%7Bcontent%3A%22/%2A%20%22%7D.md-typeset%20.critic.comment%3Aafter%7Bcontent%3A%22%20%2A/%22%7D.md-typeset%20.critic.block%7Bbox-shadow%3Anone%3Bdisplay%3Ablock%3Bmargin%3A1em%200%3Boverflow%3Aauto%3Bpadding-left%3A.8rem%3Bpadding-right%3A.8rem%7D.md-typeset%20.critic.block%3E%3Afirst-child%7Bmargin-top%3A.5em%7D.md-typeset%20.critic.block%3E%3Alast-child%7Bmargin-bottom%3A.5em%7D%3Aroot%7B--md-details-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20details%7Bdisplay%3Aflow-root%3Boverflow%3Avisible%3Bpadding-top%3A0%7D.md-typeset%20details%5Bopen%5D%3Esummary%3Aafter%7Btransform%3Arotate%2890deg%29%7D.md-typeset%20details%3Anot%28%5Bopen%5D%29%7Bbox-shadow%3Anone%3Bpadding-bottom%3A0%7D.md-typeset%20details%3Anot%28%5Bopen%5D%29%3Esummary%7Bborder-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bpadding-right%3A1.8rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bpadding-left%3A1.8rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D.md-typeset%20summary%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Bmin-height%3A1rem%3Boverflow%3Ahidden%7D.md-typeset%20summary.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-typeset%20summary%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%3Aafter%7Bright%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%3Aafter%7Bleft%3A.4rem%7D.md-typeset%20summary%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bheight%3A1rem%3B-webkit-mask-image%3Avar%28--md-details-icon%29%3Bmask-image%3Avar%28--md-details-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A.625em%3Btransform%3Arotate%280deg%29%3Btransition%3Atransform%20.25s%3Bwidth%3A1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%3Aafter%7Btransform%3Arotate%28180deg%29%7D.md-typeset%20summary%3A%3Amarker%7Bdisplay%3Anone%7D.md-typeset%20summary%3A%3A-webkit-details-marker%7Bdisplay%3Anone%7D.md-typeset%20.emojione%2C.md-typeset%20.gemoji%2C.md-typeset%20.twemoji%7B--md-icon-size%3A1.125em%3Bdisplay%3Ainline-flex%3Bheight%3Avar%28--md-icon-size%29%3Bvertical-align%3Atext-top%7D.md-typeset%20.emojione%20svg%2C.md-typeset%20.gemoji%20svg%2C.md-typeset%20.twemoji%20svg%7Bfill%3Acurrentcolor%3Bmax-height%3A100%25%3Bwidth%3Avar%28--md-icon-size%29%7D.md-typeset%20.lg%2C.md-typeset%20.xl%2C.md-typeset%20.xxl%2C.md-typeset%20.xxxl%7Bvertical-align%3Atext-bottom%7D.md-typeset%20.middle%7Bvertical-align%3Amiddle%7D.md-typeset%20.lg%7B--md-icon-size%3A1.5em%7D.md-typeset%20.xl%7B--md-icon-size%3A2.25em%7D.md-typeset%20.xxl%7B--md-icon-size%3A3em%7D.md-typeset%20.xxxl%7B--md-icon-size%3A4em%7D.highlight%20.o%2C.highlight%20.ow%7Bcolor%3Avar%28--md-code-hl-operator-color%29%7D.highlight%20.p%7Bcolor%3Avar%28--md-code-hl-punctuation-color%29%7D.highlight%20.cpf%2C.highlight%20.l%2C.highlight%20.s%2C.highlight%20.s1%2C.highlight%20.s2%2C.highlight%20.sb%2C.highlight%20.sc%2C.highlight%20.si%2C.highlight%20.ss%7Bcolor%3Avar%28--md-code-hl-string-color%29%7D.highlight%20.cp%2C.highlight%20.se%2C.highlight%20.sh%2C.highlight%20.sr%2C.highlight%20.sx%7Bcolor%3Avar%28--md-code-hl-special-color%29%7D.highlight%20.il%2C.highlight%20.m%2C.highlight%20.mb%2C.highlight%20.mf%2C.highlight%20.mh%2C.highlight%20.mi%2C.highlight%20.mo%7Bcolor%3Avar%28--md-code-hl-number-color%29%7D.highlight%20.k%2C.highlight%20.kd%2C.highlight%20.kn%2C.highlight%20.kp%2C.highlight%20.kr%2C.highlight%20.kt%7Bcolor%3Avar%28--md-code-hl-keyword-color%29%7D.highlight%20.kc%2C.highlight%20.n%7Bcolor%3Avar%28--md-code-hl-name-color%29%7D.highlight%20.bp%2C.highlight%20.nb%2C.highlight%20.no%7Bcolor%3Avar%28--md-code-hl-constant-color%29%7D.highlight%20.nc%2C.highlight%20.ne%2C.highlight%20.nf%2C.highlight%20.nn%7Bcolor%3Avar%28--md-code-hl-function-color%29%7D.highlight%20.nd%2C.highlight%20.ni%2C.highlight%20.nl%2C.highlight%20.nt%7Bcolor%3Avar%28--md-code-hl-keyword-color%29%7D.highlight%20.c%2C.highlight%20.c1%2C.highlight%20.ch%2C.highlight%20.cm%2C.highlight%20.cs%2C.highlight%20.sd%7Bcolor%3Avar%28--md-code-hl-comment-color%29%7D.highlight%20.na%2C.highlight%20.nv%2C.highlight%20.vc%2C.highlight%20.vg%2C.highlight%20.vi%7Bcolor%3Avar%28--md-code-hl-variable-color%29%7D.highlight%20.ge%2C.highlight%20.gh%2C.highlight%20.go%2C.highlight%20.gp%2C.highlight%20.gr%2C.highlight%20.gs%2C.highlight%20.gt%2C.highlight%20.gu%7Bcolor%3Avar%28--md-code-hl-generic-color%29%7D.highlight%20.gd%2C.highlight%20.gi%7Bborder-radius%3A.1rem%3Bmargin%3A0%20-.125em%3Bpadding%3A0%20.125em%7D.highlight%20.gd%7Bbackground-color%3Avar%28--md-typeset-del-color%29%7D.highlight%20.gi%7Bbackground-color%3Avar%28--md-typeset-ins-color%29%7D.highlight%20.hll%7Bbackground-color%3Avar%28--md-code-hl-color--light%29%3Bbox-shadow%3A2px%200%200%200%20var%28--md-code-hl-color%29%20inset%3Bdisplay%3Ablock%3Bmargin%3A0%20-1.1764705882em%3Bpadding%3A0%201.1764705882em%7D.highlight%20span.filename%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bborder-bottom%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bborder-top-left-radius%3A.1rem%3Bborder-top-right-radius%3A.1rem%3Bdisplay%3Aflow-root%3Bfont-size%3A.85em%3Bfont-weight%3A700%3Bmargin-top%3A1em%3Bpadding%3A.6617647059em%201.1764705882em%3Bposition%3Arelative%7D.highlight%20span.filename%2Bpre%7Bmargin-top%3A0%7D.highlight%20span.filename%2Bpre%3Ecode%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%7D.highlight%20%5Bdata-linenos%5D%3Abefore%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bbox-shadow%3A-.05rem%200%20var%28--md-default-fg-color--lightest%29%20inset%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcontent%3Aattr%28data-linenos%29%3Bfloat%3Aleft%3Bleft%3A-1.1764705882em%3Bmargin-left%3A-1.1764705882em%3Bmargin-right%3A1.1764705882em%3Bpadding-left%3A1.1764705882em%3Bposition%3Asticky%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bz-index%3A3%7D.highlight%20code%20a%5Bid%5D%7Bposition%3Aabsolute%3Bvisibility%3Ahidden%7D.highlight%20code%5Bdata-md-copying%5D%7Bdisplay%3Ainitial%7D.highlight%20code%5Bdata-md-copying%5D%20.hll%7Bdisplay%3Acontents%7D.highlight%20code%5Bdata-md-copying%5D%20.md-annotation%7Bdisplay%3Anone%7D.highlighttable%7Bdisplay%3Aflow-root%7D.highlighttable%20tbody%2C.highlighttable%20td%7Bdisplay%3Ablock%3Bpadding%3A0%7D.highlighttable%20tr%7Bdisplay%3Aflex%7D.highlighttable%20pre%7Bmargin%3A0%7D.highlighttable%20th.filename%7Bflex-grow%3A1%3Bpadding%3A0%3Btext-align%3Aleft%7D.highlighttable%20th.filename%20span.filename%7Bmargin-top%3A0%7D.highlighttable%20.linenos%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bborder-bottom-left-radius%3A.1rem%3Bborder-top-left-radius%3A.1rem%3Bfont-size%3A.85em%3Bpadding%3A.7720588235em%200%20.7720588235em%201.1764705882em%3B-webkit-user-select%3Anone%3Buser-select%3Anone%7D.highlighttable%20.linenodiv%7Bbox-shadow%3A-.05rem%200%20var%28--md-default-fg-color--lightest%29%20inset%7D.highlighttable%20.linenodiv%20pre%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Btext-align%3Aright%7D.highlighttable%20.linenodiv%20span%5Bclass%5D%7Bpadding-right%3A.5882352941em%7D.highlighttable%20.code%7Bflex%3A1%3Bmin-width%3A0%7D.linenodiv%20a%7Bcolor%3Ainherit%7D.md-typeset%20.highlighttable%7Bdirection%3Altr%3Bmargin%3A1em%200%7D.md-typeset%20.highlighttable%3Etbody%3Etr%3E.code%3Ediv%3Epre%3Ecode%7Bborder-bottom-left-radius%3A0%3Bborder-top-left-radius%3A0%7D.md-typeset%20.highlight%2B.result%7Bborder%3A.05rem%20solid%20var%28--md-code-bg-color%29%3Bborder-bottom-left-radius%3A.1rem%3Bborder-bottom-right-radius%3A.1rem%3Bborder-top-width%3A.1rem%3Bmargin-top%3A-1.125em%3Boverflow%3Avisible%3Bpadding%3A0%201em%7D.md-typeset%20.highlight%2B.result%3Aafter%7Bclear%3Aboth%3Bcontent%3A%22%22%3Bdisplay%3Ablock%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-content__inner%3E.highlight%7Bmargin%3A1em%20-.8rem%7D.md-content__inner%3E.highlight%3E.filename%2C.md-content__inner%3E.highlight%3E.highlighttable%3Etbody%3Etr%3E.code%3Ediv%3Epre%3Ecode%2C.md-content__inner%3E.highlight%3E.highlighttable%3Etbody%3Etr%3E.filename%20span.filename%2C.md-content__inner%3E.highlight%3E.highlighttable%3Etbody%3Etr%3E.linenos%2C.md-content__inner%3E.highlight%3Epre%3Ecode%7Bborder-radius%3A0%7D.md-content__inner%3E.highlight%2B.result%7Bborder-left-width%3A0%3Bborder-radius%3A0%3Bborder-right-width%3A0%3Bmargin-left%3A-.8rem%3Bmargin-right%3A-.8rem%7D%7D.md-typeset%20.keys%20kbd%3Aafter%2C.md-typeset%20.keys%20kbd%3Abefore%7B-moz-osx-font-smoothing%3Ainitial%3B-webkit-font-smoothing%3Ainitial%3Bcolor%3Ainherit%3Bmargin%3A0%3Bposition%3Arelative%7D.md-typeset%20.keys%20span%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bpadding%3A0%20.2em%7D.md-typeset%20.keys%20.key-alt%3Abefore%2C.md-typeset%20.keys%20.key-left-alt%3Abefore%2C.md-typeset%20.keys%20.key-right-alt%3Abefore%7Bcontent%3A%22%E2%8E%87%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-command%3Abefore%2C.md-typeset%20.keys%20.key-left-command%3Abefore%2C.md-typeset%20.keys%20.key-right-command%3Abefore%7Bcontent%3A%22%E2%8C%98%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-control%3Abefore%2C.md-typeset%20.keys%20.key-left-control%3Abefore%2C.md-typeset%20.keys%20.key-right-control%3Abefore%7Bcontent%3A%22%E2%8C%83%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-meta%3Abefore%2C.md-typeset%20.keys%20.key-meta%3Abefore%2C.md-typeset%20.keys%20.key-right-meta%3Abefore%7Bcontent%3A%22%E2%97%86%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-option%3Abefore%2C.md-typeset%20.keys%20.key-option%3Abefore%2C.md-typeset%20.keys%20.key-right-option%3Abefore%7Bcontent%3A%22%E2%8C%A5%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-shift%3Abefore%2C.md-typeset%20.keys%20.key-right-shift%3Abefore%2C.md-typeset%20.keys%20.key-shift%3Abefore%7Bcontent%3A%22%E2%87%A7%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-super%3Abefore%2C.md-typeset%20.keys%20.key-right-super%3Abefore%2C.md-typeset%20.keys%20.key-super%3Abefore%7Bcontent%3A%22%E2%9D%96%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-windows%3Abefore%2C.md-typeset%20.keys%20.key-right-windows%3Abefore%2C.md-typeset%20.keys%20.key-windows%3Abefore%7Bcontent%3A%22%E2%8A%9E%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-down%3Abefore%7Bcontent%3A%22%E2%86%93%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-left%3Abefore%7Bcontent%3A%22%E2%86%90%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-right%3Abefore%7Bcontent%3A%22%E2%86%92%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-up%3Abefore%7Bcontent%3A%22%E2%86%91%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-backspace%3Abefore%7Bcontent%3A%22%E2%8C%AB%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-backtab%3Abefore%7Bcontent%3A%22%E2%87%A4%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-caps-lock%3Abefore%7Bcontent%3A%22%E2%87%AA%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-clear%3Abefore%7Bcontent%3A%22%E2%8C%A7%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-context-menu%3Abefore%7Bcontent%3A%22%E2%98%B0%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-delete%3Abefore%7Bcontent%3A%22%E2%8C%A6%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-eject%3Abefore%7Bcontent%3A%22%E2%8F%8F%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-end%3Abefore%7Bcontent%3A%22%E2%A4%93%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-escape%3Abefore%7Bcontent%3A%22%E2%8E%8B%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-home%3Abefore%7Bcontent%3A%22%E2%A4%92%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-insert%3Abefore%7Bcontent%3A%22%E2%8E%80%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-page-down%3Abefore%7Bcontent%3A%22%E2%87%9F%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-page-up%3Abefore%7Bcontent%3A%22%E2%87%9E%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-print-screen%3Abefore%7Bcontent%3A%22%E2%8E%99%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-tab%3Aafter%7Bcontent%3A%22%E2%87%A5%22%3Bpadding-left%3A.4em%7D.md-typeset%20.keys%20.key-num-enter%3Aafter%7Bcontent%3A%22%E2%8C%A4%22%3Bpadding-left%3A.4em%7D.md-typeset%20.keys%20.key-enter%3Aafter%7Bcontent%3A%22%E2%8F%8E%22%3Bpadding-left%3A.4em%7D%3Aroot%7B--md-tabbed-icon--prev%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M15.41%2016.58%2010.83%2012l4.58-4.59L14%206l-6%206%206%206z%22/%3E%3C/svg%3E%27%29%3B--md-tabbed-icon--next%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.tabbed-set%7Bborder-radius%3A.1rem%3Bdisplay%3Aflex%3Bflex-flow%3Acolumn%20wrap%3Bmargin%3A1em%200%3Bposition%3Arelative%7D.md-typeset%20.tabbed-set%3Einput%7Bheight%3A0%3Bopacity%3A0%3Bposition%3Aabsolute%3Bwidth%3A0%7D.md-typeset%20.tabbed-set%3Einput%3Atarget%7B--md-scroll-offset%3A0.625em%7D.md-typeset%20.tabbed-set%3Einput.focus-visible~.tabbed-labels%3Abefore%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.tabbed-labels%7B-ms-overflow-style%3Anone%3Bbox-shadow%3A0%20-.05rem%20var%28--md-default-fg-color--lightest%29%20inset%3Bdisplay%3Aflex%3Bmax-width%3A100%25%3Boverflow%3Aauto%3Bscrollbar-width%3Anone%7D%40media%20print%7B.md-typeset%20.tabbed-labels%7Bdisplay%3Acontents%7D%7D%40media%20screen%7B.js%20.md-typeset%20.tabbed-labels%7Bposition%3Arelative%7D.js%20.md-typeset%20.tabbed-labels%3Abefore%7Bbackground%3Avar%28--md-default-fg-color%29%3Bbottom%3A0%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A2px%3Bleft%3A0%3Bposition%3Aabsolute%3Btransform%3AtranslateX%28var%28--md-indicator-x%29%29%3Btransition%3Awidth%20225ms%2Cbackground-color%20.25s%2Ctransform%20.25s%3Btransition-timing-function%3Acubic-bezier%28.4%2C0%2C.2%2C1%29%3Bwidth%3Avar%28--md-indicator-width%29%7D%7D.md-typeset%20.tabbed-labels%3A%3A-webkit-scrollbar%7Bdisplay%3Anone%7D.md-typeset%20.tabbed-labels%3Elabel%7Bborder-bottom%3A.1rem%20solid%20%230000%3Bborder-radius%3A.1rem%20.1rem%200%200%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bflex-shrink%3A0%3Bfont-size%3A.64rem%3Bfont-weight%3A700%3Bpadding%3A.78125em%201.25em%20.625em%3Bscroll-margin-inline-start%3A1rem%3Btransition%3Abackground-color%20.25s%2Ccolor%20.25s%3Bwhite-space%3Anowrap%3Bwidth%3Aauto%7D%40media%20print%7B.md-typeset%20.tabbed-labels%3Elabel%3Afirst-child%7Border%3A1%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%282%29%7Border%3A2%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%283%29%7Border%3A3%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%284%29%7Border%3A4%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%285%29%7Border%3A5%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%286%29%7Border%3A6%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%287%29%7Border%3A7%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%288%29%7Border%3A8%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%289%29%7Border%3A9%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2810%29%7Border%3A10%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2811%29%7Border%3A11%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2812%29%7Border%3A12%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2813%29%7Border%3A13%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2814%29%7Border%3A14%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2815%29%7Border%3A15%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2816%29%7Border%3A16%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2817%29%7Border%3A17%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2818%29%7Border%3A18%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2819%29%7Border%3A19%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2820%29%7Border%3A20%7D%7D.md-typeset%20.tabbed-labels%3Elabel%3Ahover%7Bcolor%3Avar%28--md-default-fg-color%29%7D.md-typeset%20.tabbed-labels%3Elabel%3E%5Bhref%5D%3Afirst-child%7Bcolor%3Ainherit%7D.md-typeset%20.tabbed-labels--linked%3Elabel%7Bpadding%3A0%7D.md-typeset%20.tabbed-labels--linked%3Elabel%3Ea%7Bdisplay%3Ablock%3Bpadding%3A.78125em%201.25em%20.625em%7D.md-typeset%20.tabbed-content%7Bwidth%3A100%25%7D%40media%20print%7B.md-typeset%20.tabbed-content%7Bdisplay%3Acontents%7D%7D.md-typeset%20.tabbed-block%7Bdisplay%3Anone%7D%40media%20print%7B.md-typeset%20.tabbed-block%7Bdisplay%3Ablock%7D.md-typeset%20.tabbed-block%3Afirst-child%7Border%3A1%7D.md-typeset%20.tabbed-block%3Anth-child%282%29%7Border%3A2%7D.md-typeset%20.tabbed-block%3Anth-child%283%29%7Border%3A3%7D.md-typeset%20.tabbed-block%3Anth-child%284%29%7Border%3A4%7D.md-typeset%20.tabbed-block%3Anth-child%285%29%7Border%3A5%7D.md-typeset%20.tabbed-block%3Anth-child%286%29%7Border%3A6%7D.md-typeset%20.tabbed-block%3Anth-child%287%29%7Border%3A7%7D.md-typeset%20.tabbed-block%3Anth-child%288%29%7Border%3A8%7D.md-typeset%20.tabbed-block%3Anth-child%289%29%7Border%3A9%7D.md-typeset%20.tabbed-block%3Anth-child%2810%29%7Border%3A10%7D.md-typeset%20.tabbed-block%3Anth-child%2811%29%7Border%3A11%7D.md-typeset%20.tabbed-block%3Anth-child%2812%29%7Border%3A12%7D.md-typeset%20.tabbed-block%3Anth-child%2813%29%7Border%3A13%7D.md-typeset%20.tabbed-block%3Anth-child%2814%29%7Border%3A14%7D.md-typeset%20.tabbed-block%3Anth-child%2815%29%7Border%3A15%7D.md-typeset%20.tabbed-block%3Anth-child%2816%29%7Border%3A16%7D.md-typeset%20.tabbed-block%3Anth-child%2817%29%7Border%3A17%7D.md-typeset%20.tabbed-block%3Anth-child%2818%29%7Border%3A18%7D.md-typeset%20.tabbed-block%3Anth-child%2819%29%7Border%3A19%7D.md-typeset%20.tabbed-block%3Anth-child%2820%29%7Border%3A20%7D%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3Epre%2C.md-typeset%20.tabbed-block%3Epre%3Afirst-child%7Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3Epre%3Ecode%2C.md-typeset%20.tabbed-block%3Epre%3Afirst-child%3Ecode%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.filename%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%3Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%7Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%3Etbody%3Etr%3E.filename%20span.filename%2C.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%3Etbody%3Etr%3E.linenos%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%3Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%3Etbody%3Etr%3E.code%3Ediv%3Epre%3Ecode%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%2B.result%7Bmargin-top%3A-.125em%7D.md-typeset%20.tabbed-block%3E.tabbed-set%7Bmargin%3A0%7D.md-typeset%20.tabbed-button%7Balign-self%3Acenter%3Bborder-radius%3A100%25%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bdisplay%3Ablock%3Bheight%3A.9rem%3Bmargin-top%3A.1rem%3Bpointer-events%3Aauto%3Btransition%3Abackground-color%20.25s%3Bwidth%3A.9rem%7D.md-typeset%20.tabbed-button%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.tabbed-button%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-tabbed-icon--prev%29%3Bmask-image%3Avar%28--md-tabbed-icon--prev%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Abackground-color%20.25s%2Ctransform%20.25s%3Bwidth%3A100%25%7D.md-typeset%20.tabbed-control%7Bbackground%3Alinear-gradient%28to%20right%2Cvar%28--md-default-bg-color%29%2060%25%2C%230000%29%3Bdisplay%3Aflex%3Bheight%3A1.9rem%3Bjustify-content%3Astart%3Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btransition%3Aopacity%20125ms%3Bwidth%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.tabbed-control%7Btransform%3Arotate%28180deg%29%7D.md-typeset%20.tabbed-control%5Bhidden%5D%7Bopacity%3A0%7D.md-typeset%20.tabbed-control--next%7Bbackground%3Alinear-gradient%28to%20left%2Cvar%28--md-default-bg-color%29%2060%25%2C%230000%29%3Bjustify-content%3Aend%3Bright%3A0%7D.md-typeset%20.tabbed-control--next%20.tabbed-button%3Aafter%7B-webkit-mask-image%3Avar%28--md-tabbed-icon--next%29%3Bmask-image%3Avar%28--md-tabbed-icon--next%29%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%7Bpadding-left%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%7Bpadding-right%3A.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels%7Bmargin%3A0%20-.8rem%3Bmax-width%3A100vw%3Bscroll-padding-inline-start%3A.8rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%3Aafter%7Bpadding-right%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%3Aafter%7Bpadding-left%3A.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels%3Aafter%7Bcontent%3A%22%22%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bpadding-left%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bpadding-right%3A.8rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bmargin-left%3A-.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bmargin-right%3A-.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bwidth%3A2rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bpadding-right%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bpadding-left%3A.8rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bmargin-right%3A-.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bmargin-left%3A-.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bwidth%3A2rem%7D%7D%40media%20screen%7B.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%7Bcolor%3Avar%28--md-default-fg-color%29%7D.md-typeset%20.no-js%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%7Bborder-color%3Avar%28--md-default-fg-color%29%7D%7D.md-typeset%20.tabbed-set%3Einput%3Afirst-child.focus-visible~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29.focus-visible~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29.focus-visible~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29.focus-visible~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29.focus-visible~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29.focus-visible~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29.focus-visible~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29.focus-visible~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29.focus-visible~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29.focus-visible~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29.focus-visible~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29.focus-visible~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29.focus-visible~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29.focus-visible~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29.focus-visible~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29.focus-visible~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29.focus-visible~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29.focus-visible~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29.focus-visible~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29.focus-visible~.tabbed-labels%3E%3Anth-child%289%29%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-content%3E%3Afirst-child%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-content%3E%3Anth-child%2810%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-content%3E%3Anth-child%2811%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-content%3E%3Anth-child%2812%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-content%3E%3Anth-child%2813%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-content%3E%3Anth-child%2814%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-content%3E%3Anth-child%2815%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-content%3E%3Anth-child%2816%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-content%3E%3Anth-child%2817%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-content%3E%3Anth-child%2818%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-content%3E%3Anth-child%2819%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-content%3E%3Anth-child%282%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-content%3E%3Anth-child%2820%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-content%3E%3Anth-child%283%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-content%3E%3Anth-child%284%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-content%3E%3Anth-child%285%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-content%3E%3Anth-child%286%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-content%3E%3Anth-child%287%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-content%3E%3Anth-child%288%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-content%3E%3Anth-child%289%29%7Bdisplay%3Ablock%7D%3Aroot%7B--md-tasklist-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M1%2012C1%205.925%205.925%201%2012%201s11%204.925%2011%2011-4.925%2011-11%2011S1%2018.075%201%2012m16.28-2.72a.75.75%200%200%200-.018-1.042.75.75%200%200%200-1.042-.018l-5.97%205.97-2.47-2.47a.75.75%200%200%200-1.042.018.75.75%200%200%200-.018%201.042l3%203a.75.75%200%200%200%201.06%200Z%22/%3E%3C/svg%3E%27%29%3B--md-tasklist-icon--checked%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M1%2012C1%205.925%205.925%201%2012%201s11%204.925%2011%2011-4.925%2011-11%2011S1%2018.075%201%2012m16.28-2.72a.75.75%200%200%200-.018-1.042.75.75%200%200%200-1.042-.018l-5.97%205.97-2.47-2.47a.75.75%200%200%200-1.042.018.75.75%200%200%200-.018%201.042l3%203a.75.75%200%200%200%201.06%200Z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.task-list-item%7Blist-style-type%3Anone%3Bposition%3Arelative%7D%5Bdir%3Dltr%5D%20.md-typeset%20.task-list-item%20%5Btype%3Dcheckbox%5D%7Bleft%3A-2em%7D%5Bdir%3Drtl%5D%20.md-typeset%20.task-list-item%20%5Btype%3Dcheckbox%5D%7Bright%3A-2em%7D.md-typeset%20.task-list-item%20%5Btype%3Dcheckbox%5D%7Bposition%3Aabsolute%3Btop%3A.45em%7D.md-typeset%20.task-list-control%20%5Btype%3Dcheckbox%5D%7Bopacity%3A0%3Bz-index%3A-1%7D%5Bdir%3Dltr%5D%20.md-typeset%20.task-list-indicator%3Abefore%7Bleft%3A-1.5em%7D%5Bdir%3Drtl%5D%20.md-typeset%20.task-list-indicator%3Abefore%7Bright%3A-1.5em%7D.md-typeset%20.task-list-indicator%3Abefore%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcontent%3A%22%22%3Bheight%3A1.25em%3B-webkit-mask-image%3Avar%28--md-tasklist-icon%29%3Bmask-image%3Avar%28--md-tasklist-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A.15em%3Bwidth%3A1.25em%7D.md-typeset%20%5Btype%3Dcheckbox%5D%3Achecked%2B.task-list-indicator%3Abefore%7Bbackground-color%3A%2300e676%3B-webkit-mask-image%3Avar%28--md-tasklist-icon--checked%29%3Bmask-image%3Avar%28--md-tasklist-icon--checked%29%7D%40media%20print%7B.giscus%2C%5Bid%3D__comments%5D%7Bdisplay%3Anone%7D%7D%3Aroot%3E%2A%7B--md-mermaid-font-family%3Avar%28--md-text-font-family%29%2Csans-serif%3B--md-mermaid-edge-color%3Avar%28--md-code-fg-color%29%3B--md-mermaid-node-bg-color%3Avar%28--md-accent-fg-color--transparent%29%3B--md-mermaid-node-fg-color%3Avar%28--md-accent-fg-color%29%3B--md-mermaid-label-bg-color%3Avar%28--md-default-bg-color%29%3B--md-mermaid-label-fg-color%3Avar%28--md-code-fg-color%29%3B--md-mermaid-sequence-actor-bg-color%3Avar%28--md-mermaid-label-bg-color%29%3B--md-mermaid-sequence-actor-fg-color%3Avar%28--md-mermaid-label-fg-color%29%3B--md-mermaid-sequence-actor-border-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-actor-line-color%3Avar%28--md-default-fg-color--lighter%29%3B--md-mermaid-sequence-actorman-bg-color%3Avar%28--md-mermaid-label-bg-color%29%3B--md-mermaid-sequence-actorman-line-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-box-bg-color%3Avar%28--md-mermaid-node-bg-color%29%3B--md-mermaid-sequence-box-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-label-bg-color%3Avar%28--md-mermaid-node-bg-color%29%3B--md-mermaid-sequence-label-fg-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-loop-bg-color%3Avar%28--md-mermaid-node-bg-color%29%3B--md-mermaid-sequence-loop-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-loop-border-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-message-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-message-line-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-note-bg-color%3Avar%28--md-mermaid-label-bg-color%29%3B--md-mermaid-sequence-note-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-note-border-color%3Avar%28--md-mermaid-label-fg-color%29%3B--md-mermaid-sequence-number-bg-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-number-fg-color%3Avar%28--md-accent-bg-color%29%7D.mermaid%7Bline-height%3Anormal%3Bmargin%3A1em%200%7D.md-typeset%20.grid%7Bgrid-gap%3A.4rem%3Bdisplay%3Agrid%3Bgrid-template-columns%3Arepeat%28auto-fit%2Cminmax%28min%28100%25%2C16rem%29%2C1fr%29%29%3Bmargin%3A1em%200%7D.md-typeset%20.grid.cards%3Eol%2C.md-typeset%20.grid.cards%3Eul%7Bdisplay%3Acontents%7D.md-typeset%20.grid.cards%3Eol%3Eli%2C.md-typeset%20.grid.cards%3Eul%3Eli%2C.md-typeset%20.grid%3E.card%7Bborder%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bborder-radius%3A.1rem%3Bdisplay%3Ablock%3Bmargin%3A0%3Bpadding%3A.8rem%3Btransition%3Aborder%20.25s%2Cbox-shadow%20.25s%7D.md-typeset%20.grid.cards%3Eol%3Eli%3Afocus-within%2C.md-typeset%20.grid.cards%3Eol%3Eli%3Ahover%2C.md-typeset%20.grid.cards%3Eul%3Eli%3Afocus-within%2C.md-typeset%20.grid.cards%3Eul%3Eli%3Ahover%2C.md-typeset%20.grid%3E.card%3Afocus-within%2C.md-typeset%20.grid%3E.card%3Ahover%7Bborder-color%3A%230000%3Bbox-shadow%3Avar%28--md-shadow-z2%29%7D.md-typeset%20.grid.cards%3Eol%3Eli%3Ehr%2C.md-typeset%20.grid.cards%3Eul%3Eli%3Ehr%2C.md-typeset%20.grid%3E.card%3Ehr%7Bmargin-bottom%3A1em%3Bmargin-top%3A1em%7D.md-typeset%20.grid.cards%3Eol%3Eli%3E%3Afirst-child%2C.md-typeset%20.grid.cards%3Eul%3Eli%3E%3Afirst-child%2C.md-typeset%20.grid%3E.card%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-typeset%20.grid.cards%3Eol%3Eli%3E%3Alast-child%2C.md-typeset%20.grid.cards%3Eul%3Eli%3E%3Alast-child%2C.md-typeset%20.grid%3E.card%3E%3Alast-child%7Bmargin-bottom%3A0%7D.md-typeset%20.grid%3E%2A%2C.md-typeset%20.grid%3E.admonition%2C.md-typeset%20.grid%3E.highlight%3E%2A%2C.md-typeset%20.grid%3E.highlighttable%2C.md-typeset%20.grid%3E.md-typeset%20details%2C.md-typeset%20.grid%3Edetails%2C.md-typeset%20.grid%3Epre%7Bmargin-bottom%3A0%3Bmargin-top%3A0%7D.md-typeset%20.grid%3E.highlight%3Epre%3Aonly-child%2C.md-typeset%20.grid%3E.highlight%3Epre%3Ecode%2C.md-typeset%20.grid%3E.highlighttable%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%3E.highlight%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%3E.highlight%3Epre%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%3E.highlight%3Epre%3Ecode%7Bheight%3A100%25%7D.md-typeset%20.grid%3E.tabbed-set%7Bmargin-bottom%3A0%3Bmargin-top%3A0%7D%40media%20screen%20and%20%28min-width%3A45em%29%7B%5Bdir%3Dltr%5D%20.md-typeset%20.inline%7Bfloat%3Aleft%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline%7Bfloat%3Aright%7D%5Bdir%3Dltr%5D%20.md-typeset%20.inline%7Bmargin-right%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline%7Bmargin-left%3A.8rem%7D.md-typeset%20.inline%7Bmargin-bottom%3A.8rem%3Bmargin-top%3A0%3Bwidth%3A11.7rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.inline.end%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline.end%7Bfloat%3Aleft%7D%5Bdir%3Dltr%5D%20.md-typeset%20.inline.end%7Bmargin-left%3A.8rem%3Bmargin-right%3A0%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline.end%7Bmargin-left%3A0%3Bmargin-right%3A.8rem%7D%7D" rel="stylesheet"/><!--URL:../assets/stylesheets/main.484c7ddc.min.css-->
|
|
<link href="data:text/css,%40media%20screen%7B%5Bdata-md-color-scheme%3Dslate%5D%7B--md-default-fg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.82%29%3B--md-default-fg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.56%29%3B--md-default-fg-color--lighter%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.32%29%3B--md-default-fg-color--lightest%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.12%29%3B--md-default-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C1%29%3B--md-default-bg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C0.54%29%3B--md-default-bg-color--lighter%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C0.26%29%3B--md-default-bg-color--lightest%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C0.07%29%3B--md-code-fg-color%3Ahsla%28var%28--md-hue%29%2C18%25%2C86%25%2C0.82%29%3B--md-code-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C18%25%2C1%29%3B--md-code-bg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C18%25%2C0.9%29%3B--md-code-bg-color--lighter%3Ahsla%28var%28--md-hue%29%2C15%25%2C18%25%2C0.54%29%3B--md-code-hl-color%3A%232977ff%3B--md-code-hl-color--light%3A%232977ff1a%3B--md-code-hl-number-color%3A%23e6695b%3B--md-code-hl-special-color%3A%23f06090%3B--md-code-hl-function-color%3A%23c973d9%3B--md-code-hl-constant-color%3A%239383e2%3B--md-code-hl-keyword-color%3A%236791e0%3B--md-code-hl-string-color%3A%232fb170%3B--md-code-hl-name-color%3Avar%28--md-code-fg-color%29%3B--md-code-hl-operator-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-punctuation-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-comment-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-generic-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-variable-color%3Avar%28--md-default-fg-color--light%29%3B--md-typeset-color%3Avar%28--md-default-fg-color%29%3B--md-typeset-a-color%3Avar%28--md-primary-fg-color%29%3B--md-typeset-kbd-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.12%29%3B--md-typeset-kbd-accent-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.2%29%3B--md-typeset-kbd-border-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C1%29%3B--md-typeset-mark-color%3A%234287ff4d%3B--md-typeset-table-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C95%25%2C0.12%29%3B--md-typeset-table-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C95%25%2C0.035%29%3B--md-admonition-fg-color%3Avar%28--md-default-fg-color%29%3B--md-admonition-bg-color%3Avar%28--md-default-bg-color%29%3B--md-footer-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C10%25%2C0.87%29%3B--md-footer-bg-color--dark%3Ahsla%28var%28--md-hue%29%2C15%25%2C8%25%2C1%29%3B--md-shadow-z1%3A0%200.2rem%200.5rem%20%230000000d%2C0%200%200.05rem%20%230000001a%3B--md-shadow-z2%3A0%200.2rem%200.5rem%20%2300000040%2C0%200%200.05rem%20%2300000040%3B--md-shadow-z3%3A0%200.2rem%200.5rem%20%230006%2C0%200%200.05rem%20%2300000059%3Bcolor-scheme%3Adark%7D%5Bdata-md-color-scheme%3Dslate%5D%20img%5Bsrc%24%3D%22%23gh-light-mode-only%22%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%20img%5Bsrc%24%3D%22%23only-light%22%5D%7Bdisplay%3Anone%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dpink%5D%7B--md-typeset-a-color%3A%23ed5487%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dpurple%5D%7B--md-typeset-a-color%3A%23c46fd3%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Ddeep-purple%5D%7B--md-typeset-a-color%3A%23a47bea%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dindigo%5D%7B--md-typeset-a-color%3A%235488e8%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dteal%5D%7B--md-typeset-a-color%3A%2300ccb8%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dgreen%5D%7B--md-typeset-a-color%3A%2371c174%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Ddeep-orange%5D%7B--md-typeset-a-color%3A%23ff764d%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dbrown%5D%7B--md-typeset-a-color%3A%23c1775c%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dblack%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dblue-grey%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dgrey%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dwhite%5D%7B--md-typeset-a-color%3A%235e8bde%7D%5Bdata-md-color-switching%5D%20%2A%2C%5Bdata-md-color-switching%5D%20%3Aafter%2C%5Bdata-md-color-switching%5D%20%3Abefore%7Btransition-duration%3A0ms%21important%7D%7D%5Bdata-md-color-accent%3Dred%5D%7B--md-accent-fg-color%3A%23ff1947%3B--md-accent-fg-color--transparent%3A%23ff19471a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dpink%5D%7B--md-accent-fg-color%3A%23f50056%3B--md-accent-fg-color--transparent%3A%23f500561a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dpurple%5D%7B--md-accent-fg-color%3A%23df41fb%3B--md-accent-fg-color--transparent%3A%23df41fb1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Ddeep-purple%5D%7B--md-accent-fg-color%3A%237c4dff%3B--md-accent-fg-color--transparent%3A%237c4dff1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dindigo%5D%7B--md-accent-fg-color%3A%23526cfe%3B--md-accent-fg-color--transparent%3A%23526cfe1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dblue%5D%7B--md-accent-fg-color%3A%234287ff%3B--md-accent-fg-color--transparent%3A%234287ff1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dlight-blue%5D%7B--md-accent-fg-color%3A%230091eb%3B--md-accent-fg-color--transparent%3A%230091eb1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dcyan%5D%7B--md-accent-fg-color%3A%2300bad6%3B--md-accent-fg-color--transparent%3A%2300bad61a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dteal%5D%7B--md-accent-fg-color%3A%2300bda4%3B--md-accent-fg-color--transparent%3A%2300bda41a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dgreen%5D%7B--md-accent-fg-color%3A%2300c753%3B--md-accent-fg-color--transparent%3A%2300c7531a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dlight-green%5D%7B--md-accent-fg-color%3A%2363de17%3B--md-accent-fg-color--transparent%3A%2363de171a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dlime%5D%7B--md-accent-fg-color%3A%23b0eb00%3B--md-accent-fg-color--transparent%3A%23b0eb001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Dyellow%5D%7B--md-accent-fg-color%3A%23ffd500%3B--md-accent-fg-color--transparent%3A%23ffd5001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Damber%5D%7B--md-accent-fg-color%3A%23fa0%3B--md-accent-fg-color--transparent%3A%23ffaa001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Dorange%5D%7B--md-accent-fg-color%3A%23ff9100%3B--md-accent-fg-color--transparent%3A%23ff91001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Ddeep-orange%5D%7B--md-accent-fg-color%3A%23ff6e42%3B--md-accent-fg-color--transparent%3A%23ff6e421a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dred%5D%7B--md-primary-fg-color%3A%23ef5552%3B--md-primary-fg-color--light%3A%23e57171%3B--md-primary-fg-color--dark%3A%23e53734%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dpink%5D%7B--md-primary-fg-color%3A%23e92063%3B--md-primary-fg-color--light%3A%23ec417a%3B--md-primary-fg-color--dark%3A%23c3185d%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dpurple%5D%7B--md-primary-fg-color%3A%23ab47bd%3B--md-primary-fg-color--light%3A%23bb69c9%3B--md-primary-fg-color--dark%3A%238c24a8%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Ddeep-purple%5D%7B--md-primary-fg-color%3A%237e56c2%3B--md-primary-fg-color--light%3A%239574cd%3B--md-primary-fg-color--dark%3A%23673ab6%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dindigo%5D%7B--md-primary-fg-color%3A%234051b5%3B--md-primary-fg-color--light%3A%235d6cc0%3B--md-primary-fg-color--dark%3A%23303fa1%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dblue%5D%7B--md-primary-fg-color%3A%232094f3%3B--md-primary-fg-color--light%3A%2342a5f5%3B--md-primary-fg-color--dark%3A%231975d2%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dlight-blue%5D%7B--md-primary-fg-color%3A%2302a6f2%3B--md-primary-fg-color--light%3A%2328b5f6%3B--md-primary-fg-color--dark%3A%230287cf%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dcyan%5D%7B--md-primary-fg-color%3A%2300bdd6%3B--md-primary-fg-color--light%3A%2325c5da%3B--md-primary-fg-color--dark%3A%230097a8%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dteal%5D%7B--md-primary-fg-color%3A%23009485%3B--md-primary-fg-color--light%3A%2326a699%3B--md-primary-fg-color--dark%3A%23007a6c%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dgreen%5D%7B--md-primary-fg-color%3A%234cae4f%3B--md-primary-fg-color--light%3A%2368bb6c%3B--md-primary-fg-color--dark%3A%23398e3d%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dlight-green%5D%7B--md-primary-fg-color%3A%238bc34b%3B--md-primary-fg-color--light%3A%239ccc66%3B--md-primary-fg-color--dark%3A%23689f38%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dlime%5D%7B--md-primary-fg-color%3A%23cbdc38%3B--md-primary-fg-color--light%3A%23d3e156%3B--md-primary-fg-color--dark%3A%23b0b52c%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Dyellow%5D%7B--md-primary-fg-color%3A%23ffec3d%3B--md-primary-fg-color--light%3A%23ffee57%3B--md-primary-fg-color--dark%3A%23fbc02d%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Damber%5D%7B--md-primary-fg-color%3A%23ffc105%3B--md-primary-fg-color--light%3A%23ffc929%3B--md-primary-fg-color--dark%3A%23ffa200%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Dorange%5D%7B--md-primary-fg-color%3A%23ffa724%3B--md-primary-fg-color--light%3A%23ffa724%3B--md-primary-fg-color--dark%3A%23fa8900%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Ddeep-orange%5D%7B--md-primary-fg-color%3A%23ff6e42%3B--md-primary-fg-color--light%3A%23ff8a66%3B--md-primary-fg-color--dark%3A%23f4511f%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dbrown%5D%7B--md-primary-fg-color%3A%23795649%3B--md-primary-fg-color--light%3A%238d6e62%3B--md-primary-fg-color--dark%3A%235d4037%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dgrey%5D%7B--md-primary-fg-color%3A%23757575%3B--md-primary-fg-color--light%3A%239e9e9e%3B--md-primary-fg-color--dark%3A%23616161%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dblue-grey%5D%7B--md-primary-fg-color%3A%23546d78%3B--md-primary-fg-color--light%3A%23607c8a%3B--md-primary-fg-color--dark%3A%23455a63%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dlight-green%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%2372ad2e%7D%5Bdata-md-color-primary%3Dlime%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%238b990a%7D%5Bdata-md-color-primary%3Dyellow%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%23b8a500%7D%5Bdata-md-color-primary%3Damber%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%23d19d00%7D%5Bdata-md-color-primary%3Dorange%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%23e68a00%7D%5Bdata-md-color-primary%3Dwhite%5D%7B--md-primary-fg-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C1%29%3B--md-primary-fg-color--light%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C0.7%29%3B--md-primary-fg-color--dark%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C0.07%29%3B--md-primary-bg-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C0.87%29%3B--md-primary-bg-color--light%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C0.54%29%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-button%7Bcolor%3Avar%28--md-typeset-a-color%29%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-button--primary%7Bbackground-color%3Avar%28--md-typeset-a-color%29%3Bborder-color%3Avar%28--md-typeset-a-color%29%3Bcolor%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C1%29%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdata-md-color-primary%3Dwhite%5D%20.md-search__form%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C.07%29%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-search__form%3Ahover%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C.32%29%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-search__input%2B.md-search__icon%7Bcolor%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C.87%29%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdata-md-color-primary%3Dwhite%5D%20.md-tabs%7Bborder-bottom%3A.05rem%20solid%20%2300000012%7D%7D%5Bdata-md-color-primary%3Dblack%5D%7B--md-primary-fg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%3B--md-primary-fg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C0.54%29%3B--md-primary-fg-color--dark%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%3B--md-primary-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C100%25%2C1%29%3B--md-primary-bg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C100%25%2C0.7%29%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dblack%5D%20.md-button%7Bcolor%3Avar%28--md-typeset-a-color%29%7D%5Bdata-md-color-primary%3Dblack%5D%20.md-button--primary%7Bbackground-color%3Avar%28--md-typeset-a-color%29%3Bborder-color%3Avar%28--md-typeset-a-color%29%3Bcolor%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C1%29%7D%5Bdata-md-color-primary%3Dblack%5D%20.md-header%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdata-md-color-primary%3Dblack%5D%20.md-nav__source%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C11%25%2C.87%29%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7Bhtml%20%5Bdata-md-color-primary%3Dblack%5D%20.md-nav--primary%20.md-nav__title%5Bfor%3D__drawer%5D%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdata-md-color-primary%3Dblack%5D%20.md-tabs%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%7D%7D" rel="stylesheet"/><!--URL:../assets/stylesheets/palette.ab4e12ef.min.css-->
|
|
<link href="data:text/css,%0A/%2A%20%0AThe%20print-site%20banner%0A%2A/%0A%23print-site-banner%20%7B%0A%20%20%20%20border%3A2px%3B%20%0A%20%20%20%20border-style%3Asolid%3B%20%0A%20%20%20%20border-color%3A%23000000%3B%20%0A%20%20%20%20padding%3A%200em%201em%200em%201em%3B%20%0A%20%20%20%20margin-bottom%3A%202em%3B%0A%7D%0A%23print-site-banner%20h3%20%7B%0A%20%20%20%20margin-top%3A%201rem%3B%0A%7D%0A%0A/%2A%20Enumerate%20figures%20%2A/%0A.print-site-enumerate-figures%20figcaption%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20figurecounter%3B%0A%20%20%20%20content%3A%20%22Figure%20%22%20counter%28figurecounter%29%20%22%3A%20%22%3B%0A%7D%0A%0A%0A/%2A%20Print%20URLS%3A%20%0AChange%20a%20%27link%27%20to%20%27link%20%28target%29%27%20%2A/%0Adiv.print-site-add-full-url%20section.print-page%20a%5Bhref%5E%3D%22http%22%5D%3A%3Aafter%7B%0A%20%20%20%20content%3A%20%22%20%28%22%20attr%28href%29%20%22%29%20%22%3B%0A%7D%0A%0A%0A/%2A%20Do%20some%20nice%20animations%20when%20clicking%20on%20a%20ToC%20link%20%2A/%0A%23print-site-page%20h1%3Atarget%2C%20%0A%23print-site-page%20h2%3Atarget%2C%20%0A%23print-site-page%20h3%3Atarget%2C%20%0A%23print-site-page%20h4%3Atarget%2C%20%0A%23print-site-page%20h5%3Atarget%2C%20%0A%23print-site-page%20h6%3Atarget%20%7B%0A%20%20%20%20animation%3A%20highlight%201.5s%20ease%3B%0A%7D%0A%23print-site-page%20.print-page%3Atarget%20h1%20%7B%0A%20%20%20%20animation%3A%20highlight%201.5s%20ease%3B%0A%7D%0A%40keyframes%20highlight%20%7B%0A%20%20%20%20from%20%7B%20color%3A%20orange%3B%20%7D%0A%20%20%20%20to%20%7B%20color%3A%20none%3B%20%7D%0A%7D%0A%0A%0A/%2A%20%0APrint%20site%20table%20of%20contents%20styling%0A%20%2A/%0A/%2A%20Don%27t%20display%20the%20table%20of%20contents%20in%20HTML%20version%20%2A/%0A%23print-page-toc%20%7B%20display%3A%20none%20%7D%0A%0A%0A.print-page-toc-nav%20%7B%0A%20%20%20%20padding-bottom%3A%202em%3B%0A%7D%0A%0A%23print-page-toc%20ul%20%7B%0A%20%20%20%20list-style-position%3A%20inside%3B%0A%20%20%20%20list-style-type%3A%20none%3B%0A%7D%0A%0A%23print-site-page%20ul%20%7B%0A%20%20%20%20margin-left%3A%200em%3B%0A%7D%0A%0A/%2A%20Be%20able%20to%20not%20print%20certain%20elements%20%2A/%0A%23print-site-page%20.print-site-plugin-ignore%20%7B%20display%3A%20none%3B%7D%0A%0A%40media%20print%20%7B%20%20%20%20%0A%0A%20%20%20%20/%2A%20included%20bookmarks%20on%20h1%20and%20h2%0A%20%20%20%20Doesn%27t%20work%2C%20but%20included%20In%20case%20Chrome%20gets%20support%20%0A%20%20%20%20for%20these%20experimental%20CSS%20features%20that%20define%20PDF%20bookmarks%20%2A/%0A%20%20%20%20/%2A%20%23print-site-page%20h1%20%7B%0A%20%20%20%20%20%20%20%20bookmark-level%3A%201%3B%0A%20%20%20%20%20%20%20%20bookmark-label%3A%20content%28%29%3B%20%0A%20%20%20%20%20%20%20%20-ah-bookmark-level%3A%201%3B%0A%20%20%20%20%20%20%20%20-ro-pdf-bookmark-level%3A%201%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-page%20h2%20%7B%0A%20%20%20%20%20%20%20%20bookmark-level%3A%202%3B%0A%20%20%20%20%20%20%20%20bookmark-label%3A%20content%28%29%3B%20%0A%20%20%20%20%20%20%20%20-ah-bookmark-level%3A%202%3B%0A%20%20%20%20%20%20%20%20-ro-pdf-bookmark-level%3A%202%3B%0A%20%20%20%20%7D%20%2A/%0A%0A%20%20%20%20/%2A%20Be%20able%20to%20not%20print%20certain%20elements%20%2A/%0A%20%20%20%20.print-site-plugin-ignore%20%7B%20display%3A%20none%3B%20%7D%0A%0A%20%20%20%20/%2A%20Remove%20print%20site%20banner%20%2A/%0A%20%20%20%20%23print-site-banner%20%7B%20display%3A%20none%3B%20%7D%0A%0A%20%20%20%20/%2A%20display%20the%20table%20of%20contents%20in%20print%20version%20%2A/%0A%20%20%20%20%23print-page-toc%20%7B%20display%3A%20block%20%7D%0A%0A%20%20%20%20/%2A%20PDF%20page%20breaks%20on%20each%20MkDocs%20page%2C%20except%20the%20first%20one%20%2A/%0A%20%20%20%20%23print-site-page%20section.print-page%20%7B%0A%20%20%20%20%20%20%20%20page-break-before%3A%20always%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-page%20%3E%20section.print-page%3Afirst-of-type%20%7B%0A%20%20%20%20%20%20%20%20page-break-before%3A%20avoid%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20/%2A%20PDF%20page%20breaks%20-%20separate%20title%20page%20for%20each%20section%20%2A/%0A%20%20%20%20%23print-site-page%20section.print-page.md-section%20%3E%20h1%20%7B%0A%20%20%20%20%20%20%20%20align-content%3A%20center%3B%0A%20%20%20%20%20%20%20%20text-align%3A%20center%3B%0A%20%20%20%20%20%20%20%20vertical-align%3A%20middle%3B%0A%20%20%20%20%20%20%20%20padding%3A%205rem%200rem%3B%0A%20%20%20%20%20%20%20%20font-size%3A%202.5em%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%23print-site-page%20p%2C%20%0A%20%20%20%20%23print-site-page%20pre%2C%20%0A%20%20%20%20%23print-site-page%20blockquote%2C%20%0A%20%20%20%20%23print-site-page%20.tabbed-set%20%7B%0A%20%20%20%20%20%20%20%20page-break-inside%3A%20avoid%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20/%2A%20Avoid%20a%20page%20break%20immediately%20after%20a%20heading%20%2A/%0A%20%20%20%20/%2A%20Credits%20https%3A//stackoverflow.com/a/9238898/5525118%20%2A/%0A%20%20%20%20%23print-site-page%20h1%20%7B%0A%20%20%20%20%20%20%20%20page-break-inside%3A%20avoid%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-page%20h1%3A%3Aafter%20%7B%0A%20%20%20%20%20%20%20%20content%3A%20%22%22%3B%0A%20%20%20%20%20%20%20%20/%2A%20display%3A%20block%3B%20%2A/%0A%20%20%20%20%20%20%20%20height%3A%20100px%3B%0A%20%20%20%20%20%20%20%20margin-bottom%3A%20-100px%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%23print-site-page%20footer%20%7B%20display%20%3A%20none%3B%20%7D%0A%20%20%20%20%0A%20%20%20%20%23print-site-cover-page%20%7B%0A%20%20%20%20%20%20%20%20display%3A%20block%3B%0A%20%20%20%20%20%20%20%20width%3A100%25%3B%20%0A%20%20%20%20%20%20%20%20text-align%3A%20center%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-cover-page%20h1%20%7B%0A%20%20%20%20%20%20%20%20font-size%3A%20300%25%3B%0A%20%20%20%20%7D%0A%7D%0A" rel="stylesheet"/><!--URL:../css/print-site.css-->
|
|
<link href="data:text/css,/%2A%20print%20styles%20for%20mkdocs%20material%20theme%20%0Ahttps%3A//github.com/squidfunk/mkdocs-material%20%2A/%0A%0A%0A/%2A%20Table%20of%20Contents%20styling%20%2A/%0A%23print-site-page%20ul.toc-section-line-border%20%7B%20%0A%20%20%20%20border-left%3A%205px%20solid%20var%28--md-default-fg-color--lightest%29%3B%0A%7D%0A%0A%0A/%2A%20Box%20shadows%20don%27t%20do%20well%20in%20PDFs%20%2A/%0A%23print-site-page%20table%20%7B%0A%20%20%20%20border%3A%201px%20solid%20hsla%28200%2C%2018%25%2C%2026%25%2C%201%29%3B%20/%2A%20%23EFEFEF%20%2A/%0A%20%20%20%20box-shadow%3A%20none%20%21important%3B%0A%7D%0A%0A%40media%20print%20%7B%0A%20%20%20%20%23print-site-page%20td%20%7B%0A%20%20%20%20%20%20%20%20word-wrap%3A%20break-word%3B%0A%20%20%20%20%7D%0A%0A%7D%0A%0A%40page%20%7B%0A%0A%20%20%20%20size%3A%20A4%20portrait%3B%0A%20%20%20%20margin%3A%204em%201.5em%204em%201.5em%3B%0A%20%20%20%20padding%3A%200em%200em%200em%200em%3B%0A%20%20%20%20counter-increment%3A%20page%3B%0A%0A%20%20%20%20%40bottom-center%20%7B%0A%20%20%20%20%20%20%20%20content%3A%20string%28chapter%29%3B%0A%20%20%20%20%7D%0A%20%20%20%20%40bottom-right%20%7B%0A%20%20%20%20%20%20%20%20content%3A%20%27Page%20%27%20counter%28page%29%3B%0A%20%20%20%20%7D%0A%0A%7D" rel="stylesheet"/><!--URL:../css/print-site-material.css-->
|
|
<link href="data:text/css,%0A/%2A%20Avoid%20breaking%20parameter%20names%2C%20etc.%20in%20table%20cells.%20%2A/%0A.doc-contents%20td%20code%20%7B%0A%20%20word-break%3A%20normal%20%21important%3B%0A%7D%0A%0A/%2A%20No%20line%20break%20before%20first%20paragraph%20of%20descriptions.%20%2A/%0A.doc-md-description%2C%0A.doc-md-description%3Ep%3Afirst-child%20%7B%0A%20%20display%3A%20inline%3B%0A%7D%0A%0A/%2A%20No%20text%20transformation%20from%20Material%20for%20MkDocs%20for%20H5%20headings.%20%2A/%0A.md-typeset%20h5%20.doc-object-name%20%7B%0A%20%20text-transform%3A%20none%3B%0A%7D%0A%0A/%2A%20Max%20width%20for%20docstring%20sections%20tables.%20%2A/%0A.doc%20.md-typeset__table%2C%0A.doc%20.md-typeset__table%20table%20%7B%0A%20%20display%3A%20table%20%21important%3B%0A%20%20width%3A%20100%25%3B%0A%7D%0A%0A.doc%20.md-typeset__table%20tr%20%7B%0A%20%20display%3A%20table-row%3B%0A%7D%0A%0A/%2A%20Defaults%20in%20Spacy%20table%20style.%20%2A/%0A.doc-param-default%2C%0A.doc-type_param-default%20%7B%0A%20%20float%3A%20right%3B%0A%7D%0A%0A/%2A%20Parameter%20headings%20must%20be%20inline%2C%20not%20blocks.%20%2A/%0A.doc-heading-parameter%2C%0A.doc-heading-type_parameter%20%7B%0A%20%20display%3A%20inline%3B%0A%7D%0A%0A/%2A%20Default%20font%20size%20for%20parameter%20headings.%20%2A/%0A.md-typeset%20.doc-heading-parameter%20%7B%0A%20%20font-size%3A%20inherit%3B%0A%7D%0A%0A/%2A%20Prefer%20space%20on%20the%20right%2C%20not%20the%20left%20of%20parameter%20permalinks.%20%2A/%0A.doc-heading-parameter%20.headerlink%2C%0A.doc-heading-type_parameter%20.headerlink%20%7B%0A%20%20margin-left%3A%200%20%21important%3B%0A%20%20margin-right%3A%200.2rem%3B%0A%7D%0A%0A/%2A%20Backward-compatibility%3A%20docstring%20section%20titles%20in%20bold.%20%2A/%0A.doc-section-title%20%7B%0A%20%20font-weight%3A%20bold%3B%0A%7D%0A%0A/%2A%20Backlinks%20crumb%20separator.%20%2A/%0A.doc-backlink-crumb%20%7B%0A%20%20display%3A%20inline-flex%3B%0A%20%20gap%3A%20.2rem%3B%0A%20%20white-space%3A%20nowrap%3B%0A%20%20align-items%3A%20center%3B%0A%20%20vertical-align%3A%20middle%3B%0A%7D%0A.doc-backlink-crumb%3Anot%28%3Afirst-child%29%3A%3Abefore%20%7B%0A%20%20background-color%3A%20var%28--md-default-fg-color--lighter%29%3B%0A%20%20content%3A%20%22%22%3B%0A%20%20display%3A%20inline%3B%0A%20%20height%3A%201rem%3B%0A%20%20--md-path-icon%3A%20url%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%3B%0A%20%20-webkit-mask-image%3A%20var%28--md-path-icon%29%3B%0A%20%20mask-image%3A%20var%28--md-path-icon%29%3B%0A%20%20width%3A%201rem%3B%0A%7D%0A.doc-backlink-crumb.last%20%7B%0A%20%20font-weight%3A%20bold%3B%0A%7D%0A%0A/%2A%20Symbols%20in%20Navigation%20and%20ToC.%20%2A/%0A%3Aroot%2C%20%3Ahost%2C%0A%5Bdata-md-color-scheme%3D%22default%22%5D%20%7B%0A%20%20--doc-symbol-parameter-fg-color%3A%20%23df50af%3B%0A%20%20--doc-symbol-type_parameter-fg-color%3A%20%23df50af%3B%0A%20%20--doc-symbol-attribute-fg-color%3A%20%23953800%3B%0A%20%20--doc-symbol-function-fg-color%3A%20%238250df%3B%0A%20%20--doc-symbol-method-fg-color%3A%20%238250df%3B%0A%20%20--doc-symbol-class-fg-color%3A%20%230550ae%3B%0A%20%20--doc-symbol-type_alias-fg-color%3A%20%230550ae%3B%0A%20%20--doc-symbol-module-fg-color%3A%20%235cad0f%3B%0A%0A%20%20--doc-symbol-parameter-bg-color%3A%20%23df50af1a%3B%0A%20%20--doc-symbol-type_parameter-bg-color%3A%20%23df50af1a%3B%0A%20%20--doc-symbol-attribute-bg-color%3A%20%239538001a%3B%0A%20%20--doc-symbol-function-bg-color%3A%20%238250df1a%3B%0A%20%20--doc-symbol-method-bg-color%3A%20%238250df1a%3B%0A%20%20--doc-symbol-class-bg-color%3A%20%230550ae1a%3B%0A%20%20--doc-symbol-type_alias-bg-color%3A%20%230550ae1a%3B%0A%20%20--doc-symbol-module-bg-color%3A%20%235cad0f1a%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20%7B%0A%20%20--doc-symbol-parameter-fg-color%3A%20%23ffa8cc%3B%0A%20%20--doc-symbol-type_parameter-fg-color%3A%20%23ffa8cc%3B%0A%20%20--doc-symbol-attribute-fg-color%3A%20%23ffa657%3B%0A%20%20--doc-symbol-function-fg-color%3A%20%23d2a8ff%3B%0A%20%20--doc-symbol-method-fg-color%3A%20%23d2a8ff%3B%0A%20%20--doc-symbol-class-fg-color%3A%20%2379c0ff%3B%0A%20%20--doc-symbol-type_alias-fg-color%3A%20%2379c0ff%3B%0A%20%20--doc-symbol-module-fg-color%3A%20%23baff79%3B%0A%0A%20%20--doc-symbol-parameter-bg-color%3A%20%23ffa8cc1a%3B%0A%20%20--doc-symbol-type_parameter-bg-color%3A%20%23ffa8cc1a%3B%0A%20%20--doc-symbol-attribute-bg-color%3A%20%23ffa6571a%3B%0A%20%20--doc-symbol-function-bg-color%3A%20%23d2a8ff1a%3B%0A%20%20--doc-symbol-method-bg-color%3A%20%23d2a8ff1a%3B%0A%20%20--doc-symbol-class-bg-color%3A%20%2379c0ff1a%3B%0A%20%20--doc-symbol-type_alias-bg-color%3A%20%2379c0ff1a%3B%0A%20%20--doc-symbol-module-bg-color%3A%20%23baff791a%3B%0A%7D%0A%0Acode.doc-symbol%20%7B%0A%20%20border-radius%3A%20.1rem%3B%0A%20%20font-size%3A%20.85em%3B%0A%20%20padding%3A%200%20.3em%3B%0A%20%20font-weight%3A%20bold%3B%0A%7D%0A%0Acode.doc-symbol-parameter%2C%0Aa%20code.doc-symbol-parameter%20%7B%0A%20%20color%3A%20var%28--doc-symbol-parameter-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-parameter-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-parameter%3A%3Aafter%20%7B%0A%20%20content%3A%20%22param%22%3B%0A%7D%0A%0Acode.doc-symbol-type_parameter%2C%0Aa%20code.doc-symbol-type_parameter%20%7B%0A%20%20color%3A%20var%28--doc-symbol-type_parameter-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-type_parameter-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-type_parameter%3A%3Aafter%20%7B%0A%20%20content%3A%20%22type-param%22%3B%0A%7D%0A%0Acode.doc-symbol-attribute%2C%0Aa%20code.doc-symbol-attribute%20%7B%0A%20%20color%3A%20var%28--doc-symbol-attribute-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-attribute-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-attribute%3A%3Aafter%20%7B%0A%20%20content%3A%20%22attr%22%3B%0A%7D%0A%0Acode.doc-symbol-function%2C%0Aa%20code.doc-symbol-function%20%7B%0A%20%20color%3A%20var%28--doc-symbol-function-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-function-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-function%3A%3Aafter%20%7B%0A%20%20content%3A%20%22func%22%3B%0A%7D%0A%0Acode.doc-symbol-method%2C%0Aa%20code.doc-symbol-method%20%7B%0A%20%20color%3A%20var%28--doc-symbol-method-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-method-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-method%3A%3Aafter%20%7B%0A%20%20content%3A%20%22meth%22%3B%0A%7D%0A%0Acode.doc-symbol-class%2C%0Aa%20code.doc-symbol-class%20%7B%0A%20%20color%3A%20var%28--doc-symbol-class-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-class-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-class%3A%3Aafter%20%7B%0A%20%20content%3A%20%22class%22%3B%0A%7D%0A%0A%0Acode.doc-symbol-type_alias%2C%0Aa%20code.doc-symbol-type_alias%20%7B%0A%20%20color%3A%20var%28--doc-symbol-type_alias-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-type_alias-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-type_alias%3A%3Aafter%20%7B%0A%20%20content%3A%20%22type%22%3B%0A%7D%0A%0Acode.doc-symbol-module%2C%0Aa%20code.doc-symbol-module%20%7B%0A%20%20color%3A%20var%28--doc-symbol-module-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-module-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-module%3A%3Aafter%20%7B%0A%20%20content%3A%20%22mod%22%3B%0A%7D%0A%0A.doc-signature%20.autorefs%20%7B%0A%20%20color%3A%20inherit%3B%0A%20%20border-bottom%3A%201px%20dotted%20currentcolor%3B%0A%7D%0A%0A/%2A%20Source%20code%20blocks%20%28admonitions%29.%20%2A/%0A%3Aroot%20%7B%0A%20%20--md-admonition-icon--mkdocstrings-source%3A%20url%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M15.22%204.97a.75.75%200%200%201%201.06%200l6.5%206.5a.75.75%200%200%201%200%201.06l-6.5%206.5a.749.749%200%200%201-1.275-.326.75.75%200%200%201%20.215-.734L21.19%2012l-5.97-5.97a.75.75%200%200%201%200-1.06m-6.44%200a.75.75%200%200%201%200%201.06L2.81%2012l5.97%205.97a.749.749%200%200%201-.326%201.275.75.75%200%200%201-.734-.215l-6.5-6.5a.75.75%200%200%201%200-1.06l6.5-6.5a.75.75%200%200%201%201.06%200%22/%3E%3C/svg%3E%27%29%0A%7D%0A.md-typeset%20.admonition.mkdocstrings-source%2C%0A.md-typeset%20details.mkdocstrings-source%20%7B%0A%20%20border%3A%20none%3B%0A%20%20padding%3A%200%3B%0A%7D%0A.md-typeset%20.admonition.mkdocstrings-source%3Afocus-within%2C%0A.md-typeset%20details.mkdocstrings-source%3Afocus-within%20%7B%0A%20%20box-shadow%3A%20none%3B%0A%7D%0A.md-typeset%20.mkdocstrings-source%20%3E%20.admonition-title%2C%0A.md-typeset%20.mkdocstrings-source%20%3E%20summary%20%7B%0A%20%20background-color%3A%20inherit%3B%0A%7D%0A.md-typeset%20.mkdocstrings-source%20%3E%20.admonition-title%3A%3Abefore%2C%0A.md-typeset%20.mkdocstrings-source%20%3E%20summary%3A%3Abefore%20%7B%0A%20%20background-color%3A%20var%28--md-default-fg-color%29%3B%0A%20%20-webkit-mask-image%3A%20var%28--md-admonition-icon--mkdocstrings-source%29%3B%0A%20%20%20%20%20%20%20%20%20%20mask-image%3A%20var%28--md-admonition-icon--mkdocstrings-source%29%3B%0A%7D%0A" rel="stylesheet"/><!--URL:../assets/_mkdocstrings.css-->
|
|
<link href="data:text/css,.md-typeset%20.arithmatex%20%7B%0A%20%20overflow-x%3A%20auto%3B%0A%7D%0A%0A.md-typeset%20.doc-contents%20%7B%0A%20%20overflow-wrap%3A%20anywhere%3B%0A%7D%0A%0A.md-typeset%20h1%20code%2C%0A.md-typeset%20h2%20code%2C%0A.md-typeset%20h3%20code%20%7B%0A%20%20word-break%3A%20break-word%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20%7B%0A%20%20--md-default-bg-color%3A%20%230f141c%3B%0A%20%20--md-default-fg-color%3A%20%23e8eef7%3B%0A%20%20--md-default-fg-color--light%3A%20%23b3bfd1%3B%0A%20%20--md-default-fg-color--lighter%3A%20%237f8ba0%3B%0A%20%20--md-default-fg-color--lightest%3A%20%235d6880%3B%0A%20%20--md-code-bg-color%3A%20%23111923%3B%0A%20%20--md-code-fg-color%3A%20%23e4edf8%3B%0A%20%20--md-accent-fg-color%3A%20%237dd3fc%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-header%2C%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-tabs%20%7B%0A%20%20background%3A%20linear-gradient%2890deg%2C%20%23111923%200%25%2C%20%23162235%20100%25%29%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-typeset%20pre%20%3E%20code%2C%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-typeset%20code%20%7B%0A%20%20border%3A%201px%20solid%20rgba%28125%2C%20211%2C%20252%2C%200.14%29%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-typeset%20table%3Anot%28%5Bclass%5D%29%20%7B%0A%20%20background%3A%20rgba%28255%2C%20255%2C%20255%2C%200.015%29%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%20%7B%0A%20%20background%3A%20rgba%28125%2C%20211%2C%20252%2C%200.08%29%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-typeset%20.admonition%2C%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-typeset%20details%20%7B%0A%20%20background%3A%20rgba%28255%2C%20255%2C%20255%2C%200.02%29%3B%0A%20%20border-color%3A%20rgba%28125%2C%20211%2C%20252%2C%200.2%29%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20.md-typeset%20.arithmatex%20%7B%0A%20%20padding%3A%200.1rem%200%3B%0A%7D%0A" rel="stylesheet"/><!--URL:../stylesheets/extra.css-->
|
|
<script>__md_scope=new URL("/docs/meanas/",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
|
<script type="text/javascript">
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
remove_material_navigation();remove_mkdocs_theme_navigation();generate_toc();
|
|
})
|
|
</script>
|
|
</head>
|
|
<body data-md-color-accent="cyan" data-md-color-primary="blue-grey" data-md-color-scheme="slate" dir="ltr">
|
|
<input autocomplete="off" class="md-toggle" data-md-toggle="drawer" id="__drawer" type="checkbox"/>
|
|
<input autocomplete="off" class="md-toggle" data-md-toggle="search" id="__search" type="checkbox"/>
|
|
<label class="md-overlay" for="__drawer"></label>
|
|
<div data-md-component="skip">
|
|
<a class="md-skip" href="#index">
|
|
Skip to content
|
|
</a>
|
|
</div>
|
|
<div data-md-component="announce">
|
|
</div>
|
|
<header class="md-header md-header--shadow" data-md-component="header">
|
|
<nav aria-label="Header" class="md-header__inner md-grid">
|
|
<a aria-label="meanas" class="md-header__button md-logo" data-md-component="logo" href=".." title="meanas">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg>
|
|
</a>
|
|
<label class="md-header__button md-icon" for="__drawer">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"></path></svg>
|
|
</label>
|
|
<div class="md-header__title" data-md-component="header-title">
|
|
<div class="md-header__ellipsis">
|
|
<div class="md-header__topic">
|
|
<span class="md-ellipsis">
|
|
meanas
|
|
</span>
|
|
</div>
|
|
<div class="md-header__topic" data-md-component="header-topic">
|
|
<span class="md-ellipsis">
|
|
|
|
Print Site
|
|
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<form class="md-header__option" data-md-component="palette">
|
|
<input aria-label="Switch to light mode" class="md-option" data-md-color-accent="cyan" data-md-color-media="" data-md-color-primary="blue-grey" data-md-color-scheme="slate" id="__palette_0" name="__palette" type="radio"/>
|
|
<label class="md-header__button md-icon" for="__palette_1" hidden="" title="Switch to light mode">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"></path></svg>
|
|
</label>
|
|
<input aria-label="Switch to dark mode" class="md-option" data-md-color-accent="indigo" data-md-color-media="" data-md-color-primary="teal" data-md-color-scheme="default" id="__palette_1" name="__palette" type="radio"/>
|
|
<label class="md-header__button md-icon" for="__palette_0" hidden="" title="Switch to dark mode">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"></path></svg>
|
|
</label>
|
|
</form>
|
|
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
|
<label class="md-header__button md-icon" for="__search">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg>
|
|
</label>
|
|
<div class="md-search" data-md-component="search" role="dialog">
|
|
<label class="md-search__overlay" for="__search"></label>
|
|
<div class="md-search__inner" role="search">
|
|
<form class="md-search__form" name="search">
|
|
<input aria-label="Search" autocapitalize="off" autocomplete="off" autocorrect="off" class="md-search__input" data-md-component="search-query" name="query" placeholder="Search" required="" spellcheck="false" type="text"/>
|
|
<label class="md-search__icon md-icon" for="__search">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg>
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"></path></svg>
|
|
</label>
|
|
<nav aria-label="Search" class="md-search__options">
|
|
<button aria-label="Clear" class="md-search__icon md-icon" tabindex="-1" title="Clear" type="reset">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg>
|
|
</button>
|
|
</nav>
|
|
</form>
|
|
<div class="md-search__output">
|
|
<div class="md-search__scrollwrap" data-md-scrollfix="" tabindex="0">
|
|
<div class="md-search-result" data-md-component="search-result">
|
|
<div class="md-search-result__meta">
|
|
Initializing search
|
|
</div>
|
|
<ol class="md-search-result__list" role="presentation"></ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="md-header__source">
|
|
<a class="md-source" data-md-component="source" href="https://mpxd.net/code/jan/meanas" title="Go to repository">
|
|
<div class="md-source__icon md-icon">
|
|
<svg viewbox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"></path></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
meanas
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</nav>
|
|
</header>
|
|
<div class="md-container" data-md-component="container">
|
|
<main class="md-main" data-md-component="main">
|
|
<div class="md-main__inner md-grid">
|
|
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation">
|
|
<div class="md-sidebar__scrollwrap">
|
|
<div class="md-sidebar__inner">
|
|
<nav aria-label="Navigation" class="md-nav md-nav--primary" data-md-level="0">
|
|
<label class="md-nav__title" for="__drawer">
|
|
<a aria-label="meanas" class="md-nav__button md-logo" data-md-component="logo" href=".." title="meanas">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg>
|
|
</a>
|
|
meanas
|
|
</label>
|
|
<div class="md-nav__source">
|
|
<a class="md-source" data-md-component="source" href="https://mpxd.net/code/jan/meanas" title="Go to repository">
|
|
<div class="md-source__icon md-icon">
|
|
<svg viewbox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"></path></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
meanas
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<ul class="md-nav__list" data-md-scrollfix="">
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="..">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Home
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
<input class="md-nav__toggle md-toggle" id="__nav_2" type="checkbox"/>
|
|
<div class="md-nav__link md-nav__container">
|
|
<a class="md-nav__link" href="../api/">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
API
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
</div>
|
|
<nav aria-expanded="false" aria-labelledby="__nav_2_label" class="md-nav" data-md-level="1">
|
|
<label class="md-nav__title" for="__nav_2">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
API
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix="">
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="../api/meanas/">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
meanas
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="../api/eigensolvers/">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
eigensolvers
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="../api/fdfd/">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
fdfd
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="../api/waveguides/">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
waveguides
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="../api/fdtd/">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
fdtd
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="../api/fdmath/">
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
fdmath
|
|
|
|
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc">
|
|
<div class="md-sidebar__scrollwrap">
|
|
<div class="md-sidebar__inner">
|
|
<nav aria-label="Table of contents" class="md-nav md-nav--secondary">
|
|
<label class="md-nav__title" for="__toc">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
Table of contents
|
|
</label>
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix="">
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#index">
|
|
<span class="md-ellipsis">
|
|
|
|
1 Home
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#section-2">
|
|
<span class="md-ellipsis">
|
|
|
|
2 API
|
|
|
|
</span>
|
|
</a>
|
|
<nav aria-label="2 API" class="md-nav">
|
|
<ul class="md-nav__list">
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#api">
|
|
<span class="md-ellipsis">
|
|
|
|
2.1 Overview
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#api-meanas">
|
|
<span class="md-ellipsis">
|
|
|
|
2.2 meanas
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#api-eigensolvers">
|
|
<span class="md-ellipsis">
|
|
|
|
2.3 eigensolvers
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#api-fdfd">
|
|
<span class="md-ellipsis">
|
|
|
|
2.4 fdfd
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#api-waveguides">
|
|
<span class="md-ellipsis">
|
|
|
|
2.5 waveguides
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#api-fdtd">
|
|
<span class="md-ellipsis">
|
|
|
|
2.6 fdtd
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="md-nav__item">
|
|
<a class="md-nav__link" href="#api-fdmath">
|
|
<span class="md-ellipsis">
|
|
|
|
2.7 fdmath
|
|
|
|
</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="md-content" data-md-component="content">
|
|
<article class="md-content__inner md-typeset">
|
|
<div class="print-site-enumerate-headings print-site-enumerate-figures" id="print-site-page">
|
|
<section class="print-page">
|
|
<div data-toc-depth="3" id="print-page-toc">
|
|
<nav class="print-page-toc-nav" role="navigation">
|
|
<h1 class="print-page-toc-title">Table of Contents</h1>
|
|
</nav>
|
|
</div>
|
|
</section>
|
|
<section class="print-page" heading-number="1" id="index"><h1 id="index-meanas">meanas<a class="headerlink" href="#index-meanas" title="Permanent link">¶</a></h1>
|
|
<p><code>meanas</code> is a Python package for finite-difference electromagnetic simulation.
|
|
It combines:</p>
|
|
<ul>
|
|
<li><code>meanas.fdfd</code> for frequency-domain operators, sources, waveguide modes, and SCPML</li>
|
|
<li><code>meanas.fdtd</code> for Yee-grid timestepping, CPML, energy/flux accounting, and phasor extraction</li>
|
|
<li><code>meanas.fdmath</code> for the shared discrete operators and derivations underneath both solvers</li>
|
|
</ul>
|
|
<p>This documentation is built directly from the package docstrings. The API pages
|
|
are the source of truth for the mathematical derivations and calling
|
|
conventions.</p>
|
|
<h2 id="index-examples-and-api-map">Examples and API Map<a class="headerlink" href="#index-examples-and-api-map" title="Permanent link">¶</a></h2>
|
|
<p>For most users, the tracked examples under <code>examples/</code> are the right entry
|
|
point. They show the intended combinations of tools for solving complete
|
|
problems.</p>
|
|
<p>Relevant starting examples:</p>
|
|
<ul>
|
|
<li><code>examples/fdtd.py</code> for broadband pulse excitation and phasor extraction</li>
|
|
<li><code>examples/waveguide.py</code> for guided phasor-domain FDTD/FDFD comparison</li>
|
|
<li><code>examples/waveguide_real.py</code> for real-valued continuous-wave FDTD compared
|
|
against real fields reconstructed from an FDFD solution, including guided-core,
|
|
mode-weighted, and guided-mode / residual comparisons</li>
|
|
<li><code>examples/eme.py</code> for straight-interface mode matching / EME and modal
|
|
scattering between two nearby waveguide cross-sections</li>
|
|
<li><code>examples/eme_bend.py</code> for straight-to-bent mode matching with cylindrical
|
|
bend modes and a cascaded bend-network example</li>
|
|
<li><code>examples/fdfd.py</code> for direct frequency-domain waveguide excitation</li>
|
|
</ul>
|
|
<p>For solver equivalence, prefer the phasor-based examples first. They compare
|
|
the extracted <code>+\omega</code> content of the FDTD run directly against the FDFD
|
|
solution and are the main accuracy benchmarks in the test suite.</p>
|
|
<p><code>examples/waveguide_real.py</code> answers a different, stricter question: how well a
|
|
late raw real snapshot matches <code>Re(E_\omega e^{i\omega t})</code> on a monitor plane.
|
|
That diagnostic is useful, but it also includes orthogonal residual structure
|
|
that the phasor comparison intentionally filters out.</p>
|
|
<p>The API pages are better read as a toolbox map and derivation reference:</p>
|
|
<ul>
|
|
<li>Use the <a href="#api-fdtd">FDTD API</a> for time-domain stepping, CPML, phasor
|
|
extraction, and real-field reconstruction from FDFD phasors.</li>
|
|
<li>Use the <a href="#api-fdfd">FDFD API</a> for driven frequency-domain solves and sparse
|
|
operator algebra.</li>
|
|
<li>Use the <a href="#api-waveguides">Waveguide API</a> for mode solving, port sources,
|
|
and overlap windows.</li>
|
|
<li>Use the <a href="#api-fdmath">fdmath API</a> for the lower-level finite-difference
|
|
operators and the shared discrete derivations underneath both solvers.</li>
|
|
</ul>
|
|
<h2 id="index-build-outputs">Build outputs<a class="headerlink" href="#index-build-outputs" title="Permanent link">¶</a></h2>
|
|
<p>The docs build generates two HTML views from the same source:</p>
|
|
<ul>
|
|
<li>a normal multi-page site</li>
|
|
<li>a print-oriented combined page under <code>site/print_page/</code></li>
|
|
</ul>
|
|
<p>If <code>htmlark</code> is installed, <code>./make_docs.sh</code> also writes a fully inlined
|
|
<code>site/standalone.html</code>.</p></section>
|
|
<section class="print-page md-section" heading-number="2" id="section-2">
|
|
<h1>API<a class="headerlink" href="#section-2" title="Permanent link"></a>
|
|
</h1>
|
|
<section class="print-page" heading-number="2.1" id="api"><h1 id="api-api-overview">API Overview<a class="headerlink" href="#api-api-overview" title="Permanent link">¶</a></h1>
|
|
<p>The package is documented directly from its docstrings. The most useful entry
|
|
points are:</p>
|
|
<ul>
|
|
<li><a href="#api-meanas">meanas</a>: top-level package overview</li>
|
|
<li><a href="#api-eigensolvers">eigensolvers</a>: generic eigenvalue utilities used by the mode solvers</li>
|
|
<li><a href="#api-fdfd">fdfd</a>: frequency-domain operators, sources, PML, solvers, and far-field transforms</li>
|
|
<li><a href="#api-waveguides">waveguides</a>: straight, cylindrical, and 3D waveguide mode helpers</li>
|
|
<li><a href="#api-fdtd">fdtd</a>: timestepping, CPML, energy/flux helpers, and phasor extraction</li>
|
|
<li><a href="#api-fdmath">fdmath</a>: shared discrete operators, vectorization helpers, and derivation background</li>
|
|
</ul>
|
|
<p>The waveguide and FDTD pages are the best places to start if you want the
|
|
mathematical derivations rather than just the callable reference.</p></section><section class="print-page" heading-number="2.2" id="api-meanas"><h1 id="api-meanas-meanas_1">meanas<a class="headerlink" href="#api-meanas-meanas_1" title="Permanent link">¶</a></h1>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-meanas-meanas">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas</span>
|
|
<a class="headerlink" href="#api-meanas-meanas" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Electromagnetic simulation tools</p>
|
|
<p>See the tracked examples for end-to-end workflows, and <code>help(meanas)</code> for the
|
|
toolbox overview and API derivations.</p>
|
|
<div class="doc doc-children">
|
|
</div>
|
|
</div>
|
|
</div></section><section class="print-page" heading-number="2.3" id="api-eigensolvers"><h1 id="api-eigensolvers-eigensolvers">eigensolvers<a class="headerlink" href="#api-eigensolvers-eigensolvers" title="Permanent link">¶</a></h1>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.eigensolvers</span>
|
|
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Solvers for eigenvalue / eigenvector problems</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers.power_iteration">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">power_iteration</span>
|
|
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers.power_iteration" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-eigensolvers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">power_iteration</span><span class="p">(</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">operator</span><span class="p">:</span> <span class="n">spmatrix</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">guess_vector</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complex128</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">iterations</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">complex</span><span class="p">,</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Use power iteration to estimate the dominant eigenvector of a matrix.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>operator</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.spmatrix" title="scipy.sparse.spmatrix">spmatrix</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Matrix to analyze.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>guess_vector</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>] | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Starting point for the eigenvector. Default is a randomly chosen vector.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>iterations</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Number of iterations to perform. Default 20.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>20</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#complex">complex</a>, <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>(Largest-magnitude eigenvalue, Corresponding eigenvector estimate)</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers.rayleigh_quotient_iteration">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">rayleigh_quotient_iteration</span>
|
|
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers.rayleigh_quotient_iteration" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-eigensolvers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">rayleigh_quotient_iteration</span><span class="p">(</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">operator</span><span class="p">:</span> <span class="n">spmatrix</span> <span class="o">|</span> <span class="n">LinearOperator</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">guess_vector</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complex128</span><span class="p">],</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">iterations</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">40</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">tolerance</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1e-13</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">solver</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complex128</span><span class="p">]]</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">complex</span><span class="p">,</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Use Rayleigh quotient iteration to refine an eigenvector guess.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>operator</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.spmatrix" title="scipy.sparse.spmatrix">spmatrix</a> | <a class="autorefs autorefs-internal" href="#scipy.sparse.linalg.LinearOperator" title="scipy.sparse.linalg.LinearOperator">LinearOperator</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Matrix to analyze.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>guess_vector</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Eigenvector to refine.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>iterations</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Maximum number of iterations to perform. Default 40.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>40</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>tolerance</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Stop iteration if <code>(A - I*eigenvalue) @ v < num_vectors * tolerance</code>,
|
|
Default 1e-13.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1e-13</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>solver</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[..., <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]] | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Solver function of the form <code>x = solver(A, b)</code>.
|
|
By default, use scipy.sparse.spsolve for sparse matrices and
|
|
scipy.sparse.bicgstab for general LinearOperator instances.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#complex">complex</a>, <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>(eigenvalues, eigenvectors)</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers.signed_eigensolve">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">signed_eigensolve</span>
|
|
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers.signed_eigensolve" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-eigensolvers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">signed_eigensolve</span><span class="p">(</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">operator</span><span class="p">:</span> <span class="n">spmatrix</span> <span class="o">|</span> <span class="n">LinearOperator</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">how_many</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">negative</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
|
|
<a href="#api-eigensolvers-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Find the largest-magnitude positive-only (or negative-only) eigenvalues and
|
|
eigenvectors of the provided matrix.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>operator</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.spmatrix" title="scipy.sparse.spmatrix">spmatrix</a> | <a class="autorefs autorefs-internal" href="#scipy.sparse.linalg.LinearOperator" title="scipy.sparse.linalg.LinearOperator">LinearOperator</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Matrix to analyze.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>how_many</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>How many eigenvalues to find.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>negative</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Whether to find negative-only eigenvalues.
|
|
Default False (positive only).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>False</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>(sorted list of eigenvalues, 2D ndarray of corresponding eigenvectors)</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>eigenvectors[:, k]</code> corresponds to the k-th eigenvalue</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div></section><section class="print-page" heading-number="2.4" id="api-fdfd"><h1 id="api-fdfd-fdfd">fdfd<a class="headerlink" href="#api-fdfd-fdfd" title="Permanent link">¶</a></h1>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Tools for finite difference frequency-domain (FDFD) simulations and calculations.</p>
|
|
<p>These mostly involve picking a single frequency, then setting up and solving a
|
|
matrix equation (Ax=b) or eigenvalue problem.</p>
|
|
<p>Submodules:</p>
|
|
<ul>
|
|
<li><code>operators</code>, <code>functional</code>: General FDFD problem setup.</li>
|
|
<li><code>solvers</code>: Solver interface and reference implementation.</li>
|
|
<li><code>scpml</code>: Stretched-coordinate perfectly matched layer (SCPML) boundary conditions.</li>
|
|
<li><code>waveguide_2d</code>: Operators and mode-solver for waveguides with constant cross-section.</li>
|
|
<li><code>waveguide_3d</code>: Functions for transforming <code>waveguide_2d</code> results into 3D,
|
|
including mode-source and overlap-window construction.</li>
|
|
<li><code>farfield</code>, <code>bloch</code>, <code>eme</code>: specialized helper modules for near/far transforms,
|
|
Bloch-periodic problems, and eigenmode expansion.</li>
|
|
</ul>
|
|
<p>================================================================</p>
|
|
<p>From the "Frequency domain" section of <code>meanas.fdmath</code>, we have</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{E}_{l, \vec{r}} &= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
|
|
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &= \tilde{H}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
|
|
\tilde{J}_{l, \vec{r}} &= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
|
|
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &= \tilde{M}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega l \Delta_t} \\
|
|
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
|
|
-\Omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} &= -\imath \Omega \tilde{J}_{\vec{r}} e^{\imath \omega \Delta_t / 2} \\
|
|
\Omega &= 2 \sin(\omega \Delta_t / 2) / \Delta_t
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>resulting in</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{\partial}_t &\Rightarrow -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
|
|
\hat{\partial}_t &\Rightarrow -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Maxwell's equations are then</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &=
|
|
\imath \Omega e^{-\imath \omega \Delta_t / 2} \hat{B}_{\vec{r} + \frac{1}{2}}
|
|
- \hat{M}_{\vec{r} + \frac{1}{2}} \\
|
|
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &=
|
|
-\imath \Omega e^{ \imath \omega \Delta_t / 2} \tilde{D}_{\vec{r}}
|
|
+ \tilde{J}_{\vec{r}} \\
|
|
\tilde{\nabla} \cdot \hat{B}_{\vec{r} + \frac{1}{2}} &= 0 \\
|
|
\hat{\nabla} \cdot \tilde{D}_{\vec{r}} &= \rho_{\vec{r}}
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>With <span class="arithmatex">\(\Delta_t \to 0\)</span>, this simplifies to</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{E}_{l, \vec{r}} &\to \tilde{E}_{\vec{r}} \\
|
|
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &\to \tilde{H}_{\vec{r} + \frac{1}{2}} \\
|
|
\tilde{J}_{l, \vec{r}} &\to \tilde{J}_{\vec{r}} \\
|
|
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &\to \tilde{M}_{\vec{r} + \frac{1}{2}} \\
|
|
\Omega &\to \omega \\
|
|
\tilde{\partial}_t &\to -\imath \omega \\
|
|
\hat{\partial}_t &\to -\imath \omega \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>and then</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &=
|
|
\imath \omega \hat{B}_{\vec{r} + \frac{1}{2}}
|
|
- \hat{M}_{\vec{r} + \frac{1}{2}} \\
|
|
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &=
|
|
-\imath \omega \tilde{D}_{\vec{r}}
|
|
+ \tilde{J}_{\vec{r}} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<div class="arithmatex">\[
|
|
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
|
|
-\omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} = -\imath \omega \tilde{J}_{\vec{r}} \\
|
|
\]</div>
|
|
<div class="doc doc-children">
|
|
</div>
|
|
</div>
|
|
</div><h2 id="core-operator-layers">Core operator layers<a class="headerlink" href="#api-fdfd-core-operator-layers" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.functional</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Functional versions of many FDFD operators. These can be useful for performing
|
|
FDFD calculations without needing to construct large matrices in memory.</p>
|
|
<p>The functions generated here expect <code>cfdfield_t</code> inputs with shape (3, X, Y, Z),
|
|
e.g. E = [E_x, E_y, E_z] where each (complex) component has shape (X, Y, Z)</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.e_full">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_full</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.e_full" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_full</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_updater_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Wave operator for use with E-field. See <code>operators.e_full</code> for details.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> implementing the wave operator</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>f(E)</code> -> <code>-i * omega * J</code></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.eh_full">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">eh_full</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.eh_full" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">eh_full</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">Callable</span><span class="p">[</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="p">[</span><span class="n">cfdfield</span><span class="p">,</span> <span class="n">cfdfield</span><span class="p">],</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">cfdfield_t</span><span class="p">,</span> <span class="n">cfdfield_t</span><span class="p">]</span>
|
|
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Wave operator for full (both E and H) field representation.
|
|
See <code>operators.eh_full</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> implementing the wave operator</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>f(E, H)</code> -> <code>(J, -M)</code></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.e2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.e2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_updater_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operator for converting the <code>E</code> field into the <code>H</code> field.
|
|
For use with <code>e_full</code> -- assumes that there is no magnetic current <code>M</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> for converting <code>E</code> to <code>H</code>,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>f(E)</code> -> <code>H</code></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.m2j">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">m2j</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.m2j" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">m2j</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_updater_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operator for converting magnetic current <code>M</code> distribution
|
|
into equivalent electric current distribution <code>J</code>.
|
|
For use with e.g. <code>e_full</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> for converting <code>M</code> to <code>J</code>,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>f(M)</code> -> <code>J</code></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.e_tfsf_source">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_tfsf_source</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.e_tfsf_source" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_tfsf_source</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">TF_region</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_updater_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator that turns an E-field distribution into a total-field/scattered-field
|
|
(TFSF) source.</p>
|
|
<p>If <code>A</code> is the full wave operator from <code>e_full(...)</code> and <code>Q</code> is the diagonal
|
|
mask selecting the total-field region, then the TFSF source is the commutator</p>
|
|
<div class="arithmatex">\[
|
|
\frac{A Q - Q A}{-i \omega} E.
|
|
\]</div>
|
|
<p>This vanishes in the interior of the total-field and scattered-field regions
|
|
and is supported only at their shared boundary, where the mask discontinuity
|
|
makes <code>A</code> and <code>Q</code> fail to commute. The returned current is therefore the
|
|
distributed source needed to inject the desired total field without also
|
|
forcing the scattered-field region.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>TF_region</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>mask which is set to 1 in the total-field region, and 0 elsewhere
|
|
(i.e. in the scattered-field region).
|
|
Should have the same shape as the simulation grid, e.g. <code>epsilon[0].shape</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant distribution</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> which takes an E field and returns a current distribution,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>f(E)</code> -> <code>J</code></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.poynting_e_cross_h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_e_cross_h</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.poynting_e_cross_h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_e_cross_h</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">Callable</span><span class="p">[[</span><span class="n">cfdfield</span><span class="p">,</span> <span class="n">cfdfield</span><span class="p">],</span> <span class="n">cfdfield_t</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Generates a function that takes the single-frequency <code>E</code> and <code>H</code> fields
|
|
and calculates the cross product <code>E</code> x <code>H</code> = <span class="arithmatex">\(E \times H\)</span> as required
|
|
for the Poynting vector, <span class="arithmatex">\(S = E \times H\)</span>.</p>
|
|
<p>On the Yee grid, the electric and magnetic components are not stored at the
|
|
same locations. This helper therefore applies the same one-cell electric-field
|
|
shifts used by the sparse <code>operators.poynting_e_cross(...)</code> construction so
|
|
that the discrete cross product matches the face-centered energy flux used in
|
|
<code>meanas.fdtd.energy.poynting(...)</code>.</p>
|
|
<details class="note" open="">
|
|
<summary>Note</summary>
|
|
<p>This function also shifts the input <code>E</code> field by one cell as required
|
|
for computing the Poynting cross product (see <code>meanas.fdfd</code> module docs).</p>
|
|
</details>
|
|
<details class="note" open="">
|
|
<summary>Note</summary>
|
|
<p>If <code>E</code> and <code>H</code> are peak amplitudes as assumed elsewhere in this code,
|
|
the time-average of the poynting vector is <code><S> = Re(S)/2 = Re(E x H*) / 2</code>.
|
|
The factor of <code>1/2</code> can be omitted if root-mean-square quantities are used
|
|
instead.</p>
|
|
</details>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> that returns the staggered-grid cross product <code>E \times H</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>For time-average power, call it as <code>f(E, H.conj())</code> and take <code>Re(...) / 2</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.operators</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Sparse matrix operators for use with electromagnetic wave equations.</p>
|
|
<p>These functions return sparse-matrix (<code>scipy.sparse.sparray</code>) representations of
|
|
a variety of operators, intended for use with E and H fields vectorized using the
|
|
<code>meanas.fdmath.vectorization.vec()</code> and <code>meanas.fdmath.vectorization.unvec()</code> functions.</p>
|
|
<p>E- and H-field values are defined on a Yee cell; <code>epsilon</code> values should be calculated for
|
|
cells centered at each E component (<code>mu</code> at each H component).</p>
|
|
<p>Many of these functions require a <code>dxes</code> parameter, of type <code>dx_lists_t</code>; see
|
|
the <code>meanas.fdmath.types</code> submodule for details.</p>
|
|
<p>The following operators are included:</p>
|
|
<ul>
|
|
<li>E-only wave operator</li>
|
|
<li>H-only wave operator</li>
|
|
<li>EH wave operator</li>
|
|
<li>Curl for use with E, H fields</li>
|
|
<li>E to H conversion</li>
|
|
<li>M to J conversion</li>
|
|
<li>Poynting cross products</li>
|
|
<li>Circular shifts</li>
|
|
<li>Discrete derivatives</li>
|
|
<li>Averaging operators</li>
|
|
<li>Cross product matrices</li>
|
|
</ul>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_full">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_full</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_full" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_full</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="n">vcfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Wave operator
|
|
|
|
<div class="arithmatex">\[ \nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon \]</div>
|
|
</p>
|
|
<div class="highlight"><pre><span></span><code>del x (1/mu * del x) - omega**2 * epsilon
|
|
</code></pre></div>
|
|
<p>for use with the E-field, with wave equation
|
|
|
|
<div class="arithmatex">\[ (\nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon) E = -\imath \omega J \]</div>
|
|
</p>
|
|
<div class="highlight"><pre><span></span><code>(del x (1/mu * del x) - omega**2 * epsilon) E = -i * omega * J
|
|
</code></pre></div>
|
|
<p>To make this matrix symmetric, use the preconditioners from <code>e_full_preconditioners()</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability (default 1 everywhere).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pec</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mask specifying PEC cells. Any cells where <code>pec != 0</code> are interpreted
|
|
as containing a perfect electrical conductor (PEC).
|
|
The PEC is applied per-field-component (i.e. <code>pec.size == epsilon.size</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pmc</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
|
|
as containing a perfect magnetic conductor (PMC).
|
|
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix containing the wave operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_full_preconditioners">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_full_preconditioners</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_full_preconditioners" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_full_preconditioners</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">,</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Left and right preconditioners <code>(Pl, Pr)</code> for symmetrizing the <code>e_full</code> wave operator.</p>
|
|
<p>The preconditioned matrix <code>A_symm = (Pl @ A @ Pr)</code> is complex-symmetric
|
|
(non-Hermitian unless there is no loss or PMLs).</p>
|
|
<p>The preconditioner matrices are diagonal and complex, with <code>Pr = 1 / Pl</code></p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>, <a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Preconditioner matrices <code>(Pl, Pr)</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.h_full">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">h_full</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.h_full" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">h_full</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Wave operator
|
|
|
|
<div class="arithmatex">\[ \nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu \]</div>
|
|
</p>
|
|
<div class="highlight"><pre><span></span><code>del x (1/epsilon * del x) - omega**2 * mu
|
|
</code></pre></div>
|
|
<p>for use with the H-field, with wave equation
|
|
|
|
<div class="arithmatex">\[ (\nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu) E = \imath \omega M \]</div>
|
|
</p>
|
|
<div class="highlight"><pre><span></span><code>(del x (1/epsilon * del x) - omega**2 * mu) E = i * omega * M
|
|
</code></pre></div>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pec</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mask specifying PEC cells. Any cells where <code>pec != 0</code> are interpreted
|
|
as containing a perfect electrical conductor (PEC).
|
|
The PEC is applied per-field-component (i.e. <code>pec.size == epsilon.size</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pmc</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
|
|
as containing a perfect magnetic conductor (PMC).
|
|
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix containing the wave operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.eh_full">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">eh_full</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.eh_full" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">eh_full</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Wave operator for <code>[E, H]</code> field representation. This operator implements Maxwell's
|
|
equations without cancelling out either E or H. The operator is</p>
|
|
<div class="arithmatex">\[
|
|
\begin{bmatrix}
|
|
-\imath \omega \epsilon & \nabla \times \\
|
|
\nabla \times & \imath \omega \mu
|
|
\end{bmatrix}
|
|
\]</div>
|
|
<div class="highlight"><pre><span></span><code>[[-i * omega * epsilon, del x ],
|
|
[del x, i * omega * mu]]
|
|
</code></pre></div>
|
|
<p>for use with a field vector of the form <code>cat(vec(E), vec(H))</code>:</p>
|
|
<div class="arithmatex">\[
|
|
\begin{bmatrix}
|
|
-\imath \omega \epsilon & \nabla \times \\
|
|
\nabla \times & \imath \omega \mu
|
|
\end{bmatrix}
|
|
\begin{bmatrix} E \\
|
|
H
|
|
\end{bmatrix}
|
|
= \begin{bmatrix} J \\
|
|
-M
|
|
\end{bmatrix}
|
|
\]</div>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pec</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mask specifying PEC cells. Any cells where <code>pec != 0</code> are interpreted
|
|
as containing a perfect electrical conductor (PEC).
|
|
The PEC is applied per-field-component (i.e. <code>pec.size == epsilon.size</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pmc</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
|
|
as containing a perfect magnetic conductor (PMC).
|
|
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix containing the wave operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operator for converting the E field into the H field.
|
|
For use with <code>e_full()</code> -- assumes that there is no magnetic current M.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pmc</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
|
|
as containing a perfect magnetic conductor (PMC).
|
|
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for converting E to H.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.m2j">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">m2j</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.m2j" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">m2j</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator for converting a magnetic current M into an electric current J.
|
|
For use with eg. <code>e_full()</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for converting M to J.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.poynting_e_cross">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_e_cross</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.poynting_e_cross" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_e_cross</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e</span><span class="p">:</span> <span class="n">vcfdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator for computing the staggered-grid <code>(E \times)</code> part of the Poynting vector.</p>
|
|
<p>On the Yee grid the E and H components live on different edges, so the
|
|
electric field must be shifted by one cell in the appropriate direction
|
|
before forming the discrete cross product. This sparse operator encodes that
|
|
shifted cross product directly and is the matrix equivalent of
|
|
<code>functional.poynting_e_cross_h(...)</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized E-field for the ExH cross product</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix containing the <code>(E \times)</code> part of the staggered Poynting</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>cross product.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.poynting_h_cross">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_h_cross</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.poynting_h_cross" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_h_cross</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h</span><span class="p">:</span> <span class="n">vcfdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator for computing the staggered-grid <code>(H \times)</code> part of the Poynting vector.</p>
|
|
<p>Together with <code>poynting_e_cross(...)</code>, this provides the matrix form of the
|
|
Yee-grid cross product used in the flux helpers. The two are related by the
|
|
usual antisymmetry of the cross product,</p>
|
|
<div class="arithmatex">\[
|
|
H \times E = -(E \times H),
|
|
\]</div>
|
|
<p>once the same staggered field placement is used on both sides.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized H-field for the HxE cross product</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix containing the <code>(H \times)</code> part of the staggered Poynting</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>cross product.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_tfsf_source">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_tfsf_source</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_tfsf_source" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_tfsf_source</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">TF_region</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator that turns a desired E-field distribution into a
|
|
total-field/scattered-field (TFSF) source.</p>
|
|
<p>Let <code>A</code> be the full wave operator from <code>e_full(...)</code>, and let
|
|
<code>Q = \mathrm{diag}(TF_region)</code> be the projector onto the total-field region.
|
|
Then the TFSF current operator is the commutator</p>
|
|
<div class="arithmatex">\[
|
|
\frac{A Q - Q A}{-i \omega}.
|
|
\]</div>
|
|
<p>Inside regions where <code>Q</code> is locally constant, <code>A</code> and <code>Q</code> commute and the
|
|
source vanishes. Only cells at the TF/SF boundary contribute nonzero current,
|
|
which is exactly the desired distributed source for injecting the chosen
|
|
field into the total-field region without directly forcing the
|
|
scattered-field region.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>TF_region</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Mask, which is set to 1 inside the total-field region and 0 in the
|
|
scattered-field region</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability (default 1 everywhere).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix that turns an E-field into a current (J) distribution.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_boundary_source">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_boundary_source</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_boundary_source" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_boundary_source</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mask</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">periodic_mask_edges</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator that turns an E-field distrubtion into a current (J) distribution
|
|
along the edges (external and internal) of the provided mask. This is just an
|
|
<code>e_tfsf_source()</code> with an additional masking step.</p>
|
|
<p>Equivalently, this helper first constructs the TFSF commutator source for the
|
|
full mask and then zeroes out all cells except the mask boundary. The
|
|
boundary is defined as the set of cells whose mask value changes under a
|
|
one-cell shift in any Cartesian direction. With <code>periodic_mask_edges=False</code>
|
|
the shifts mirror at the domain boundary; with <code>True</code> they wrap periodically.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mask</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The current distribution is generated at the edges of the mask,
|
|
i.e. any points where shifting the mask by one cell in any direction
|
|
would change its value.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability (default 1 everywhere).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix that turns an E-field into a current (J) distribution.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.solvers">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.solvers</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.solvers" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Solvers and solver interface for FDFD problems.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.solvers.generic">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">generic</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.solvers.generic" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generic</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">J</span><span class="p">:</span> <span class="n">vcfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">adjoint</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">matrix_solver</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">ArrayLike</span><span class="p">]</span> <span class="o">=</span> <span class="n">_scipy_qmr</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">matrix_solver_opts</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="n">E_guess</span><span class="p">:</span> <span class="n">vcfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="p">)</span> <span class="o">-></span> <span class="n">vcfdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Conjugate gradient FDFD solver using CSR sparse matrices.</p>
|
|
<p>All ndarray arguments should be 1D arrays, as returned by <code>meanas.fdmath.vectorization.vec()</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Complex frequency to solve at.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>[[dx_e, dy_e, dz_e], [dx_h, dy_h, dz_h]]</code> (complex cell sizes) as
|
|
discussed in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>J</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Electric current distribution (at E-field locations)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant distribution (at E-field locations)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability distribution (at H-field locations)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pec</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Perfect electric conductor distribution
|
|
(at E-field locations; non-zero value indicates PEC is present)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>pmc</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Perfect magnetic conductor distribution
|
|
(at H-field locations; non-zero value indicates PMC is present)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>adjoint</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>If true, solves the adjoint problem.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>False</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>matrix_solver</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[..., <a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Called as <code>matrix_solver(A, b, **matrix_solver_opts) -> x</code>,
|
|
where <code>A</code>: <code>scipy.sparse.csr_array</code>;
|
|
<code>b</code>: <code>ArrayLike</code>;
|
|
<code>x</code>: <code>ArrayLike</code>;
|
|
Default is a wrapped version of <code>scipy.sparse.linalg.qmr()</code>
|
|
which doesn't return convergence info and logs the residual
|
|
every 100 iterations.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdfd.solvers._scipy_qmr" title="meanas.fdfd.solvers._scipy_qmr">_scipy_qmr</a></code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>matrix_solver_opts</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>] | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Passed as kwargs to <code>matrix_solver(...)</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>E_guess</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Guess at the solution E-field. <code>matrix_solver</code> must accept an
|
|
<code>x0</code> argument with the same purpose.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdfield_t" title="meanas.fdmath.vcfdfield_t">vcfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field which solves the system.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.scpml</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Functions for creating stretched coordinate perfectly matched layer (PML) absorbers.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-attribute">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.s_function_t">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">s_function_t</span>
|
|
<span class="doc doc-labels">
|
|
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
|
|
</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">s_function_t</span> <span class="o">=</span> <span class="n">Callable</span><span class="p">[</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">float64</span><span class="p">]],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">float64</span><span class="p">]</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Typedef for s-functions, see <code>prepare_s_function()</code></p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.prepare_s_function">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">prepare_s_function</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.prepare_s_function" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">prepare_s_function</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">ln_R</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="o">-</span><span class="mi">16</span><span class="p">,</span> <span class="n">m</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">4</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">s_function_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Create an s_function to pass to the SCPML functions. This is used when you would like to
|
|
customize the PML parameters.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>ln_R</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Natural logarithm of the desired reflectance</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>-16</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>m</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Polynomial order for the PML (imaginary part increases as distance ** m)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>4</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdfd.scpml.s_function_t)">s_function_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>An s_function, which takes an ndarray (distances) and returns an ndarray (complex part</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdfd.scpml.s_function_t)">s_function_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>of the cell width; needs to be divided by <code>sqrt(epilon_effective) * real(omega))</code></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdfd.scpml.s_function_t)">s_function_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>before use.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.uniform_grid_scpml">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">uniform_grid_scpml</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.uniform_grid_scpml" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">uniform_grid_scpml</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">thicknesses</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon_effective</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">s_function</span><span class="p">:</span> <span class="n">s_function_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">]]]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Create dx arrays for a uniform grid with a cell width of 1 and a pml.</p>
|
|
<p>If you want something more fine-grained, check out <code>stretch_with_scpml(...)</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shape</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Shape of the grid, including the PMLs (which are 2*thicknesses thick)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>thicknesses</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>[th_x, th_y, th_z]</code>
|
|
Thickness of the PML in each direction.
|
|
Both polarities are added.
|
|
Each th_ of pml is applied twice, once on each edge of the grid along the given axis.
|
|
<code>th_*</code> may be zero, in which case no pml is added.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency for the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon_effective</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Effective epsilon of the PML. Match this to the material
|
|
at the edge of your grid.
|
|
Default 1.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1.0</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>s_function</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdfd.scpml.s_function_t)">s_function_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>created by <code>prepare_s_function(...)</code>, allowing customization of pml parameters.
|
|
Default uses <code>prepare_s_function()</code> with no parameters.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Complex cell widths (dx_lists_mut) as discussed in <code>meanas.fdmath.types</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">stretch_with_scpml</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">stretch_with_scpml</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">float64</span><span class="p">]]],</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon_effective</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">thickness</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">s_function</span><span class="p">:</span> <span class="n">s_function_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">]]]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Stretch dxes to contain a stretched-coordinate PML (SCPML) in one direction along one axis.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>axis to stretch (0=x, 1=y, 2=z)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>polarity</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>direction to stretch (-1 for -ve, +1 for +ve)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency for the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon_effective</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Effective epsilon of the PML. Match this to the material at the
|
|
edge of your grid. Default 1.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1.0</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>thickness</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>number of cells to use for pml (default 10)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>10</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>s_function</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdfd.scpml.s_function_t)">s_function_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Created by <code>prepare_s_function(...)</code>, allowing customization
|
|
of pml parameters. Default uses <code>prepare_s_function()</code> with no parameters.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Complex cell widths (dx_lists_mut) as discussed in <code>meanas.fdmath.types</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Multiple calls to this function may be necessary if multiple absorpbing boundaries are needed.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.farfield">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.farfield</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.farfield" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Functions for performing near-to-farfield transformation (and the reverse).</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.farfield.near_to_farfield">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">near_to_farfield</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.farfield.near_to_farfield" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">near_to_farfield</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E_near</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">H_near</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dx</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dy</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">padded_size</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">|</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Compute the farfield, i.e. the distribution of the fields after propagation
|
|
through several wavelengths of uniform medium.</p>
|
|
<p>The input fields should be complex phasors.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>E_near</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
|
|
E fields (e.g. [Ex, Ey] for calculating the farfield toward the z-direction).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>H_near</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
|
|
H fields (e.g. [Hx, hy] for calculating the farfield towrad the z-direction).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Cell size along x-dimension, in units of wavelength.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dy</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Cell size along y-dimension, in units of wavelength.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>padded_size</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>] | <a class="autorefs autorefs-internal" href="#print-page-toc">int</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Shape of the output. A single integer <code>n</code> will be expanded to <code>(n, n)</code>.
|
|
Powers of 2 are most efficient for FFT computation.
|
|
Default is the smallest power of 2 larger than the input, for each axis.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dict with keys</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>E_far</code>: Normalized E-field farfield; multiply by
|
|
(i k exp(-i k r) / (4 pi r)) to get the actual field value.</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>H_far</code>: Normalized H-field farfield; multiply by
|
|
(i k exp(-i k r) / (4 pi r)) to get the actual field value.</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>kx</code>, <code>ky</code>: Wavevector values corresponding to the x- and y- axes in E_far and H_far,
|
|
normalized to wavelength (dimensionless).</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>dkx</code>, <code>dky</code>: step size for kx and ky, normalized to wavelength.</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>theta</code>: arctan2(ky, kx) corresponding to each (kx, ky).
|
|
This is the angle in the x-y plane, counterclockwise from above, starting from +x.</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>phi</code>: arccos(kz / k) corresponding to each (kx, ky).
|
|
This is the angle away from +z.</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.farfield.far_to_nearfield">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">far_to_nearfield</span>
|
|
<a class="headerlink" href="#api-fdfd-meanas.fdfd.farfield.far_to_nearfield" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">far_to_nearfield</span><span class="p">(</span>
|
|
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E_far</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">H_far</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dkx</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dky</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">padded_size</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">|</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Compute the farfield, i.e. the distribution of the fields after propagation
|
|
through several wavelengths of uniform medium.</p>
|
|
<p>The input fields should be complex phasors.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>E_far</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
|
|
E fields (e.g. [Ex, Ey] for calculating the nearfield toward the z-direction).
|
|
Fields should be normalized so that
|
|
E_far = E_far_actual / (i k exp(-i k r) / (4 pi r))</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>H_far</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
|
|
H fields (e.g. [Hx, hy] for calculating the nearfield toward the z-direction).
|
|
Fields should be normalized so that
|
|
H_far = H_far_actual / (i k exp(-i k r) / (4 pi r))</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dkx</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>kx discretization, in units of wavelength.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dky</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>ky discretization, in units of wavelength.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>padded_size</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>] | <a class="autorefs autorefs-internal" href="#print-page-toc">int</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Shape of the output. A single integer <code>n</code> will be expanded to <code>(n, n)</code>.
|
|
Powers of 2 are most efficient for FFT computation.
|
|
Default is the smallest power of 2 larger than the input, for each axis.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dict with keys</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>E</code>: E-field nearfield</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>H</code>: H-field nearfield</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>dx</code>, <code>dy</code>: spatial discretization, normalized to wavelength (dimensionless)</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div></section><section class="print-page" heading-number="2.5" id="api-waveguides"><h1 id="api-waveguides-waveguides">waveguides<a class="headerlink" href="#api-waveguides-waveguides" title="Permanent link">¶</a></h1>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.waveguide_2d</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Operators and helper functions for waveguides with unchanging cross-section.</p>
|
|
<p>The propagation direction is chosen to be along the z axis, and all fields
|
|
are given an implicit z-dependence of the form <code>exp(-1 * wavenumber * z)</code>.</p>
|
|
<p>As the z-dependence is known, all the functions in this file assume a 2D grid
|
|
(i.e. <code>dxes = [[[dx_e[0], dx_e[1], ...], [dy_e[0], ...]], [[dx_h[0], ...], [dy_h[0], ...]]]</code>).</p>
|
|
<p>===============</p>
|
|
<p>Consider Maxwell's equations in continuous space, in the frequency domain. Assuming
|
|
a structure with some (x, y) cross-section extending uniformly into the z dimension,
|
|
with a diagonal <span class="arithmatex">\(\epsilon\)</span> tensor, we have</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\nabla \times \vec{E}(x, y, z) &= -\imath \omega \mu \vec{H} \\
|
|
\nabla \times \vec{H}(x, y, z) &= \imath \omega \epsilon \vec{E} \\
|
|
\vec{E}(x,y,z) &= (\vec{E}_t(x, y) + E_z(x, y)\vec{z}) e^{-\imath \beta z} \\
|
|
\vec{H}(x,y,z) &= (\vec{H}_t(x, y) + H_z(x, y)\vec{z}) e^{-\imath \beta z} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Expanding the first two equations into vector components, we get</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{xx} H_x &= \partial_y E_z - \partial_z E_y \\
|
|
-\imath \omega \mu_{yy} H_y &= \partial_z E_x - \partial_x E_z \\
|
|
-\imath \omega \mu_{zz} H_z &= \partial_x E_y - \partial_y E_x \\
|
|
\imath \omega \epsilon_{xx} E_x &= \partial_y H_z - \partial_z H_y \\
|
|
\imath \omega \epsilon_{yy} E_y &= \partial_z H_x - \partial_x H_z \\
|
|
\imath \omega \epsilon_{zz} E_z &= \partial_x H_y - \partial_y H_x \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Substituting in our expressions for <span class="arithmatex">\(\vec{E}\)</span>, <span class="arithmatex">\(\vec{H}\)</span> and discretizing:</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{xx} H_x &= \tilde{\partial}_y E_z + \imath \beta E_y \\
|
|
-\imath \omega \mu_{yy} H_y &= -\imath \beta E_x - \tilde{\partial}_x E_z \\
|
|
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_x E_y - \tilde{\partial}_y E_x \\
|
|
\imath \omega \epsilon_{xx} E_x &= \hat{\partial}_y H_z + \imath \beta H_y \\
|
|
\imath \omega \epsilon_{yy} E_y &= -\imath \beta H_x - \hat{\partial}_x H_z \\
|
|
\imath \omega \epsilon_{zz} E_z &= \hat{\partial}_x H_y - \hat{\partial}_y H_x \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Rewrite the last three equations as</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\imath \beta H_y &= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
|
|
\imath \beta H_x &= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
|
|
\imath \omega E_z &= \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y - \frac{1}{\epsilon_{zz}} \hat{\partial}_y H_x \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Now apply <span class="arithmatex">\(\imath \beta \tilde{\partial}_x\)</span> to the last equation,
|
|
then substitute in for <span class="arithmatex">\(\imath \beta H_x\)</span> and <span class="arithmatex">\(\imath \beta H_y\)</span>:</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\imath \beta \tilde{\partial}_x \imath \omega E_z &= \imath \beta \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y
|
|
- \imath \beta \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y H_x \\
|
|
&= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z)
|
|
- \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (-\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z) \\
|
|
&= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x)
|
|
- \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (-\imath \omega \epsilon_{yy} E_y) \\
|
|
\imath \beta \tilde{\partial}_x E_z &= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
|
+ \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y) \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>With a similar approach (but using <span class="arithmatex">\(\imath \beta \tilde{\partial}_y\)</span> instead), we can get</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\imath \beta \tilde{\partial}_y E_z &= \tilde{\partial}_y \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
|
+ \tilde{\partial}_y \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y) \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>We can combine this equation for <span class="arithmatex">\(\imath \beta \tilde{\partial}_y E_z\)</span> with
|
|
the unused <span class="arithmatex">\(\imath \omega \mu_{xx} H_x\)</span> and <span class="arithmatex">\(\imath \omega \mu_{yy} H_y\)</span> equations to get</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{xx} \imath \beta H_x &= -\beta^2 E_y + \imath \beta \tilde{\partial}_y E_z \\
|
|
-\imath \omega \mu_{xx} \imath \beta H_x &= -\beta^2 E_y + \tilde{\partial}_y (
|
|
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
|
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
|
)\\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>and</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{yy} \imath \beta H_y &= \beta^2 E_x - \imath \beta \tilde{\partial}_x E_z \\
|
|
-\imath \omega \mu_{yy} \imath \beta H_y &= \beta^2 E_x - \tilde{\partial}_x (
|
|
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
|
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
|
)\\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>However, based on our rewritten equation for <span class="arithmatex">\(\imath \beta H_x\)</span> and the so-far unused
|
|
equation for <span class="arithmatex">\(\imath \omega \mu_{zz} H_z\)</span> we can also write</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{xx} (\imath \beta H_x) &= -\imath \omega \mu_{xx} (-\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z) \\
|
|
&= -\omega^2 \mu_{xx} \epsilon_{yy} E_y + \imath \omega \mu_{xx} \hat{\partial}_x (
|
|
\frac{1}{-\imath \omega \mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x)) \\
|
|
&= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
|
|
-\mu_{xx} \hat{\partial}_x \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>and, similarly,</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{yy} (\imath \beta H_y) &= \omega^2 \mu_{yy} \epsilon_{xx} E_x
|
|
+\mu_{yy} \hat{\partial}_y \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>By combining both pairs of expressions, we get</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\beta^2 E_x - \tilde{\partial}_x (
|
|
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
|
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
|
) &= \omega^2 \mu_{yy} \epsilon_{xx} E_x
|
|
+\mu_{yy} \hat{\partial}_y \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
|
-\beta^2 E_y + \tilde{\partial}_y (
|
|
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
|
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
|
) &= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
|
|
-\mu_{xx} \hat{\partial}_x \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Using these, we can construct the eigenvalue problem</p>
|
|
<div class="arithmatex">\[
|
|
\beta^2 \begin{bmatrix} E_x \\
|
|
E_y \end{bmatrix} =
|
|
(\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} & 0 \\
|
|
0 & \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
|
\begin{bmatrix} -\mu_{yy} \hat{\partial}_y \\
|
|
\mu_{xx} \hat{\partial}_x \end{bmatrix} \mu_{zz}^{-1}
|
|
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
|
\begin{bmatrix} \tilde{\partial}_x \\
|
|
\tilde{\partial}_y \end{bmatrix} \epsilon_{zz}^{-1}
|
|
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} & \hat{\partial}_y \epsilon_{yy} \end{bmatrix})
|
|
\begin{bmatrix} E_x \\
|
|
E_y \end{bmatrix}
|
|
\]</div>
|
|
<p>In the literature, <span class="arithmatex">\(\beta\)</span> is usually used to denote the lossless/real part of the propagation constant,
|
|
but in <code>meanas</code> it is allowed to be complex.</p>
|
|
<p>An equivalent eigenvalue problem can be formed using the <span class="arithmatex">\(H_x\)</span> and <span class="arithmatex">\(H_y\)</span> fields, if those are more convenient.</p>
|
|
<p>Note that <span class="arithmatex">\(E_z\)</span> was never discretized, so <span class="arithmatex">\(\beta\)</span> will need adjustment to account for numerical dispersion
|
|
if the result is introduced into a space with a discretized z-axis.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.operator_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">operator_e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.operator_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">operator_e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Waveguide operator of the form</p>
|
|
<div class="highlight"><pre><span></span><code>omega**2 * mu * epsilon +
|
|
mu * [[-Dy], [Dx]] / mu * [-Dy, Dx] +
|
|
[[Dx], [Dy]] / epsilon * [Dx, Dy] * epsilon
|
|
</code></pre></div>
|
|
<p>for use with a field vector of the form <code>cat([E_x, E_y])</code>.</p>
|
|
<p>More precisely, the operator is</p>
|
|
<div class="arithmatex">\[
|
|
\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} & 0 \\
|
|
0 & \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
|
\begin{bmatrix} -\mu_{yy} \hat{\partial}_y \\
|
|
\mu_{xx} \hat{\partial}_x \end{bmatrix} \mu_{zz}^{-1}
|
|
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
|
\begin{bmatrix} \tilde{\partial}_x \\
|
|
\tilde{\partial}_y \end{bmatrix} \epsilon_{zz}^{-1}
|
|
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} & \hat{\partial}_y \epsilon_{yy} \end{bmatrix}
|
|
\]</div>
|
|
<p><span class="arithmatex">\(\tilde{\partial}_x\)</span> and <span class="arithmatex">\(\hat{\partial}_x\)</span> are the forward and backward derivatives along x,
|
|
and each <span class="arithmatex">\(\epsilon_{xx}\)</span>, <span class="arithmatex">\(\mu_{yy}\)</span>, etc. is a diagonal matrix containing the vectorized material
|
|
property distribution.</p>
|
|
<p>This operator can be used to form an eigenvalue problem of the form
|
|
<code>operator_e(...) @ [E_x, E_y] = wavenumber**2 * [E_x, E_y]</code></p>
|
|
<p>which can then be solved for the eigenmodes of the system (an <code>exp(-i * wavenumber * z)</code>
|
|
z-dependence is assumed for the fields).</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.operator_h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">operator_h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.operator_h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">operator_h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Waveguide operator of the form</p>
|
|
<div class="highlight"><pre><span></span><code>omega**2 * epsilon * mu +
|
|
epsilon * [[-Dy], [Dx]] / epsilon * [-Dy, Dx] +
|
|
[[Dx], [Dy]] / mu * [Dx, Dy] * mu
|
|
</code></pre></div>
|
|
<p>for use with a field vector of the form <code>cat([H_x, H_y])</code>.</p>
|
|
<p>More precisely, the operator is</p>
|
|
<div class="arithmatex">\[
|
|
\omega^2 \begin{bmatrix} \epsilon_{yy} \mu_{xx} & 0 \\
|
|
0 & \epsilon_{xx} \mu_{yy} \end{bmatrix} +
|
|
\begin{bmatrix} -\epsilon_{yy} \tilde{\partial}_y \\
|
|
\epsilon_{xx} \tilde{\partial}_x \end{bmatrix} \epsilon_{zz}^{-1}
|
|
\begin{bmatrix} -\hat{\partial}_y & \hat{\partial}_x \end{bmatrix} +
|
|
\begin{bmatrix} \hat{\partial}_x \\
|
|
\hat{\partial}_y \end{bmatrix} \mu_{zz}^{-1}
|
|
\begin{bmatrix} \tilde{\partial}_x \mu_{xx} & \tilde{\partial}_y \mu_{yy} \end{bmatrix}
|
|
\]</div>
|
|
<p><span class="arithmatex">\(\tilde{\partial}_x\)</span> and <span class="arithmatex">\(\hat{\partial}_x\)</span> are the forward and backward derivatives along x,
|
|
and each <span class="arithmatex">\(\epsilon_{xx}\)</span>, <span class="arithmatex">\(\mu_{yy}\)</span>, etc. is a diagonal matrix containing the vectorized material
|
|
property distribution.</p>
|
|
<p>This operator can be used to form an eigenvalue problem of the form
|
|
<code>operator_h(...) @ [H_x, H_y] = wavenumber**2 * [H_x, H_y]</code></p>
|
|
<p>which can then be solved for the eigenmodes of the system (an <code>exp(-i * wavenumber * z)</code>
|
|
z-dependence is assumed for the fields).</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">normalized_fields_e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">normalized_fields_e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_xy</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">vcfdslice_t</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given a vector <code>e_xy</code> containing the vectorized E_x and E_y fields,
|
|
returns normalized, vectorized E and H fields for the system.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e_xy</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vector containing E_x and E_y fields</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
|
|
It should satisfy <code>operator_e() @ e_xy == wavenumber**2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>prop_phase</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Phase shift <code>(dz * corrected_wavenumber)</code> over 1 cell in propagation direction.
|
|
Default 0 (continuous propagation direction, i.e. dz->0).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>0</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>(e, h)</code>, where each field is vectorized, normalized,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>and contains all three vector components.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details class="notes" open="">
|
|
<summary>Notes</summary>
|
|
<p><code>e_xy</code> is only the transverse electric eigenvector. This helper first
|
|
reconstructs the full three-component <code>E</code> and <code>H</code> fields with <code>exy2e(...)</code>
|
|
and <code>exy2h(...)</code>, then normalizes them to unit forward power using
|
|
<code>_normalized_fields(...)</code>.</p>
|
|
<p>The normalization target is</p>
|
|
<div class="arithmatex">\[
|
|
\Re\left[\mathrm{inner\_product}(e, h, \mathrm{conj\_h}=True)\right] = 1,
|
|
\]</div>
|
|
<p>so the returned fields represent a unit-power forward mode under the
|
|
discrete Yee-grid Poynting inner product.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">normalized_fields_h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">normalized_fields_h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h_xy</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">vcfdslice_t</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given a vector <code>h_xy</code> containing the vectorized H_x and H_y fields,
|
|
returns normalized, vectorized E and H fields for the system.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h_xy</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vector containing H_x and H_y fields</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
|
|
It should satisfy <code>operator_h() @ h_xy == wavenumber**2 * h_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>prop_phase</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Phase shift <code>(dz * corrected_wavenumber)</code> over 1 cell in propagation direction.
|
|
Default 0 (continuous propagation direction, i.e. dz->0).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>0</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>(e, h)</code>, where each field is vectorized, normalized,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>and contains all three vector components.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details class="notes" open="">
|
|
<summary>Notes</summary>
|
|
<p>This is the <code>H_x/H_y</code> analogue of <code>normalized_fields_e(...)</code>. The final
|
|
normalized mode should describe the same physical solution, but because
|
|
the overall complex phase and sign are chosen heuristically,
|
|
<code>normalized_fields_e(...)</code> and <code>normalized_fields_h(...)</code> need not return
|
|
identical representatives for nearly symmetric modes.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.exy2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.exy2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_x and E_y fields,
|
|
into a vectorized H containing all three H components</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
|
|
It should satisfy <code>operator_e() @ e_xy == wavenumber**2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representing the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.hxy2e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">hxy2e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.hxy2e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">hxy2e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator which transforms the vector <code>h_xy</code> containing the vectorized H_x and H_y fields,
|
|
into a vectorized E containing all three E components</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
|
|
It should satisfy <code>operator_h() @ h_xy == wavenumber**2 * h_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representing the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.hxy2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">hxy2h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.hxy2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">hxy2h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator which transforms the vector <code>h_xy</code> containing the vectorized H_x and H_y fields,
|
|
into a vectorized H containing all three H components</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
|
|
It should satisfy <code>operator_h() @ h_xy == wavenumber**2 * h_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representing the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.exy2e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.exy2e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_x and E_y fields,
|
|
into a vectorized E containing all three E components</p>
|
|
<p>From the operator derivation (see module docs), we have</p>
|
|
<div class="arithmatex">\[
|
|
\imath \omega \epsilon_{zz} E_z = \hat{\partial}_x H_y - \hat{\partial}_y H_x \\
|
|
\]</div>
|
|
<p>as well as the intermediate equations</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\imath \beta H_y &= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
|
|
\imath \beta H_x &= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Combining these, we get</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
E_z &= \frac{1}{- \omega \beta \epsilon_{zz}} ((
|
|
\hat{\partial}_y \hat{\partial}_x H_z
|
|
-\hat{\partial}_x \hat{\partial}_y H_z)
|
|
+ \imath \omega (\hat{\partial}_x \epsilon_{xx} E_x + \hat{\partial}_y \epsilon{yy} E_y))
|
|
&= \frac{1}{\imath \beta \epsilon_{zz}} (\hat{\partial}_x \epsilon_{xx} E_x + \hat{\partial}_y \epsilon{yy} E_y)
|
|
\end{aligned}
|
|
\]</div>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>
|
|
It should satisfy <code>operator_e() @ e_xy == wavenumber**2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representing the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.e2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.e2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Returns an operator which, when applied to a vectorized E eigenfield, produces
|
|
the vectorized H eigenfield slice.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.h2e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">h2e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.h2e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">h2e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Returns an operator which, when applied to a vectorized H eigenfield, produces
|
|
the vectorized E eigenfield slice.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.curl_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.curl_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Discretized curl operator for use with the waveguide E field slice.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.curl_h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.curl_h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Discretized curl operator for use with the waveguide H field slice.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.h_err">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">h_err</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.h_err" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">h_err</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculates the relative error in the H field</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized H field</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Relative error <code>norm(A_h @ h) / norm(h)</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.e_err">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_err</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.e_err" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_err</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculates the relative error in the E field</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized E field</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Relative error <code>norm(A_e @ e) / norm(e)</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.sensitivity">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">sensitivity</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.sensitivity" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">sensitivity</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_norm</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h_norm</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">vcfdslice_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given a waveguide structure (<code>dxes</code>, <code>epsilon</code>, <code>mu</code>) and mode fields
|
|
(<code>e_norm</code>, <code>h_norm</code>, <code>wavenumber</code>, <code>omega</code>), calculates the sensitivity of the wavenumber
|
|
<span class="arithmatex">\(\beta\)</span> to changes in the dielectric structure <span class="arithmatex">\(\epsilon\)</span>.</p>
|
|
<p>The output is a vector of the same size as <code>vec(epsilon)</code>, with each element specifying the
|
|
sensitivity of <code>wavenumber</code> to changes in the corresponding element in <code>vec(epsilon)</code>, i.e.</p>
|
|
<div class="arithmatex">\[ sens_{i} = \frac{\partial\beta}{\partial\epsilon_i} \]</div>
|
|
<p>An adjoint approach is used to calculate the sensitivity; the derivation is provided here:</p>
|
|
<p>Starting with the eigenvalue equation</p>
|
|
<div class="arithmatex">\[ \beta^2 E_{xy} = A_E E_{xy} \]</div>
|
|
<p>where <span class="arithmatex">\(A_E\)</span> is the waveguide operator from <code>operator_e()</code>, and <span class="arithmatex">\(E_{xy} = \begin{bmatrix} E_x \\
|
|
E_y \end{bmatrix}\)</span>,
|
|
we can differentiate with respect to one of the <span class="arithmatex">\(\epsilon\)</span> elements (i.e. at one Yee grid point), <span class="arithmatex">\(\epsilon_i\)</span>:</p>
|
|
<div class="arithmatex">\[
|
|
(2 \beta) \partial_{\epsilon_i}(\beta) E_{xy} + \beta^2 \partial_{\epsilon_i} E_{xy}
|
|
= \partial_{\epsilon_i}(A_E) E_{xy} + A_E \partial_{\epsilon_i} E_{xy}
|
|
\]</div>
|
|
<p>We then multiply by <span class="arithmatex">\(H_{yx}^\star = \begin{bmatrix}H_y^\star \\ -H_x^\star \end{bmatrix}\)</span> from the left:</p>
|
|
<div class="arithmatex">\[
|
|
(2 \beta) \partial_{\epsilon_i}(\beta) H_{yx}^\star E_{xy} + \beta^2 H_{yx}^\star \partial_{\epsilon_i} E_{xy}
|
|
= H_{yx}^\star \partial_{\epsilon_i}(A_E) E_{xy} + H_{yx}^\star A_E \partial_{\epsilon_i} E_{xy}
|
|
\]</div>
|
|
<p>However, <span class="arithmatex">\(H_{yx}^\star\)</span> is actually a left-eigenvector of <span class="arithmatex">\(A_E\)</span>. This can be verified by inspecting
|
|
the form of <code>operator_h</code> (<span class="arithmatex">\(A_H\)</span>) and comparing its conjugate transpose to <code>operator_e</code> (<span class="arithmatex">\(A_E\)</span>). Also, note
|
|
<span class="arithmatex">\(H_{yx}^\star \cdot E_{xy} = H^\star \times E\)</span> recalls the mode orthogonality relation. See doi:10.5194/ars-9-85-201
|
|
for a similar approach. Therefore,</p>
|
|
<div class="arithmatex">\[
|
|
H_{yx}^\star A_E \partial_{\epsilon_i} E_{xy} = \beta^2 H_{yx}^\star \partial_{\epsilon_i} E_{xy}
|
|
\]</div>
|
|
<p>and we can simplify to</p>
|
|
<div class="arithmatex">\[
|
|
\partial_{\epsilon_i}(\beta)
|
|
= \frac{1}{2 \beta} \frac{H_{yx}^\star \partial_{\epsilon_i}(A_E) E_{xy} }{H_{yx}^\star E_{xy}}
|
|
\]</div>
|
|
<p>This expression can be quickly calculated for all <span class="arithmatex">\(i\)</span> by writing out the various terms of
|
|
<span class="arithmatex">\(\partial_{\epsilon_i} A_E\)</span> and recognizing that the vector-matrix-vector products (i.e. scalars)
|
|
<span class="arithmatex">\(sens_i = \vec{v}_{left} \partial_{\epsilon_i} (\epsilon_{xyz}) \vec{v}_{right}\)</span>, indexed by <span class="arithmatex">\(i\)</span>, can be expressed as
|
|
elementwise multiplications <span class="arithmatex">\(\vec{sens} = \vec{v}_{left} \star \vec{v}_{right}\)</span></p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e_norm</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Normalized, vectorized E_xyz field for the mode. E.g. as returned by <code>normalized_fields_e</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h_norm</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Normalized, vectorized H_xyz field for the mode. E.g. as returned by <code>normalized_fields_e</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation constant for the mode. The z-axis is assumed to be continuous (i.e. without numerical dispersion).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.solve_modes">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_modes</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.solve_modes" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_modes</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_numbers</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mode_margin</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
|
|
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given a 2D region, attempts to solve for the eigenmode with the specified mode numbers.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mode_numbers</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of 0-indexed mode numbers to solve for</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mode_margin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The eigensolver will actually solve for <code>(max(mode_number) + mode_margin)</code>
|
|
modes, but only return the target mode. Increasing this value can improve the solver's
|
|
ability to find the correct mode. Default 2.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>2</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th> <th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td><code>e_xys</code></td> <td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>NDArray of vfdfield_t specifying fields. First dimension is mode number.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td><code>wavenumbers</code></td> <td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>list of wavenumbers</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.solve_mode">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_mode</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.solve_mode" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_mode</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_number</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdfield2_t</span><span class="p">,</span> <span class="nb">complex</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Wrapper around <code>solve_modes()</code> that solves for a single mode.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mode_number</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>0-indexed mode number to solve for</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>*args</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>passed to <code>solve_modes()</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>()</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>**kwargs</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>passed to <code>solve_modes()</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>{}</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdfield2_t" title="meanas.fdmath.vcfdfield2_t">vcfdfield2_t</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>(e_xy, wavenumber)</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.inner_product">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">inner_product</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.inner_product" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">inner_product</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e1</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h2</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">conj_h</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">trapezoid</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">complex</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Compute the discrete waveguide overlap / Poynting inner product.</p>
|
|
<p>This is the 2D transverse integral corresponding to the time-averaged
|
|
longitudinal Poynting flux,</p>
|
|
<div class="arithmatex">\[
|
|
\frac{1}{2}\int (E_x H_y - E_y H_x) \, dx \, dy
|
|
\]</div>
|
|
<p>with the Yee-grid staggering and optional propagation-phase adjustment used
|
|
by the waveguide helpers in this module.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e1</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized electric field, typically from <code>exy2e(...)</code> or
|
|
<code>normalized_fields_e(...)</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h2</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic field, typically from <code>hxy2h(...)</code>,
|
|
<code>exy2h(...)</code>, or one of the normalization helpers.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Two-dimensional Yee-grid spacing lists <code>[dx_e, dx_h]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>prop_phase</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Phase advance over one propagation cell. This is used to
|
|
shift the H field into the same longitudinal reference plane as the
|
|
E field.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>0</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>conj_h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Whether to conjugate <code>h2</code> before forming the overlap. Use
|
|
<code>True</code> for the usual time-averaged power normalization.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>False</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>trapezoid</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Whether to use trapezoidal quadrature instead of the default
|
|
rectangular Yee-cell sum.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>False</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Complex overlap / longitudinal power integral.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.waveguide_3d</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Tools for working with waveguide modes in 3D domains.</p>
|
|
<p>This module relies heavily on <code>waveguide_2d</code> and mostly just transforms
|
|
its parameters into 2D equivalents and expands the results back into 3D.</p>
|
|
<p>The intended workflow is:</p>
|
|
<ol>
|
|
<li>Select a single-cell slice normal to the propagation axis.</li>
|
|
<li>Solve the corresponding 2D mode problem with <code>solve_mode(...)</code>.</li>
|
|
<li>Turn that mode into a one-sided source with <code>compute_source(...)</code>.</li>
|
|
<li>Build an overlap window with <code>compute_overlap_e(...)</code> for port readout.</li>
|
|
</ol>
|
|
<p><code>polarity</code> is part of the public convention throughout this module:</p>
|
|
<ul>
|
|
<li><code>+1</code> means forward propagation toward increasing index along <code>axis</code></li>
|
|
<li><code>-1</code> means backward propagation toward decreasing index along <code>axis</code></li>
|
|
</ul>
|
|
<p>That same convention controls which side of the selected slice is used for the
|
|
overlap window and how the expanded field is phased.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.solve_mode">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_mode</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.solve_mode" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_mode</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_number</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">complex</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given a 3D grid, selects a slice from the grid and attempts to
|
|
solve for an eigenmode propagating through that slice.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mode_number</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Number of the mode, 0-indexed</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation axis (0=x, 1=y, 2=z)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>polarity</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>slices</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdslice">slice</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
|
|
as the waveguide cross-section. <code>slices[axis]</code> must select exactly one item.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dictionary containing:</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>E</code>: full-grid electric field for the solved mode</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>H</code>: full-grid magnetic field for the solved mode</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>wavenumber</code>: propagation constant corrected for the discretized
|
|
propagation axis</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>wavenumber_2d</code>: propagation constant of the reduced 2D eigenproblem</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details class="notes" open="">
|
|
<summary>Notes</summary>
|
|
<p>The returned fields are normalized through the <code>waveguide_2d</code>
|
|
normalization convention before being expanded back to 3D.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.compute_source">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">compute_source</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.compute_source" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">compute_source</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E</span><span class="p">:</span> <span class="n">cfdfield</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given an eigenmode obtained by <code>solve_mode</code>, returns the current source distribution
|
|
necessary to position a unidirectional source at the slice location.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>E</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field of the mode</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber of the mode</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation axis (0=x, 1=y, 2=z)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>polarity</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>slices</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdslice">slice</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
|
|
as the waveguide cross-section. <code>slices[axis]</code> should select only one item.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>J</code> distribution for a one-sided electric-current source.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details class="notes" open="">
|
|
<summary>Notes</summary>
|
|
<p>The source is built from the expanded mode field and a boundary-source
|
|
operator. The resulting current is intended to be injected with the
|
|
same sign convention used elsewhere in the package:</p>
|
|
<p><code>E -= dt * J / epsilon</code></p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.compute_overlap_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">compute_overlap_e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.compute_overlap_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">compute_overlap_e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Build an overlap field for projecting another 3D electric field onto a mode.</p>
|
|
<p>The returned field is intended for the discrete overlap expression</p>
|
|
<div class="arithmatex">\[
|
|
\sum \mathrm{overlap\_e} \; E_\mathrm{other}^*
|
|
\]</div>
|
|
<p>where the sum is over the full Yee-grid field storage.</p>
|
|
<p>The construction uses a two-cell window immediately upstream of the selected
|
|
slice:</p>
|
|
<ul>
|
|
<li>for <code>polarity=+1</code>, the two cells just before <code>slices[axis].start</code></li>
|
|
<li>for <code>polarity=-1</code>, the two cells just after <code>slices[axis].stop</code></li>
|
|
</ul>
|
|
<p>The window is clipped to the simulation domain if necessary. A clipped but
|
|
non-empty window raises <code>RuntimeWarning</code>; an empty window raises
|
|
<code>ValueError</code>.</p>
|
|
<p>The derivation below assumes reflection symmetry and the standard waveguide
|
|
overlap relation involving</p>
|
|
<div class="arithmatex">\[
|
|
\int ((E \times H_\mathrm{mode}) + (E_\mathrm{mode} \times H)) \cdot dn.
|
|
\]</div>
|
|
<p>E x H_mode + E_mode x H
|
|
-> Ex Hmy - EyHmx + Emx Hy - Emy Hx (Z-prop)
|
|
Ex we/B Emx + Ex i/B dy Hmz - Ey (-we/B Emy) - Ey i/B dx Hmz
|
|
we/B (Ex Emx + Ey Emy) + i/B (Ex dy Hmz - Ey dx Hmz)
|
|
we/B (Ex Emx + Ey Emy) + i/B (Ex dy (dx Emy - dy Emx) - Ey dx (dx Emy - dy Emx))
|
|
we/B (Ex Emx + Ey Emy) + i/B (Ex dy dx Emy - Ex dy dy Emx - Ey dx dx Emy - Ey dx dy Emx)</p>
|
|
<p>Ex j/wu (-jB Emx - dx Emz) - Ey j/wu (dy Emz + jB Emy)
|
|
B/wu (Ex Emx + Ey Emy) - j/wu (Ex dx Emz + Ey dy Emz)</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>E</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field of the mode</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber of the mode</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation axis (0=x, 1=y, 2=z)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>polarity</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>slices</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdslice">slice</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
|
|
as the waveguide cross-section. slices[axis] should select only one item.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>overlap_e</code> normalized so that <code>numpy.sum(overlap_e * E.conj()) == 1</code></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>over the retained overlap window.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.expand_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">expand_e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.expand_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">expand_e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E</span><span class="p">:</span> <span class="n">cfdfield</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given an eigenmode obtained by <code>solve_mode</code>, expands the E-field from the 2D
|
|
slice where the mode was calculated to the entire domain (along the propagation
|
|
axis). This assumes the epsilon cross-section remains constant throughout the
|
|
entire domain; it is up to the caller to truncate the expansion to any regions
|
|
where it is valid.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>E</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field of the mode</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber of the mode</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation axis (0=x, 1=y, 2=z)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>polarity</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>slices</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdslice">slice</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
|
|
as the waveguide cross-section. slices[axis] should select only one item.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>E</code>, with the original field expanded along the specified <code>axis</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details class="notes" open="">
|
|
<summary>Notes</summary>
|
|
<p>This helper assumes that the waveguide cross-section remains constant
|
|
along the propagation axis and applies the phase factor</p>
|
|
<div class="arithmatex">\[
|
|
e^{-i \, \mathrm{polarity} \, wavenumber \, \Delta z}
|
|
\]</div>
|
|
<p>to each copied slice.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.waveguide_cyl</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Operators and helper functions for cylindrical waveguides with unchanging cross-section.</p>
|
|
<p>Waveguide operator is derived according to 10.1364/OL.33.001848.</p>
|
|
<p>As in <code>waveguide_2d</code>, the propagation dependence is separated from the
|
|
transverse solve. Here the propagation coordinate is the bend angle <code>\theta</code>,
|
|
and the fields are assumed to have the form</p>
|
|
<div class="arithmatex">\[
|
|
\vec{E}(r, y, \theta), \vec{H}(r, y, \theta) \propto e^{-\imath m \theta},
|
|
\]</div>
|
|
<p>where <code>m</code> is the angular wavenumber returned by <code>solve_mode(s)</code>. It is often
|
|
convenient to introduce the corresponding linear wavenumber</p>
|
|
<div class="arithmatex">\[
|
|
\beta = \frac{m}{r_{\min}},
|
|
\]</div>
|
|
<p>so that the cylindrical problem resembles the straight-waveguide problem with
|
|
additional metric factors.</p>
|
|
<p>Those metric factors live on the staggered radial Yee grids. If the left edge of
|
|
the computational window is at <code>r = r_{\min}</code>, define the electric-grid and
|
|
magnetic-grid radial sample locations by</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
r_a(n) &= r_{\min} + \sum_{j \le n} \Delta r_{e, j}, \\
|
|
r_b\!\left(n + \tfrac{1}{2}\right) &= r_{\min} + \tfrac{1}{2}\Delta r_{e, n}
|
|
+ \sum_{j < n} \Delta r_{h, j},
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>and from them the diagonal metric matrices</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
T_a &= \operatorname{diag}(r_a / r_{\min}), \\
|
|
T_b &= \operatorname{diag}(r_b / r_{\min}).
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>With the same forward/backward derivative notation used in <code>waveguide_2d</code>, the
|
|
coordinate-transformed discrete curl equations used here are</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{rr} H_r &= \tilde{\partial}_y E_z + \imath \beta T_a^{-1} E_y, \\
|
|
-\imath \omega \mu_{yy} H_y &= -\imath \beta T_b^{-1} E_r
|
|
- T_b^{-1} \tilde{\partial}_r (T_a E_z), \\
|
|
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_r E_y - \tilde{\partial}_y E_r, \\
|
|
\imath \beta H_y &= -\imath \omega T_b \epsilon_{rr} E_r - T_b \hat{\partial}_y H_z, \\
|
|
\imath \beta H_r &= \imath \omega T_a \epsilon_{yy} E_y
|
|
- T_b T_a^{-1} \hat{\partial}_r (T_b H_z), \\
|
|
\imath \omega E_z &= T_a \epsilon_{zz}^{-1}
|
|
\left(\hat{\partial}_r H_y - \hat{\partial}_y H_r\right).
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>The first three equations are the cylindrical analogue of the straight-guide
|
|
relations for <code>H_r</code>, <code>H_y</code>, and <code>H_z</code>. The next two are the metric-weighted
|
|
versions of the straight-guide identities for <code>\imath \beta H_y</code> and
|
|
<code>\imath \beta H_r</code>, and the last equation plays the same role as the
|
|
longitudinal <code>E_z</code> reconstruction in <code>waveguide_2d</code>.</p>
|
|
<p>Following the same elimination steps as in <code>waveguide_2d</code>, apply
|
|
<code>\imath \beta \tilde{\partial}_r</code> and <code>\imath \beta \tilde{\partial}_y</code> to the
|
|
equation for <code>E_z</code>, substitute for <code>\imath \beta H_r</code> and <code>\imath \beta H_y</code>,
|
|
and then eliminate <code>H_z</code> with</p>
|
|
<div class="arithmatex">\[
|
|
H_z = \frac{1}{-\imath \omega \mu_{zz}}
|
|
\left(\tilde{\partial}_r E_y - \tilde{\partial}_y E_r\right).
|
|
\]</div>
|
|
<p>This yields the transverse electric eigenproblem implemented by
|
|
<code>cylindrical_operator(...)</code>:</p>
|
|
<div class="arithmatex">\[
|
|
\beta^2
|
|
\begin{bmatrix} E_r \\ E_y \end{bmatrix}
|
|
=
|
|
\left(
|
|
\omega^2
|
|
\begin{bmatrix}
|
|
T_b^2 \mu_{yy} \epsilon_{xx} & 0 \\
|
|
0 & T_a^2 \mu_{xx} \epsilon_{yy}
|
|
\end{bmatrix}
|
|
+
|
|
\begin{bmatrix}
|
|
-T_b \mu_{yy} \hat{\partial}_y \\
|
|
T_a \mu_{xx} \hat{\partial}_x
|
|
\end{bmatrix}
|
|
T_b \mu_{zz}^{-1}
|
|
\begin{bmatrix}
|
|
-\tilde{\partial}_y & \tilde{\partial}_x
|
|
\end{bmatrix}
|
|
+
|
|
\begin{bmatrix}
|
|
\tilde{\partial}_x \\
|
|
\tilde{\partial}_y
|
|
\end{bmatrix}
|
|
T_a \epsilon_{zz}^{-1}
|
|
\begin{bmatrix}
|
|
\hat{\partial}_x T_b \epsilon_{xx} &
|
|
\hat{\partial}_y T_a \epsilon_{yy}
|
|
\end{bmatrix}
|
|
\right)
|
|
\begin{bmatrix} E_r \\ E_y \end{bmatrix}.
|
|
\]</div>
|
|
<p>Since <code>\beta = m / r_{\min}</code>, the solver implemented in this file returns the
|
|
angular wavenumber <code>m</code>, while the operator itself is most naturally written in
|
|
terms of the linear quantity <code>\beta</code>. The helpers below reconstruct the full
|
|
field components from the solved transverse eigenvector and then normalize the
|
|
mode to unit forward power with the same discrete longitudinal Poynting inner
|
|
product used by <code>waveguide_2d</code>.</p>
|
|
<p>As in the straight-waveguide case, all functions here assume a 2D grid:</p>
|
|
<p><code>dxes = [[[dr_e_0, dr_e_1, ...], [dy_e_0, ...]], [[dr_h_0, ...], [dy_h_0, ...]]]</code>.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.cylindrical_operator">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">cylindrical_operator</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.cylindrical_operator" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">cylindrical_operator</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Cylindrical coordinate waveguide operator of the form</p>
|
|
<div class="arithmatex">\[
|
|
(\omega^2 \begin{bmatrix} T_b T_b \mu_{yy} \epsilon_{xx} & 0 \\
|
|
0 & T_a T_a \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
|
\begin{bmatrix} -T_b \mu_{yy} \hat{\partial}_y \\
|
|
T_a \mu_{xx} \hat{\partial}_x \end{bmatrix} T_b \mu_{zz}^{-1}
|
|
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
|
\begin{bmatrix} \tilde{\partial}_x \\
|
|
\tilde{\partial}_y \end{bmatrix} T_a \epsilon_{zz}^{-1}
|
|
\begin{bmatrix} \hat{\partial}_x T_b \epsilon_{xx} & \hat{\partial}_y T_a \epsilon_{yy} \end{bmatrix})
|
|
\begin{bmatrix} E_r \\
|
|
E_y \end{bmatrix}
|
|
\]</div>
|
|
<p>for use with a field vector of the form <code>[E_r, E_y]</code>.</p>
|
|
<p>This operator can be used to form an eigenvalue problem of the form
|
|
A @ [E_r, E_y] = beta**2 * [E_r, E_y]</p>
|
|
<p>which can then be solved for the eigenmodes of the system
|
|
(an <code>exp(-i * angular_wavenumber * theta)</code> theta-dependence is assumed for
|
|
the fields, with <code>beta = angular_wavenumber / rmin</code>).</p>
|
|
<p>(NOTE: See module docs and 10.1364/OL.33.001848)</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.solve_modes">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_modes</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.solve_modes" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_modes</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_numbers</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mode_margin</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
|
|
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given a 2d (r, y) slice of epsilon, attempts to solve for the eigenmode
|
|
of the bent waveguide with the specified mode number.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mode_numbers</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Mode numbers to solve, 0-indexed.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Angular frequency of the simulation</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters [dx_e, dx_h] as described in meanas.fdmath.types.
|
|
The first coordinate is assumed to be r, the second is y.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius of curvature for the simulation. This should be the minimum value of
|
|
r within the simulation domain.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th> <th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td><code>e_xys</code></td> <td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>NDArray of vfdfield_t specifying fields. First dimension is mode number.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td><code>angular_wavenumbers</code></td> <td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>list of wavenumbers in 1/rad units.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.solve_mode">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_mode</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.solve_mode" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_mode</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_number</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice</span><span class="p">,</span> <span class="nb">complex</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Wrapper around <code>solve_modes()</code> that solves for a single mode.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mode_number</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>0-indexed mode number to solve for</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>*args</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>passed to <code>solve_modes()</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>()</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>**kwargs</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>passed to <code>solve_modes()</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>{}</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>(e_xy, angular_wavenumber)</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.linear_wavenumbers">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">linear_wavenumbers</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.linear_wavenumbers" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">linear_wavenumbers</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_xys</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">vcfdfield2_t</span><span class="p">],</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">angular_wavenumbers</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculate linear wavenumbers (1/distance) based on angular wavenumbers (1/rad)
|
|
and the mode's energy distribution.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e_xys</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdfield2_t" title="meanas.fdmath.vcfdfield2_t">vcfdfield2_t</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized mode fields with shape (num_modes, 2 * x *y)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>angular_wavenumbers</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumbers assuming fields have theta-dependence of
|
|
<code>exp(-i * angular_wavenumber * theta)</code>. They should satisfy
|
|
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid with shape (3, x, y)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>NDArray containing the calculated linear (1/distance) wavenumbers</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.exy2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.exy2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_r and E_y fields,
|
|
into a vectorized H containing all three H components</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>angular_wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have theta-dependence of
|
|
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
|
|
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representing the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.exy2e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.exy2e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_r and E_y fields,
|
|
into a vectorized E containing all three E components</p>
|
|
<p>Unlike the straight waveguide case, the H_z components do not cancel and must be calculated
|
|
from E_r and E_y in order to then calculate E_z.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>angular_wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have theta-dependence of
|
|
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
|
|
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representing the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.e2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.e2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Returns an operator which, when applied to a vectorized E eigenfield, produces
|
|
the vectorized H eigenfield.</p>
|
|
<p>This operator is created directly from the initial coordinate-transformed equations:</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
-\imath \omega \mu_{rr} H_r &= \tilde{\partial}_y E_z + \imath \beta T_a^{-1} E_y, \\
|
|
-\imath \omega \mu_{yy} H_y &= -\imath \beta T_b^{-1} E_r
|
|
- T_b^{-1} \tilde{\partial}_r (T_a E_z), \\
|
|
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_r E_y - \tilde{\partial}_y E_r,
|
|
\end{aligned}
|
|
\]</div>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>angular_wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have theta-dependence of
|
|
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
|
|
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix representation of the operator.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.dxes2T">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">dxes2T</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.dxes2T" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">dxes2T</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">]]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Construct the cylindrical metric matrices <span class="arithmatex">\(T_a\)</span> and <span class="arithmatex">\(T_b\)</span>.</p>
|
|
<p><code>T_a</code> is sampled on the E-grid radial locations, while <code>T_b</code> is sampled on
|
|
the staggered H-grid radial locations. These are the diagonal matrices that
|
|
convert the straight-waveguide algebra into its cylindrical counterpart.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>], <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse diagonal matrices <code>(T_a, T_b)</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.normalized_fields_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">normalized_fields_e</span>
|
|
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.normalized_fields_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">normalized_fields_e</span><span class="p">(</span>
|
|
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_xy</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">vcfdslice_t</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Given a vector <code>e_xy</code> containing the vectorized E_r and E_y fields,
|
|
returns normalized, vectorized E and H fields for the system.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e_xy</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vector containing E_r and E_y fields</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>angular_wavenumber</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Wavenumber assuming fields have theta-dependence of
|
|
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
|
|
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>omega</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The angular frequency of the system</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>rmin</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized dielectric constant grid</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>prop_phase</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Phase shift <code>(dz * corrected_wavenumber)</code> over 1 cell in propagation direction.
|
|
Default 0 (continuous propagation direction, i.e. dz->0).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>0</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>(e, h)</code>, where each field is vectorized, normalized,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>and contains all three vector components.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details class="notes" open="">
|
|
<summary>Notes</summary>
|
|
<p>The normalization step is delegated to <code>_normalized_fields(...)</code>, which
|
|
enforces unit forward power under the discrete inner product</p>
|
|
<div class="arithmatex">\[
|
|
\frac{1}{2}\int (E_r H_y^* - E_y H_r^*) \, dr \, dy.
|
|
\]</div>
|
|
<p>The angular wavenumber <code>m</code> is first converted into the full three-component
|
|
fields, then the overall complex phase and sign are fixed so the result is
|
|
reproducible for symmetric modes.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div></section><section class="print-page" heading-number="2.6" id="api-fdtd"><h1 id="api-fdtd-fdtd">fdtd<a class="headerlink" href="#api-fdtd-fdtd" title="Permanent link">¶</a></h1>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Utilities for running finite-difference time-domain (FDTD) simulations</p>
|
|
<p>See the discussion of <code>Maxwell's Equations</code> in <code>meanas.fdmath</code> for basic
|
|
mathematical background.</p>
|
|
<h3 id="api-fdtd-meanas.fdtd--timestep">Timestep<a class="headerlink" href="#api-fdtd-meanas.fdtd--timestep" title="Permanent link">¶</a></h3>
|
|
<p>From the discussion of "Plane waves and the Dispersion relation" in <code>meanas.fdmath</code>,
|
|
we have</p>
|
|
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} < 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
|
|
<p>or, if <span class="arithmatex">\(\Delta_x = \Delta_y = \Delta_z\)</span>, then <span class="arithmatex">\(c \Delta_t < \frac{\Delta_x}{\sqrt{3}}\)</span>.</p>
|
|
<p>Based on this, we can set</p>
|
|
<div class="highlight"><pre><span></span><code>dt = sqrt(mu.min() * epsilon.min()) / sqrt(1/dx_min**2 + 1/dy_min**2 + 1/dz_min**2)
|
|
</code></pre></div>
|
|
<p>The <code>dx_min</code>, <code>dy_min</code>, <code>dz_min</code> should be the minimum value across both the base and derived grids.</p>
|
|
<h3 id="api-fdtd-meanas.fdtd--poynting-vector-and-energy-conservation">Poynting Vector and Energy Conservation<a class="headerlink" href="#api-fdtd-meanas.fdtd--poynting-vector-and-energy-conservation" title="Permanent link">¶</a></h3>
|
|
<p>Let</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{S}_{l, l', \vec{r}} &=& &\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}} \\
|
|
&=& &\vec{x} (\tilde{E}^y_{l,m+1,n,p} \hat{H}^z_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^z_{l,m+1,n,p} \hat{H}^y_{l', \vec{r} + \frac{1}{2}}) \\
|
|
& &+ &\vec{y} (\tilde{E}^z_{l,m,n+1,p} \hat{H}^x_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^x_{l,m,n+1,p} \hat{H}^z_{l', \vec{r} + \frac{1}{2}}) \\
|
|
& &+ &\vec{z} (\tilde{E}^x_{l,m,n,p+1} \hat{H}^y_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^y_{l,m,n,p+1} \hat{H}^z_{l', \vec{r} + \frac{1}{2}})
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>where <span class="arithmatex">\(\vec{r} = (m, n, p)\)</span> and <span class="arithmatex">\(\otimes\)</span> is a modified cross product
|
|
in which the <span class="arithmatex">\(\tilde{E}\)</span> terms are shifted as indicated.</p>
|
|
<p>By taking the divergence and rearranging terms, we can show that</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\hat{\nabla} \cdot \tilde{S}_{l, l', \vec{r}}
|
|
&= \hat{\nabla} \cdot (\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}}) \\
|
|
&= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l, \vec{r}} -
|
|
\tilde{E}_{l, \vec{r}} \cdot \hat{\nabla} \times \hat{H}_{l', \vec{r} + \frac{1}{2}} \\
|
|
&= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot
|
|
(-\tilde{\partial}_t \mu_{\vec{r} + \frac{1}{2}} \hat{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} -
|
|
\hat{M}_{l, \vec{r} + \frac{1}{2}}) -
|
|
\tilde{E}_{l, \vec{r}} \cdot (\hat{\partial}_t \tilde{\epsilon}_{\vec{r}} \tilde{E}_{l'+\frac{1}{2}, \vec{r}} +
|
|
\tilde{J}_{l', \vec{r}}) \\
|
|
&= \hat{H}_{l'} \cdot (-\mu / \Delta_t)(\hat{H}_{l + \frac{1}{2}} - \hat{H}_{l - \frac{1}{2}}) -
|
|
\tilde{E}_l \cdot (\epsilon / \Delta_t )(\tilde{E}_{l'+\frac{1}{2}} - \tilde{E}_{l'-\frac{1}{2}})
|
|
- \hat{H}_{l'} \cdot \hat{M}_{l} - \tilde{E}_l \cdot \tilde{J}_{l'} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>where in the last line the spatial subscripts have been dropped to emphasize
|
|
the time subscripts <span class="arithmatex">\(l, l'\)</span>, i.e.</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{E}_l &= \tilde{E}_{l, \vec{r}} \\
|
|
\hat{H}_l &= \tilde{H}_{l, \vec{r} + \frac{1}{2}} \\
|
|
\tilde{\epsilon} &= \tilde{\epsilon}_{\vec{r}} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>etc.
|
|
For <span class="arithmatex">\(l' = l + \frac{1}{2}\)</span> we get</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}}
|
|
&= \hat{H}_{l + \frac{1}{2}} \cdot
|
|
(-\mu / \Delta_t)(\hat{H}_{l + \frac{1}{2}} - \hat{H}_{l - \frac{1}{2}}) -
|
|
\tilde{E}_l \cdot (\epsilon / \Delta_t)(\tilde{E}_{l+1} - \tilde{E}_l)
|
|
- \hat{H}_{l'} \cdot \hat{M}_l - \tilde{E}_l \cdot \tilde{J}_{l + \frac{1}{2}} \\
|
|
&= (-\mu / \Delta_t)(\hat{H}^2_{l + \frac{1}{2}} - \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}) -
|
|
(\epsilon / \Delta_t)(\tilde{E}_{l+1} \cdot \tilde{E}_l - \tilde{E}^2_l)
|
|
- \hat{H}_{l'} \cdot \hat{M}_l - \tilde{E}_l \cdot \tilde{J}_{l + \frac{1}{2}} \\
|
|
&= -(\mu \hat{H}^2_{l + \frac{1}{2}}
|
|
+\epsilon \tilde{E}_{l+1} \cdot \tilde{E}_l) / \Delta_t \\
|
|
+(\mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}
|
|
+\epsilon \tilde{E}^2_l) / \Delta_t \\
|
|
- \hat{H}_{l+\frac{1}{2}} \cdot \hat{M}_l \\
|
|
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>and for <span class="arithmatex">\(l' = l - \frac{1}{2}\)</span>,</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}}
|
|
&= (\mu \hat{H}^2_{l - \frac{1}{2}}
|
|
+\epsilon \tilde{E}_{l-1} \cdot \tilde{E}_l) / \Delta_t \\
|
|
-(\mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}
|
|
+\epsilon \tilde{E}^2_l) / \Delta_t \\
|
|
- \hat{H}_{l-\frac{1}{2}} \cdot \hat{M}_l \\
|
|
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>These two results form the discrete time-domain analogue to Poynting's theorem.
|
|
They hint at the expressions for the energy, which can be calculated at the same
|
|
time-index as either the E or H field:</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
U_l &= \epsilon \tilde{E}^2_l + \mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}} \\
|
|
U_{l + \frac{1}{2}} &= \epsilon \tilde{E}_l \cdot \tilde{E}_{l + 1} + \mu \hat{H}^2_{l + \frac{1}{2}} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>Rewriting the Poynting theorem in terms of the energy expressions,</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
(U_{l+\frac{1}{2}} - U_l) / \Delta_t
|
|
&= -\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}} \\
|
|
- \hat{H}_{l+\frac{1}{2}} \cdot \hat{M}_l \\
|
|
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
|
|
(U_l - U_{l-\frac{1}{2}}) / \Delta_t
|
|
&= -\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}} \\
|
|
- \hat{H}_{l-\frac{1}{2}} \cdot \hat{M}_l \\
|
|
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>This result is exact and should practically hold to within numerical precision. No time-
|
|
or spatial-averaging is necessary.</p>
|
|
<p>Note that each value of <span class="arithmatex">\(J\)</span> contributes to the energy twice (i.e. once per field update)
|
|
despite only causing the value of <span class="arithmatex">\(E\)</span> to change once (same for <span class="arithmatex">\(M\)</span> and <span class="arithmatex">\(H\)</span>).</p>
|
|
<h3 id="api-fdtd-meanas.fdtd--sources">Sources<a class="headerlink" href="#api-fdtd-meanas.fdtd--sources" title="Permanent link">¶</a></h3>
|
|
<p>It is often useful to excite the simulation with an arbitrary broadband pulse and then
|
|
extract the frequency-domain response by performing an on-the-fly Fourier transform
|
|
of the time-domain fields.</p>
|
|
<p><code>accumulate_phasor</code> in <code>meanas.fdtd.phasor</code> performs the phase accumulation for one
|
|
or more target frequencies, while leaving source normalization and simulation-loop
|
|
policy to the caller. <code>temporal_phasor(...)</code> and <code>temporal_phasor_scale(...)</code>
|
|
apply the same Fourier sum to a scalar waveform, which is useful when a pulsed
|
|
source envelope must be normalized before being applied to a point source or
|
|
mode source. <code>real_injection_scale(...)</code> is the corresponding helper for the
|
|
common real-valued injection pattern <code>numpy.real(scale * waveform)</code>. Convenience
|
|
wrappers <code>accumulate_phasor_e</code>, <code>accumulate_phasor_h</code>, and <code>accumulate_phasor_j</code>
|
|
apply the usual Yee time offsets. <code>reconstruct_real(...)</code> and the corresponding
|
|
<code>reconstruct_real_e/h/j(...)</code> wrappers perform the inverse operation, converting
|
|
phasors back into real-valued field snapshots at explicit Yee-aligned times.
|
|
For scalar <code>omega</code>, the reconstruction helpers accept either a plain field
|
|
phasor or the batched <code>(1, *sample_shape)</code> form used by the accumulator helpers.
|
|
The helpers accumulate</p>
|
|
<div class="arithmatex">\[ \Delta_t \sum_l w_l e^{-i \omega t_l} f_l \]</div>
|
|
<p>with caller-provided sample times and weights. In this codebase the matching
|
|
electric-current convention is typically <code>E -= dt * J / epsilon</code> in FDTD and
|
|
<code>-i \omega J</code> on the right-hand side of the FDFD wave equation.</p>
|
|
<p>For FDTD/FDFD equivalence, this phasor path is the primary comparison workflow.
|
|
It isolates the guided <code>+\omega</code> response that the frequency-domain solver
|
|
targets directly, regardless of whether the underlying FDTD run used real- or
|
|
complex-valued fields.</p>
|
|
<p>For exact pulsed FDTD/FDFD equivalence it is often simplest to keep the
|
|
injected source, fields, and CPML auxiliary state complex-valued. The
|
|
<code>real_injection_scale(...)</code> helper is instead for the more ordinary one-run
|
|
real-valued source path, where the intended positive-frequency waveform is
|
|
injected through <code>numpy.real(scale * waveform)</code> and any remaining negative-
|
|
frequency leakage is controlled by the pulse bandwidth and run length.</p>
|
|
<p><code>reconstruct_real(...)</code> is for a different question: given a phasor, what late
|
|
real-valued field snapshot should it produce? That raw-snapshot comparison is
|
|
stricter and noisier because a monitor plane generally contains both the guided
|
|
field and the remaining orthogonal content,</p>
|
|
<div class="arithmatex">\[ E_{\text{monitor}} = E_{\text{guided}} + E_{\text{residual}} . \]</div>
|
|
<p>Phasor/modal comparisons mostly validate the guided <code>+\omega</code> term. Raw
|
|
real-field comparisons expose both terms at once, so they should be treated as
|
|
secondary diagnostics rather than the main solver-equivalence benchmark.</p>
|
|
<p>The Ricker wavelet (normalized second derivative of a Gaussian) is commonly used for the pulse
|
|
shape. It can be written</p>
|
|
<div class="arithmatex">\[ f_r(t) = (1 - \frac{1}{2} (\omega (t - \tau))^2) e^{-(\frac{\omega (t - \tau)}{2})^2} \]</div>
|
|
<p>with <span class="arithmatex">\(\tau > \frac{2 * \pi}{\omega}\)</span> as a minimum delay to avoid a discontinuity at
|
|
t=0 (assuming the source is off for t<0 this gives <span class="arithmatex">\(\sim 10^{-3}\)</span> error at t=0).</p>
|
|
<h3 id="api-fdtd-meanas.fdtd--boundary-conditions">Boundary conditions<a class="headerlink" href="#api-fdtd-meanas.fdtd--boundary-conditions" title="Permanent link">¶</a></h3>
|
|
<p><code>meanas.fdtd</code> exposes two boundary-related building blocks:</p>
|
|
<ul>
|
|
<li><code>conducting_boundary(...)</code> for simple perfect-electric-conductor style field
|
|
clamping at one face of the domain.</li>
|
|
<li><code>cpml_params(...)</code> and <code>updates_with_cpml(...)</code> for convolutional perfectly
|
|
matched layers (CPMLs) attached to one or more faces of the Yee grid.</li>
|
|
</ul>
|
|
<p><code>updates_with_cpml(...)</code> accepts a three-by-two table of CPML parameter blocks:</p>
|
|
<div class="highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>cpml_params[axis][polarity_index]
|
|
</code></pre></div>
|
|
<p>where <code>axis</code> is <code>0</code>, <code>1</code>, or <code>2</code> and <code>polarity_index</code> corresponds to <code>(-1, +1)</code>.
|
|
Passing <code>None</code> for one entry disables CPML on that face while leaving the other
|
|
directions unchanged. This is how mixed boundary setups such as "absorbing in x,
|
|
periodic in y/z" are expressed.</p>
|
|
<p>When comparing an FDTD run against an FDFD solve, use the same stretched
|
|
coordinate system in both places:</p>
|
|
<ol>
|
|
<li>Build the FDTD update with the desired CPML parameters.</li>
|
|
<li>Stretch the FDFD <code>dxes</code> with the matching SCPML transform.</li>
|
|
<li>Compare the extracted phasor against the FDFD field or residual on those
|
|
stretched <code>dxes</code>.</li>
|
|
</ol>
|
|
<p>The electric-current sign convention used throughout the examples and tests is</p>
|
|
<div class="arithmatex">\[
|
|
E \leftarrow E - \Delta_t J / \epsilon
|
|
\]</div>
|
|
<p>which matches the FDFD right-hand side</p>
|
|
<div class="arithmatex">\[
|
|
-i \omega J.
|
|
\]</div>
|
|
<div class="doc doc-children">
|
|
</div>
|
|
</div>
|
|
</div><h2 id="core-update-and-analysis-helpers">Core update and analysis helpers<a class="headerlink" href="#api-fdtd-core-update-and-analysis-helpers" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.base">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.base</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.base" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Basic FDTD field updates</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.base.maxwell_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">maxwell_e</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.base.maxwell_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">maxwell_e</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_updater_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Build a function which performs a portion the time-domain E-field update,</p>
|
|
<div class="highlight"><pre><span></span><code>E += curl_back(H[t]) / epsilon
|
|
</code></pre></div>
|
|
<p>The full update should be</p>
|
|
<div class="highlight"><pre><span></span><code>E += (curl_back(H[t]) + J) / epsilon
|
|
</code></pre></div>
|
|
<p>which requires an additional step of <code>E += J / epsilon</code> which is not performed
|
|
by the generated function.</p>
|
|
<p>See <code>meanas.fdmath</code> for descriptions of</p>
|
|
<ul>
|
|
<li>This update step: "Maxwell's equations" section</li>
|
|
<li><code>dxes</code>: "Datastructure: dx_lists_t" section</li>
|
|
<li><code>epsilon</code>: "Permittivity and Permeability" section</li>
|
|
</ul>
|
|
<p>Also see the "Timestep" section of <code>meanas.fdtd</code> for a discussion of
|
|
the <code>dt</code> parameter.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dt</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Timestep. See <code>meanas.fdtd</code> for details.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; see <code>meanas.fdmath</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.fdfield_updater_t)">fdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f(E_old, H_old, epsilon) -> E_new</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.base.maxwell_h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">maxwell_h</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.base.maxwell_h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">maxwell_h</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_updater_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Build a function which performs part of the time-domain H-field update,</p>
|
|
<div class="highlight"><pre><span></span><code>H -= curl_forward(E[t]) / mu
|
|
</code></pre></div>
|
|
<p>The full update should be</p>
|
|
<div class="highlight"><pre><span></span><code>H -= (curl_forward(E[t]) + M) / mu
|
|
</code></pre></div>
|
|
<p>which requires an additional step of <code>H -= M / mu</code> which is not performed
|
|
by the generated function; this step can be omitted if there is no magnetic
|
|
current <code>M</code>.</p>
|
|
<p>See <code>meanas.fdmath</code> for descriptions of</p>
|
|
<ul>
|
|
<li>This update step: "Maxwell's equations" section</li>
|
|
<li><code>dxes</code>: "Datastructure: dx_lists_t" section</li>
|
|
<li><code>mu</code>: "Permittivity and Permeability" section</li>
|
|
</ul>
|
|
<p>Also see the "Timestep" section of <code>meanas.fdtd</code> for a discussion of
|
|
the <code>dt</code> parameter.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dt</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Timestep. See <code>meanas.fdtd</code> for details.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; see <code>meanas.fdmath</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.fdfield_updater_t)">fdfield_updater_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f(E_old, H_old, epsilon) -> E_new</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.pml">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.pml</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.pml" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Convolutional perfectly matched layer (CPML) support for FDTD updates.</p>
|
|
<p>The helpers in this module construct per-face CPML parameters and then wrap the
|
|
standard Yee updates with the additional auxiliary <code>psi</code> fields needed by the
|
|
CPML recurrence.</p>
|
|
<p>The intended call pattern is:</p>
|
|
<ol>
|
|
<li>Build a <code>cpml_params[axis][polarity_index]</code> table with <code>cpml_params(...)</code>.</li>
|
|
<li>Pass that table into <code>updates_with_cpml(...)</code> together with <code>dt</code>, <code>dxes</code>, and
|
|
<code>epsilon</code>.</li>
|
|
<li>Advance the returned <code>update_E</code> / <code>update_H</code> closures in the simulation loop.</li>
|
|
</ol>
|
|
<p>Each face can be enabled or disabled independently by replacing one table entry
|
|
with <code>None</code>.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.pml.cpml_params">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">cpml_params</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.pml.cpml_params" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">cpml_params</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">thickness</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">8</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">ln_R_per_layer</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.6</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon_eff</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu_eff</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">m</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">3.5</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">ma</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">cfs_alpha</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Construct the parameter block for one CPML face.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Which Cartesian axis the CPML is normal to (<code>0</code>, <code>1</code>, or <code>2</code>).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>polarity</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Which face along that axis (<code>-1</code> for the low-index face,
|
|
<code>+1</code> for the high-index face).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dt</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Timestep used by the Yee update.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>thickness</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Number of Yee cells occupied by the CPML region.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>8</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>ln_R_per_layer</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Logarithmic attenuation target per layer.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>-1.6</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon_eff</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Effective permittivity used when choosing the CPML scaling.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu_eff</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Effective permeability used when choosing the CPML scaling.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>m</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Polynomial grading exponent for <code>sigma</code> and <code>kappa</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>3.5</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>ma</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Polynomial grading exponent for the complex-frequency shift <code>alpha</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>cfs_alpha</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Maximum complex-frequency shift parameter.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>0</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dictionary with:</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>param_e</code>: <code>(p0, p1, p2)</code> arrays for the E update</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>param_h</code>: <code>(p0, p1, p2)</code> arrays for the H update</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>region</code>: slice tuple selecting the CPML cells on that face</li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.pml.updates_with_cpml">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">updates_with_cpml</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.pml.updates_with_cpml" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">updates_with_cpml</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">cpml_params</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">Sequence</span><span class="p">[</span><span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span><span class="p">]],</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dtype</span><span class="p">:</span> <span class="n">DTypeLike</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">float32</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">Callable</span><span class="p">[[</span><span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">],</span> <span class="kc">None</span><span class="p">],</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">Callable</span><span class="p">[[</span><span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">],</span> <span class="kc">None</span><span class="p">],</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Build Yee-step update closures augmented with CPML terms.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>cpml_params</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>] | None]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Three-by-two sequence indexed as <code>[axis][polarity_index]</code>.
|
|
Entries are the dictionaries returned by <code>cpml_params(...)</code>; use
|
|
<code>None</code> to disable CPML on one face.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dt</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Timestep.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Yee-grid spacing lists <code>[dx_e, dx_h]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Electric material distribution used by the E update.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dtype</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.typing.DTypeLike" title="numpy.typing.DTypeLike">DTypeLike</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Storage dtype for the auxiliary CPML state arrays.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#numpy.float32" title="numpy.float32">float32</a></code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>(update_E, update_H)</code> closures with the same call shape as the basic</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Yee updates:</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None], <a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>update_E(e, h, epsilon)</code></li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None], <a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<ul>
|
|
<li><code>update_H(e, h, mu)</code></li>
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None], <a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>The closures retain the CPML auxiliary state internally.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.boundaries">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.boundaries</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.boundaries" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Boundary conditions</p>
|
|
<h3 id="api-fdtd-meanas.fdtd.boundaries--todo-conducting-boundary-documentation">TODO conducting boundary documentation<a class="headerlink" href="#api-fdtd-meanas.fdtd.boundaries--todo-conducting-boundary-documentation" title="Permanent link">¶</a></h3>
|
|
<div class="doc doc-children">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.energy</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.poynting">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.poynting" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">h</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculate the poynting vector <code>S</code> (<span class="arithmatex">\(S\)</span>).</p>
|
|
<p>This is the energy transfer rate (amount of energy <code>U</code> per <code>dt</code> transferred
|
|
between adjacent cells) in each direction that happens during the half-step
|
|
bounded by the two provided fields.</p>
|
|
<p>The returned vector field <code>S</code> is the energy flow across +x, +y, and +z
|
|
boundaries of the corresponding <code>U</code> cell. For example,</p>
|
|
<div class="highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a> mx = numpy.roll(mask, -1, axis=0)
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> my = numpy.roll(mask, -1, axis=1)
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> mz = numpy.roll(mask, -1, axis=2)
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> u_hstep = fdtd.energy_hstep(e0=es[ii - 1], h1=hs[ii], e2=es[ii], **args)
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> u_estep = fdtd.energy_estep(h0=hs[ii], e1=es[ii], h2=hs[ii + 1], **args)
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> delta_j_B = fdtd.delta_energy_j(j0=js[ii], e1=es[ii], dxes=dxes)
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> du_half_h2e = u_estep - u_hstep - delta_j_B
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> s_h2e = -fdtd.poynting(e=es[ii], h=hs[ii], dxes=dxes) * dt
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> planes = [s_h2e[0, mask].sum(), -s_h2e[0, mx].sum(),
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> s_h2e[1, mask].sum(), -s_h2e[1, my].sum(),
|
|
<a href="#api-fdtd-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> s_h2e[2, mask].sum(), -s_h2e[2, mz].sum()]
|
|
<a href="#api-fdtd-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a>
|
|
<a href="#api-fdtd-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> assert_close(sum(planes), du_half_h2e[mask])
|
|
</code></pre></div>
|
|
<p>(see <code>meanas.tests.test_fdtd.test_poynting_planes</code>)</p>
|
|
<p>The full relationship is</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
(U_{l+\frac{1}{2}} - U_l) / \Delta_t
|
|
&= -\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}} \\
|
|
- \hat{H}_{l+\frac{1}{2}} \cdot \hat{M}_l \\
|
|
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
|
|
(U_l - U_{l-\frac{1}{2}}) / \Delta_t
|
|
&= -\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}} \\
|
|
- \hat{H}_{l-\frac{1}{2}} \cdot \hat{M}_l \\
|
|
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>These equalities are exact and should practically hold to within numerical precision.
|
|
No time- or spatial-averaging is necessary. (See <code>meanas.fdtd</code> docs for derivation.)</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field (one half-timestep before or after <code>e</code>)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; see <code>meanas.fdmath</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th> <th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td><code>s</code></td> <td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vector field. Components indicate the energy transfer rate from the
|
|
corresponding energy cell into its +x, +y, and +z neighbors during
|
|
the half-step from the time of the earlier input field until the
|
|
time of later input field.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.poynting_divergence">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_divergence</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.poynting_divergence" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_divergence</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">s</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">e</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">h</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculate the divergence of the poynting vector.</p>
|
|
<p>This is the net energy flow for each cell, i.e. the change in energy <code>U</code>
|
|
per <code>dt</code> caused by transfer of energy to nearby cells (rather than
|
|
absorption/emission by currents <code>J</code> or <code>M</code>).</p>
|
|
<p>See <code>poynting</code> and <code>meanas.fdtd</code> for more details.
|
|
Args:
|
|
s: Poynting vector, as calculated with <code>poynting</code>. Optional; caller
|
|
can provide <code>e</code> and <code>h</code> instead.
|
|
e: E-field (optional; need either <code>s</code> or both <code>e</code> and <code>h</code>)
|
|
h: H-field (optional; need either <code>s</code> or both <code>e</code> and <code>h</code>)
|
|
dxes: Grid description; see <code>meanas.fdmath</code>.</p>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th> <th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td><code>ds</code></td> <td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Divergence of the poynting vector.
|
|
Entries indicate the net energy flow out of the corresponding
|
|
energy cell.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.energy_hstep">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">energy_hstep</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.energy_hstep" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">energy_hstep</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">e2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculate energy <code>U</code> at the time of the provided H-field <code>h1</code>.</p>
|
|
<p>TODO: Figure out what this means spatially.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e0</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field one half-timestep before the energy.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h1</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field (at the same timestep as the energy).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e2</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field one half-timestep after the energy.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; see <code>meanas.fdmath</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Energy, at the time of the H-field <code>h1</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.energy_estep">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">energy_estep</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.energy_estep" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">energy_estep</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">e1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">h2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculate energy <code>U</code> at the time of the provided E-field <code>e1</code>.</p>
|
|
<p>TODO: Figure out what this means spatially.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h0</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field one half-timestep before the energy.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e1</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field (at the same timestep as the energy).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h2</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field one half-timestep after the energy.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; see <code>meanas.fdmath</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Energy, at the time of the E-field <code>e1</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.delta_energy_h2e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">delta_energy_h2e</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.delta_energy_h2e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">delta_energy_h2e</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">e0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">h1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">e2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">h3</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Change in energy during the half-step from <code>h1</code> to <code>e2</code>.</p>
|
|
<p>This is just from (e2 * e2 + h3 * h1) - (h1 * h1 + e0 * e2)</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e0</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field one half-timestep before the start of the energy delta.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h1</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field at the start of the energy delta.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e2</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field at the end of the energy delta (one half-timestep after <code>h1</code>).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h3</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field one half-timestep after the end of the energy delta.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; see <code>meanas.fdmath</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Change in energy from the time of <code>h1</code> to the time of <code>e2</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.delta_energy_e2h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">delta_energy_e2h</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.delta_energy_e2h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">delta_energy_e2h</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">e1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">h2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">e3</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Change in energy during the half-step from <code>e1</code> to <code>h2</code>.</p>
|
|
<p>This is just from (h2 * h2 + e3 * e1) - (e1 * e1 + h0 * h2)</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h0</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field one half-timestep before the start of the energy delta.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e1</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field at the start of the energy delta.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>h2</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>E-field at the end of the energy delta (one half-timestep after <code>e1</code>).</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e3</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>H-field one half-timestep after the end of the energy delta.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Dielectric constant distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic permeability distribution.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; see <code>meanas.fdmath</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Change in energy from the time of <code>e1</code> to the time of <code>h2</code>.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.delta_energy_j">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">delta_energy_j</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.delta_energy_j" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">delta_energy_j</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">j0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">e1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Calculate the electric-current work term <span class="arithmatex">\(J \cdot E\)</span> on the Yee grid.</p>
|
|
<p>This is the source contribution that appears beside the flux divergence in
|
|
the discrete Poynting identities documented in <code>meanas.fdtd</code>.</p>
|
|
<p>Note that each value of <code>J</code> contributes twice in a full Yee cycle (once per
|
|
half-step energy balance) even though it directly changes <code>E</code> only once.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>j0</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Electric-current density sampled at the same half-step as the
|
|
current work term.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>e1</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Electric field sampled at the matching integer timestep.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; defaults to unit spacing.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Per-cell source-work contribution with the scalar field shape.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.dxmul">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">dxmul</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.dxmul" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">dxmul</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">ee</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">hh</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="nb">float</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="nb">float</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Multiply E- and H-like field products by material weights and cell volumes.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>ee</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Three-component electric-field product, such as <code>e0 * e2</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>hh</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Three-component magnetic-field product, such as <code>h1 * h1</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>epsilon</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | <a class="autorefs autorefs-internal" href="#float">float</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Electric material weight; defaults to <code>1</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>mu</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | <a class="autorefs autorefs-internal" href="#float">float</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Magnetic material weight; defaults to <code>1</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dxes</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Grid description; defaults to unit spacing.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Scalar field containing the weighted electric plus magnetic contribution</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>for each Yee cell.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.phasor</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Helpers for extracting single- or multi-frequency phasors from FDTD samples.</p>
|
|
<p>These helpers are intentionally low-level: callers own the accumulator arrays and
|
|
the sampling policy. The accumulated quantity is</p>
|
|
<div class="highlight"><pre><span></span><code>dt * sum(weight * exp(-1j * omega * t_step) * sample_step)
|
|
</code></pre></div>
|
|
<p>where <code>t_step = (step + offset_steps) * dt</code>.</p>
|
|
<p>The usual Yee offsets are:</p>
|
|
<ul>
|
|
<li><code>accumulate_phasor_e(..., step=l)</code> for <code>E_l</code></li>
|
|
<li><code>accumulate_phasor_h(..., step=l)</code> for <code>H_{l + 1/2}</code></li>
|
|
<li><code>accumulate_phasor_j(..., step=l)</code> for <code>J_{l + 1/2}</code></li>
|
|
</ul>
|
|
<p><code>temporal_phasor(...)</code> and <code>temporal_phasor_scale(...)</code> apply the same Fourier
|
|
sum to a 1D scalar waveform. They are useful for normalizing a pulsed source
|
|
before that scalar waveform is applied to a point source or spatial mode source.
|
|
<code>real_injection_scale(...)</code> is a companion helper for the common real-valued
|
|
injection pattern <code>numpy.real(scale * waveform)</code>, where <code>waveform</code> is the
|
|
analytic positive-frequency signal and the injected real current should still
|
|
produce a desired phasor response.
|
|
<code>reconstruct_real(...)</code> and its <code>E/H/J</code> wrappers perform the inverse operation:
|
|
they turn one or more phasors back into real-valued field snapshots at explicit
|
|
Yee-aligned sample times. For a scalar target frequency they accept either a
|
|
plain field phasor or the batched <code>(1, *sample_shape)</code> form used elsewhere in
|
|
this module.</p>
|
|
<p>These helpers do not choose warmup/accumulation windows or pulse-envelope
|
|
normalization. They also do not impose a current sign convention. In this
|
|
codebase, electric-current injection normally appears as <code>E -= dt * J / epsilon</code>,
|
|
which matches the FDFD right-hand side <code>-1j * omega * J</code>.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Add one time-domain sample into a phasor accumulator.</p>
|
|
<p>The added quantity is</p>
|
|
<div class="highlight"><pre><span></span><code>dt * weight * exp(-1j * omega * t_step) * sample
|
|
</code></pre></div>
|
|
<p>where <code>t_step = (step + offset_steps) * dt</code>.</p>
|
|
<details class="note" open="">
|
|
<summary>Note</summary>
|
|
<p>This helper already multiplies by <code>dt</code>. If the caller's normalization
|
|
factor was derived from a discrete sum that already includes <code>dt</code>, pass
|
|
<code>weight / dt</code> here.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.temporal_phasor">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">temporal_phasor</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.temporal_phasor" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">temporal_phasor</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">samples</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">start_step</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Fourier-project a 1D temporal waveform onto one or more angular frequencies.</p>
|
|
<p>The returned quantity is</p>
|
|
<div class="highlight"><pre><span></span><code>dt * sum(exp(-1j * omega * t_step) * samples[step_index])
|
|
</code></pre></div>
|
|
<p>where <code>t_step = (start_step + step_index + offset_steps) * dt</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.temporal_phasor_scale">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">temporal_phasor_scale</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.temporal_phasor_scale" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">temporal_phasor_scale</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">samples</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">start_step</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">target</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Return the scalar multiplier that gives a desired temporal phasor response.</p>
|
|
<p>The returned scale satisfies</p>
|
|
<div class="highlight"><pre><span></span><code>temporal_phasor(scale * samples, omegas, dt, ...) == target
|
|
</code></pre></div>
|
|
<p>for each target frequency. The result keeps a leading frequency axis even
|
|
when <code>omegas</code> is scalar.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.real_injection_scale">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">real_injection_scale</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.real_injection_scale" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">real_injection_scale</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">samples</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">start_step</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">target</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Return the scale for a real-valued injection built from an analytic waveform.</p>
|
|
<p>If the time-domain source is applied as</p>
|
|
<div class="highlight"><pre><span></span><code>numpy.real(scale * samples[step])
|
|
</code></pre></div>
|
|
<p>then the desired positive-frequency phasor is obtained by compensating for
|
|
the 1/2 factor between the real-valued source and its analytic component:</p>
|
|
<div class="highlight"><pre><span></span><code>scale = 2 * target / temporal_phasor(samples, ...)
|
|
</code></pre></div>
|
|
<p>This helper normalizes only the intended positive-frequency component. Any
|
|
residual negative-frequency leakage is controlled by the waveform design and
|
|
the accumulation window.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.reconstruct_real">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.reconstruct_real" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">reconstruct_real</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Reconstruct a real-valued field snapshot from one or more phasors.</p>
|
|
<p>The returned quantity is</p>
|
|
<div class="highlight"><pre><span></span><code>real(phasor * exp(1j * omega * t_step))
|
|
</code></pre></div>
|
|
<p>where <code>t_step = (step + offset_steps) * dt</code>.</p>
|
|
<p>For multi-frequency inputs, the leading frequency axis is preserved. For a
|
|
scalar <code>omega</code>, callers may pass either <code>(1, *sample_shape)</code> or
|
|
<code>sample_shape</code>; the return shape matches that choice.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor_e</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor_e</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Accumulate an E-field sample taken at integer timestep <code>step</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor_h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor_h</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor_h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor_h</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Accumulate an H-field sample corresponding to <code>H_{step + 1/2}</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor_j">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor_j</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor_j" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor_j</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Accumulate a current sample corresponding to <code>J_{step + 1/2}</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.reconstruct_real_e">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real_e</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.reconstruct_real_e" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">reconstruct_real_e</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Reconstruct a real E-field snapshot taken at integer timestep <code>step</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.reconstruct_real_h">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real_h</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.reconstruct_real_h" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">reconstruct_real_h</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Reconstruct a real H-field snapshot corresponding to <code>H_{step + 1/2}</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.reconstruct_real_j">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real_j</span>
|
|
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.reconstruct_real_j" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">reconstruct_real_j</span><span class="p">(</span>
|
|
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
|
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
|
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
|
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
|
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Reconstruct a real current snapshot corresponding to <code>J_{step + 1/2}</code>.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div></section><section class="print-page" heading-number="2.7" id="api-fdmath"><h1 id="api-fdmath-fdmath">fdmath<a class="headerlink" href="#api-fdmath-fdmath" title="Permanent link">¶</a></h1>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Basic discrete calculus for finite difference (fd) simulations.</p>
|
|
<h3 id="api-fdmath-meanas.fdmath--fields-functions-and-operators">Fields, Functions, and Operators<a class="headerlink" href="#api-fdmath-meanas.fdmath--fields-functions-and-operators" title="Permanent link">¶</a></h3>
|
|
<p>Discrete fields are stored in one of two forms:</p>
|
|
<ul>
|
|
<li>The <code>fdfield_t</code> form is a multidimensional <code>numpy.NDArray</code><ul>
|
|
<li>For a scalar field, this is just <code>U[m, n, p]</code>, where <code>m</code>, <code>n</code>, and <code>p</code> are
|
|
discrete indices referring to positions on the x, y, and z axes respectively.</li>
|
|
<li>For a vector field, the first index specifies which vector component is accessed:
|
|
<code>E[:, m, n, p] = [Ex[m, n, p], Ey[m, n, p], Ez[m, n, p]]</code>.</li>
|
|
</ul>
|
|
</li>
|
|
<li>The <code>vfdfield_t</code> form is simply a vectorzied (i.e. 1D) version of the <code>fdfield_t</code>,
|
|
as obtained by <code>meanas.fdmath.vectorization.vec</code> (effectively just <code>numpy.ravel</code>)</li>
|
|
</ul>
|
|
<details class="operators-which-act-on-fields-also-come-in-two-forms" open="">
|
|
<summary>Operators which act on fields also come in two forms</summary>
|
|
<ul>
|
|
<li>Python functions, created by the functions in <code>meanas.fdmath.functional</code>.
|
|
The generated functions act on fields in the <code>fdfield_t</code> form.</li>
|
|
<li>Linear operators, usually 2D sparse matrices using <code>scipy.sparse</code>, created
|
|
by <code>meanas.fdmath.operators</code>. These operators act on vectorized fields in the
|
|
<code>vfdfield_t</code> form.</li>
|
|
</ul>
|
|
</details> <p>The operations performed should be equivalent: <code>functional.op(*args)(E)</code> should be
|
|
equivalent to <code>unvec(operators.op(*args) @ vec(E), E.shape[1:])</code>.</p>
|
|
<p>Generally speaking the <code>field_t</code> form is easier to work with, but can be harder or less
|
|
efficient to compose (e.g. it is easy to generate a single matrix by multiplying a
|
|
series of other matrices).</p>
|
|
<h3 id="api-fdmath-meanas.fdmath--discrete-calculus">Discrete calculus<a class="headerlink" href="#api-fdmath-meanas.fdmath--discrete-calculus" title="Permanent link">¶</a></h3>
|
|
<p>This documentation and approach is roughly based on W.C. Chew's excellent
|
|
"Electromagnetic Theory on a Lattice" (doi:10.1063/1.355770),
|
|
which covers a superset of this material with similar notation and more detail.</p>
|
|
<h4 id="api-fdmath-meanas.fdmath--scalar-derivatives-and-cell-shifts">Scalar derivatives and cell shifts<a class="headerlink" href="#api-fdmath-meanas.fdmath--scalar-derivatives-and-cell-shifts" title="Permanent link">¶</a></h4>
|
|
<p>Define the discrete forward derivative as
|
|
|
|
<div class="arithmatex">\[ [\tilde{\partial}_x f]_{m + \frac{1}{2}} = \frac{1}{\Delta_{x, m}} (f_{m + 1} - f_m) \]</div></p>
|
|
<p>where <span class="arithmatex">\(f\)</span> is a function defined at discrete locations on the x-axis (labeled using <span class="arithmatex">\(m\)</span>).
|
|
The value at <span class="arithmatex">\(m\)</span> occupies a length <span class="arithmatex">\(\Delta_{x, m}\)</span> along the x-axis. Note that <span class="arithmatex">\(m\)</span>
|
|
is an index along the x-axis, <em>not</em> necessarily an x-coordinate, since each length
|
|
<span class="arithmatex">\(\Delta_{x, m}, \Delta_{x, m+1}, ...\)</span> is independently chosen.</p>
|
|
<p>If we treat <code>f</code> as a 1D array of values, with the <code>i</code>-th value <code>f[i]</code> taking up a length <code>dx[i]</code>
|
|
along the x-axis, the forward derivative is</p>
|
|
<div class="highlight"><pre><span></span><code>deriv_forward(f)[i] = (f[i + 1] - f[i]) / dx[i]
|
|
</code></pre></div>
|
|
<p>Likewise, discrete reverse derivative is
|
|
|
|
<div class="arithmatex">\[ [\hat{\partial}_x f ]_{m - \frac{1}{2}} = \frac{1}{\Delta_{x, m}} (f_{m} - f_{m - 1}) \]</div></p>
|
|
<p>or</p>
|
|
<div class="highlight"><pre><span></span><code>deriv_back(f)[i] = (f[i] - f[i - 1]) / dx[i]
|
|
</code></pre></div>
|
|
<p>The derivatives' values are shifted by a half-cell relative to the original function, and
|
|
will have different cell widths if all the <code>dx[i]</code> ( <span class="arithmatex">\(\Delta_{x, m}\)</span> ) are not
|
|
identical:</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: derivatives and cell sizes]
|
|
dx0 dx1 dx2 dx3 cell sizes for function
|
|
----- ----- ----------- -----
|
|
______________________________
|
|
| | | |
|
|
f0 | f1 | f2 | f3 | function
|
|
_____|_____|___________|_____|
|
|
| | | |
|
|
| Df0 | Df1 | Df2 | Df3 forward derivative (periodic boundary)
|
|
__|_____|________|________|___
|
|
|
|
dx'3] dx'0 dx'1 dx'2 [dx'3 cell sizes for forward derivative
|
|
-- ----- -------- -------- ---
|
|
dx'0] dx'1 dx'2 dx'3 [dx'0 cell sizes for reverse derivative
|
|
______________________________
|
|
| | | |
|
|
| df1 | df2 | df3 | df0 reverse derivative (periodic boundary)
|
|
__|_____|________|________|___
|
|
|
|
Periodic boundaries are used here and elsewhere unless otherwise noted.
|
|
</code></pre></div>
|
|
<p>In the above figure,
|
|
<code>f0 =</code> <span class="arithmatex">\(f_0\)</span>, <code>f1 =</code> <span class="arithmatex">\(f_1\)</span>
|
|
<code>Df0 =</code> <span class="arithmatex">\([\tilde{\partial}f]_{0 + \frac{1}{2}}\)</span>
|
|
<code>Df1 =</code> <span class="arithmatex">\([\tilde{\partial}f]_{1 + \frac{1}{2}}\)</span>
|
|
<code>df0 =</code> <span class="arithmatex">\([\hat{\partial}f]_{0 - \frac{1}{2}}\)</span>
|
|
etc.</p>
|
|
<p>The fractional subscript <span class="arithmatex">\(m + \frac{1}{2}\)</span> is used to indicate values defined
|
|
at shifted locations relative to the original <span class="arithmatex">\(m\)</span>, with corresponding lengths
|
|
|
|
<div class="arithmatex">\[ \Delta_{x, m + \frac{1}{2}} = \frac{1}{2} * (\Delta_{x, m} + \Delta_{x, m + 1}) \]</div>
|
|
</p>
|
|
<p>Just as <span class="arithmatex">\(m\)</span> is not itself an x-coordinate, neither is <span class="arithmatex">\(m + \frac{1}{2}\)</span>;
|
|
carefully note the positions of the various cells in the above figure vs their labels.
|
|
If the positions labeled with <span class="arithmatex">\(m\)</span> are considered the "base" or "original" grid,
|
|
the positions labeled with <span class="arithmatex">\(m + \frac{1}{2}\)</span> are said to lie on a "dual" or
|
|
"derived" grid.</p>
|
|
<p>For the remainder of the <code>Discrete calculus</code> section, all figures will show
|
|
constant-length cells in order to focus on the vector derivatives themselves.
|
|
See the <code>Grid description</code> section below for additional information on this topic
|
|
and generalization to three dimensions.</p>
|
|
<h4 id="api-fdmath-meanas.fdmath--gradients-and-fore-vectors">Gradients and fore-vectors<a class="headerlink" href="#api-fdmath-meanas.fdmath--gradients-and-fore-vectors" title="Permanent link">¶</a></h4>
|
|
<p>Expanding to three dimensions, we can define two gradients
|
|
<br/>
|
|
<div class="arithmatex">\[
|
|
[\tilde{\nabla} f]_{m,n,p} = \vec{x} [\tilde{\partial}_x f]_{m + \frac{1}{2},n,p} +
|
|
\vec{y} [\tilde{\partial}_y f]_{m,n + \frac{1}{2},p} +
|
|
\vec{z} [\tilde{\partial}_z f]_{m,n,p + \frac{1}{2}}
|
|
\]</div></p>
|
|
<div class="arithmatex">\[
|
|
[\hat{\nabla} f]_{m,n,p} = \vec{x} [\hat{\partial}_x f]_{m + \frac{1}{2},n,p} +
|
|
\vec{y} [\hat{\partial}_y f]_{m,n + \frac{1}{2},p} +
|
|
\vec{z} [\hat{\partial}_z f]_{m,n,p + \frac{1}{2}}
|
|
\]</div>
|
|
<p>or</p>
|
|
<div class="highlight"><pre><span></span><code>[code: gradients]
|
|
grad_forward(f)[i,j,k] = [Dx_forward(f)[i, j, k],
|
|
Dy_forward(f)[i, j, k],
|
|
Dz_forward(f)[i, j, k]]
|
|
= [(f[i + 1, j, k] - f[i, j, k]) / dx[i],
|
|
(f[i, j + 1, k] - f[i, j, k]) / dy[i],
|
|
(f[i, j, k + 1] - f[i, j, k]) / dz[i]]
|
|
|
|
grad_back(f)[i,j,k] = [Dx_back(f)[i, j, k],
|
|
Dy_back(f)[i, j, k],
|
|
Dz_back(f)[i, j, k]]
|
|
= [(f[i, j, k] - f[i - 1, j, k]) / dx[i],
|
|
(f[i, j, k] - f[i, j - 1, k]) / dy[i],
|
|
(f[i, j, k] - f[i, j, k - 1]) / dz[i]]
|
|
</code></pre></div>
|
|
<p>The three derivatives in the gradient cause shifts in different
|
|
directions, so the x/y/z components of the resulting "vector" are defined
|
|
at different points: the x-component is shifted in the x-direction,
|
|
y in y, and z in z.</p>
|
|
<p>We call the resulting object a "fore-vector" or "back-vector", depending
|
|
on the direction of the shift. We write it as
|
|
<br/>
|
|
<div class="arithmatex">\[
|
|
\tilde{g}_{m,n,p} = \vec{x} g^x_{m + \frac{1}{2},n,p} +
|
|
\vec{y} g^y_{m,n + \frac{1}{2},p} +
|
|
\vec{z} g^z_{m,n,p + \frac{1}{2}}
|
|
\]</div></p>
|
|
<div class="arithmatex">\[
|
|
\hat{g}_{m,n,p} = \vec{x} g^x_{m - \frac{1}{2},n,p} +
|
|
\vec{y} g^y_{m,n - \frac{1}{2},p} +
|
|
\vec{z} g^z_{m,n,p - \frac{1}{2}}
|
|
\]</div>
|
|
<div class="highlight"><pre><span></span><code>[figure: gradient / fore-vector]
|
|
(m, n+1, p+1) ______________ (m+1, n+1, p+1)
|
|
/: /|
|
|
/ : / |
|
|
/ : / |
|
|
(m, n, p+1)/_____________/ | The forward derivatives are defined
|
|
| : | | at the Dx, Dy, Dz points,
|
|
| :.........|...| but the forward-gradient fore-vector
|
|
z y Dz / | / is the set of all three
|
|
|/_x | Dy | / and is said to be "located" at (m,n,p)
|
|
|/ |/
|
|
(m, n, p)|_____Dx______| (m+1, n, p)
|
|
</code></pre></div>
|
|
<h4 id="api-fdmath-meanas.fdmath--divergences">Divergences<a class="headerlink" href="#api-fdmath-meanas.fdmath--divergences" title="Permanent link">¶</a></h4>
|
|
<p>There are also two divergences,</p>
|
|
<div class="arithmatex">\[
|
|
d_{n,m,p} = [\tilde{\nabla} \cdot \hat{g}]_{n,m,p}
|
|
= [\tilde{\partial}_x g^x]_{m,n,p} +
|
|
[\tilde{\partial}_y g^y]_{m,n,p} +
|
|
[\tilde{\partial}_z g^z]_{m,n,p}
|
|
\]</div>
|
|
<div class="arithmatex">\[
|
|
d_{n,m,p} = [\hat{\nabla} \cdot \tilde{g}]_{n,m,p}
|
|
= [\hat{\partial}_x g^x]_{m,n,p} +
|
|
[\hat{\partial}_y g^y]_{m,n,p} +
|
|
[\hat{\partial}_z g^z]_{m,n,p}
|
|
\]</div>
|
|
<p>or</p>
|
|
<div class="highlight"><pre><span></span><code>[code: divergences]
|
|
div_forward(g)[i,j,k] = Dx_forward(gx)[i, j, k] +
|
|
Dy_forward(gy)[i, j, k] +
|
|
Dz_forward(gz)[i, j, k]
|
|
= (gx[i + 1, j, k] - gx[i, j, k]) / dx[i] +
|
|
(gy[i, j + 1, k] - gy[i, j, k]) / dy[i] +
|
|
(gz[i, j, k + 1] - gz[i, j, k]) / dz[i]
|
|
|
|
div_back(g)[i,j,k] = Dx_back(gx)[i, j, k] +
|
|
Dy_back(gy)[i, j, k] +
|
|
Dz_back(gz)[i, j, k]
|
|
= (gx[i, j, k] - gx[i - 1, j, k]) / dx[i] +
|
|
(gy[i, j, k] - gy[i, j - 1, k]) / dy[i] +
|
|
(gz[i, j, k] - gz[i, j, k - 1]) / dz[i]
|
|
</code></pre></div>
|
|
<p>where <code>g = [gx, gy, gz]</code> is a fore- or back-vector field.</p>
|
|
<p>Since we applied the forward divergence to the back-vector (and vice-versa), the resulting scalar value
|
|
is defined at the back-vector's (fore-vector's) location <span class="arithmatex">\((m,n,p)\)</span> and not at the locations of its components
|
|
<span class="arithmatex">\((m \pm \frac{1}{2},n,p)\)</span> etc.</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: divergence]
|
|
^^
|
|
(m-1/2, n+1/2, p+1/2) _____||_______ (m+1/2, n+1/2, p+1/2)
|
|
/: || ,, /|
|
|
/ : || // / | The divergence at (m, n, p) (the center
|
|
/ : // / | of this cube) of a fore-vector field
|
|
(m-1/2, n-1/2, p+1/2)/_____________/ | is the sum of the outward-pointing
|
|
| : | | fore-vector components, which are
|
|
z y <==|== :.........|.====> located at the face centers.
|
|
|/_x | / | /
|
|
| / // | / Note that in a nonuniform grid, each
|
|
|/ // || |/ dimension is normalized by the cell width.
|
|
(m-1/2, n-1/2, p-1/2)|____//_______| (m+1/2, n-1/2, p-1/2)
|
|
'' ||
|
|
VV
|
|
</code></pre></div>
|
|
<h4 id="api-fdmath-meanas.fdmath--curls">Curls<a class="headerlink" href="#api-fdmath-meanas.fdmath--curls" title="Permanent link">¶</a></h4>
|
|
<p>The two curls are then</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\hat{h}_{m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2}} &= \\
|
|
[\tilde{\nabla} \times \tilde{g}]_{m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2}} &=
|
|
\vec{x} (\tilde{\partial}_y g^z_{m,n,p + \frac{1}{2}} - \tilde{\partial}_z g^y_{m,n + \frac{1}{2},p}) \\
|
|
&+ \vec{y} (\tilde{\partial}_z g^x_{m + \frac{1}{2},n,p} - \tilde{\partial}_x g^z_{m,n,p + \frac{1}{2}}) \\
|
|
&+ \vec{z} (\tilde{\partial}_x g^y_{m,n + \frac{1}{2},p} - \tilde{\partial}_y g^z_{m + \frac{1}{2},n,p})
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>and</p>
|
|
<div class="arithmatex">\[
|
|
\tilde{h}_{m - \frac{1}{2}, n - \frac{1}{2}, p - \frac{1}{2}} =
|
|
[\hat{\nabla} \times \hat{g}]_{m - \frac{1}{2}, n - \frac{1}{2}, p - \frac{1}{2}}
|
|
\]</div>
|
|
<p>where <span class="arithmatex">\(\hat{g}\)</span> and <span class="arithmatex">\(\tilde{g}\)</span> are located at <span class="arithmatex">\((m,n,p)\)</span>
|
|
with components at <span class="arithmatex">\((m \pm \frac{1}{2},n,p)\)</span> etc.,
|
|
while <span class="arithmatex">\(\hat{h}\)</span> and <span class="arithmatex">\(\tilde{h}\)</span> are located at <span class="arithmatex">\((m \pm \frac{1}{2}, n \pm \frac{1}{2}, p \pm \frac{1}{2})\)</span>
|
|
with components at <span class="arithmatex">\((m, n \pm \frac{1}{2}, p \pm \frac{1}{2})\)</span> etc.</p>
|
|
<div class="highlight"><pre><span></span><code>[code: curls]
|
|
curl_forward(g)[i,j,k] = [Dy_forward(gz)[i, j, k] - Dz_forward(gy)[i, j, k],
|
|
Dz_forward(gx)[i, j, k] - Dx_forward(gz)[i, j, k],
|
|
Dx_forward(gy)[i, j, k] - Dy_forward(gx)[i, j, k]]
|
|
|
|
curl_back(g)[i,j,k] = [Dy_back(gz)[i, j, k] - Dz_back(gy)[i, j, k],
|
|
Dz_back(gx)[i, j, k] - Dx_back(gz)[i, j, k],
|
|
Dx_back(gy)[i, j, k] - Dy_back(gx)[i, j, k]]
|
|
</code></pre></div>
|
|
<p>For example, consider the forward curl, at (m, n, p), of a back-vector field <code>g</code>, defined
|
|
on a grid containing (m + 1/2, n + 1/2, p + 1/2).
|
|
The curl will be a fore-vector, so its z-component will be defined at (m, n, p + 1/2).
|
|
Take the nearest x- and y-components of <code>g</code> in the xy plane where the curl's z-component
|
|
is located; these are</p>
|
|
<div class="highlight"><pre><span></span><code>[curl components]
|
|
(m, n + 1/2, p + 1/2) : x-component of back-vector at (m + 1/2, n + 1/2, p + 1/2)
|
|
(m + 1, n + 1/2, p + 1/2) : x-component of back-vector at (m + 3/2, n + 1/2, p + 1/2)
|
|
(m + 1/2, n , p + 1/2) : y-component of back-vector at (m + 1/2, n + 1/2, p + 1/2)
|
|
(m + 1/2, n + 1 , p + 1/2) : y-component of back-vector at (m + 1/2, n + 3/2, p + 1/2)
|
|
</code></pre></div>
|
|
<p>These four xy-components can be used to form a loop around the curl's z-component; its magnitude and sign
|
|
is set by their loop-oriented sum (i.e. two have their signs flipped to complete the loop).</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: z-component of curl]
|
|
: |
|
|
z y : ^^ |
|
|
|/_x :....||.<.....| (m+1, n+1, p+1/2)
|
|
/ || /
|
|
| v || | ^
|
|
|/ |/
|
|
(m, n, p+1/2) |_____>______| (m+1, n, p+1/2)
|
|
</code></pre></div>
|
|
<h3 id="api-fdmath-meanas.fdmath--maxwells-equations">Maxwell's Equations<a class="headerlink" href="#api-fdmath-meanas.fdmath--maxwells-equations" title="Permanent link">¶</a></h3>
|
|
<p>If we discretize both space (m,n,p) and time (l), Maxwell's equations become</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &= -\tilde{\partial}_t \hat{B}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}
|
|
- \hat{M}_{l, \vec{r} + \frac{1}{2}} \\
|
|
\hat{\nabla} \times \hat{H}_{l-\frac{1}{2},\vec{r} + \frac{1}{2}} &= \hat{\partial}_t \tilde{D}_{l, \vec{r}}
|
|
+ \tilde{J}_{l-\frac{1}{2},\vec{r}} \\
|
|
\tilde{\nabla} \cdot \hat{B}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} &= 0 \\
|
|
\hat{\nabla} \cdot \tilde{D}_{l,\vec{r}} &= \rho_{l,\vec{r}}
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>with</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\hat{B}_{\vec{r}} &= \mu_{\vec{r} + \frac{1}{2}} \cdot \hat{H}_{\vec{r} + \frac{1}{2}} \\
|
|
\tilde{D}_{\vec{r}} &= \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}}
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>where the spatial subscripts are abbreviated as <span class="arithmatex">\(\vec{r} = (m, n, p)\)</span> and
|
|
<span class="arithmatex">\(\vec{r} + \frac{1}{2} = (m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2})\)</span>,
|
|
<span class="arithmatex">\(\tilde{E}\)</span> and <span class="arithmatex">\(\hat{H}\)</span> are the electric and magnetic fields,
|
|
<span class="arithmatex">\(\tilde{J}\)</span> and <span class="arithmatex">\(\hat{M}\)</span> are the electric and magnetic current distributions,
|
|
and <span class="arithmatex">\(\epsilon\)</span> and <span class="arithmatex">\(\mu\)</span> are the dielectric permittivity and magnetic permeability.</p>
|
|
<p>The above is Yee's algorithm, written in a form analogous to Maxwell's equations.
|
|
The time derivatives can be expanded to form the update equations:</p>
|
|
<div class="highlight"><pre><span></span><code>[code: Maxwell's equations updates]
|
|
H[i, j, k] -= dt * (curl_forward(E)[i, j, k] + M[t, i, j, k]) / mu[i, j, k]
|
|
E[i, j, k] += dt * (curl_back( H)[i, j, k] + J[t, i, j, k]) / epsilon[i, j, k]
|
|
</code></pre></div>
|
|
<p>Note that the E-field fore-vector and H-field back-vector are offset by a half-cell, resulting
|
|
in distinct locations for all six E- and H-field components:</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: Field components]
|
|
|
|
(m - 1/2,=> ____________Hx__________[H] <= r + 1/2 = (m + 1/2,
|
|
n + 1/2, /: /: /| n + 1/2,
|
|
z y p + 1/2) / : / : / | p + 1/2)
|
|
|/_x / : / : / |
|
|
/ : Ez__________Hy | Locations of the E- and
|
|
/ : : : /| | H-field components for the
|
|
(m - 1/2, / : : Ey...../.|..Hz [E] fore-vector at r = (m,n,p)
|
|
n - 1/2, =>/________________________/ | /| (the large cube's center)
|
|
p + 1/2) | : : / | | / | and [H] back-vector at r + 1/2
|
|
| : :/ | |/ | (the top right corner)
|
|
| : [E].......|.Ex |
|
|
| :.................|......| <= (m + 1/2, n + 1/2, p + 1/2)
|
|
| / | /
|
|
| / | /
|
|
| / | / This is the Yee discretization
|
|
| / | / scheme ("Yee cell").
|
|
r - 1/2 = | / | /
|
|
(m - 1/2, |/ |/
|
|
n - 1/2,=> |________________________| <= (m + 1/2, n - 1/2, p - 1/2)
|
|
p - 1/2)
|
|
</code></pre></div>
|
|
<p>Each component forms its own grid, offset from the others:</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: E-fields for adjacent cells]
|
|
|
|
H1__________Hx0_________H0
|
|
z y /: /|
|
|
|/_x / : / | This figure shows H back-vector locations
|
|
/ : / | H0, H1, etc. and their associated components
|
|
Hy1 : Hy0 | H0 = (Hx0, Hy0, Hz0) etc.
|
|
/ : / |
|
|
/ Hz1 / Hz0
|
|
H2___________Hx3_________H3 | The equivalent drawing for E would have
|
|
| : | | fore-vectors located at the cube's
|
|
| : | | center (and the centers of adjacent cubes),
|
|
| : | | with components on the cube's faces.
|
|
| H5..........Hx4...|......H4
|
|
| / | /
|
|
Hz2 / Hz2 /
|
|
| / | /
|
|
| Hy6 | Hy4
|
|
| / | /
|
|
|/ |/
|
|
H6__________Hx7__________H7
|
|
</code></pre></div>
|
|
<p>The divergence equations can be derived by taking the divergence of the curl equations
|
|
and combining them with charge continuity,
|
|
|
|
<div class="arithmatex">\[ \hat{\nabla} \cdot \tilde{J} + \hat{\partial}_t \rho = 0 \]</div></p>
|
|
<p>implying that the discrete Maxwell's equations do not produce spurious charges.</p>
|
|
<h4 id="api-fdmath-meanas.fdmath--wave-equation">Wave equation<a class="headerlink" href="#api-fdmath-meanas.fdmath--wave-equation" title="Permanent link">¶</a></h4>
|
|
<p>Taking the backward curl of the <span class="arithmatex">\(\tilde{\nabla} \times \tilde{E}\)</span> equation and
|
|
replacing the resulting <span class="arithmatex">\(\hat{\nabla} \times \hat{H}\)</span> term using its respective equation,
|
|
and setting <span class="arithmatex">\(\hat{M}\)</span> to zero, we can form the discrete wave equation:</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &=
|
|
-\tilde{\partial}_t \hat{B}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}
|
|
- \hat{M}_{l-1, \vec{r} + \frac{1}{2}} \\
|
|
\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &=
|
|
-\tilde{\partial}_t \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} \\
|
|
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
|
\hat{\nabla} \times (-\tilde{\partial}_t \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}) \\
|
|
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
|
-\tilde{\partial}_t \hat{\nabla} \times \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} \\
|
|
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
|
-\tilde{\partial}_t \hat{\partial}_t \epsilon_{\vec{r}} \tilde{E}_{l, \vec{r}} + \hat{\partial}_t \tilde{J}_{l-\frac{1}{2},\vec{r}} \\
|
|
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}})
|
|
+ \tilde{\partial}_t \hat{\partial}_t \epsilon_{\vec{r}} \cdot \tilde{E}_{l, \vec{r}}
|
|
&= \tilde{\partial}_t \tilde{J}_{l - \frac{1}{2}, \vec{r}}
|
|
\end{aligned}
|
|
\]</div>
|
|
<h4 id="api-fdmath-meanas.fdmath--frequency-domain">Frequency domain<a class="headerlink" href="#api-fdmath-meanas.fdmath--frequency-domain" title="Permanent link">¶</a></h4>
|
|
<p>We can substitute in a time-harmonic fields</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{E}_{l, \vec{r}} &= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
|
|
\tilde{J}_{l, \vec{r}} &= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t}
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>resulting in</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{\partial}_t &\Rightarrow (e^{ \imath \omega \Delta_t} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{-\imath \omega \Delta_t / 2} = -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
|
|
\hat{\partial}_t &\Rightarrow (1 - e^{-\imath \omega \Delta_t}) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{ \imath \omega \Delta_t / 2} = -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
|
|
\Omega &= 2 \sin(\omega \Delta_t / 2) / \Delta_t
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>This gives the frequency-domain wave equation,</p>
|
|
<div class="arithmatex">\[
|
|
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
|
|
-\Omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} = -\imath \Omega \tilde{J}_{\vec{r}} e^{\imath \omega \Delta_t / 2} \\
|
|
\]</div>
|
|
<h4 id="api-fdmath-meanas.fdmath--plane-waves-and-dispersion-relation">Plane waves and Dispersion relation<a class="headerlink" href="#api-fdmath-meanas.fdmath--plane-waves-and-dispersion-relation" title="Permanent link">¶</a></h4>
|
|
<p>With uniform material distribution and no sources</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\mu_{\vec{r} + \frac{1}{2}} &= \mu \\
|
|
\epsilon_{\vec{r}} &= \epsilon \\
|
|
\tilde{J}_{\vec{r}} &= 0 \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>the frequency domain wave equation simplifies to</p>
|
|
<div class="arithmatex">\[ \hat{\nabla} \times \tilde{\nabla} \times \tilde{E}_{\vec{r}} - \Omega^2 \epsilon \mu \tilde{E}_{\vec{r}} = 0 \]</div>
|
|
<p>Since <span class="arithmatex">\(\hat{\nabla} \cdot \tilde{E}_{\vec{r}} = 0\)</span>, we can simplify</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\hat{\nabla} \times \tilde{\nabla} \times \tilde{E}_{\vec{r}}
|
|
&= \tilde{\nabla}(\hat{\nabla} \cdot \tilde{E}_{\vec{r}}) - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
|
|
&= - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
|
|
&= - \tilde{\nabla}^2 \tilde{E}_{\vec{r}}
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>and we get</p>
|
|
<div class="arithmatex">\[ \tilde{\nabla}^2 \tilde{E}_{\vec{r}} + \Omega^2 \epsilon \mu \tilde{E}_{\vec{r}} = 0 \]</div>
|
|
<p>We can convert this to three scalar-wave equations of the form</p>
|
|
<div class="arithmatex">\[ (\tilde{\nabla}^2 + K^2) \phi_{\vec{r}} = 0 \]</div>
|
|
<p>with <span class="arithmatex">\(K^2 = \Omega^2 \mu \epsilon\)</span>. Now we let</p>
|
|
<div class="arithmatex">\[ \phi_{\vec{r}} = A e^{\imath (k_x m \Delta_x + k_y n \Delta_y + k_z p \Delta_z)} \]</div>
|
|
<p>resulting in</p>
|
|
<div class="arithmatex">\[
|
|
\begin{aligned}
|
|
\tilde{\partial}_x &\Rightarrow (e^{ \imath k_x \Delta_x} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{ \imath k_x \Delta_x / 2} = \imath K_x e^{ \imath k_x \Delta_x / 2}\\
|
|
\hat{\partial}_x &\Rightarrow (1 - e^{-\imath k_x \Delta_x}) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{-\imath k_x \Delta_x / 2} = \imath K_x e^{-\imath k_x \Delta_x / 2}\\
|
|
K_x &= 2 \sin(k_x \Delta_x / 2) / \Delta_x \\
|
|
\end{aligned}
|
|
\]</div>
|
|
<p>with similar expressions for the y and z dimnsions (and <span class="arithmatex">\(K_y, K_z\)</span>).</p>
|
|
<p>This implies</p>
|
|
<div class="arithmatex">\[
|
|
\tilde{\nabla}^2 = -(K_x^2 + K_y^2 + K_z^2) \phi_{\vec{r}} \\
|
|
K_x^2 + K_y^2 + K_z^2 = \Omega^2 \mu \epsilon = \Omega^2 / c^2
|
|
\]</div>
|
|
<p>where <span class="arithmatex">\(c = \sqrt{\mu \epsilon}\)</span>.</p>
|
|
<p>Assuming real <span class="arithmatex">\((k_x, k_y, k_z), \omega\)</span> will be real only if</p>
|
|
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} < 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
|
|
<p>If <span class="arithmatex">\(\Delta_x = \Delta_y = \Delta_z\)</span>, this simplifies to <span class="arithmatex">\(c \Delta_t < \Delta_x / \sqrt{3}\)</span>.
|
|
This last form can be interpreted as enforcing causality; the distance that light
|
|
travels in one timestep (i.e., <span class="arithmatex">\(c \Delta_t\)</span>) must be less than the diagonal
|
|
of the smallest cell ( <span class="arithmatex">\(\Delta_x / \sqrt{3}\)</span> when on a uniform cubic grid).</p>
|
|
<h3 id="api-fdmath-meanas.fdmath--grid-description">Grid description<a class="headerlink" href="#api-fdmath-meanas.fdmath--grid-description" title="Permanent link">¶</a></h3>
|
|
<p>As described in the section on scalar discrete derivatives above, cell widths
|
|
(<code>dx[i]</code>, <code>dy[j]</code>, <code>dz[k]</code>) along each axis can be arbitrary and independently
|
|
defined. Moreover, all field components are actually defined at "derived" or "dual"
|
|
positions, in-between the "base" grid points on one or more axes.</p>
|
|
<p>To get a better sense of how this works, let's start by drawing a grid with uniform
|
|
<code>dy</code> and <code>dz</code> and nonuniform <code>dx</code>. We will only draw one cell in the y and z dimensions
|
|
to make the illustration simpler; we need at least two cells in the x dimension to
|
|
demonstrate how nonuniform <code>dx</code> affects the various components.</p>
|
|
<p>Place the E fore-vectors at integer indices <span class="arithmatex">\(r = (m, n, p)\)</span> and the H back-vectors
|
|
at fractional indices <span class="arithmatex">\(r + \frac{1}{2} = (m + \frac{1}{2}, n + \frac{1}{2},
|
|
p + \frac{1}{2})\)</span>. Remember that these are indices and not coordinates; they can
|
|
correspond to arbitrary (monotonically increasing) coordinates depending on the cell widths.</p>
|
|
<p>Draw lines to denote the planes on which the H components and back-vectors are defined.
|
|
For simplicity, don't draw the equivalent planes for the E components and fore-vectors,
|
|
except as necessary to show their locations -- it's easiest to just connect them to their
|
|
associated H-equivalents.</p>
|
|
<p>The result looks something like this:</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: Component centers]
|
|
p=
|
|
[H]__________Hx___________[H]_____Hx______[H] __ +1/2
|
|
z y /: /: /: /: /| | |
|
|
|/_x / : / : / : / : / | | |
|
|
/ : / : / : / : / | | |
|
|
Hy : Ez...........Hy : Ez......Hy | | |
|
|
/: : : : /: : : : /| | | |
|
|
/ : Hz : Ey....../.:..Hz : Ey./.|..Hz __ 0 | dz[0]
|
|
/ : /: : / / : /: : / / | /| | |
|
|
/_________________________/_______________/ | / | | |
|
|
| :/ : :/ | :/ : :/ | |/ | | |
|
|
| Ex : [E].......|..Ex : [E]..|..Ex | | |
|
|
| : | : | | | |
|
|
| [H]..........Hx....|......[H].....H|x.....[H] __ --------- (n=+1/2, p=-1/2)
|
|
| / | / | / / /
|
|
Hz / Hz / Hz / / /
|
|
| / | / | / / /
|
|
| Hy | Hy | Hy __ 0 / dy[0]
|
|
| / | / | / / /
|
|
| / | / | / / /
|
|
|/ |/ |/ / /
|
|
[H]__________Hx___________[H]_____Hx______[H] __ -1/2 /
|
|
=n
|
|
|------------|------------|-------|-------|
|
|
-1/2 0 +1/2 +1 +3/2 = m
|
|
|
|
------------------------- ----------------
|
|
dx[0] dx[1]
|
|
|
|
Part of a nonuniform "base grid", with labels specifying
|
|
positions of the various field components. [E] fore-vectors
|
|
are at the cell centers, and [H] back-vectors are at the
|
|
vertices. H components along the near (-y) top (+z) edge
|
|
have been omitted to make the insides of the cubes easier
|
|
to visualize.
|
|
</code></pre></div>
|
|
<p>The above figure shows where all the components are located; however, it is also useful to show
|
|
what volumes those components correspond to. Consider the Ex component at <code>m = +1/2</code>: it is
|
|
shifted in the x-direction by a half-cell from the E fore-vector at <code>m = 0</code> (labeled <code>[E]</code>
|
|
in the figure). It corresponds to a volume between <code>m = 0</code> and <code>m = +1</code> (the other
|
|
dimensions are not shifted, i.e. they are still bounded by <code>n, p = +-1/2</code>). (See figure
|
|
below). Since <code>m</code> is an index and not an x-coordinate, the Ex component is not necessarily
|
|
at the center of the volume it represents, and the x-length of its volume is the derived
|
|
quantity <code>dx'[0] = (dx[0] + dx[1]) / 2</code> rather than the base <code>dx</code>.
|
|
(See also <code>Scalar derivatives and cell shifts</code>).</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: Ex volumes]
|
|
p=
|
|
<_________________________________________> __ +1/2
|
|
z y << /: / /: >> | |
|
|
|/_x < < / : / / : > > | |
|
|
< < / : / / : > > | |
|
|
< < / : / / : > > | |
|
|
<: < / : : / : >: > | |
|
|
< : < / : : / : > : > __ 0 | dz[0]
|
|
< : < / : : / :> : > | |
|
|
<____________/____________________/_______> : > | |
|
|
< : < | : : | > : > | |
|
|
< Ex < | : Ex | > Ex > | |
|
|
< : < | : : | > : > | |
|
|
< : <....|.......:........:...|.......>...:...> __ --------- (n=+1/2, p=-1/2)
|
|
< : < | / : /| /> : > / /
|
|
< : < | / : / | / > : > / /
|
|
< :< | / :/ | / > :> / /
|
|
< < | / : | / > > _ 0 / dy[0]
|
|
< < | / | / > > / /
|
|
< < | / | / > > / /
|
|
<< |/ |/ >> / /
|
|
<____________|____________________|_______> __ -1/2 /
|
|
=n
|
|
|------------|------------|-------|-------|
|
|
-1/2 0 +1/2 +1 +3/2 = m
|
|
|
|
~------------ -------------------- -------~
|
|
dx'[-1] dx'[0] dx'[1]
|
|
|
|
The Ex values are positioned on the x-faces of the base
|
|
grid. They represent the Ex field in volumes shifted by
|
|
a half-cell in the x-dimension, as shown here. Only the
|
|
center cell (with width dx'[0]) is fully shown; the
|
|
other two are truncated (shown using >< markers).
|
|
|
|
Note that the Ex positions are the in the same positions
|
|
as the previous figure; only the cell boundaries have moved.
|
|
Also note that the points at which Ex is defined are not
|
|
necessarily centered in the volumes they represent; non-
|
|
uniform cell sizes result in off-center volumes like the
|
|
center cell here.
|
|
</code></pre></div>
|
|
<p>The next figure shows the volumes corresponding to the Hy components, which
|
|
are shifted in two dimensions (x and z) compared to the base grid.</p>
|
|
<div class="highlight"><pre><span></span><code>[figure: Hy volumes]
|
|
p=
|
|
z y mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm __ +1/2 s
|
|
|/_x << m: m: >> | |
|
|
< < m : m : > > | | dz'[1]
|
|
< < m : m : > > | |
|
|
Hy........... m........Hy...........m......Hy > | |
|
|
< < m : m : > > | |
|
|
< ______ m_____:_______________m_____:_>______ __ 0
|
|
< < m /: m / > > | |
|
|
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm > | |
|
|
< < | / : | / > > | | dz'[0]
|
|
< < | / : | / > > | |
|
|
< < | / : | / > > | |
|
|
< wwwww|w/wwwwwwwwwwwwwwwwwww|w/wwwww>wwwwwwww __ s
|
|
< < |/ w |/ w> > / /
|
|
_____________|_____________________|________ > / /
|
|
< < | w | w > > / /
|
|
< Hy........|...w........Hy.......|...w...>..Hy _ 0 / dy[0]
|
|
< < | w | w > > / /
|
|
<< | w | w > > / /
|
|
< |w |w >> / /
|
|
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww __ -1/2 /
|
|
|
|
|------------|------------|--------|-------|
|
|
-1/2 0 +1/2 +1 +3/2 = m
|
|
|
|
~------------ --------------------- -------~
|
|
dx'[-1] dx'[0] dx'[1]
|
|
|
|
The Hy values are positioned on the y-edges of the base
|
|
grid. Again here, the 'Hy' labels represent the same points
|
|
as in the basic grid figure above; the edges have shifted
|
|
by a half-cell along the x- and z-axes.
|
|
|
|
The grid lines _|:/ are edges of the area represented by
|
|
each Hy value, and the lines drawn using <m>.w represent
|
|
edges where a cell's faces extend beyond the drawn area
|
|
(i.e. where the drawing is truncated in the x- or z-
|
|
directions).
|
|
</code></pre></div>
|
|
<h4 id="api-fdmath-meanas.fdmath--datastructure-dx_lists_t">Datastructure: dx_lists_t<a class="headerlink" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t" title="Permanent link">¶</a></h4>
|
|
<p>In this documentation, the E fore-vectors are placed on the base grid. An
|
|
equivalent formulation could place the H back-vectors on the base grid instead.
|
|
However, in the case of a non-uniform grid, the operation to get from the "base"
|
|
cell widths to "derived" ones is not its own inverse.</p>
|
|
<p>The base grid's cell sizes could be fully described by a list of three 1D arrays,
|
|
specifying the cell widths along all three axes:</p>
|
|
<div class="highlight"><pre><span></span><code>[dx, dy, dz] = [[dx[0], dx[1], ...], [dy[0], ...], [dz[0], ...]]
|
|
</code></pre></div>
|
|
<p>Note that this is a list-of-arrays rather than a 2D array, as the simulation domain
|
|
may have a different number of cells along each axis.</p>
|
|
<p>Knowing the base grid's cell widths and the boundary conditions (periodic unless
|
|
otherwise noted) is enough information to calculate the cell widths <code>dx'</code>, <code>dy'</code>,
|
|
and <code>dz'</code> for the derived grids.</p>
|
|
<p>However, since most operations are trivially generalized to allow either E or H
|
|
to be defined on the base grid, they are written to take the a full set of base
|
|
and derived cell widths, distinguished by which field they apply to rather than
|
|
their "base" or "derived" status. This removes the need for each function to
|
|
generate the derived widths, and makes the "base" vs "derived" distinction
|
|
unnecessary in the code.</p>
|
|
<p>The resulting data structure containing all the cell widths takes the form of a
|
|
list-of-lists-of-arrays. The first list-of-arrays provides the cell widths for
|
|
the E-field fore-vectors, while the second list-of-arrays does the same for the
|
|
H-field back-vectors:</p>
|
|
<div class="highlight"><pre><span></span><code> [[[dx_e[0], dx_e[1], ...], [dy_e[0], ...], [dz_e[0], ...]],
|
|
[[dx_h[0], dx_h[1], ...], [dy_h[0], ...], [dz_h[0], ...]]]
|
|
</code></pre></div>
|
|
<p>where <code>dx_e[0]</code> is the x-width of the <code>m=0</code> cells, as used when calculating dE/dx,
|
|
and <code>dy_h[0]</code> is the y-width of the <code>n=0</code> cells, as used when calculating dH/dy, etc.</p>
|
|
<h3 id="api-fdmath-meanas.fdmath--permittivity-and-permeability">Permittivity and Permeability<a class="headerlink" href="#api-fdmath-meanas.fdmath--permittivity-and-permeability" title="Permanent link">¶</a></h3>
|
|
<p>Since each vector component of E and H is defined in a different location and represents
|
|
a different volume, the value of the spatially-discrete <code>epsilon</code> and <code>mu</code> can also be
|
|
different for all three field components, even when representing a simple planar interface
|
|
between two isotropic materials.</p>
|
|
<p>As a result, <code>epsilon</code> and <code>mu</code> are taken to have the same dimensions as the field, and
|
|
composed of the three diagonal tensor components:</p>
|
|
<div class="highlight"><pre><span></span><code>[equations: epsilon_and_mu]
|
|
epsilon = [epsilon_xx, epsilon_yy, epsilon_zz]
|
|
mu = [mu_xx, mu_yy, mu_zz]
|
|
</code></pre></div>
|
|
<p>or</p>
|
|
<div class="arithmatex">\[
|
|
\epsilon = \begin{bmatrix} \epsilon_{xx} & 0 & 0 \\
|
|
0 & \epsilon_{yy} & 0 \\
|
|
0 & 0 & \epsilon_{zz} \end{bmatrix}
|
|
\]</div>
|
|
<div class="arithmatex">\[
|
|
\mu = \begin{bmatrix} \mu_{xx} & 0 & 0 \\
|
|
0 & \mu_{yy} & 0 \\
|
|
0 & 0 & \mu_{zz} \end{bmatrix}
|
|
\]</div>
|
|
<p>where the off-diagonal terms (e.g. <code>epsilon_xy</code>) are assumed to be zero.</p>
|
|
<p>High-accuracy volumetric integration of shapes on multiple grids can be performed
|
|
by the <a href="https://mpxd.net/code/jan/gridlock">gridlock</a> module.</p>
|
|
<p>The values of the vacuum permittivity and permability effectively become scaling
|
|
factors that appear in several locations (e.g. between the E and H fields). In
|
|
order to limit floating-point inaccuracy and simplify calculations, they are often
|
|
set to 1 and relative permittivities and permeabilities are used in their places;
|
|
the true values can be multiplied back in after the simulation is complete if non-
|
|
normalized results are needed.</p>
|
|
<div class="doc doc-children">
|
|
</div>
|
|
</div>
|
|
</div><h2 id="functional-and-sparse-operators">Functional and sparse operators<a class="headerlink" href="#api-fdmath-functional-and-sparse-operators" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.functional</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Math functions for finite difference simulations</p>
|
|
<p>Basic discrete calculus etc.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.deriv_forward">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_forward</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.deriv_forward" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_forward</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span>
|
|
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operators for taking discretized derivatives (backward variant).</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_e</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of functions for taking forward derivatives along each axis.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.deriv_back">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_back</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.deriv_back" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_back</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span>
|
|
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operators for taking discretized derivatives (forward variant).</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
|
|
|
|
|
|
|
|
module-attribute
|
|
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of functions for taking forward derivatives along each axis.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.curl_forward">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_forward</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.curl_forward" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_forward</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-></span> <span class="n">Callable</span><span class="p">[[</span><span class="n">TT</span><span class="p">],</span> <span class="n">TT</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Curl operator for use with the E field.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_e</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> for taking the discrete forward curl of a field,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>f(E)</code> -> curlE <span class="arithmatex">\(= \nabla_f \times E\)</span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.curl_back">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_back</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.curl_back" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_back</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-></span> <span class="n">Callable</span><span class="p">[[</span><span class="n">TT</span><span class="p">],</span> <span class="n">TT</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Create a function which takes the backward curl of a field.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>None</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Function <code>f</code> for taking the discrete backward curl of a field,</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>f(H)</code> -> curlH <span class="arithmatex">\(= \nabla_b \times H\)</span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.operators</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Matrix operators for finite difference simulations</p>
|
|
<p>Basic discrete calculus etc.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.shift_circ">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">shift_circ</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.shift_circ" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">shift_circ</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">shift_distance</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operator for performing a circular shift along a specified axis by a
|
|
specified number of elements.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Axis to shift along. x=0, y=1, z=2</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shape</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Shape of the grid being shifted</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shift_distance</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Number of cells to shift by. May be negative. Default 1.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for performing the circular shift.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.shift_with_mirror">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">shift_with_mirror</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.shift_with_mirror" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">shift_with_mirror</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">shift_distance</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operator for performing an n-element shift along a specified axis, with mirror
|
|
boundary conditions applied to the cells beyond the receding edge.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Axis to shift along. x=0, y=1, z=2</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shape</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Shape of the grid being shifted</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shift_distance</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Number of cells to shift by. May be negative. Default 1.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>1</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for performing the shift-with-mirror.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.deriv_forward">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_forward</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.deriv_forward" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_forward</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">[</span><span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operators for taking discretized derivatives (forward variant).</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_e</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of operators for taking forward derivatives along each axis.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.deriv_back">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_back</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.deriv_back" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_back</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">[</span><span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Utility operators for taking discretized derivatives (backward variant).</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List of operators for taking forward derivatives along each axis.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.cross">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">cross</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.cross" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">cross</span><span class="p">(</span><span class="n">B</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">sparray</span><span class="p">])</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Cross product operator</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>B</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>List <code>[Bx, By, Bz]</code> of sparse matrices corresponding to the x, y, z
|
|
portions of the operator on the left side of the cross product.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix corresponding to (B x), where x is the cross product.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.vec_cross">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">vec_cross</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.vec_cross" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec_cross</span><span class="p">(</span><span class="n">b</span><span class="p">:</span> <span class="n">vfdfield_t</span><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Vector cross product operator</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>b</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield_t" title="meanas.fdmath.types.vfdfield_t">vfdfield_t</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Vector on the left side of the cross product.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Returns:</p>
|
|
<div class="highlight"><pre><span></span><code>Sparse matrix corresponding to (b x), where x is the cross product.
|
|
</code></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.avg_forward">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">avg_forward</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.avg_forward" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">avg_forward</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Forward average operator <code>(x4 = (x4 + x5) / 2)</code></p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Axis to average along (x=0, y=1, z=2)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shape</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Shape of the grid to average</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for forward average operation.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.avg_back">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">avg_back</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.avg_back" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">avg_back</span><span class="p">(</span><span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Backward average operator <code>(x4 = (x4 + x3) / 2)</code></p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>axis</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Axis to average along (x=0, y=1, z=2)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shape</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Shape of the grid to average</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for backward average operation.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.curl_forward">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_forward</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.curl_forward" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_forward</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Curl operator for use with the E field.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_e</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for taking the discretized curl of the E-field</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.curl_back">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_back</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.curl_back" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_back</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Curl operator for use with the H field.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>dx_h</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Lists of cell sizes for all axes
|
|
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Sparse matrix for taking the discretized curl of the H-field</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.vectorization">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.vectorization</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.vectorization" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Functions for moving between a vector field (list of 3 ndarrays, <code>[f_x, f_y, f_z]</code>)
|
|
and a 1D array representation of that field <code>[f_x0, f_x1, f_x2,... f_y0,... f_z0,...]</code>.
|
|
Vectorized versions of the field use row-major (ie., C-style) ordering.</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.vectorization.vec">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">vec</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.vectorization.vec" title="Permanent link">¶</a></h3>
|
|
<div class="doc-overloads">
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">fdfield_t</span><span class="p">)</span> <span class="o">-></span> <span class="n">vfdfield_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">)</span> <span class="o">-></span> <span class="n">vcfdfield_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">fdfield2_t</span><span class="p">)</span> <span class="o">-></span> <span class="n">vfdfield2_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">cfdfield2_t</span><span class="p">)</span> <span class="o">-></span> <span class="n">vcfdfield2_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">fdslice_t</span><span class="p">)</span> <span class="o">-></span> <span class="n">vfdslice_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">cfdslice_t</span><span class="p">)</span> <span class="o">-></span> <span class="n">vcfdslice_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span>
|
|
</code></pre></div> </div>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">f</span><span class="p">:</span> <span class="n">fdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="n">cfdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="n">fdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">cfdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">fdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">|</span> <span class="n">cfdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="o">|</span> <span class="n">ArrayLike</span>
|
|
<a href="#api-fdmath-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdmath-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-></span> <span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">vfdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="o">|</span> <span class="n">vcfdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="o">|</span> <span class="n">vfdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> <span class="o">|</span> <span class="n">vcfdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> <span class="o">|</span> <span class="n">vfdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> <span class="o">|</span> <span class="n">vcfdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> <span class="o">|</span> <span class="n">NDArray</span>
|
|
<a href="#api-fdmath-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> <span class="o">|</span> <span class="kc">None</span>
|
|
<a href="#api-fdmath-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="p">)</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Create a 1D ndarray from a vector field which spans a 1-3D region.</p>
|
|
<p>Returns <code>None</code> if called with <code>f=None</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>f</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield_t" title="meanas.fdmath.types.fdfield_t">fdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield_t" title="meanas.fdmath.types.cfdfield_t">cfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield2_t" title="meanas.fdmath.types.fdfield2_t">fdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield2_t" title="meanas.fdmath.types.cfdfield2_t">cfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdslice_t" title="meanas.fdmath.types.fdslice_t">fdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdslice_t" title="meanas.fdmath.types.cfdslice_t">cfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>A vector field, e.g. <code>[f_x, f_y, f_z]</code> where each <code>f_</code> component is a 1- to
|
|
3-D ndarray (<code>f_*</code> should all be the same size). Doesn't fail with <code>f=None</code>.</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield_t" title="meanas.fdmath.types.vfdfield_t">vfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield_t" title="meanas.fdmath.types.vcfdfield_t">vcfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield2_t" title="meanas.fdmath.types.vfdfield2_t">vfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield2_t" title="meanas.fdmath.types.vcfdfield2_t">vcfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdslice_t" title="meanas.fdmath.types.vfdslice_t">vfdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdslice_t" title="meanas.fdmath.types.vcfdslice_t">vcfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>1D ndarray containing the linearized field (or <code>None</code>)</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-function">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.vectorization.unvec">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">unvec</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.vectorization.unvec" title="Permanent link">¶</a></h3>
|
|
<div class="doc-overloads">
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdfield_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vcfdfield_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdfield2_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdfield2_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vcfdfield2_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdfield2_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdslice_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">fdslice_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">cfdslice_t</span>
|
|
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span>
|
|
</code></pre></div> </div>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="n">vcfdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="n">vfdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">vcfdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">vfdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">|</span> <span class="n">vcfdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="o">|</span> <span class="n">ArrayLike</span>
|
|
<a href="#api-fdmath-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
|
|
<a href="#api-fdmath-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
|
|
<a href="#api-fdmath-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span>
|
|
<a href="#api-fdmath-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="p">(</span>
|
|
<a href="#api-fdmath-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="n">fdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> <span class="o">|</span> <span class="n">cfdfield_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> <span class="o">|</span> <span class="n">fdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> <span class="o">|</span> <span class="n">cfdfield2_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> <span class="o">|</span> <span class="n">fdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> <span class="o">|</span> <span class="n">cfdslice_t</span>
|
|
<a href="#api-fdmath-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> <span class="o">|</span> <span class="n">NDArray</span>
|
|
<a href="#api-fdmath-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> <span class="o">|</span> <span class="kc">None</span>
|
|
<a href="#api-fdmath-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="p">)</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Perform the inverse of vec(): take a 1D ndarray and output an <code>nvdim</code>-component field
|
|
of form e.g. <code>[f_x, f_y, f_z]</code> (<code>nvdim=3</code>) where each of <code>f_*</code> is a len(shape)-dimensional
|
|
ndarray.</p>
|
|
<p>Returns <code>None</code> if called with <code>v=None</code>.</p>
|
|
<p><span class="doc-section-title">Parameters:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>v</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield_t" title="meanas.fdmath.types.vfdfield_t">vfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield_t" title="meanas.fdmath.types.vcfdfield_t">vcfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield2_t" title="meanas.fdmath.types.vfdfield2_t">vfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield2_t" title="meanas.fdmath.types.vcfdfield2_t">vcfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdslice_t" title="meanas.fdmath.types.vfdslice_t">vfdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdslice_t" title="meanas.fdmath.types.vcfdslice_t">vcfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>1D ndarray representing a vector field of shape shape (or None)</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>shape</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#print-page-toc">int</a>]</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>shape of the vector field</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<em>required</em>
|
|
</td>
|
|
</tr>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code>nvdim</code>
|
|
</td>
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#print-page-toc">int</a></code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p>Number of components in each vector</p>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<code>3</code>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><span class="doc-section-title">Returns:</span></p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="doc-section-item">
|
|
<td>
|
|
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield_t" title="meanas.fdmath.types.fdfield_t">fdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield_t" title="meanas.fdmath.types.cfdfield_t">cfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield2_t" title="meanas.fdmath.types.fdfield2_t">fdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield2_t" title="meanas.fdmath.types.cfdfield2_t">cfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdslice_t" title="meanas.fdmath.types.fdslice_t">fdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdslice_t" title="meanas.fdmath.types.cfdslice_t">cfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a> | None</code>
|
|
</td>
|
|
<td>
|
|
<div class="doc-md-description">
|
|
<p><code>[f_x, f_y, f_z]</code> where each <code>f_</code> is a <code>len(shape)</code> dimensional ndarray (or <code>None</code>)</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-module">
|
|
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.types</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types" title="Permanent link">¶</a></h2>
|
|
<div class="doc doc-contents first">
|
|
<p>Types shared across multiple submodules</p>
|
|
<div class="doc doc-children">
|
|
<div class="doc doc-object doc-attribute">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists_t">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists_t</span>
|
|
<span class="doc doc-labels">
|
|
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
|
|
</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists_t</span> <span class="o">=</span> <span class="n">Sequence</span><span class="p">[</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>'dxes' datastructure which contains grid cell width information in the following format:</p>
|
|
<div class="highlight"><pre><span></span><code>[[[dx_e[0], dx_e[1], ...], [dy_e[0], ...], [dz_e[0], ...]],
|
|
[[dx_h[0], dx_h[1], ...], [dy_h[0], ...], [dz_h[0], ...]]]
|
|
</code></pre></div>
|
|
<p>where <code>dx_e[0]</code> is the x-width of the <code>x=0</code> cells, as used when calculating dE/dx,
|
|
and <code>dy_h[0]</code> is the y-width of the <code>y=0</code> cells, as used when calculating dH/dy, etc.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-attribute">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists2_t">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists2_t</span>
|
|
<span class="doc doc-labels">
|
|
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
|
|
</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists2_t</span> <span class="o">=</span> <span class="n">Sequence</span><span class="p">[</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>2D 'dxes' datastructure which contains grid cell width information in the following format:</p>
|
|
<div class="highlight"><pre><span></span><code>[[[dx_e[0], dx_e[1], ...], [dy_e[0], ...]],
|
|
[[dx_h[0], dx_h[1], ...], [dy_h[0], ...]]]
|
|
</code></pre></div>
|
|
<p>where <code>dx_e[0]</code> is the x-width of the <code>x=0</code> cells, as used when calculating dE/dx,
|
|
and <code>dy_h[0]</code> is the y-width of the <code>y=0</code> cells, as used when calculating dH/dy, etc.</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-attribute">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists_mut">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists_mut</span>
|
|
<span class="doc doc-labels">
|
|
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
|
|
</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists_mut</span> <span class="o">=</span> <span class="n">MutableSequence</span><span class="p">[</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">MutableSequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Mutable version of <code>dx_lists_t</code></p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-attribute">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists2_mut">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists2_mut</span>
|
|
<span class="doc doc-labels">
|
|
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
|
|
</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists2_mut" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists2_mut</span> <span class="o">=</span> <span class="n">MutableSequence</span><span class="p">[</span>
|
|
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">MutableSequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
|
|
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Mutable version of <code>dx_lists2_t</code></p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-attribute">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdfield_updater_t">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">fdfield_updater_t</span>
|
|
<span class="doc doc-labels">
|
|
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
|
|
</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">fdfield_updater_t</span> <span class="o">=</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Convenience type for functions which take and return an fdfield_t</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-attribute">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdfield_updater_t">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">cfdfield_updater_t</span>
|
|
<span class="doc doc-labels">
|
|
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
|
|
</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">cfdfield_updater_t</span> <span class="o">=</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">cfdfield_t</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Convenience type for functions which take and return an cfdfield_t</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdfield">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">fdfield</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdfield" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">fdfield</span> <span class="o">=</span> <span class="n">fdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Vector field with shape (3, X, Y, Z) (e.g. <code>[E_x, E_y, E_z]</code>)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vfdfield">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vfdfield</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vfdfield" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vfdfield</span> <span class="o">=</span> <span class="n">vfdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Linearized vector field (single vector of length 3<em>X</em>Y*Z)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdfield">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">cfdfield</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdfield" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">cfdfield</span> <span class="o">=</span> <span class="n">cfdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Complex vector field with shape (3, X, Y, Z) (e.g. <code>[E_x, E_y, E_z]</code>)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vcfdfield">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vcfdfield</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vcfdfield" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vcfdfield</span> <span class="o">=</span> <span class="n">vcfdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Linearized complex vector field (single vector of length 3<em>X</em>Y*Z)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdslice">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">fdslice</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdslice" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">fdslice</span> <span class="o">=</span> <span class="n">fdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Vector field slice with shape (3, X, Y) (e.g. <code>[E_x, E_y, E_z]</code> at a single Z position)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vfdslice">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vfdslice</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vfdslice" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vfdslice</span> <span class="o">=</span> <span class="n">vfdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Linearized vector field slice (single vector of length 3<em>X</em>Y)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdslice">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">cfdslice</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdslice" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">cfdslice</span> <span class="o">=</span> <span class="n">cfdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Complex vector field slice with shape (3, X, Y) (e.g. <code>[E_x, E_y, E_z]</code> at a single Z position)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vcfdslice">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vcfdslice</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vcfdslice</span> <span class="o">=</span> <span class="n">vcfdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>Linearized complex vector field slice (single vector of length 3<em>X</em>Y)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdfield2">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">fdfield2</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdfield2" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">fdfield2</span> <span class="o">=</span> <span class="n">fdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>2D Vector field with shape (2, X, Y) (e.g. <code>[E_x, E_y]</code>)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vfdfield2">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vfdfield2</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vfdfield2</span> <span class="o">=</span> <span class="n">vfdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>2D Linearized vector field (single vector of length 2<em>X</em>Y)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdfield2">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">cfdfield2</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">cfdfield2</span> <span class="o">=</span> <span class="n">cfdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>2D Complex vector field with shape (2, X, Y) (e.g. <code>[E_x, E_y]</code>)</p>
|
|
</div>
|
|
</div>
|
|
<div class="doc doc-object doc-type_alias">
|
|
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vcfdfield2">
|
|
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vcfdfield2</span>
|
|
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title="Permanent link">¶</a></h3>
|
|
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vcfdfield2</span> <span class="o">=</span> <span class="n">vcfdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
|
|
</code></pre></div>
|
|
<div class="doc doc-contents">
|
|
<p>2D Linearized complex vector field (single vector of length 2<em>X</em>Y)</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div></section></section></div><style>.print-site-enumerate-headings #index > h1:before { content: '1 ' }
|
|
|
|
.print-site-enumerate-headings #index h2:before { content: '1.' counter(counter-index-2) ' ' }
|
|
.print-site-enumerate-headings #index h2 { counter-reset: counter-index-3 ; counter-increment: counter-index-2 }
|
|
|
|
.print-site-enumerate-headings #index h3:before { content: '1.' counter(counter-index-2) '.' counter(counter-index-3) ' ' }
|
|
.print-site-enumerate-headings #index h3 { counter-increment: counter-index-3 }
|
|
|
|
.print-site-enumerate-headings #section-2 > h1:before { content: '2 ' }
|
|
.print-site-enumerate-headings #api > h1:before { content: '2.1 ' }
|
|
|
|
.print-site-enumerate-headings #api h2:before { content: '2.1.' counter(counter-api-2) ' ' }
|
|
.print-site-enumerate-headings #api h2 { counter-increment: counter-api-2 }
|
|
|
|
.print-site-enumerate-headings #api-meanas > h1:before { content: '2.2 ' }
|
|
|
|
.print-site-enumerate-headings #api-meanas h2:before { content: '2.2.' counter(counter-api-meanas-2) ' ' }
|
|
.print-site-enumerate-headings #api-meanas h2 { counter-increment: counter-api-meanas-2 }
|
|
|
|
.print-site-enumerate-headings #api-eigensolvers > h1:before { content: '2.3 ' }
|
|
|
|
.print-site-enumerate-headings #api-eigensolvers h2:before { content: '2.3.' counter(counter-api-eigensolvers-2) ' ' }
|
|
.print-site-enumerate-headings #api-eigensolvers h2 { counter-increment: counter-api-eigensolvers-2 }
|
|
|
|
.print-site-enumerate-headings #api-fdfd > h1:before { content: '2.4 ' }
|
|
|
|
.print-site-enumerate-headings #api-fdfd h2:before { content: '2.4.' counter(counter-api-fdfd-2) ' ' }
|
|
.print-site-enumerate-headings #api-fdfd h2 { counter-increment: counter-api-fdfd-2 }
|
|
|
|
.print-site-enumerate-headings #api-waveguides > h1:before { content: '2.5 ' }
|
|
|
|
.print-site-enumerate-headings #api-waveguides h2:before { content: '2.5.' counter(counter-api-waveguides-2) ' ' }
|
|
.print-site-enumerate-headings #api-waveguides h2 { counter-increment: counter-api-waveguides-2 }
|
|
|
|
.print-site-enumerate-headings #api-fdtd > h1:before { content: '2.6 ' }
|
|
|
|
.print-site-enumerate-headings #api-fdtd h2:before { content: '2.6.' counter(counter-api-fdtd-2) ' ' }
|
|
.print-site-enumerate-headings #api-fdtd h2 { counter-increment: counter-api-fdtd-2 }
|
|
|
|
.print-site-enumerate-headings #api-fdmath > h1:before { content: '2.7 ' }
|
|
|
|
.print-site-enumerate-headings #api-fdmath h2:before { content: '2.7.' counter(counter-api-fdmath-2) ' ' }
|
|
.print-site-enumerate-headings #api-fdmath h2 { counter-increment: counter-api-fdmath-2 }
|
|
</style>
|
|
</article>
|
|
</div>
|
|
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
|
</div>
|
|
<button class="md-top md-icon" data-md-component="top" hidden="" type="button">
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"></path></svg>
|
|
Back to top
|
|
</button>
|
|
</main>
|
|
<footer class="md-footer">
|
|
<div class="md-footer-meta md-typeset">
|
|
<div class="md-footer-meta__inner md-grid">
|
|
<div class="md-copyright">
|
|
|
|
|
|
Made with
|
|
<a href="https://squidfunk.github.io/mkdocs-material/" rel="noopener" target="_blank">
|
|
Material for MkDocs
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
<div class="md-dialog" data-md-component="dialog">
|
|
<div class="md-dialog__inner md-typeset"></div>
|
|
</div>
|
|
<script id="__config" type="application/json">{"annotate": null, "base": "/docs/meanas/", "features": ["navigation.indexes", "navigation.sections", "navigation.top", "content.code.copy", "toc.follow"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
|
|
<script src="data:text/javascript;base64,InVzZSBzdHJpY3QiOygoKT0+e3ZhciBaaT1PYmplY3QuY3JlYXRlO3ZhciBfcj1PYmplY3QuZGVmaW5lUHJvcGVydHk7dmFyIGVhPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7dmFyIHRhPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzLEJ0PU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMscmE9T2JqZWN0LmdldFByb3RvdHlwZU9mLEFyPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksYm89T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgaG89KGUsdCxyKT0+dCBpbiBlP19yKGUsdCx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6cn0pOmVbdF09cixQPShlLHQpPT57Zm9yKHZhciByIGluIHR8fCh0PXt9KSlBci5jYWxsKHQscikmJmhvKGUscix0W3JdKTtpZihCdClmb3IodmFyIHIgb2YgQnQodCkpYm8uY2FsbCh0LHIpJiZobyhlLHIsdFtyXSk7cmV0dXJuIGV9O3ZhciB2bz0oZSx0KT0+e3ZhciByPXt9O2Zvcih2YXIgbyBpbiBlKUFyLmNhbGwoZSxvKSYmdC5pbmRleE9mKG8pPDAmJihyW29dPWVbb10pO2lmKGUhPW51bGwmJkJ0KWZvcih2YXIgbyBvZiBCdChlKSl0LmluZGV4T2Yobyk8MCYmYm8uY2FsbChlLG8pJiYocltvXT1lW29dKTtyZXR1cm4gcn07dmFyIENyPShlLHQpPT4oKT0+KHR8fGUoKHQ9e2V4cG9ydHM6e319KS5leHBvcnRzLHQpLHQuZXhwb3J0cyk7dmFyIG9hPShlLHQscixvKT0+e2lmKHQmJnR5cGVvZiB0PT0ib2JqZWN0Inx8dHlwZW9mIHQ9PSJmdW5jdGlvbiIpZm9yKGxldCBuIG9mIHRhKHQpKSFBci5jYWxsKGUsbikmJm4hPT1yJiZfcihlLG4se2dldDooKT0+dFtuXSxlbnVtZXJhYmxlOiEobz1lYSh0LG4pKXx8by5lbnVtZXJhYmxlfSk7cmV0dXJuIGV9O3ZhciAkdD0oZSx0LHIpPT4ocj1lIT1udWxsP1ppKHJhKGUpKTp7fSxvYSh0fHwhZXx8IWUuX19lc01vZHVsZT9fcihyLCJkZWZhdWx0Iix7dmFsdWU6ZSxlbnVtZXJhYmxlOiEwfSk6cixlKSk7dmFyIGdvPShlLHQscik9Pm5ldyBQcm9taXNlKChvLG4pPT57dmFyIGk9Yz0+e3RyeXthKHIubmV4dChjKSl9Y2F0Y2gocCl7bihwKX19LHM9Yz0+e3RyeXthKHIudGhyb3coYykpfWNhdGNoKHApe24ocCl9fSxhPWM9PmMuZG9uZT9vKGMudmFsdWUpOlByb21pc2UucmVzb2x2ZShjLnZhbHVlKS50aGVuKGkscyk7YSgocj1yLmFwcGx5KGUsdCkpLm5leHQoKSl9KTt2YXIgeG89Q3IoKGtyLHlvKT0+eyhmdW5jdGlvbihlLHQpe3R5cGVvZiBrcj09Im9iamVjdCImJnR5cGVvZiB5byE9InVuZGVmaW5lZCI/dCgpOnR5cGVvZiBkZWZpbmU9PSJmdW5jdGlvbiImJmRlZmluZS5hbWQ/ZGVmaW5lKHQpOnQoKX0pKGtyLChmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBlKHIpe3ZhciBvPSEwLG49ITEsaT1udWxsLHM9e3RleHQ6ITAsc2VhcmNoOiEwLHVybDohMCx0ZWw6ITAsZW1haWw6ITAscGFzc3dvcmQ6ITAsbnVtYmVyOiEwLGRhdGU6ITAsbW9udGg6ITAsd2VlazohMCx0aW1lOiEwLGRhdGV0aW1lOiEwLCJkYXRldGltZS1sb2NhbCI6ITB9O2Z1bmN0aW9uIGEoayl7cmV0dXJuISEoayYmayE9PWRvY3VtZW50JiZrLm5vZGVOYW1lIT09IkhUTUwiJiZrLm5vZGVOYW1lIT09IkJPRFkiJiYiY2xhc3NMaXN0ImluIGsmJiJjb250YWlucyJpbiBrLmNsYXNzTGlzdCl9ZnVuY3Rpb24gYyhrKXt2YXIgdXQ9ay50eXBlLGplPWsudGFnTmFtZTtyZXR1cm4hIShqZT09PSJJTlBVVCImJnNbdXRdJiYhay5yZWFkT25seXx8amU9PT0iVEVYVEFSRUEiJiYhay5yZWFkT25seXx8ay5pc0NvbnRlbnRFZGl0YWJsZSl9ZnVuY3Rpb24gcChrKXtrLmNsYXNzTGlzdC5jb250YWlucygiZm9jdXMtdmlzaWJsZSIpfHwoay5jbGFzc0xpc3QuYWRkKCJmb2N1cy12aXNpYmxlIiksay5zZXRBdHRyaWJ1dGUoImRhdGEtZm9jdXMtdmlzaWJsZS1hZGRlZCIsIiIpKX1mdW5jdGlvbiBsKGspe2suaGFzQXR0cmlidXRlKCJkYXRhLWZvY3VzLXZpc2libGUtYWRkZWQiKSYmKGsuY2xhc3NMaXN0LnJlbW92ZSgiZm9jdXMtdmlzaWJsZSIpLGsucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWZvY3VzLXZpc2libGUtYWRkZWQiKSl9ZnVuY3Rpb24gZihrKXtrLm1ldGFLZXl8fGsuYWx0S2V5fHxrLmN0cmxLZXl8fChhKHIuYWN0aXZlRWxlbWVudCkmJnAoci5hY3RpdmVFbGVtZW50KSxvPSEwKX1mdW5jdGlvbiB1KGspe289ITF9ZnVuY3Rpb24gZChrKXthKGsudGFyZ2V0KSYmKG98fGMoay50YXJnZXQpKSYmcChrLnRhcmdldCl9ZnVuY3Rpb24gdihrKXthKGsudGFyZ2V0KSYmKGsudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucygiZm9jdXMtdmlzaWJsZSIpfHxrLnRhcmdldC5oYXNBdHRyaWJ1dGUoImRhdGEtZm9jdXMtdmlzaWJsZS1hZGRlZCIpKSYmKG49ITAsd2luZG93LmNsZWFyVGltZW91dChpKSxpPXdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7bj0hMX0sMTAwKSxsKGsudGFyZ2V0KSl9ZnVuY3Rpb24gUyhrKXtkb2N1bWVudC52aXNpYmlsaXR5U3RhdGU9PT0iaGlkZGVuIiYmKG4mJihvPSEwKSxYKCkpfWZ1bmN0aW9uIFgoKXtkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJtb3VzZW1vdmUiLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWRvd24iLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJtb3VzZXVwIixlZSksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigicG9pbnRlcm1vdmUiLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJwb2ludGVyZG93biIsZWUpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoInBvaW50ZXJ1cCIsZWUpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsZWUpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJ0b3VjaGVuZCIsZWUpfWZ1bmN0aW9uIHJlKCl7ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibW91c2Vkb3duIixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsZWUpLGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoInBvaW50ZXJtb3ZlIixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigicG9pbnRlcmRvd24iLGVlKSxkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCJwb2ludGVydXAiLGVlKSxkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCJ0b3VjaG1vdmUiLGVlKSxkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCJ0b3VjaHN0YXJ0IixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigidG91Y2hlbmQiLGVlKX1mdW5jdGlvbiBlZShrKXtrLnRhcmdldC5ub2RlTmFtZSYmay50YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PSJodG1sInx8KG89ITEscmUoKSl9ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigia2V5ZG93biIsZiwhMCksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vkb3duIix1LCEwKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJwb2ludGVyZG93biIsdSwhMCksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsdSwhMCksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigidmlzaWJpbGl0eWNoYW5nZSIsUywhMCksWCgpLHIuYWRkRXZlbnRMaXN0ZW5lcigiZm9jdXMiLGQsITApLHIuYWRkRXZlbnRMaXN0ZW5lcigiYmx1ciIsdiwhMCksci5ub2RlVHlwZT09PU5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSYmci5ob3N0P3IuaG9zdC5zZXRBdHRyaWJ1dGUoImRhdGEtanMtZm9jdXMtdmlzaWJsZSIsIiIpOnIubm9kZVR5cGU9PT1Ob2RlLkRPQ1VNRU5UX05PREUmJihkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgianMtZm9jdXMtdmlzaWJsZSIpLGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoImRhdGEtanMtZm9jdXMtdmlzaWJsZSIsIiIpKX1pZih0eXBlb2Ygd2luZG93IT0idW5kZWZpbmVkIiYmdHlwZW9mIGRvY3VtZW50IT0idW5kZWZpbmVkIil7d2luZG93LmFwcGx5Rm9jdXNWaXNpYmxlUG9seWZpbGw9ZTt2YXIgdDt0cnl7dD1uZXcgQ3VzdG9tRXZlbnQoImZvY3VzLXZpc2libGUtcG9seWZpbGwtcmVhZHkiKX1jYXRjaChyKXt0PWRvY3VtZW50LmNyZWF0ZUV2ZW50KCJDdXN0b21FdmVudCIpLHQuaW5pdEN1c3RvbUV2ZW50KCJmb2N1cy12aXNpYmxlLXBvbHlmaWxsLXJlYWR5IiwhMSwhMSx7fSl9d2luZG93LmRpc3BhdGNoRXZlbnQodCl9dHlwZW9mIGRvY3VtZW50IT0idW5kZWZpbmVkIiYmZShkb2N1bWVudCl9KSl9KTt2YXIgcm89Q3IoKGp5LFJuKT0+eyJ1c2Ugc3RyaWN0IjsvKiEKICogZXNjYXBlLWh0bWwKICogQ29weXJpZ2h0KGMpIDIwMTItMjAxMyBUSiBIb2xvd2F5Y2h1awogKiBDb3B5cmlnaHQoYykgMjAxNSBBbmRyZWFzIEx1YmJlCiAqIENvcHlyaWdodChjKSAyMDE1IFRpYW5jaGVuZyAiVGltb3RoeSIgR3UKICogTUlUIExpY2Vuc2VkCiAqL3ZhciBxYT0vWyInJjw+XS87Um4uZXhwb3J0cz1LYTtmdW5jdGlvbiBLYShlKXt2YXIgdD0iIitlLHI9cWEuZXhlYyh0KTtpZighcilyZXR1cm4gdDt2YXIgbyxuPSIiLGk9MCxzPTA7Zm9yKGk9ci5pbmRleDtpPHQubGVuZ3RoO2krKyl7c3dpdGNoKHQuY2hhckNvZGVBdChpKSl7Y2FzZSAzNDpvPSImcXVvdDsiO2JyZWFrO2Nhc2UgMzg6bz0iJmFtcDsiO2JyZWFrO2Nhc2UgMzk6bz0iJiMzOTsiO2JyZWFrO2Nhc2UgNjA6bz0iJmx0OyI7YnJlYWs7Y2FzZSA2MjpvPSImZ3Q7IjticmVhaztkZWZhdWx0OmNvbnRpbnVlfXMhPT1pJiYobis9dC5zdWJzdHJpbmcocyxpKSkscz1pKzEsbis9b31yZXR1cm4gcyE9PWk/bit0LnN1YnN0cmluZyhzLGkpOm59fSk7dmFyIGFvPUNyKChOdCxpbyk9PnsvKiEKICogY2xpcGJvYXJkLmpzIHYyLjAuMTEKICogaHR0cHM6Ly9jbGlwYm9hcmRqcy5jb20vCiAqCiAqIExpY2Vuc2VkIE1JVCDCqSBaZW5vIFJvY2hhCiAqLyhmdW5jdGlvbih0LHIpe3R5cGVvZiBOdD09Im9iamVjdCImJnR5cGVvZiBpbz09Im9iamVjdCI/aW8uZXhwb3J0cz1yKCk6dHlwZW9mIGRlZmluZT09ImZ1bmN0aW9uIiYmZGVmaW5lLmFtZD9kZWZpbmUoW10scik6dHlwZW9mIE50PT0ib2JqZWN0Ij9OdC5DbGlwYm9hcmRKUz1yKCk6dC5DbGlwYm9hcmRKUz1yKCl9KShOdCxmdW5jdGlvbigpe3JldHVybihmdW5jdGlvbigpe3ZhciBlPXs2ODY6KGZ1bmN0aW9uKG8sbixpKXsidXNlIHN0cmljdCI7aS5kKG4se2RlZmF1bHQ6ZnVuY3Rpb24oKXtyZXR1cm4gWGl9fSk7dmFyIHM9aSgyNzkpLGE9aS5uKHMpLGM9aSgzNzApLHA9aS5uKGMpLGw9aSg4MTcpLGY9aS5uKGwpO2Z1bmN0aW9uIHUocSl7dHJ5e3JldHVybiBkb2N1bWVudC5leGVjQ29tbWFuZChxKX1jYXRjaChDKXtyZXR1cm4hMX19dmFyIGQ9ZnVuY3Rpb24oQyl7dmFyIF89ZigpKEMpO3JldHVybiB1KCJjdXQiKSxffSx2PWQ7ZnVuY3Rpb24gUyhxKXt2YXIgQz1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKCJkaXIiKT09PSJydGwiLF89ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGV4dGFyZWEiKTtfLnN0eWxlLmZvbnRTaXplPSIxMnB0IixfLnN0eWxlLmJvcmRlcj0iMCIsXy5zdHlsZS5wYWRkaW5nPSIwIixfLnN0eWxlLm1hcmdpbj0iMCIsXy5zdHlsZS5wb3NpdGlvbj0iYWJzb2x1dGUiLF8uc3R5bGVbQz8icmlnaHQiOiJsZWZ0Il09Ii05OTk5cHgiO3ZhciBEPXdpbmRvdy5wYWdlWU9mZnNldHx8ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcDtyZXR1cm4gXy5zdHlsZS50b3A9IiIuY29uY2F0KEQsInB4IiksXy5zZXRBdHRyaWJ1dGUoInJlYWRvbmx5IiwiIiksXy52YWx1ZT1xLF99dmFyIFg9ZnVuY3Rpb24oQyxfKXt2YXIgRD1TKEMpO18uY29udGFpbmVyLmFwcGVuZENoaWxkKEQpO3ZhciBOPWYoKShEKTtyZXR1cm4gdSgiY29weSIpLEQucmVtb3ZlKCksTn0scmU9ZnVuY3Rpb24oQyl7dmFyIF89YXJndW1lbnRzLmxlbmd0aD4xJiZhcmd1bWVudHNbMV0hPT12b2lkIDA/YXJndW1lbnRzWzFdOntjb250YWluZXI6ZG9jdW1lbnQuYm9keX0sRD0iIjtyZXR1cm4gdHlwZW9mIEM9PSJzdHJpbmciP0Q9WChDLF8pOkMgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50JiYhWyJ0ZXh0Iiwic2VhcmNoIiwidXJsIiwidGVsIiwicGFzc3dvcmQiXS5pbmNsdWRlcyhDPT1udWxsP3ZvaWQgMDpDLnR5cGUpP0Q9WChDLnZhbHVlLF8pOihEPWYoKShDKSx1KCJjb3B5IikpLER9LGVlPXJlO2Z1bmN0aW9uIGsocSl7IkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mIjtyZXR1cm4gdHlwZW9mIFN5bWJvbD09ImZ1bmN0aW9uIiYmdHlwZW9mIFN5bWJvbC5pdGVyYXRvcj09InN5bWJvbCI/az1mdW5jdGlvbihfKXtyZXR1cm4gdHlwZW9mIF99Oms9ZnVuY3Rpb24oXyl7cmV0dXJuIF8mJnR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJl8uY29uc3RydWN0b3I9PT1TeW1ib2wmJl8hPT1TeW1ib2wucHJvdG90eXBlPyJzeW1ib2wiOnR5cGVvZiBffSxrKHEpfXZhciB1dD1mdW5jdGlvbigpe3ZhciBDPWFyZ3VtZW50cy5sZW5ndGg+MCYmYXJndW1lbnRzWzBdIT09dm9pZCAwP2FyZ3VtZW50c1swXTp7fSxfPUMuYWN0aW9uLEQ9Xz09PXZvaWQgMD8iY29weSI6XyxOPUMuY29udGFpbmVyLEc9Qy50YXJnZXQsV2U9Qy50ZXh0O2lmKEQhPT0iY29weSImJkQhPT0iY3V0Iil0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgImFjdGlvbiIgdmFsdWUsIHVzZSBlaXRoZXIgImNvcHkiIG9yICJjdXQiJyk7aWYoRyE9PXZvaWQgMClpZihHJiZrKEcpPT09Im9iamVjdCImJkcubm9kZVR5cGU9PT0xKXtpZihEPT09ImNvcHkiJiZHLmhhc0F0dHJpYnV0ZSgiZGlzYWJsZWQiKSl0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgInRhcmdldCIgYXR0cmlidXRlLiBQbGVhc2UgdXNlICJyZWFkb25seSIgaW5zdGVhZCBvZiAiZGlzYWJsZWQiIGF0dHJpYnV0ZScpO2lmKEQ9PT0iY3V0IiYmKEcuaGFzQXR0cmlidXRlKCJyZWFkb25seSIpfHxHLmhhc0F0dHJpYnV0ZSgiZGlzYWJsZWQiKSkpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkICJ0YXJnZXQiIGF0dHJpYnV0ZS4gWW91IGNhbid0IGN1dCB0ZXh0IGZyb20gZWxlbWVudHMgd2l0aCAicmVhZG9ubHkiIG9yICJkaXNhYmxlZCIgYXR0cmlidXRlc2ApfWVsc2UgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkICJ0YXJnZXQiIHZhbHVlLCB1c2UgYSB2YWxpZCBFbGVtZW50Jyk7aWYoV2UpcmV0dXJuIGVlKFdlLHtjb250YWluZXI6Tn0pO2lmKEcpcmV0dXJuIEQ9PT0iY3V0Ij92KEcpOmVlKEcse2NvbnRhaW5lcjpOfSl9LGplPXV0O2Z1bmN0aW9uIFIocSl7IkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mIjtyZXR1cm4gdHlwZW9mIFN5bWJvbD09ImZ1bmN0aW9uIiYmdHlwZW9mIFN5bWJvbC5pdGVyYXRvcj09InN5bWJvbCI/Uj1mdW5jdGlvbihfKXtyZXR1cm4gdHlwZW9mIF99OlI9ZnVuY3Rpb24oXyl7cmV0dXJuIF8mJnR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJl8uY29uc3RydWN0b3I9PT1TeW1ib2wmJl8hPT1TeW1ib2wucHJvdG90eXBlPyJzeW1ib2wiOnR5cGVvZiBffSxSKHEpfWZ1bmN0aW9uIHNlKHEsQyl7aWYoIShxIGluc3RhbmNlb2YgQykpdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIil9ZnVuY3Rpb24gY2UocSxDKXtmb3IodmFyIF89MDtfPEMubGVuZ3RoO18rKyl7dmFyIEQ9Q1tfXTtELmVudW1lcmFibGU9RC5lbnVtZXJhYmxlfHwhMSxELmNvbmZpZ3VyYWJsZT0hMCwidmFsdWUiaW4gRCYmKEQud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShxLEQua2V5LEQpfX1mdW5jdGlvbiBoZShxLEMsXyl7cmV0dXJuIEMmJmNlKHEucHJvdG90eXBlLEMpLF8mJmNlKHEsXykscX1mdW5jdGlvbiBTZShxLEMpe2lmKHR5cGVvZiBDIT0iZnVuY3Rpb24iJiZDIT09bnVsbCl0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiIpO3EucHJvdG90eXBlPU9iamVjdC5jcmVhdGUoQyYmQy5wcm90b3R5cGUse2NvbnN0cnVjdG9yOnt2YWx1ZTpxLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSxDJiZVZShxLEMpfWZ1bmN0aW9uIFVlKHEsQyl7cmV0dXJuIFVlPU9iamVjdC5zZXRQcm90b3R5cGVPZnx8ZnVuY3Rpb24oRCxOKXtyZXR1cm4gRC5fX3Byb3RvX189TixEfSxVZShxLEMpfWZ1bmN0aW9uIFFpKHEpe3ZhciBDPUdpKCk7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIEQ9UXQocSksTjtpZihDKXt2YXIgRz1RdCh0aGlzKS5jb25zdHJ1Y3RvcjtOPVJlZmxlY3QuY29uc3RydWN0KEQsYXJndW1lbnRzLEcpfWVsc2UgTj1ELmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gWWkodGhpcyxOKX19ZnVuY3Rpb24gWWkocSxDKXtyZXR1cm4gQyYmKFIoQyk9PT0ib2JqZWN0Inx8dHlwZW9mIEM9PSJmdW5jdGlvbiIpP0M6QmkocSl9ZnVuY3Rpb24gQmkocSl7aWYocT09PXZvaWQgMCl0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpO3JldHVybiBxfWZ1bmN0aW9uIEdpKCl7aWYodHlwZW9mIFJlZmxlY3Q9PSJ1bmRlZmluZWQifHwhUmVmbGVjdC5jb25zdHJ1Y3R8fFJlZmxlY3QuY29uc3RydWN0LnNoYW0pcmV0dXJuITE7aWYodHlwZW9mIFByb3h5PT0iZnVuY3Rpb24iKXJldHVybiEwO3RyeXtyZXR1cm4gRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChEYXRlLFtdLGZ1bmN0aW9uKCl7fSkpLCEwfWNhdGNoKHEpe3JldHVybiExfX1mdW5jdGlvbiBRdChxKXtyZXR1cm4gUXQ9T2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5nZXRQcm90b3R5cGVPZjpmdW5jdGlvbihfKXtyZXR1cm4gXy5fX3Byb3RvX198fE9iamVjdC5nZXRQcm90b3R5cGVPZihfKX0sUXQocSl9ZnVuY3Rpb24gTXIocSxDKXt2YXIgXz0iZGF0YS1jbGlwYm9hcmQtIi5jb25jYXQocSk7aWYoQy5oYXNBdHRyaWJ1dGUoXykpcmV0dXJuIEMuZ2V0QXR0cmlidXRlKF8pfXZhciBKaT0oZnVuY3Rpb24ocSl7U2UoXyxxKTt2YXIgQz1RaShfKTtmdW5jdGlvbiBfKEQsTil7dmFyIEc7cmV0dXJuIHNlKHRoaXMsXyksRz1DLmNhbGwodGhpcyksRy5yZXNvbHZlT3B0aW9ucyhOKSxHLmxpc3RlbkNsaWNrKEQpLEd9cmV0dXJuIGhlKF8sW3trZXk6InJlc29sdmVPcHRpb25zIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBOPWFyZ3VtZW50cy5sZW5ndGg+MCYmYXJndW1lbnRzWzBdIT09dm9pZCAwP2FyZ3VtZW50c1swXTp7fTt0aGlzLmFjdGlvbj10eXBlb2YgTi5hY3Rpb249PSJmdW5jdGlvbiI/Ti5hY3Rpb246dGhpcy5kZWZhdWx0QWN0aW9uLHRoaXMudGFyZ2V0PXR5cGVvZiBOLnRhcmdldD09ImZ1bmN0aW9uIj9OLnRhcmdldDp0aGlzLmRlZmF1bHRUYXJnZXQsdGhpcy50ZXh0PXR5cGVvZiBOLnRleHQ9PSJmdW5jdGlvbiI/Ti50ZXh0OnRoaXMuZGVmYXVsdFRleHQsdGhpcy5jb250YWluZXI9UihOLmNvbnRhaW5lcik9PT0ib2JqZWN0Ij9OLmNvbnRhaW5lcjpkb2N1bWVudC5ib2R5fX0se2tleToibGlzdGVuQ2xpY2siLHZhbHVlOmZ1bmN0aW9uKE4pe3ZhciBHPXRoaXM7dGhpcy5saXN0ZW5lcj1wKCkoTiwiY2xpY2siLGZ1bmN0aW9uKFdlKXtyZXR1cm4gRy5vbkNsaWNrKFdlKX0pfX0se2tleToib25DbGljayIsdmFsdWU6ZnVuY3Rpb24oTil7dmFyIEc9Ti5kZWxlZ2F0ZVRhcmdldHx8Ti5jdXJyZW50VGFyZ2V0LFdlPXRoaXMuYWN0aW9uKEcpfHwiY29weSIsWXQ9amUoe2FjdGlvbjpXZSxjb250YWluZXI6dGhpcy5jb250YWluZXIsdGFyZ2V0OnRoaXMudGFyZ2V0KEcpLHRleHQ6dGhpcy50ZXh0KEcpfSk7dGhpcy5lbWl0KFl0PyJzdWNjZXNzIjoiZXJyb3IiLHthY3Rpb246V2UsdGV4dDpZdCx0cmlnZ2VyOkcsY2xlYXJTZWxlY3Rpb246ZnVuY3Rpb24oKXtHJiZHLmZvY3VzKCksd2luZG93LmdldFNlbGVjdGlvbigpLnJlbW92ZUFsbFJhbmdlcygpfX0pfX0se2tleToiZGVmYXVsdEFjdGlvbiIsdmFsdWU6ZnVuY3Rpb24oTil7cmV0dXJuIE1yKCJhY3Rpb24iLE4pfX0se2tleToiZGVmYXVsdFRhcmdldCIsdmFsdWU6ZnVuY3Rpb24oTil7dmFyIEc9TXIoInRhcmdldCIsTik7aWYoRylyZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihHKX19LHtrZXk6ImRlZmF1bHRUZXh0Iix2YWx1ZTpmdW5jdGlvbihOKXtyZXR1cm4gTXIoInRleHQiLE4pfX0se2tleToiZGVzdHJveSIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLmxpc3RlbmVyLmRlc3Ryb3koKX19XSxbe2tleToiY29weSIsdmFsdWU6ZnVuY3Rpb24oTil7dmFyIEc9YXJndW1lbnRzLmxlbmd0aD4xJiZhcmd1bWVudHNbMV0hPT12b2lkIDA/YXJndW1lbnRzWzFdOntjb250YWluZXI6ZG9jdW1lbnQuYm9keX07cmV0dXJuIGVlKE4sRyl9fSx7a2V5OiJjdXQiLHZhbHVlOmZ1bmN0aW9uKE4pe3JldHVybiB2KE4pfX0se2tleToiaXNTdXBwb3J0ZWQiLHZhbHVlOmZ1bmN0aW9uKCl7dmFyIE49YXJndW1lbnRzLmxlbmd0aD4wJiZhcmd1bWVudHNbMF0hPT12b2lkIDA/YXJndW1lbnRzWzBdOlsiY29weSIsImN1dCJdLEc9dHlwZW9mIE49PSJzdHJpbmciP1tOXTpOLFdlPSEhZG9jdW1lbnQucXVlcnlDb21tYW5kU3VwcG9ydGVkO3JldHVybiBHLmZvckVhY2goZnVuY3Rpb24oWXQpe1dlPVdlJiYhIWRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN1cHBvcnRlZChZdCl9KSxXZX19XSksX30pKGEoKSksWGk9Sml9KSw4Mjg6KGZ1bmN0aW9uKG8pe3ZhciBuPTk7aWYodHlwZW9mIEVsZW1lbnQhPSJ1bmRlZmluZWQiJiYhRWxlbWVudC5wcm90b3R5cGUubWF0Y2hlcyl7dmFyIGk9RWxlbWVudC5wcm90b3R5cGU7aS5tYXRjaGVzPWkubWF0Y2hlc1NlbGVjdG9yfHxpLm1vek1hdGNoZXNTZWxlY3Rvcnx8aS5tc01hdGNoZXNTZWxlY3Rvcnx8aS5vTWF0Y2hlc1NlbGVjdG9yfHxpLndlYmtpdE1hdGNoZXNTZWxlY3Rvcn1mdW5jdGlvbiBzKGEsYyl7Zm9yKDthJiZhLm5vZGVUeXBlIT09bjspe2lmKHR5cGVvZiBhLm1hdGNoZXM9PSJmdW5jdGlvbiImJmEubWF0Y2hlcyhjKSlyZXR1cm4gYTthPWEucGFyZW50Tm9kZX19by5leHBvcnRzPXN9KSw0Mzg6KGZ1bmN0aW9uKG8sbixpKXt2YXIgcz1pKDgyOCk7ZnVuY3Rpb24gYShsLGYsdSxkLHYpe3ZhciBTPXAuYXBwbHkodGhpcyxhcmd1bWVudHMpO3JldHVybiBsLmFkZEV2ZW50TGlzdGVuZXIodSxTLHYpLHtkZXN0cm95OmZ1bmN0aW9uKCl7bC5yZW1vdmVFdmVudExpc3RlbmVyKHUsUyx2KX19fWZ1bmN0aW9uIGMobCxmLHUsZCx2KXtyZXR1cm4gdHlwZW9mIGwuYWRkRXZlbnRMaXN0ZW5lcj09ImZ1bmN0aW9uIj9hLmFwcGx5KG51bGwsYXJndW1lbnRzKTp0eXBlb2YgdT09ImZ1bmN0aW9uIj9hLmJpbmQobnVsbCxkb2N1bWVudCkuYXBwbHkobnVsbCxhcmd1bWVudHMpOih0eXBlb2YgbD09InN0cmluZyImJihsPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwobCkpLEFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChsLGZ1bmN0aW9uKFMpe3JldHVybiBhKFMsZix1LGQsdil9KSl9ZnVuY3Rpb24gcChsLGYsdSxkKXtyZXR1cm4gZnVuY3Rpb24odil7di5kZWxlZ2F0ZVRhcmdldD1zKHYudGFyZ2V0LGYpLHYuZGVsZWdhdGVUYXJnZXQmJmQuY2FsbChsLHYpfX1vLmV4cG9ydHM9Y30pLDg3OTooZnVuY3Rpb24obyxuKXtuLm5vZGU9ZnVuY3Rpb24oaSl7cmV0dXJuIGkhPT12b2lkIDAmJmkgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmaS5ub2RlVHlwZT09PTF9LG4ubm9kZUxpc3Q9ZnVuY3Rpb24oaSl7dmFyIHM9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGkpO3JldHVybiBpIT09dm9pZCAwJiYocz09PSJbb2JqZWN0IE5vZGVMaXN0XSJ8fHM9PT0iW29iamVjdCBIVE1MQ29sbGVjdGlvbl0iKSYmImxlbmd0aCJpbiBpJiYoaS5sZW5ndGg9PT0wfHxuLm5vZGUoaVswXSkpfSxuLnN0cmluZz1mdW5jdGlvbihpKXtyZXR1cm4gdHlwZW9mIGk9PSJzdHJpbmcifHxpIGluc3RhbmNlb2YgU3RyaW5nfSxuLmZuPWZ1bmN0aW9uKGkpe3ZhciBzPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpKTtyZXR1cm4gcz09PSJbb2JqZWN0IEZ1bmN0aW9uXSJ9fSksMzcwOihmdW5jdGlvbihvLG4saSl7dmFyIHM9aSg4NzkpLGE9aSg0MzgpO2Z1bmN0aW9uIGModSxkLHYpe2lmKCF1JiYhZCYmIXYpdGhyb3cgbmV3IEVycm9yKCJNaXNzaW5nIHJlcXVpcmVkIGFyZ3VtZW50cyIpO2lmKCFzLnN0cmluZyhkKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJTZWNvbmQgYXJndW1lbnQgbXVzdCBiZSBhIFN0cmluZyIpO2lmKCFzLmZuKHYpKXRocm93IG5ldyBUeXBlRXJyb3IoIlRoaXJkIGFyZ3VtZW50IG11c3QgYmUgYSBGdW5jdGlvbiIpO2lmKHMubm9kZSh1KSlyZXR1cm4gcCh1LGQsdik7aWYocy5ub2RlTGlzdCh1KSlyZXR1cm4gbCh1LGQsdik7aWYocy5zdHJpbmcodSkpcmV0dXJuIGYodSxkLHYpO3Rocm93IG5ldyBUeXBlRXJyb3IoIkZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBTdHJpbmcsIEhUTUxFbGVtZW50LCBIVE1MQ29sbGVjdGlvbiwgb3IgTm9kZUxpc3QiKX1mdW5jdGlvbiBwKHUsZCx2KXtyZXR1cm4gdS5hZGRFdmVudExpc3RlbmVyKGQsdikse2Rlc3Ryb3k6ZnVuY3Rpb24oKXt1LnJlbW92ZUV2ZW50TGlzdGVuZXIoZCx2KX19fWZ1bmN0aW9uIGwodSxkLHYpe3JldHVybiBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHUsZnVuY3Rpb24oUyl7Uy5hZGRFdmVudExpc3RlbmVyKGQsdil9KSx7ZGVzdHJveTpmdW5jdGlvbigpe0FycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwodSxmdW5jdGlvbihTKXtTLnJlbW92ZUV2ZW50TGlzdGVuZXIoZCx2KX0pfX19ZnVuY3Rpb24gZih1LGQsdil7cmV0dXJuIGEoZG9jdW1lbnQuYm9keSx1LGQsdil9by5leHBvcnRzPWN9KSw4MTc6KGZ1bmN0aW9uKG8pe2Z1bmN0aW9uIG4oaSl7dmFyIHM7aWYoaS5ub2RlTmFtZT09PSJTRUxFQ1QiKWkuZm9jdXMoKSxzPWkudmFsdWU7ZWxzZSBpZihpLm5vZGVOYW1lPT09IklOUFVUInx8aS5ub2RlTmFtZT09PSJURVhUQVJFQSIpe3ZhciBhPWkuaGFzQXR0cmlidXRlKCJyZWFkb25seSIpO2F8fGkuc2V0QXR0cmlidXRlKCJyZWFkb25seSIsIiIpLGkuc2VsZWN0KCksaS5zZXRTZWxlY3Rpb25SYW5nZSgwLGkudmFsdWUubGVuZ3RoKSxhfHxpLnJlbW92ZUF0dHJpYnV0ZSgicmVhZG9ubHkiKSxzPWkudmFsdWV9ZWxzZXtpLmhhc0F0dHJpYnV0ZSgiY29udGVudGVkaXRhYmxlIikmJmkuZm9jdXMoKTt2YXIgYz13aW5kb3cuZ2V0U2VsZWN0aW9uKCkscD1kb2N1bWVudC5jcmVhdGVSYW5nZSgpO3Auc2VsZWN0Tm9kZUNvbnRlbnRzKGkpLGMucmVtb3ZlQWxsUmFuZ2VzKCksYy5hZGRSYW5nZShwKSxzPWMudG9TdHJpbmcoKX1yZXR1cm4gc31vLmV4cG9ydHM9bn0pLDI3OTooZnVuY3Rpb24obyl7ZnVuY3Rpb24gbigpe31uLnByb3RvdHlwZT17b246ZnVuY3Rpb24oaSxzLGEpe3ZhciBjPXRoaXMuZXx8KHRoaXMuZT17fSk7cmV0dXJuKGNbaV18fChjW2ldPVtdKSkucHVzaCh7Zm46cyxjdHg6YX0pLHRoaXN9LG9uY2U6ZnVuY3Rpb24oaSxzLGEpe3ZhciBjPXRoaXM7ZnVuY3Rpb24gcCgpe2Mub2ZmKGkscCkscy5hcHBseShhLGFyZ3VtZW50cyl9cmV0dXJuIHAuXz1zLHRoaXMub24oaSxwLGEpfSxlbWl0OmZ1bmN0aW9uKGkpe3ZhciBzPVtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpLGE9KCh0aGlzLmV8fCh0aGlzLmU9e30pKVtpXXx8W10pLnNsaWNlKCksYz0wLHA9YS5sZW5ndGg7Zm9yKGM7YzxwO2MrKylhW2NdLmZuLmFwcGx5KGFbY10uY3R4LHMpO3JldHVybiB0aGlzfSxvZmY6ZnVuY3Rpb24oaSxzKXt2YXIgYT10aGlzLmV8fCh0aGlzLmU9e30pLGM9YVtpXSxwPVtdO2lmKGMmJnMpZm9yKHZhciBsPTAsZj1jLmxlbmd0aDtsPGY7bCsrKWNbbF0uZm4hPT1zJiZjW2xdLmZuLl8hPT1zJiZwLnB1c2goY1tsXSk7cmV0dXJuIHAubGVuZ3RoP2FbaV09cDpkZWxldGUgYVtpXSx0aGlzfX0sby5leHBvcnRzPW4sby5leHBvcnRzLlRpbnlFbWl0dGVyPW59KX0sdD17fTtmdW5jdGlvbiByKG8pe2lmKHRbb10pcmV0dXJuIHRbb10uZXhwb3J0czt2YXIgbj10W29dPXtleHBvcnRzOnt9fTtyZXR1cm4gZVtvXShuLG4uZXhwb3J0cyxyKSxuLmV4cG9ydHN9cmV0dXJuKGZ1bmN0aW9uKCl7ci5uPWZ1bmN0aW9uKG8pe3ZhciBuPW8mJm8uX19lc01vZHVsZT9mdW5jdGlvbigpe3JldHVybiBvLmRlZmF1bHR9OmZ1bmN0aW9uKCl7cmV0dXJuIG99O3JldHVybiByLmQobix7YTpufSksbn19KSgpLChmdW5jdGlvbigpe3IuZD1mdW5jdGlvbihvLG4pe2Zvcih2YXIgaSBpbiBuKXIubyhuLGkpJiYhci5vKG8saSkmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLGkse2VudW1lcmFibGU6ITAsZ2V0Om5baV19KX19KSgpLChmdW5jdGlvbigpe3Iubz1mdW5jdGlvbihvLG4pe3JldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobyxuKX19KSgpLHIoNjg2KX0pKCkuZGVmYXVsdH0pfSk7dmFyIFpNPSR0KHhvKCkpO3ZhciBIcj1mdW5jdGlvbihlLHQpe3JldHVybiBIcj1PYmplY3Quc2V0UHJvdG90eXBlT2Z8fHtfX3Byb3RvX186W119aW5zdGFuY2VvZiBBcnJheSYmZnVuY3Rpb24ocixvKXtyLl9fcHJvdG9fXz1vfXx8ZnVuY3Rpb24ocixvKXtmb3IodmFyIG4gaW4gbylPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobyxuKSYmKHJbbl09b1tuXSl9LEhyKGUsdCl9O2Z1bmN0aW9uIGllKGUsdCl7aWYodHlwZW9mIHQhPSJmdW5jdGlvbiImJnQhPT1udWxsKXRocm93IG5ldyBUeXBlRXJyb3IoIkNsYXNzIGV4dGVuZHMgdmFsdWUgIitTdHJpbmcodCkrIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsIik7SHIoZSx0KTtmdW5jdGlvbiByKCl7dGhpcy5jb25zdHJ1Y3Rvcj1lfWUucHJvdG90eXBlPXQ9PT1udWxsP09iamVjdC5jcmVhdGUodCk6KHIucHJvdG90eXBlPXQucHJvdG90eXBlLG5ldyByKX1mdW5jdGlvbiBFbyhlLHQscixvKXtmdW5jdGlvbiBuKGkpe3JldHVybiBpIGluc3RhbmNlb2Ygcj9pOm5ldyByKGZ1bmN0aW9uKHMpe3MoaSl9KX1yZXR1cm4gbmV3KHJ8fChyPVByb21pc2UpKShmdW5jdGlvbihpLHMpe2Z1bmN0aW9uIGEobCl7dHJ5e3Aoby5uZXh0KGwpKX1jYXRjaChmKXtzKGYpfX1mdW5jdGlvbiBjKGwpe3RyeXtwKG8udGhyb3cobCkpfWNhdGNoKGYpe3MoZil9fWZ1bmN0aW9uIHAobCl7bC5kb25lP2kobC52YWx1ZSk6bihsLnZhbHVlKS50aGVuKGEsYyl9cCgobz1vLmFwcGx5KGUsdHx8W10pKS5uZXh0KCkpfSl9ZnVuY3Rpb24gR3QoZSx0KXt2YXIgcj17bGFiZWw6MCxzZW50OmZ1bmN0aW9uKCl7aWYoaVswXSYxKXRocm93IGlbMV07cmV0dXJuIGlbMV19LHRyeXM6W10sb3BzOltdfSxvLG4saSxzPU9iamVjdC5jcmVhdGUoKHR5cGVvZiBJdGVyYXRvcj09ImZ1bmN0aW9uIj9JdGVyYXRvcjpPYmplY3QpLnByb3RvdHlwZSk7cmV0dXJuIHMubmV4dD1hKDApLHMudGhyb3c9YSgxKSxzLnJldHVybj1hKDIpLHR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJihzW1N5bWJvbC5pdGVyYXRvcl09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30pLHM7ZnVuY3Rpb24gYShwKXtyZXR1cm4gZnVuY3Rpb24obCl7cmV0dXJuIGMoW3AsbF0pfX1mdW5jdGlvbiBjKHApe2lmKG8pdGhyb3cgbmV3IFR5cGVFcnJvcigiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLiIpO2Zvcig7cyYmKHM9MCxwWzBdJiYocj0wKSkscjspdHJ5e2lmKG89MSxuJiYoaT1wWzBdJjI/bi5yZXR1cm46cFswXT9uLnRocm93fHwoKGk9bi5yZXR1cm4pJiZpLmNhbGwobiksMCk6bi5uZXh0KSYmIShpPWkuY2FsbChuLHBbMV0pKS5kb25lKXJldHVybiBpO3N3aXRjaChuPTAsaSYmKHA9W3BbMF0mMixpLnZhbHVlXSkscFswXSl7Y2FzZSAwOmNhc2UgMTppPXA7YnJlYWs7Y2FzZSA0OnJldHVybiByLmxhYmVsKysse3ZhbHVlOnBbMV0sZG9uZTohMX07Y2FzZSA1OnIubGFiZWwrKyxuPXBbMV0scD1bMF07Y29udGludWU7Y2FzZSA3OnA9ci5vcHMucG9wKCksci50cnlzLnBvcCgpO2NvbnRpbnVlO2RlZmF1bHQ6aWYoaT1yLnRyeXMsIShpPWkubGVuZ3RoPjAmJmlbaS5sZW5ndGgtMV0pJiYocFswXT09PTZ8fHBbMF09PT0yKSl7cj0wO2NvbnRpbnVlfWlmKHBbMF09PT0zJiYoIWl8fHBbMV0+aVswXSYmcFsxXTxpWzNdKSl7ci5sYWJlbD1wWzFdO2JyZWFrfWlmKHBbMF09PT02JiZyLmxhYmVsPGlbMV0pe3IubGFiZWw9aVsxXSxpPXA7YnJlYWt9aWYoaSYmci5sYWJlbDxpWzJdKXtyLmxhYmVsPWlbMl0sci5vcHMucHVzaChwKTticmVha31pWzJdJiZyLm9wcy5wb3AoKSxyLnRyeXMucG9wKCk7Y29udGludWV9cD10LmNhbGwoZSxyKX1jYXRjaChsKXtwPVs2LGxdLG49MH1maW5hbGx5e289aT0wfWlmKHBbMF0mNSl0aHJvdyBwWzFdO3JldHVybnt2YWx1ZTpwWzBdP3BbMV06dm9pZCAwLGRvbmU6ITB9fX1mdW5jdGlvbiBPZShlKXt2YXIgdD10eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZTeW1ib2wuaXRlcmF0b3Iscj10JiZlW3RdLG89MDtpZihyKXJldHVybiByLmNhbGwoZSk7aWYoZSYmdHlwZW9mIGUubGVuZ3RoPT0ibnVtYmVyIilyZXR1cm57bmV4dDpmdW5jdGlvbigpe3JldHVybiBlJiZvPj1lLmxlbmd0aCYmKGU9dm9pZCAwKSx7dmFsdWU6ZSYmZVtvKytdLGRvbmU6IWV9fX07dGhyb3cgbmV3IFR5cGVFcnJvcih0PyJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLiI6IlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC4iKX1mdW5jdGlvbiBLKGUsdCl7dmFyIHI9dHlwZW9mIFN5bWJvbD09ImZ1bmN0aW9uIiYmZVtTeW1ib2wuaXRlcmF0b3JdO2lmKCFyKXJldHVybiBlO3ZhciBvPXIuY2FsbChlKSxuLGk9W10sczt0cnl7Zm9yKDsodD09PXZvaWQgMHx8dC0tID4wKSYmIShuPW8ubmV4dCgpKS5kb25lOylpLnB1c2gobi52YWx1ZSl9Y2F0Y2goYSl7cz17ZXJyb3I6YX19ZmluYWxseXt0cnl7biYmIW4uZG9uZSYmKHI9by5yZXR1cm4pJiZyLmNhbGwobyl9ZmluYWxseXtpZihzKXRocm93IHMuZXJyb3J9fXJldHVybiBpfWZ1bmN0aW9uIEIoZSx0LHIpe2lmKHJ8fGFyZ3VtZW50cy5sZW5ndGg9PT0yKWZvcih2YXIgbz0wLG49dC5sZW5ndGgsaTtvPG47bysrKShpfHwhKG8gaW4gdCkpJiYoaXx8KGk9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodCwwLG8pKSxpW29dPXRbb10pO3JldHVybiBlLmNvbmNhdChpfHxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0KSl9ZnVuY3Rpb24gZHQoZSl7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBkdD8odGhpcy52PWUsdGhpcyk6bmV3IGR0KGUpfWZ1bmN0aW9uIHdvKGUsdCxyKXtpZighU3ltYm9sLmFzeW5jSXRlcmF0b3IpdGhyb3cgbmV3IFR5cGVFcnJvcigiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuIik7dmFyIG89ci5hcHBseShlLHR8fFtdKSxuLGk9W107cmV0dXJuIG49T2JqZWN0LmNyZWF0ZSgodHlwZW9mIEFzeW5jSXRlcmF0b3I9PSJmdW5jdGlvbiI/QXN5bmNJdGVyYXRvcjpPYmplY3QpLnByb3RvdHlwZSksYSgibmV4dCIpLGEoInRocm93IiksYSgicmV0dXJuIixzKSxuW1N5bWJvbC5hc3luY0l0ZXJhdG9yXT1mdW5jdGlvbigpe3JldHVybiB0aGlzfSxuO2Z1bmN0aW9uIHMoZCl7cmV0dXJuIGZ1bmN0aW9uKHYpe3JldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihkLGYpfX1mdW5jdGlvbiBhKGQsdil7b1tkXSYmKG5bZF09ZnVuY3Rpb24oUyl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKFgscmUpe2kucHVzaChbZCxTLFgscmVdKT4xfHxjKGQsUyl9KX0sdiYmKG5bZF09dihuW2RdKSkpfWZ1bmN0aW9uIGMoZCx2KXt0cnl7cChvW2RdKHYpKX1jYXRjaChTKXt1KGlbMF1bM10sUyl9fWZ1bmN0aW9uIHAoZCl7ZC52YWx1ZSBpbnN0YW5jZW9mIGR0P1Byb21pc2UucmVzb2x2ZShkLnZhbHVlLnYpLnRoZW4obCxmKTp1KGlbMF1bMl0sZCl9ZnVuY3Rpb24gbChkKXtjKCJuZXh0IixkKX1mdW5jdGlvbiBmKGQpe2MoInRocm93IixkKX1mdW5jdGlvbiB1KGQsdil7ZCh2KSxpLnNoaWZ0KCksaS5sZW5ndGgmJmMoaVswXVswXSxpWzBdWzFdKX19ZnVuY3Rpb24gVG8oZSl7aWYoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKXRocm93IG5ldyBUeXBlRXJyb3IoIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpO3ZhciB0PWVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdLHI7cmV0dXJuIHQ/dC5jYWxsKGUpOihlPXR5cGVvZiBPZT09ImZ1bmN0aW9uIj9PZShlKTplW1N5bWJvbC5pdGVyYXRvcl0oKSxyPXt9LG8oIm5leHQiKSxvKCJ0aHJvdyIpLG8oInJldHVybiIpLHJbU3ltYm9sLmFzeW5jSXRlcmF0b3JdPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9LHIpO2Z1bmN0aW9uIG8oaSl7cltpXT1lW2ldJiZmdW5jdGlvbihzKXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oYSxjKXtzPWVbaV0ocyksbihhLGMscy5kb25lLHMudmFsdWUpfSl9fWZ1bmN0aW9uIG4oaSxzLGEsYyl7UHJvbWlzZS5yZXNvbHZlKGMpLnRoZW4oZnVuY3Rpb24ocCl7aSh7dmFsdWU6cCxkb25lOmF9KX0scyl9fWZ1bmN0aW9uIEkoZSl7cmV0dXJuIHR5cGVvZiBlPT0iZnVuY3Rpb24ifWZ1bmN0aW9uIHl0KGUpe3ZhciB0PWZ1bmN0aW9uKG8pe0Vycm9yLmNhbGwobyksby5zdGFjaz1uZXcgRXJyb3IoKS5zdGFja30scj1lKHQpO3JldHVybiByLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSksci5wcm90b3R5cGUuY29uc3RydWN0b3I9cixyfXZhciBKdD15dChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24ocil7ZSh0aGlzKSx0aGlzLm1lc3NhZ2U9cj9yLmxlbmd0aCtgIGVycm9ycyBvY2N1cnJlZCBkdXJpbmcgdW5zdWJzY3JpcHRpb246CmArci5tYXAoZnVuY3Rpb24obyxuKXtyZXR1cm4gbisxKyIpICIrby50b1N0cmluZygpfSkuam9pbihgCiAgYCk6IiIsdGhpcy5uYW1lPSJVbnN1YnNjcmlwdGlvbkVycm9yIix0aGlzLmVycm9ycz1yfX0pO2Z1bmN0aW9uIFplKGUsdCl7aWYoZSl7dmFyIHI9ZS5pbmRleE9mKHQpOzA8PXImJmUuc3BsaWNlKHIsMSl9fXZhciBxZT0oZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQpe3RoaXMuaW5pdGlhbFRlYXJkb3duPXQsdGhpcy5jbG9zZWQ9ITEsdGhpcy5fcGFyZW50YWdlPW51bGwsdGhpcy5fZmluYWxpemVycz1udWxsfXJldHVybiBlLnByb3RvdHlwZS51bnN1YnNjcmliZT1mdW5jdGlvbigpe3ZhciB0LHIsbyxuLGk7aWYoIXRoaXMuY2xvc2VkKXt0aGlzLmNsb3NlZD0hMDt2YXIgcz10aGlzLl9wYXJlbnRhZ2U7aWYocylpZih0aGlzLl9wYXJlbnRhZ2U9bnVsbCxBcnJheS5pc0FycmF5KHMpKXRyeXtmb3IodmFyIGE9T2UocyksYz1hLm5leHQoKTshYy5kb25lO2M9YS5uZXh0KCkpe3ZhciBwPWMudmFsdWU7cC5yZW1vdmUodGhpcyl9fWNhdGNoKFMpe3Q9e2Vycm9yOlN9fWZpbmFsbHl7dHJ5e2MmJiFjLmRvbmUmJihyPWEucmV0dXJuKSYmci5jYWxsKGEpfWZpbmFsbHl7aWYodCl0aHJvdyB0LmVycm9yfX1lbHNlIHMucmVtb3ZlKHRoaXMpO3ZhciBsPXRoaXMuaW5pdGlhbFRlYXJkb3duO2lmKEkobCkpdHJ5e2woKX1jYXRjaChTKXtpPVMgaW5zdGFuY2VvZiBKdD9TLmVycm9yczpbU119dmFyIGY9dGhpcy5fZmluYWxpemVycztpZihmKXt0aGlzLl9maW5hbGl6ZXJzPW51bGw7dHJ5e2Zvcih2YXIgdT1PZShmKSxkPXUubmV4dCgpOyFkLmRvbmU7ZD11Lm5leHQoKSl7dmFyIHY9ZC52YWx1ZTt0cnl7U28odil9Y2F0Y2goUyl7aT1pIT1udWxsP2k6W10sUyBpbnN0YW5jZW9mIEp0P2k9QihCKFtdLEsoaSkpLEsoUy5lcnJvcnMpKTppLnB1c2goUyl9fX1jYXRjaChTKXtvPXtlcnJvcjpTfX1maW5hbGx5e3RyeXtkJiYhZC5kb25lJiYobj11LnJldHVybikmJm4uY2FsbCh1KX1maW5hbGx5e2lmKG8pdGhyb3cgby5lcnJvcn19fWlmKGkpdGhyb3cgbmV3IEp0KGkpfX0sZS5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQpe3ZhciByO2lmKHQmJnQhPT10aGlzKWlmKHRoaXMuY2xvc2VkKVNvKHQpO2Vsc2V7aWYodCBpbnN0YW5jZW9mIGUpe2lmKHQuY2xvc2VkfHx0Ll9oYXNQYXJlbnQodGhpcykpcmV0dXJuO3QuX2FkZFBhcmVudCh0aGlzKX0odGhpcy5fZmluYWxpemVycz0ocj10aGlzLl9maW5hbGl6ZXJzKSE9PW51bGwmJnIhPT12b2lkIDA/cjpbXSkucHVzaCh0KX19LGUucHJvdG90eXBlLl9oYXNQYXJlbnQ9ZnVuY3Rpb24odCl7dmFyIHI9dGhpcy5fcGFyZW50YWdlO3JldHVybiByPT09dHx8QXJyYXkuaXNBcnJheShyKSYmci5pbmNsdWRlcyh0KX0sZS5wcm90b3R5cGUuX2FkZFBhcmVudD1mdW5jdGlvbih0KXt2YXIgcj10aGlzLl9wYXJlbnRhZ2U7dGhpcy5fcGFyZW50YWdlPUFycmF5LmlzQXJyYXkocik/KHIucHVzaCh0KSxyKTpyP1tyLHRdOnR9LGUucHJvdG90eXBlLl9yZW1vdmVQYXJlbnQ9ZnVuY3Rpb24odCl7dmFyIHI9dGhpcy5fcGFyZW50YWdlO3I9PT10P3RoaXMuX3BhcmVudGFnZT1udWxsOkFycmF5LmlzQXJyYXkocikmJlplKHIsdCl9LGUucHJvdG90eXBlLnJlbW92ZT1mdW5jdGlvbih0KXt2YXIgcj10aGlzLl9maW5hbGl6ZXJzO3ImJlplKHIsdCksdCBpbnN0YW5jZW9mIGUmJnQuX3JlbW92ZVBhcmVudCh0aGlzKX0sZS5FTVBUWT0oZnVuY3Rpb24oKXt2YXIgdD1uZXcgZTtyZXR1cm4gdC5jbG9zZWQ9ITAsdH0pKCksZX0pKCk7dmFyICRyPXFlLkVNUFRZO2Z1bmN0aW9uIFh0KGUpe3JldHVybiBlIGluc3RhbmNlb2YgcWV8fGUmJiJjbG9zZWQiaW4gZSYmSShlLnJlbW92ZSkmJkkoZS5hZGQpJiZJKGUudW5zdWJzY3JpYmUpfWZ1bmN0aW9uIFNvKGUpe0koZSk/ZSgpOmUudW5zdWJzY3JpYmUoKX12YXIgRGU9e29uVW5oYW5kbGVkRXJyb3I6bnVsbCxvblN0b3BwZWROb3RpZmljYXRpb246bnVsbCxQcm9taXNlOnZvaWQgMCx1c2VEZXByZWNhdGVkU3luY2hyb25vdXNFcnJvckhhbmRsaW5nOiExLHVzZURlcHJlY2F0ZWROZXh0Q29udGV4dDohMX07dmFyIHh0PXtzZXRUaW1lb3V0OmZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPVtdLG89MjtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbby0yXT1hcmd1bWVudHNbb107dmFyIG49eHQuZGVsZWdhdGU7cmV0dXJuIG4hPW51bGwmJm4uc2V0VGltZW91dD9uLnNldFRpbWVvdXQuYXBwbHkobixCKFtlLHRdLEsocikpKTpzZXRUaW1lb3V0LmFwcGx5KHZvaWQgMCxCKFtlLHRdLEsocikpKX0sY2xlYXJUaW1lb3V0OmZ1bmN0aW9uKGUpe3ZhciB0PXh0LmRlbGVnYXRlO3JldHVybigodD09bnVsbD92b2lkIDA6dC5jbGVhclRpbWVvdXQpfHxjbGVhclRpbWVvdXQpKGUpfSxkZWxlZ2F0ZTp2b2lkIDB9O2Z1bmN0aW9uIFp0KGUpe3h0LnNldFRpbWVvdXQoZnVuY3Rpb24oKXt2YXIgdD1EZS5vblVuaGFuZGxlZEVycm9yO2lmKHQpdChlKTtlbHNlIHRocm93IGV9KX1mdW5jdGlvbiBnZSgpe312YXIgT289KGZ1bmN0aW9uKCl7cmV0dXJuIFByKCJDIix2b2lkIDAsdm9pZCAwKX0pKCk7ZnVuY3Rpb24gTG8oZSl7cmV0dXJuIFByKCJFIix2b2lkIDAsZSl9ZnVuY3Rpb24gTW8oZSl7cmV0dXJuIFByKCJOIixlLHZvaWQgMCl9ZnVuY3Rpb24gUHIoZSx0LHIpe3JldHVybntraW5kOmUsdmFsdWU6dCxlcnJvcjpyfX12YXIgaHQ9bnVsbDtmdW5jdGlvbiBFdChlKXtpZihEZS51c2VEZXByZWNhdGVkU3luY2hyb25vdXNFcnJvckhhbmRsaW5nKXt2YXIgdD0haHQ7aWYodCYmKGh0PXtlcnJvclRocm93bjohMSxlcnJvcjpudWxsfSksZSgpLHQpe3ZhciByPWh0LG89ci5lcnJvclRocm93bixuPXIuZXJyb3I7aWYoaHQ9bnVsbCxvKXRocm93IG59fWVsc2UgZSgpfWZ1bmN0aW9uIF9vKGUpe0RlLnVzZURlcHJlY2F0ZWRTeW5jaHJvbm91c0Vycm9ySGFuZGxpbmcmJmh0JiYoaHQuZXJyb3JUaHJvd249ITAsaHQuZXJyb3I9ZSl9dmFyIFB0PShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQocil7dmFyIG89ZS5jYWxsKHRoaXMpfHx0aGlzO3JldHVybiBvLmlzU3RvcHBlZD0hMSxyPyhvLmRlc3RpbmF0aW9uPXIsWHQocikmJnIuYWRkKG8pKTpvLmRlc3RpbmF0aW9uPXNhLG99cmV0dXJuIHQuY3JlYXRlPWZ1bmN0aW9uKHIsbyxuKXtyZXR1cm4gbmV3IGJ0KHIsbyxuKX0sdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXt0aGlzLmlzU3RvcHBlZD9JcihNbyhyKSx0aGlzKTp0aGlzLl9uZXh0KHIpfSx0LnByb3RvdHlwZS5lcnJvcj1mdW5jdGlvbihyKXt0aGlzLmlzU3RvcHBlZD9JcihMbyhyKSx0aGlzKToodGhpcy5pc1N0b3BwZWQ9ITAsdGhpcy5fZXJyb3IocikpfSx0LnByb3RvdHlwZS5jb21wbGV0ZT1mdW5jdGlvbigpe3RoaXMuaXNTdG9wcGVkP0lyKE9vLHRoaXMpOih0aGlzLmlzU3RvcHBlZD0hMCx0aGlzLl9jb21wbGV0ZSgpKX0sdC5wcm90b3R5cGUudW5zdWJzY3JpYmU9ZnVuY3Rpb24oKXt0aGlzLmNsb3NlZHx8KHRoaXMuaXNTdG9wcGVkPSEwLGUucHJvdG90eXBlLnVuc3Vic2NyaWJlLmNhbGwodGhpcyksdGhpcy5kZXN0aW5hdGlvbj1udWxsKX0sdC5wcm90b3R5cGUuX25leHQ9ZnVuY3Rpb24ocil7dGhpcy5kZXN0aW5hdGlvbi5uZXh0KHIpfSx0LnByb3RvdHlwZS5fZXJyb3I9ZnVuY3Rpb24ocil7dHJ5e3RoaXMuZGVzdGluYXRpb24uZXJyb3Iocil9ZmluYWxseXt0aGlzLnVuc3Vic2NyaWJlKCl9fSx0LnByb3RvdHlwZS5fY29tcGxldGU9ZnVuY3Rpb24oKXt0cnl7dGhpcy5kZXN0aW5hdGlvbi5jb21wbGV0ZSgpfWZpbmFsbHl7dGhpcy51bnN1YnNjcmliZSgpfX0sdH0pKHFlKTt2YXIgbmE9RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQ7ZnVuY3Rpb24gUnIoZSx0KXtyZXR1cm4gbmEuY2FsbChlLHQpfXZhciBpYT0oZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQpe3RoaXMucGFydGlhbE9ic2VydmVyPXR9cmV0dXJuIGUucHJvdG90eXBlLm5leHQ9ZnVuY3Rpb24odCl7dmFyIHI9dGhpcy5wYXJ0aWFsT2JzZXJ2ZXI7aWYoci5uZXh0KXRyeXtyLm5leHQodCl9Y2F0Y2gobyl7ZXIobyl9fSxlLnByb3RvdHlwZS5lcnJvcj1mdW5jdGlvbih0KXt2YXIgcj10aGlzLnBhcnRpYWxPYnNlcnZlcjtpZihyLmVycm9yKXRyeXtyLmVycm9yKHQpfWNhdGNoKG8pe2VyKG8pfWVsc2UgZXIodCl9LGUucHJvdG90eXBlLmNvbXBsZXRlPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5wYXJ0aWFsT2JzZXJ2ZXI7aWYodC5jb21wbGV0ZSl0cnl7dC5jb21wbGV0ZSgpfWNhdGNoKHIpe2VyKHIpfX0sZX0pKCksYnQ9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8sbil7dmFyIGk9ZS5jYWxsKHRoaXMpfHx0aGlzLHM7aWYoSShyKXx8IXIpcz17bmV4dDpyIT1udWxsP3I6dm9pZCAwLGVycm9yOm8hPW51bGw/bzp2b2lkIDAsY29tcGxldGU6biE9bnVsbD9uOnZvaWQgMH07ZWxzZXt2YXIgYTtpJiZEZS51c2VEZXByZWNhdGVkTmV4dENvbnRleHQ/KGE9T2JqZWN0LmNyZWF0ZShyKSxhLnVuc3Vic2NyaWJlPWZ1bmN0aW9uKCl7cmV0dXJuIGkudW5zdWJzY3JpYmUoKX0scz17bmV4dDpyLm5leHQmJlJyKHIubmV4dCxhKSxlcnJvcjpyLmVycm9yJiZScihyLmVycm9yLGEpLGNvbXBsZXRlOnIuY29tcGxldGUmJlJyKHIuY29tcGxldGUsYSl9KTpzPXJ9cmV0dXJuIGkuZGVzdGluYXRpb249bmV3IGlhKHMpLGl9cmV0dXJuIHR9KShQdCk7ZnVuY3Rpb24gZXIoZSl7RGUudXNlRGVwcmVjYXRlZFN5bmNocm9ub3VzRXJyb3JIYW5kbGluZz9fbyhlKTpadChlKX1mdW5jdGlvbiBhYShlKXt0aHJvdyBlfWZ1bmN0aW9uIElyKGUsdCl7dmFyIHI9RGUub25TdG9wcGVkTm90aWZpY2F0aW9uO3ImJnh0LnNldFRpbWVvdXQoZnVuY3Rpb24oKXtyZXR1cm4gcihlLHQpfSl9dmFyIHNhPXtjbG9zZWQ6ITAsbmV4dDpnZSxlcnJvcjphYSxjb21wbGV0ZTpnZX07dmFyIHd0PShmdW5jdGlvbigpe3JldHVybiB0eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZTeW1ib2wub2JzZXJ2YWJsZXx8IkBAb2JzZXJ2YWJsZSJ9KSgpO2Z1bmN0aW9uIGJlKGUpe3JldHVybiBlfWZ1bmN0aW9uIEFvKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3JldHVybiBGcihlKX1mdW5jdGlvbiBGcihlKXtyZXR1cm4gZS5sZW5ndGg9PT0wP2JlOmUubGVuZ3RoPT09MT9lWzBdOmZ1bmN0aW9uKHIpe3JldHVybiBlLnJlZHVjZShmdW5jdGlvbihvLG4pe3JldHVybiBuKG8pfSxyKX19dmFyIEY9KGZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSh0KXt0JiYodGhpcy5fc3Vic2NyaWJlPXQpfXJldHVybiBlLnByb3RvdHlwZS5saWZ0PWZ1bmN0aW9uKHQpe3ZhciByPW5ldyBlO3JldHVybiByLnNvdXJjZT10aGlzLHIub3BlcmF0b3I9dCxyfSxlLnByb3RvdHlwZS5zdWJzY3JpYmU9ZnVuY3Rpb24odCxyLG8pe3ZhciBuPXRoaXMsaT1wYSh0KT90Om5ldyBidCh0LHIsbyk7cmV0dXJuIEV0KGZ1bmN0aW9uKCl7dmFyIHM9bixhPXMub3BlcmF0b3IsYz1zLnNvdXJjZTtpLmFkZChhP2EuY2FsbChpLGMpOmM/bi5fc3Vic2NyaWJlKGkpOm4uX3RyeVN1YnNjcmliZShpKSl9KSxpfSxlLnByb3RvdHlwZS5fdHJ5U3Vic2NyaWJlPWZ1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdGhpcy5fc3Vic2NyaWJlKHQpfWNhdGNoKHIpe3QuZXJyb3Iocil9fSxlLnByb3RvdHlwZS5mb3JFYWNoPWZ1bmN0aW9uKHQscil7dmFyIG89dGhpcztyZXR1cm4gcj1DbyhyKSxuZXcgcihmdW5jdGlvbihuLGkpe3ZhciBzPW5ldyBidCh7bmV4dDpmdW5jdGlvbihhKXt0cnl7dChhKX1jYXRjaChjKXtpKGMpLHMudW5zdWJzY3JpYmUoKX19LGVycm9yOmksY29tcGxldGU6bn0pO28uc3Vic2NyaWJlKHMpfSl9LGUucHJvdG90eXBlLl9zdWJzY3JpYmU9ZnVuY3Rpb24odCl7dmFyIHI7cmV0dXJuKHI9dGhpcy5zb3VyY2UpPT09bnVsbHx8cj09PXZvaWQgMD92b2lkIDA6ci5zdWJzY3JpYmUodCl9LGUucHJvdG90eXBlW3d0XT1mdW5jdGlvbigpe3JldHVybiB0aGlzfSxlLnByb3RvdHlwZS5waXBlPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PVtdLHI9MDtyPGFyZ3VtZW50cy5sZW5ndGg7cisrKXRbcl09YXJndW1lbnRzW3JdO3JldHVybiBGcih0KSh0aGlzKX0sZS5wcm90b3R5cGUudG9Qcm9taXNlPWZ1bmN0aW9uKHQpe3ZhciByPXRoaXM7cmV0dXJuIHQ9Q28odCksbmV3IHQoZnVuY3Rpb24obyxuKXt2YXIgaTtyLnN1YnNjcmliZShmdW5jdGlvbihzKXtyZXR1cm4gaT1zfSxmdW5jdGlvbihzKXtyZXR1cm4gbihzKX0sZnVuY3Rpb24oKXtyZXR1cm4gbyhpKX0pfSl9LGUuY3JlYXRlPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KX0sZX0pKCk7ZnVuY3Rpb24gQ28oZSl7dmFyIHQ7cmV0dXJuKHQ9ZSE9bnVsbD9lOkRlLlByb21pc2UpIT09bnVsbCYmdCE9PXZvaWQgMD90OlByb21pc2V9ZnVuY3Rpb24gY2EoZSl7cmV0dXJuIGUmJkkoZS5uZXh0KSYmSShlLmVycm9yKSYmSShlLmNvbXBsZXRlKX1mdW5jdGlvbiBwYShlKXtyZXR1cm4gZSYmZSBpbnN0YW5jZW9mIFB0fHxjYShlKSYmWHQoZSl9ZnVuY3Rpb24gbGEoZSl7cmV0dXJuIEkoZT09bnVsbD92b2lkIDA6ZS5saWZ0KX1mdW5jdGlvbiBFKGUpe3JldHVybiBmdW5jdGlvbih0KXtpZihsYSh0KSlyZXR1cm4gdC5saWZ0KGZ1bmN0aW9uKHIpe3RyeXtyZXR1cm4gZShyLHRoaXMpfWNhdGNoKG8pe3RoaXMuZXJyb3Iobyl9fSk7dGhyb3cgbmV3IFR5cGVFcnJvcigiVW5hYmxlIHRvIGxpZnQgdW5rbm93biBPYnNlcnZhYmxlIHR5cGUiKX19ZnVuY3Rpb24gdyhlLHQscixvLG4pe3JldHVybiBuZXcgbWEoZSx0LHIsbyxuKX12YXIgbWE9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8sbixpLHMsYSl7dmFyIGM9ZS5jYWxsKHRoaXMscil8fHRoaXM7cmV0dXJuIGMub25GaW5hbGl6ZT1zLGMuc2hvdWxkVW5zdWJzY3JpYmU9YSxjLl9uZXh0PW8/ZnVuY3Rpb24ocCl7dHJ5e28ocCl9Y2F0Y2gobCl7ci5lcnJvcihsKX19OmUucHJvdG90eXBlLl9uZXh0LGMuX2Vycm9yPWk/ZnVuY3Rpb24ocCl7dHJ5e2kocCl9Y2F0Y2gobCl7ci5lcnJvcihsKX1maW5hbGx5e3RoaXMudW5zdWJzY3JpYmUoKX19OmUucHJvdG90eXBlLl9lcnJvcixjLl9jb21wbGV0ZT1uP2Z1bmN0aW9uKCl7dHJ5e24oKX1jYXRjaChwKXtyLmVycm9yKHApfWZpbmFsbHl7dGhpcy51bnN1YnNjcmliZSgpfX06ZS5wcm90b3R5cGUuX2NvbXBsZXRlLGN9cmV0dXJuIHQucHJvdG90eXBlLnVuc3Vic2NyaWJlPWZ1bmN0aW9uKCl7dmFyIHI7aWYoIXRoaXMuc2hvdWxkVW5zdWJzY3JpYmV8fHRoaXMuc2hvdWxkVW5zdWJzY3JpYmUoKSl7dmFyIG89dGhpcy5jbG9zZWQ7ZS5wcm90b3R5cGUudW5zdWJzY3JpYmUuY2FsbCh0aGlzKSwhbyYmKChyPXRoaXMub25GaW5hbGl6ZSk9PT1udWxsfHxyPT09dm9pZCAwfHxyLmNhbGwodGhpcykpfX0sdH0pKFB0KTt2YXIgVHQ9e3NjaGVkdWxlOmZ1bmN0aW9uKGUpe3ZhciB0PXJlcXVlc3RBbmltYXRpb25GcmFtZSxyPWNhbmNlbEFuaW1hdGlvbkZyYW1lLG89VHQuZGVsZWdhdGU7byYmKHQ9by5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUscj1vLmNhbmNlbEFuaW1hdGlvbkZyYW1lKTt2YXIgbj10KGZ1bmN0aW9uKGkpe3I9dm9pZCAwLGUoaSl9KTtyZXR1cm4gbmV3IHFlKGZ1bmN0aW9uKCl7cmV0dXJuIHI9PW51bGw/dm9pZCAwOnIobil9KX0scmVxdWVzdEFuaW1hdGlvbkZyYW1lOmZ1bmN0aW9uKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPVR0LmRlbGVnYXRlO3JldHVybigocj09bnVsbD92b2lkIDA6ci5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpfHxyZXF1ZXN0QW5pbWF0aW9uRnJhbWUpLmFwcGx5KHZvaWQgMCxCKFtdLEsoZSkpKX0sY2FuY2VsQW5pbWF0aW9uRnJhbWU6ZnVuY3Rpb24oKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9VHQuZGVsZWdhdGU7cmV0dXJuKChyPT1udWxsP3ZvaWQgMDpyLmNhbmNlbEFuaW1hdGlvbkZyYW1lKXx8Y2FuY2VsQW5pbWF0aW9uRnJhbWUpLmFwcGx5KHZvaWQgMCxCKFtdLEsoZSkpKX0sZGVsZWdhdGU6dm9pZCAwfTt2YXIga289eXQoZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKCl7ZSh0aGlzKSx0aGlzLm5hbWU9Ik9iamVjdFVuc3Vic2NyaWJlZEVycm9yIix0aGlzLm1lc3NhZ2U9Im9iamVjdCB1bnN1YnNjcmliZWQifX0pO3ZhciBUPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQoKXt2YXIgcj1lLmNhbGwodGhpcyl8fHRoaXM7cmV0dXJuIHIuY2xvc2VkPSExLHIuY3VycmVudE9ic2VydmVycz1udWxsLHIub2JzZXJ2ZXJzPVtdLHIuaXNTdG9wcGVkPSExLHIuaGFzRXJyb3I9ITEsci50aHJvd25FcnJvcj1udWxsLHJ9cmV0dXJuIHQucHJvdG90eXBlLmxpZnQ9ZnVuY3Rpb24ocil7dmFyIG89bmV3IEhvKHRoaXMsdGhpcyk7cmV0dXJuIG8ub3BlcmF0b3I9cixvfSx0LnByb3RvdHlwZS5fdGhyb3dJZkNsb3NlZD1mdW5jdGlvbigpe2lmKHRoaXMuY2xvc2VkKXRocm93IG5ldyBrb30sdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXt2YXIgbz10aGlzO0V0KGZ1bmN0aW9uKCl7dmFyIG4saTtpZihvLl90aHJvd0lmQ2xvc2VkKCksIW8uaXNTdG9wcGVkKXtvLmN1cnJlbnRPYnNlcnZlcnN8fChvLmN1cnJlbnRPYnNlcnZlcnM9QXJyYXkuZnJvbShvLm9ic2VydmVycykpO3RyeXtmb3IodmFyIHM9T2Uoby5jdXJyZW50T2JzZXJ2ZXJzKSxhPXMubmV4dCgpOyFhLmRvbmU7YT1zLm5leHQoKSl7dmFyIGM9YS52YWx1ZTtjLm5leHQocil9fWNhdGNoKHApe249e2Vycm9yOnB9fWZpbmFsbHl7dHJ5e2EmJiFhLmRvbmUmJihpPXMucmV0dXJuKSYmaS5jYWxsKHMpfWZpbmFsbHl7aWYobil0aHJvdyBuLmVycm9yfX19fSl9LHQucHJvdG90eXBlLmVycm9yPWZ1bmN0aW9uKHIpe3ZhciBvPXRoaXM7RXQoZnVuY3Rpb24oKXtpZihvLl90aHJvd0lmQ2xvc2VkKCksIW8uaXNTdG9wcGVkKXtvLmhhc0Vycm9yPW8uaXNTdG9wcGVkPSEwLG8udGhyb3duRXJyb3I9cjtmb3IodmFyIG49by5vYnNlcnZlcnM7bi5sZW5ndGg7KW4uc2hpZnQoKS5lcnJvcihyKX19KX0sdC5wcm90b3R5cGUuY29tcGxldGU9ZnVuY3Rpb24oKXt2YXIgcj10aGlzO0V0KGZ1bmN0aW9uKCl7aWYoci5fdGhyb3dJZkNsb3NlZCgpLCFyLmlzU3RvcHBlZCl7ci5pc1N0b3BwZWQ9ITA7Zm9yKHZhciBvPXIub2JzZXJ2ZXJzO28ubGVuZ3RoOylvLnNoaWZ0KCkuY29tcGxldGUoKX19KX0sdC5wcm90b3R5cGUudW5zdWJzY3JpYmU9ZnVuY3Rpb24oKXt0aGlzLmlzU3RvcHBlZD10aGlzLmNsb3NlZD0hMCx0aGlzLm9ic2VydmVycz10aGlzLmN1cnJlbnRPYnNlcnZlcnM9bnVsbH0sT2JqZWN0LmRlZmluZVByb3BlcnR5KHQucHJvdG90eXBlLCJvYnNlcnZlZCIse2dldDpmdW5jdGlvbigpe3ZhciByO3JldHVybigocj10aGlzLm9ic2VydmVycyk9PT1udWxsfHxyPT09dm9pZCAwP3ZvaWQgMDpyLmxlbmd0aCk+MH0sZW51bWVyYWJsZTohMSxjb25maWd1cmFibGU6ITB9KSx0LnByb3RvdHlwZS5fdHJ5U3Vic2NyaWJlPWZ1bmN0aW9uKHIpe3JldHVybiB0aGlzLl90aHJvd0lmQ2xvc2VkKCksZS5wcm90b3R5cGUuX3RyeVN1YnNjcmliZS5jYWxsKHRoaXMscil9LHQucHJvdG90eXBlLl9zdWJzY3JpYmU9ZnVuY3Rpb24ocil7cmV0dXJuIHRoaXMuX3Rocm93SWZDbG9zZWQoKSx0aGlzLl9jaGVja0ZpbmFsaXplZFN0YXR1c2VzKHIpLHRoaXMuX2lubmVyU3Vic2NyaWJlKHIpfSx0LnByb3RvdHlwZS5faW5uZXJTdWJzY3JpYmU9ZnVuY3Rpb24ocil7dmFyIG89dGhpcyxuPXRoaXMsaT1uLmhhc0Vycm9yLHM9bi5pc1N0b3BwZWQsYT1uLm9ic2VydmVycztyZXR1cm4gaXx8cz8kcjoodGhpcy5jdXJyZW50T2JzZXJ2ZXJzPW51bGwsYS5wdXNoKHIpLG5ldyBxZShmdW5jdGlvbigpe28uY3VycmVudE9ic2VydmVycz1udWxsLFplKGEscil9KSl9LHQucHJvdG90eXBlLl9jaGVja0ZpbmFsaXplZFN0YXR1c2VzPWZ1bmN0aW9uKHIpe3ZhciBvPXRoaXMsbj1vLmhhc0Vycm9yLGk9by50aHJvd25FcnJvcixzPW8uaXNTdG9wcGVkO24/ci5lcnJvcihpKTpzJiZyLmNvbXBsZXRlKCl9LHQucHJvdG90eXBlLmFzT2JzZXJ2YWJsZT1mdW5jdGlvbigpe3ZhciByPW5ldyBGO3JldHVybiByLnNvdXJjZT10aGlzLHJ9LHQuY3JlYXRlPWZ1bmN0aW9uKHIsbyl7cmV0dXJuIG5ldyBIbyhyLG8pfSx0fSkoRik7dmFyIEhvPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQocixvKXt2YXIgbj1lLmNhbGwodGhpcyl8fHRoaXM7cmV0dXJuIG4uZGVzdGluYXRpb249cixuLnNvdXJjZT1vLG59cmV0dXJuIHQucHJvdG90eXBlLm5leHQ9ZnVuY3Rpb24ocil7dmFyIG8sbjsobj0obz10aGlzLmRlc3RpbmF0aW9uKT09PW51bGx8fG89PT12b2lkIDA/dm9pZCAwOm8ubmV4dCk9PT1udWxsfHxuPT09dm9pZCAwfHxuLmNhbGwobyxyKX0sdC5wcm90b3R5cGUuZXJyb3I9ZnVuY3Rpb24ocil7dmFyIG8sbjsobj0obz10aGlzLmRlc3RpbmF0aW9uKT09PW51bGx8fG89PT12b2lkIDA/dm9pZCAwOm8uZXJyb3IpPT09bnVsbHx8bj09PXZvaWQgMHx8bi5jYWxsKG8scil9LHQucHJvdG90eXBlLmNvbXBsZXRlPWZ1bmN0aW9uKCl7dmFyIHIsbzsobz0ocj10aGlzLmRlc3RpbmF0aW9uKT09PW51bGx8fHI9PT12b2lkIDA/dm9pZCAwOnIuY29tcGxldGUpPT09bnVsbHx8bz09PXZvaWQgMHx8by5jYWxsKHIpfSx0LnByb3RvdHlwZS5fc3Vic2NyaWJlPWZ1bmN0aW9uKHIpe3ZhciBvLG47cmV0dXJuKG49KG89dGhpcy5zb3VyY2UpPT09bnVsbHx8bz09PXZvaWQgMD92b2lkIDA6by5zdWJzY3JpYmUocikpIT09bnVsbCYmbiE9PXZvaWQgMD9uOiRyfSx0fSkoVCk7dmFyIGpyPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQocil7dmFyIG89ZS5jYWxsKHRoaXMpfHx0aGlzO3JldHVybiBvLl92YWx1ZT1yLG99cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LnByb3RvdHlwZSwidmFsdWUiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5nZXRWYWx1ZSgpfSxlbnVtZXJhYmxlOiExLGNvbmZpZ3VyYWJsZTohMH0pLHQucHJvdG90eXBlLl9zdWJzY3JpYmU9ZnVuY3Rpb24ocil7dmFyIG89ZS5wcm90b3R5cGUuX3N1YnNjcmliZS5jYWxsKHRoaXMscik7cmV0dXJuIW8uY2xvc2VkJiZyLm5leHQodGhpcy5fdmFsdWUpLG99LHQucHJvdG90eXBlLmdldFZhbHVlPWZ1bmN0aW9uKCl7dmFyIHI9dGhpcyxvPXIuaGFzRXJyb3Isbj1yLnRocm93bkVycm9yLGk9ci5fdmFsdWU7aWYobyl0aHJvdyBuO3JldHVybiB0aGlzLl90aHJvd0lmQ2xvc2VkKCksaX0sdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXtlLnByb3RvdHlwZS5uZXh0LmNhbGwodGhpcyx0aGlzLl92YWx1ZT1yKX0sdH0pKFQpO3ZhciBSdD17bm93OmZ1bmN0aW9uKCl7cmV0dXJuKFJ0LmRlbGVnYXRlfHxEYXRlKS5ub3coKX0sZGVsZWdhdGU6dm9pZCAwfTt2YXIgSXQ9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8sbil7cj09PXZvaWQgMCYmKHI9MS8wKSxvPT09dm9pZCAwJiYobz0xLzApLG49PT12b2lkIDAmJihuPVJ0KTt2YXIgaT1lLmNhbGwodGhpcyl8fHRoaXM7cmV0dXJuIGkuX2J1ZmZlclNpemU9cixpLl93aW5kb3dUaW1lPW8saS5fdGltZXN0YW1wUHJvdmlkZXI9bixpLl9idWZmZXI9W10saS5faW5maW5pdGVUaW1lV2luZG93PSEwLGkuX2luZmluaXRlVGltZVdpbmRvdz1vPT09MS8wLGkuX2J1ZmZlclNpemU9TWF0aC5tYXgoMSxyKSxpLl93aW5kb3dUaW1lPU1hdGgubWF4KDEsbyksaX1yZXR1cm4gdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXt2YXIgbz10aGlzLG49by5pc1N0b3BwZWQsaT1vLl9idWZmZXIscz1vLl9pbmZpbml0ZVRpbWVXaW5kb3csYT1vLl90aW1lc3RhbXBQcm92aWRlcixjPW8uX3dpbmRvd1RpbWU7bnx8KGkucHVzaChyKSwhcyYmaS5wdXNoKGEubm93KCkrYykpLHRoaXMuX3RyaW1CdWZmZXIoKSxlLnByb3RvdHlwZS5uZXh0LmNhbGwodGhpcyxyKX0sdC5wcm90b3R5cGUuX3N1YnNjcmliZT1mdW5jdGlvbihyKXt0aGlzLl90aHJvd0lmQ2xvc2VkKCksdGhpcy5fdHJpbUJ1ZmZlcigpO2Zvcih2YXIgbz10aGlzLl9pbm5lclN1YnNjcmliZShyKSxuPXRoaXMsaT1uLl9pbmZpbml0ZVRpbWVXaW5kb3cscz1uLl9idWZmZXIsYT1zLnNsaWNlKCksYz0wO2M8YS5sZW5ndGgmJiFyLmNsb3NlZDtjKz1pPzE6MilyLm5leHQoYVtjXSk7cmV0dXJuIHRoaXMuX2NoZWNrRmluYWxpemVkU3RhdHVzZXMociksb30sdC5wcm90b3R5cGUuX3RyaW1CdWZmZXI9ZnVuY3Rpb24oKXt2YXIgcj10aGlzLG89ci5fYnVmZmVyU2l6ZSxuPXIuX3RpbWVzdGFtcFByb3ZpZGVyLGk9ci5fYnVmZmVyLHM9ci5faW5maW5pdGVUaW1lV2luZG93LGE9KHM/MToyKSpvO2lmKG88MS8wJiZhPGkubGVuZ3RoJiZpLnNwbGljZSgwLGkubGVuZ3RoLWEpLCFzKXtmb3IodmFyIGM9bi5ub3coKSxwPTAsbD0xO2w8aS5sZW5ndGgmJmlbbF08PWM7bCs9MilwPWw7cCYmaS5zcGxpY2UoMCxwKzEpfX0sdH0pKFQpO3ZhciAkbz0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KHIsbyl7cmV0dXJuIGUuY2FsbCh0aGlzKXx8dGhpc31yZXR1cm4gdC5wcm90b3R5cGUuc2NoZWR1bGU9ZnVuY3Rpb24ocixvKXtyZXR1cm4gbz09PXZvaWQgMCYmKG89MCksdGhpc30sdH0pKHFlKTt2YXIgRnQ9e3NldEludGVydmFsOmZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPVtdLG89MjtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbby0yXT1hcmd1bWVudHNbb107dmFyIG49RnQuZGVsZWdhdGU7cmV0dXJuIG4hPW51bGwmJm4uc2V0SW50ZXJ2YWw/bi5zZXRJbnRlcnZhbC5hcHBseShuLEIoW2UsdF0sSyhyKSkpOnNldEludGVydmFsLmFwcGx5KHZvaWQgMCxCKFtlLHRdLEsocikpKX0sY2xlYXJJbnRlcnZhbDpmdW5jdGlvbihlKXt2YXIgdD1GdC5kZWxlZ2F0ZTtyZXR1cm4oKHQ9PW51bGw/dm9pZCAwOnQuY2xlYXJJbnRlcnZhbCl8fGNsZWFySW50ZXJ2YWwpKGUpfSxkZWxlZ2F0ZTp2b2lkIDB9O3ZhciBTdD0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KHIsbyl7dmFyIG49ZS5jYWxsKHRoaXMscixvKXx8dGhpcztyZXR1cm4gbi5zY2hlZHVsZXI9cixuLndvcms9byxuLnBlbmRpbmc9ITEsbn1yZXR1cm4gdC5wcm90b3R5cGUuc2NoZWR1bGU9ZnVuY3Rpb24ocixvKXt2YXIgbjtpZihvPT09dm9pZCAwJiYobz0wKSx0aGlzLmNsb3NlZClyZXR1cm4gdGhpczt0aGlzLnN0YXRlPXI7dmFyIGk9dGhpcy5pZCxzPXRoaXMuc2NoZWR1bGVyO3JldHVybiBpIT1udWxsJiYodGhpcy5pZD10aGlzLnJlY3ljbGVBc3luY0lkKHMsaSxvKSksdGhpcy5wZW5kaW5nPSEwLHRoaXMuZGVsYXk9byx0aGlzLmlkPShuPXRoaXMuaWQpIT09bnVsbCYmbiE9PXZvaWQgMD9uOnRoaXMucmVxdWVzdEFzeW5jSWQocyx0aGlzLmlkLG8pLHRoaXN9LHQucHJvdG90eXBlLnJlcXVlc3RBc3luY0lkPWZ1bmN0aW9uKHIsbyxuKXtyZXR1cm4gbj09PXZvaWQgMCYmKG49MCksRnQuc2V0SW50ZXJ2YWwoci5mbHVzaC5iaW5kKHIsdGhpcyksbil9LHQucHJvdG90eXBlLnJlY3ljbGVBc3luY0lkPWZ1bmN0aW9uKHIsbyxuKXtpZihuPT09dm9pZCAwJiYobj0wKSxuIT1udWxsJiZ0aGlzLmRlbGF5PT09biYmdGhpcy5wZW5kaW5nPT09ITEpcmV0dXJuIG87byE9bnVsbCYmRnQuY2xlYXJJbnRlcnZhbChvKX0sdC5wcm90b3R5cGUuZXhlY3V0ZT1mdW5jdGlvbihyLG8pe2lmKHRoaXMuY2xvc2VkKXJldHVybiBuZXcgRXJyb3IoImV4ZWN1dGluZyBhIGNhbmNlbGxlZCBhY3Rpb24iKTt0aGlzLnBlbmRpbmc9ITE7dmFyIG49dGhpcy5fZXhlY3V0ZShyLG8pO2lmKG4pcmV0dXJuIG47dGhpcy5wZW5kaW5nPT09ITEmJnRoaXMuaWQhPW51bGwmJih0aGlzLmlkPXRoaXMucmVjeWNsZUFzeW5jSWQodGhpcy5zY2hlZHVsZXIsdGhpcy5pZCxudWxsKSl9LHQucHJvdG90eXBlLl9leGVjdXRlPWZ1bmN0aW9uKHIsbyl7dmFyIG49ITEsaTt0cnl7dGhpcy53b3JrKHIpfWNhdGNoKHMpe249ITAsaT1zfHxuZXcgRXJyb3IoIlNjaGVkdWxlZCBhY3Rpb24gdGhyZXcgZmFsc3kgZXJyb3IiKX1pZihuKXJldHVybiB0aGlzLnVuc3Vic2NyaWJlKCksaX0sdC5wcm90b3R5cGUudW5zdWJzY3JpYmU9ZnVuY3Rpb24oKXtpZighdGhpcy5jbG9zZWQpe3ZhciByPXRoaXMsbz1yLmlkLG49ci5zY2hlZHVsZXIsaT1uLmFjdGlvbnM7dGhpcy53b3JrPXRoaXMuc3RhdGU9dGhpcy5zY2hlZHVsZXI9bnVsbCx0aGlzLnBlbmRpbmc9ITEsWmUoaSx0aGlzKSxvIT1udWxsJiYodGhpcy5pZD10aGlzLnJlY3ljbGVBc3luY0lkKG4sbyxudWxsKSksdGhpcy5kZWxheT1udWxsLGUucHJvdG90eXBlLnVuc3Vic2NyaWJlLmNhbGwodGhpcyl9fSx0fSkoJG8pO3ZhciBVcj0oZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQscil7cj09PXZvaWQgMCYmKHI9ZS5ub3cpLHRoaXMuc2NoZWR1bGVyQWN0aW9uQ3Rvcj10LHRoaXMubm93PXJ9cmV0dXJuIGUucHJvdG90eXBlLnNjaGVkdWxlPWZ1bmN0aW9uKHQscixvKXtyZXR1cm4gcj09PXZvaWQgMCYmKHI9MCksbmV3IHRoaXMuc2NoZWR1bGVyQWN0aW9uQ3Rvcih0aGlzLHQpLnNjaGVkdWxlKG8scil9LGUubm93PVJ0Lm5vdyxlfSkoKTt2YXIgT3Q9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8pe289PT12b2lkIDAmJihvPVVyLm5vdyk7dmFyIG49ZS5jYWxsKHRoaXMscixvKXx8dGhpcztyZXR1cm4gbi5hY3Rpb25zPVtdLG4uX2FjdGl2ZT0hMSxufXJldHVybiB0LnByb3RvdHlwZS5mbHVzaD1mdW5jdGlvbihyKXt2YXIgbz10aGlzLmFjdGlvbnM7aWYodGhpcy5fYWN0aXZlKXtvLnB1c2gocik7cmV0dXJufXZhciBuO3RoaXMuX2FjdGl2ZT0hMDtkbyBpZihuPXIuZXhlY3V0ZShyLnN0YXRlLHIuZGVsYXkpKWJyZWFrO3doaWxlKHI9by5zaGlmdCgpKTtpZih0aGlzLl9hY3RpdmU9ITEsbil7Zm9yKDtyPW8uc2hpZnQoKTspci51bnN1YnNjcmliZSgpO3Rocm93IG59fSx0fSkoVXIpO3ZhciBwZT1uZXcgT3QoU3QpLFdyPXBlO3ZhciBQbz0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KHIsbyl7dmFyIG49ZS5jYWxsKHRoaXMscixvKXx8dGhpcztyZXR1cm4gbi5zY2hlZHVsZXI9cixuLndvcms9byxufXJldHVybiB0LnByb3RvdHlwZS5zY2hlZHVsZT1mdW5jdGlvbihyLG8pe3JldHVybiBvPT09dm9pZCAwJiYobz0wKSxvPjA/ZS5wcm90b3R5cGUuc2NoZWR1bGUuY2FsbCh0aGlzLHIsbyk6KHRoaXMuZGVsYXk9byx0aGlzLnN0YXRlPXIsdGhpcy5zY2hlZHVsZXIuZmx1c2godGhpcyksdGhpcyl9LHQucHJvdG90eXBlLmV4ZWN1dGU9ZnVuY3Rpb24ocixvKXtyZXR1cm4gbz4wfHx0aGlzLmNsb3NlZD9lLnByb3RvdHlwZS5leGVjdXRlLmNhbGwodGhpcyxyLG8pOnRoaXMuX2V4ZWN1dGUocixvKX0sdC5wcm90b3R5cGUucmVxdWVzdEFzeW5jSWQ9ZnVuY3Rpb24ocixvLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj0wKSxuIT1udWxsJiZuPjB8fG49PW51bGwmJnRoaXMuZGVsYXk+MD9lLnByb3RvdHlwZS5yZXF1ZXN0QXN5bmNJZC5jYWxsKHRoaXMscixvLG4pOihyLmZsdXNoKHRoaXMpLDApfSx0fSkoU3QpO3ZhciBSbz0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KCl7cmV0dXJuIGUhPT1udWxsJiZlLmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpc31yZXR1cm4gdH0pKE90KTt2YXIgRHI9bmV3IFJvKFBvKTt2YXIgSW89KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8pe3ZhciBuPWUuY2FsbCh0aGlzLHIsbyl8fHRoaXM7cmV0dXJuIG4uc2NoZWR1bGVyPXIsbi53b3JrPW8sbn1yZXR1cm4gdC5wcm90b3R5cGUucmVxdWVzdEFzeW5jSWQ9ZnVuY3Rpb24ocixvLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj0wKSxuIT09bnVsbCYmbj4wP2UucHJvdG90eXBlLnJlcXVlc3RBc3luY0lkLmNhbGwodGhpcyxyLG8sbik6KHIuYWN0aW9ucy5wdXNoKHRoaXMpLHIuX3NjaGVkdWxlZHx8KHIuX3NjaGVkdWxlZD1UdC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24oKXtyZXR1cm4gci5mbHVzaCh2b2lkIDApfSkpKX0sdC5wcm90b3R5cGUucmVjeWNsZUFzeW5jSWQ9ZnVuY3Rpb24ocixvLG4pe3ZhciBpO2lmKG49PT12b2lkIDAmJihuPTApLG4hPW51bGw/bj4wOnRoaXMuZGVsYXk+MClyZXR1cm4gZS5wcm90b3R5cGUucmVjeWNsZUFzeW5jSWQuY2FsbCh0aGlzLHIsbyxuKTt2YXIgcz1yLmFjdGlvbnM7byE9bnVsbCYmbz09PXIuX3NjaGVkdWxlZCYmKChpPXNbcy5sZW5ndGgtMV0pPT09bnVsbHx8aT09PXZvaWQgMD92b2lkIDA6aS5pZCkhPT1vJiYoVHQuY2FuY2VsQW5pbWF0aW9uRnJhbWUobyksci5fc2NoZWR1bGVkPXZvaWQgMCl9LHR9KShTdCk7dmFyIEZvPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQoKXtyZXR1cm4gZSE9PW51bGwmJmUuYXBwbHkodGhpcyxhcmd1bWVudHMpfHx0aGlzfXJldHVybiB0LnByb3RvdHlwZS5mbHVzaD1mdW5jdGlvbihyKXt0aGlzLl9hY3RpdmU9ITA7dmFyIG87cj9vPXIuaWQ6KG89dGhpcy5fc2NoZWR1bGVkLHRoaXMuX3NjaGVkdWxlZD12b2lkIDApO3ZhciBuPXRoaXMuYWN0aW9ucyxpO3I9cnx8bi5zaGlmdCgpO2RvIGlmKGk9ci5leGVjdXRlKHIuc3RhdGUsci5kZWxheSkpYnJlYWs7d2hpbGUoKHI9blswXSkmJnIuaWQ9PT1vJiZuLnNoaWZ0KCkpO2lmKHRoaXMuX2FjdGl2ZT0hMSxpKXtmb3IoOyhyPW5bMF0pJiZyLmlkPT09byYmbi5zaGlmdCgpOylyLnVuc3Vic2NyaWJlKCk7dGhyb3cgaX19LHR9KShPdCk7dmFyIHllPW5ldyBGbyhJbyk7dmFyIHk9bmV3IEYoZnVuY3Rpb24oZSl7cmV0dXJuIGUuY29tcGxldGUoKX0pO2Z1bmN0aW9uIHRyKGUpe3JldHVybiBlJiZJKGUuc2NoZWR1bGUpfWZ1bmN0aW9uIFZyKGUpe3JldHVybiBlW2UubGVuZ3RoLTFdfWZ1bmN0aW9uIHB0KGUpe3JldHVybiBJKFZyKGUpKT9lLnBvcCgpOnZvaWQgMH1mdW5jdGlvbiBGZShlKXtyZXR1cm4gdHIoVnIoZSkpP2UucG9wKCk6dm9pZCAwfWZ1bmN0aW9uIHJyKGUsdCl7cmV0dXJuIHR5cGVvZiBWcihlKT09Im51bWJlciI/ZS5wb3AoKTp0fXZhciBMdD0oZnVuY3Rpb24oZSl7cmV0dXJuIGUmJnR5cGVvZiBlLmxlbmd0aD09Im51bWJlciImJnR5cGVvZiBlIT0iZnVuY3Rpb24ifSk7ZnVuY3Rpb24gb3IoZSl7cmV0dXJuIEkoZT09bnVsbD92b2lkIDA6ZS50aGVuKX1mdW5jdGlvbiBucihlKXtyZXR1cm4gSShlW3d0XSl9ZnVuY3Rpb24gaXIoZSl7cmV0dXJuIFN5bWJvbC5hc3luY0l0ZXJhdG9yJiZJKGU9PW51bGw/dm9pZCAwOmVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKX1mdW5jdGlvbiBhcihlKXtyZXR1cm4gbmV3IFR5cGVFcnJvcigiWW91IHByb3ZpZGVkICIrKGUhPT1udWxsJiZ0eXBlb2YgZT09Im9iamVjdCI/ImFuIGludmFsaWQgb2JqZWN0IjoiJyIrZSsiJyIpKyIgd2hlcmUgYSBzdHJlYW0gd2FzIGV4cGVjdGVkLiBZb3UgY2FuIHByb3ZpZGUgYW4gT2JzZXJ2YWJsZSwgUHJvbWlzZSwgUmVhZGFibGVTdHJlYW0sIEFycmF5LCBBc3luY0l0ZXJhYmxlLCBvciBJdGVyYWJsZS4iKX1mdW5jdGlvbiBmYSgpe3JldHVybiB0eXBlb2YgU3ltYm9sIT0iZnVuY3Rpb24ifHwhU3ltYm9sLml0ZXJhdG9yPyJAQGl0ZXJhdG9yIjpTeW1ib2wuaXRlcmF0b3J9dmFyIHNyPWZhKCk7ZnVuY3Rpb24gY3IoZSl7cmV0dXJuIEkoZT09bnVsbD92b2lkIDA6ZVtzcl0pfWZ1bmN0aW9uIHByKGUpe3JldHVybiB3byh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbigpe3ZhciByLG8sbixpO3JldHVybiBHdCh0aGlzLGZ1bmN0aW9uKHMpe3N3aXRjaChzLmxhYmVsKXtjYXNlIDA6cj1lLmdldFJlYWRlcigpLHMubGFiZWw9MTtjYXNlIDE6cy50cnlzLnB1c2goWzEsLDksMTBdKSxzLmxhYmVsPTI7Y2FzZSAyOnJldHVybls0LGR0KHIucmVhZCgpKV07Y2FzZSAzOnJldHVybiBvPXMuc2VudCgpLG49by52YWx1ZSxpPW8uZG9uZSxpP1s0LGR0KHZvaWQgMCldOlszLDVdO2Nhc2UgNDpyZXR1cm5bMixzLnNlbnQoKV07Y2FzZSA1OnJldHVybls0LGR0KG4pXTtjYXNlIDY6cmV0dXJuWzQscy5zZW50KCldO2Nhc2UgNzpyZXR1cm4gcy5zZW50KCksWzMsMl07Y2FzZSA4OnJldHVyblszLDEwXTtjYXNlIDk6cmV0dXJuIHIucmVsZWFzZUxvY2soKSxbN107Y2FzZSAxMDpyZXR1cm5bMl19fSl9KX1mdW5jdGlvbiBscihlKXtyZXR1cm4gSShlPT1udWxsP3ZvaWQgMDplLmdldFJlYWRlcil9ZnVuY3Rpb24gVShlKXtpZihlIGluc3RhbmNlb2YgRilyZXR1cm4gZTtpZihlIT1udWxsKXtpZihucihlKSlyZXR1cm4gdWEoZSk7aWYoTHQoZSkpcmV0dXJuIGRhKGUpO2lmKG9yKGUpKXJldHVybiBoYShlKTtpZihpcihlKSlyZXR1cm4gam8oZSk7aWYoY3IoZSkpcmV0dXJuIGJhKGUpO2lmKGxyKGUpKXJldHVybiB2YShlKX10aHJvdyBhcihlKX1mdW5jdGlvbiB1YShlKXtyZXR1cm4gbmV3IEYoZnVuY3Rpb24odCl7dmFyIHI9ZVt3dF0oKTtpZihJKHIuc3Vic2NyaWJlKSlyZXR1cm4gci5zdWJzY3JpYmUodCk7dGhyb3cgbmV3IFR5cGVFcnJvcigiUHJvdmlkZWQgb2JqZWN0IGRvZXMgbm90IGNvcnJlY3RseSBpbXBsZW1lbnQgU3ltYm9sLm9ic2VydmFibGUiKX0pfWZ1bmN0aW9uIGRhKGUpe3JldHVybiBuZXcgRihmdW5jdGlvbih0KXtmb3IodmFyIHI9MDtyPGUubGVuZ3RoJiYhdC5jbG9zZWQ7cisrKXQubmV4dChlW3JdKTt0LmNvbXBsZXRlKCl9KX1mdW5jdGlvbiBoYShlKXtyZXR1cm4gbmV3IEYoZnVuY3Rpb24odCl7ZS50aGVuKGZ1bmN0aW9uKHIpe3QuY2xvc2VkfHwodC5uZXh0KHIpLHQuY29tcGxldGUoKSl9LGZ1bmN0aW9uKHIpe3JldHVybiB0LmVycm9yKHIpfSkudGhlbihudWxsLFp0KX0pfWZ1bmN0aW9uIGJhKGUpe3JldHVybiBuZXcgRihmdW5jdGlvbih0KXt2YXIgcixvO3RyeXtmb3IodmFyIG49T2UoZSksaT1uLm5leHQoKTshaS5kb25lO2k9bi5uZXh0KCkpe3ZhciBzPWkudmFsdWU7aWYodC5uZXh0KHMpLHQuY2xvc2VkKXJldHVybn19Y2F0Y2goYSl7cj17ZXJyb3I6YX19ZmluYWxseXt0cnl7aSYmIWkuZG9uZSYmKG89bi5yZXR1cm4pJiZvLmNhbGwobil9ZmluYWxseXtpZihyKXRocm93IHIuZXJyb3J9fXQuY29tcGxldGUoKX0pfWZ1bmN0aW9uIGpvKGUpe3JldHVybiBuZXcgRihmdW5jdGlvbih0KXtnYShlLHQpLmNhdGNoKGZ1bmN0aW9uKHIpe3JldHVybiB0LmVycm9yKHIpfSl9KX1mdW5jdGlvbiB2YShlKXtyZXR1cm4gam8ocHIoZSkpfWZ1bmN0aW9uIGdhKGUsdCl7dmFyIHIsbyxuLGk7cmV0dXJuIEVvKHRoaXMsdm9pZCAwLHZvaWQgMCxmdW5jdGlvbigpe3ZhciBzLGE7cmV0dXJuIEd0KHRoaXMsZnVuY3Rpb24oYyl7c3dpdGNoKGMubGFiZWwpe2Nhc2UgMDpjLnRyeXMucHVzaChbMCw1LDYsMTFdKSxyPVRvKGUpLGMubGFiZWw9MTtjYXNlIDE6cmV0dXJuWzQsci5uZXh0KCldO2Nhc2UgMjppZihvPWMuc2VudCgpLCEhby5kb25lKXJldHVyblszLDRdO2lmKHM9by52YWx1ZSx0Lm5leHQocyksdC5jbG9zZWQpcmV0dXJuWzJdO2MubGFiZWw9MztjYXNlIDM6cmV0dXJuWzMsMV07Y2FzZSA0OnJldHVyblszLDExXTtjYXNlIDU6cmV0dXJuIGE9Yy5zZW50KCksbj17ZXJyb3I6YX0sWzMsMTFdO2Nhc2UgNjpyZXR1cm4gYy50cnlzLnB1c2goWzYsLDksMTBdKSxvJiYhby5kb25lJiYoaT1yLnJldHVybik/WzQsaS5jYWxsKHIpXTpbMyw4XTtjYXNlIDc6Yy5zZW50KCksYy5sYWJlbD04O2Nhc2UgODpyZXR1cm5bMywxMF07Y2FzZSA5OmlmKG4pdGhyb3cgbi5lcnJvcjtyZXR1cm5bN107Y2FzZSAxMDpyZXR1cm5bN107Y2FzZSAxMTpyZXR1cm4gdC5jb21wbGV0ZSgpLFsyXX19KX0pfWZ1bmN0aW9uIF9lKGUsdCxyLG8sbil7bz09PXZvaWQgMCYmKG89MCksbj09PXZvaWQgMCYmKG49ITEpO3ZhciBpPXQuc2NoZWR1bGUoZnVuY3Rpb24oKXtyKCksbj9lLmFkZCh0aGlzLnNjaGVkdWxlKG51bGwsbykpOnRoaXMudW5zdWJzY3JpYmUoKX0sbyk7aWYoZS5hZGQoaSksIW4pcmV0dXJuIGl9ZnVuY3Rpb24geGUoZSx0KXtyZXR1cm4gdD09PXZvaWQgMCYmKHQ9MCksRShmdW5jdGlvbihyLG8pe3Iuc3Vic2NyaWJlKHcobyxmdW5jdGlvbihuKXtyZXR1cm4gX2UobyxlLGZ1bmN0aW9uKCl7cmV0dXJuIG8ubmV4dChuKX0sdCl9LGZ1bmN0aW9uKCl7cmV0dXJuIF9lKG8sZSxmdW5jdGlvbigpe3JldHVybiBvLmNvbXBsZXRlKCl9LHQpfSxmdW5jdGlvbihuKXtyZXR1cm4gX2UobyxlLGZ1bmN0aW9uKCl7cmV0dXJuIG8uZXJyb3Iobil9LHQpfSkpfSl9ZnVuY3Rpb24gZXQoZSx0KXtyZXR1cm4gdD09PXZvaWQgMCYmKHQ9MCksRShmdW5jdGlvbihyLG8pe28uYWRkKGUuc2NoZWR1bGUoZnVuY3Rpb24oKXtyZXR1cm4gci5zdWJzY3JpYmUobyl9LHQpKX0pfWZ1bmN0aW9uIFVvKGUsdCl7cmV0dXJuIFUoZSkucGlwZShldCh0KSx4ZSh0KSl9ZnVuY3Rpb24gV28oZSx0KXtyZXR1cm4gVShlKS5waXBlKGV0KHQpLHhlKHQpKX1mdW5jdGlvbiBEbyhlLHQpe3JldHVybiBuZXcgRihmdW5jdGlvbihyKXt2YXIgbz0wO3JldHVybiB0LnNjaGVkdWxlKGZ1bmN0aW9uKCl7bz09PWUubGVuZ3RoP3IuY29tcGxldGUoKTooci5uZXh0KGVbbysrXSksci5jbG9zZWR8fHRoaXMuc2NoZWR1bGUoKSl9KX0pfWZ1bmN0aW9uIFZvKGUsdCl7cmV0dXJuIG5ldyBGKGZ1bmN0aW9uKHIpe3ZhciBvO3JldHVybiBfZShyLHQsZnVuY3Rpb24oKXtvPWVbc3JdKCksX2Uocix0LGZ1bmN0aW9uKCl7dmFyIG4saSxzO3RyeXtuPW8ubmV4dCgpLGk9bi52YWx1ZSxzPW4uZG9uZX1jYXRjaChhKXtyLmVycm9yKGEpO3JldHVybn1zP3IuY29tcGxldGUoKTpyLm5leHQoaSl9LDAsITApfSksZnVuY3Rpb24oKXtyZXR1cm4gSShvPT1udWxsP3ZvaWQgMDpvLnJldHVybikmJm8ucmV0dXJuKCl9fSl9ZnVuY3Rpb24gbXIoZSx0KXtpZighZSl0aHJvdyBuZXcgRXJyb3IoIkl0ZXJhYmxlIGNhbm5vdCBiZSBudWxsIik7cmV0dXJuIG5ldyBGKGZ1bmN0aW9uKHIpe19lKHIsdCxmdW5jdGlvbigpe3ZhciBvPWVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCk7X2Uocix0LGZ1bmN0aW9uKCl7by5uZXh0KCkudGhlbihmdW5jdGlvbihuKXtuLmRvbmU/ci5jb21wbGV0ZSgpOnIubmV4dChuLnZhbHVlKX0pfSwwLCEwKX0pfSl9ZnVuY3Rpb24gTm8oZSx0KXtyZXR1cm4gbXIocHIoZSksdCl9ZnVuY3Rpb24gem8oZSx0KXtpZihlIT1udWxsKXtpZihucihlKSlyZXR1cm4gVW8oZSx0KTtpZihMdChlKSlyZXR1cm4gRG8oZSx0KTtpZihvcihlKSlyZXR1cm4gV28oZSx0KTtpZihpcihlKSlyZXR1cm4gbXIoZSx0KTtpZihjcihlKSlyZXR1cm4gVm8oZSx0KTtpZihscihlKSlyZXR1cm4gTm8oZSx0KX10aHJvdyBhcihlKX1mdW5jdGlvbiBmZShlLHQpe3JldHVybiB0P3pvKGUsdCk6VShlKX1mdW5jdGlvbiAkKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPUZlKGUpO3JldHVybiBmZShlLHIpfWZ1bmN0aW9uIE5yKGUsdCl7dmFyIHI9SShlKT9lOmZ1bmN0aW9uKCl7cmV0dXJuIGV9LG89ZnVuY3Rpb24obil7cmV0dXJuIG4uZXJyb3IocigpKX07cmV0dXJuIG5ldyBGKHQ/ZnVuY3Rpb24obil7cmV0dXJuIHQuc2NoZWR1bGUobywwLG4pfTpvKX12YXIgZnI9eXQoZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKCl7ZSh0aGlzKSx0aGlzLm5hbWU9IkVtcHR5RXJyb3IiLHRoaXMubWVzc2FnZT0ibm8gZWxlbWVudHMgaW4gc2VxdWVuY2UifX0pO2Z1bmN0aW9uIHFvKGUpe3JldHVybiBlIGluc3RhbmNlb2YgRGF0ZSYmIWlzTmFOKGUpfWZ1bmN0aW9uIG0oZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPTA7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGkpe28ubmV4dChlLmNhbGwodCxpLG4rKykpfSkpfSl9dmFyIHlhPUFycmF5LmlzQXJyYXk7ZnVuY3Rpb24geGEoZSx0KXtyZXR1cm4geWEodCk/ZS5hcHBseSh2b2lkIDAsQihbXSxLKHQpKSk6ZSh0KX1mdW5jdGlvbiBsdChlKXtyZXR1cm4gbShmdW5jdGlvbih0KXtyZXR1cm4geGEoZSx0KX0pfXZhciBFYT1BcnJheS5pc0FycmF5LHdhPU9iamVjdC5nZXRQcm90b3R5cGVPZixUYT1PYmplY3QucHJvdG90eXBlLFNhPU9iamVjdC5rZXlzO2Z1bmN0aW9uIEtvKGUpe2lmKGUubGVuZ3RoPT09MSl7dmFyIHQ9ZVswXTtpZihFYSh0KSlyZXR1cm57YXJnczp0LGtleXM6bnVsbH07aWYoT2EodCkpe3ZhciByPVNhKHQpO3JldHVybnthcmdzOnIubWFwKGZ1bmN0aW9uKG8pe3JldHVybiB0W29dfSksa2V5czpyfX19cmV0dXJue2FyZ3M6ZSxrZXlzOm51bGx9fWZ1bmN0aW9uIE9hKGUpe3JldHVybiBlJiZ0eXBlb2YgZT09Im9iamVjdCImJndhKGUpPT09VGF9ZnVuY3Rpb24gUW8oZSx0KXtyZXR1cm4gZS5yZWR1Y2UoZnVuY3Rpb24ocixvLG4pe3JldHVybiByW29dPXRbbl0scn0se30pfWZ1bmN0aW9uIHooKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9RmUoZSksbz1wdChlKSxuPUtvKGUpLGk9bi5hcmdzLHM9bi5rZXlzO2lmKGkubGVuZ3RoPT09MClyZXR1cm4gZmUoW10scik7dmFyIGE9bmV3IEYoenIoaSxyLHM/ZnVuY3Rpb24oYyl7cmV0dXJuIFFvKHMsYyl9OmJlKSk7cmV0dXJuIG8/YS5waXBlKGx0KG8pKTphfWZ1bmN0aW9uIHpyKGUsdCxyKXtyZXR1cm4gcj09PXZvaWQgMCYmKHI9YmUpLGZ1bmN0aW9uKG8pe1lvKHQsZnVuY3Rpb24oKXtmb3IodmFyIG49ZS5sZW5ndGgsaT1uZXcgQXJyYXkobikscz1uLGE9bixjPWZ1bmN0aW9uKGwpe1lvKHQsZnVuY3Rpb24oKXt2YXIgZj1mZShlW2xdLHQpLHU9ITE7Zi5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGQpe2lbbF09ZCx1fHwodT0hMCxhLS0pLGF8fG8ubmV4dChyKGkuc2xpY2UoKSkpfSxmdW5jdGlvbigpey0tc3x8by5jb21wbGV0ZSgpfSkpfSxvKX0scD0wO3A8bjtwKyspYyhwKX0sbyl9fWZ1bmN0aW9uIFlvKGUsdCxyKXtlP19lKHIsZSx0KTp0KCl9ZnVuY3Rpb24gQm8oZSx0LHIsbyxuLGkscyxhKXt2YXIgYz1bXSxwPTAsbD0wLGY9ITEsdT1mdW5jdGlvbigpe2YmJiFjLmxlbmd0aCYmIXAmJnQuY29tcGxldGUoKX0sZD1mdW5jdGlvbihTKXtyZXR1cm4gcDxvP3YoUyk6Yy5wdXNoKFMpfSx2PWZ1bmN0aW9uKFMpe2kmJnQubmV4dChTKSxwKys7dmFyIFg9ITE7VShyKFMsbCsrKSkuc3Vic2NyaWJlKHcodCxmdW5jdGlvbihyZSl7bj09bnVsbHx8bihyZSksaT9kKHJlKTp0Lm5leHQocmUpfSxmdW5jdGlvbigpe1g9ITB9LHZvaWQgMCxmdW5jdGlvbigpe2lmKFgpdHJ5e3AtLTtmb3IodmFyIHJlPWZ1bmN0aW9uKCl7dmFyIGVlPWMuc2hpZnQoKTtzP19lKHQscyxmdW5jdGlvbigpe3JldHVybiB2KGVlKX0pOnYoZWUpfTtjLmxlbmd0aCYmcDxvOylyZSgpO3UoKX1jYXRjaChlZSl7dC5lcnJvcihlZSl9fSkpfTtyZXR1cm4gZS5zdWJzY3JpYmUodyh0LGQsZnVuY3Rpb24oKXtmPSEwLHUoKX0pKSxmdW5jdGlvbigpe2E9PW51bGx8fGEoKX19ZnVuY3Rpb24gSihlLHQscil7cmV0dXJuIHI9PT12b2lkIDAmJihyPTEvMCksSSh0KT9KKGZ1bmN0aW9uKG8sbil7cmV0dXJuIG0oZnVuY3Rpb24oaSxzKXtyZXR1cm4gdChvLGksbixzKX0pKFUoZShvLG4pKSl9LHIpOih0eXBlb2YgdD09Im51bWJlciImJihyPXQpLEUoZnVuY3Rpb24obyxuKXtyZXR1cm4gQm8obyxuLGUscil9KSl9ZnVuY3Rpb24gTXQoZSl7cmV0dXJuIGU9PT12b2lkIDAmJihlPTEvMCksSihiZSxlKX1mdW5jdGlvbiBHbygpe3JldHVybiBNdCgxKX1mdW5jdGlvbiBLZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gR28oKShmZShlLEZlKGUpKSl9ZnVuY3Rpb24gSChlKXtyZXR1cm4gbmV3IEYoZnVuY3Rpb24odCl7VShlKCkpLnN1YnNjcmliZSh0KX0pfXZhciBMYT1bImFkZExpc3RlbmVyIiwicmVtb3ZlTGlzdGVuZXIiXSxNYT1bImFkZEV2ZW50TGlzdGVuZXIiLCJyZW1vdmVFdmVudExpc3RlbmVyIl0sX2E9WyJvbiIsIm9mZiJdO2Z1bmN0aW9uIGgoZSx0LHIsbyl7aWYoSShyKSYmKG89cixyPXZvaWQgMCksbylyZXR1cm4gaChlLHQscikucGlwZShsdChvKSk7dmFyIG49SyhrYShlKT9NYS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKGMpe3JldHVybiBlW2FdKHQsYyxyKX19KTpBYShlKT9MYS5tYXAoSm8oZSx0KSk6Q2EoZSk/X2EubWFwKEpvKGUsdCkpOltdLDIpLGk9blswXSxzPW5bMV07aWYoIWkmJkx0KGUpKXJldHVybiBKKGZ1bmN0aW9uKGEpe3JldHVybiBoKGEsdCxyKX0pKFUoZSkpO2lmKCFpKXRocm93IG5ldyBUeXBlRXJyb3IoIkludmFsaWQgZXZlbnQgdGFyZ2V0Iik7cmV0dXJuIG5ldyBGKGZ1bmN0aW9uKGEpe3ZhciBjPWZ1bmN0aW9uKCl7Zm9yKHZhciBwPVtdLGw9MDtsPGFyZ3VtZW50cy5sZW5ndGg7bCsrKXBbbF09YXJndW1lbnRzW2xdO3JldHVybiBhLm5leHQoMTxwLmxlbmd0aD9wOnBbMF0pfTtyZXR1cm4gaShjKSxmdW5jdGlvbigpe3JldHVybiBzKGMpfX0pfWZ1bmN0aW9uIEpvKGUsdCl7cmV0dXJuIGZ1bmN0aW9uKHIpe3JldHVybiBmdW5jdGlvbihvKXtyZXR1cm4gZVtyXSh0LG8pfX19ZnVuY3Rpb24gQWEoZSl7cmV0dXJuIEkoZS5hZGRMaXN0ZW5lcikmJkkoZS5yZW1vdmVMaXN0ZW5lcil9ZnVuY3Rpb24gQ2EoZSl7cmV0dXJuIEkoZS5vbikmJkkoZS5vZmYpfWZ1bmN0aW9uIGthKGUpe3JldHVybiBJKGUuYWRkRXZlbnRMaXN0ZW5lcikmJkkoZS5yZW1vdmVFdmVudExpc3RlbmVyKX1mdW5jdGlvbiB1cihlLHQscil7cmV0dXJuIHI/dXIoZSx0KS5waXBlKGx0KHIpKTpuZXcgRihmdW5jdGlvbihvKXt2YXIgbj1mdW5jdGlvbigpe2Zvcih2YXIgcz1bXSxhPTA7YTxhcmd1bWVudHMubGVuZ3RoO2ErKylzW2FdPWFyZ3VtZW50c1thXTtyZXR1cm4gby5uZXh0KHMubGVuZ3RoPT09MT9zWzBdOnMpfSxpPWUobik7cmV0dXJuIEkodCk/ZnVuY3Rpb24oKXtyZXR1cm4gdChuLGkpfTp2b2lkIDB9KX1mdW5jdGlvbiBIZShlLHQscil7ZT09PXZvaWQgMCYmKGU9MCkscj09PXZvaWQgMCYmKHI9V3IpO3ZhciBvPS0xO3JldHVybiB0IT1udWxsJiYodHIodCk/cj10Om89dCksbmV3IEYoZnVuY3Rpb24obil7dmFyIGk9cW8oZSk/K2Utci5ub3coKTplO2k8MCYmKGk9MCk7dmFyIHM9MDtyZXR1cm4gci5zY2hlZHVsZShmdW5jdGlvbigpe24uY2xvc2VkfHwobi5uZXh0KHMrKyksMDw9bz90aGlzLnNjaGVkdWxlKHZvaWQgMCxvKTpuLmNvbXBsZXRlKCkpfSxpKX0pfWZ1bmN0aW9uIEwoKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9RmUoZSksbz1ycihlLDEvMCksbj1lO3JldHVybiBuLmxlbmd0aD9uLmxlbmd0aD09PTE/VShuWzBdKTpNdChvKShmZShuLHIpKTp5fXZhciB0dD1uZXcgRihnZSk7dmFyIEhhPUFycmF5LmlzQXJyYXk7ZnVuY3Rpb24gZHIoZSl7cmV0dXJuIGUubGVuZ3RoPT09MSYmSGEoZVswXSk/ZVswXTplfWZ1bmN0aW9uIGcoZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPTA7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGkpe3JldHVybiBlLmNhbGwodCxpLG4rKykmJm8ubmV4dChpKX0pKX0pfWZ1bmN0aW9uIHJ0KCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPXB0KGUpLG89ZHIoZSk7cmV0dXJuIG8ubGVuZ3RoP25ldyBGKGZ1bmN0aW9uKG4pe3ZhciBpPW8ubWFwKGZ1bmN0aW9uKCl7cmV0dXJuW119KSxzPW8ubWFwKGZ1bmN0aW9uKCl7cmV0dXJuITF9KTtuLmFkZChmdW5jdGlvbigpe2k9cz1udWxsfSk7Zm9yKHZhciBhPWZ1bmN0aW9uKHApe1Uob1twXSkuc3Vic2NyaWJlKHcobixmdW5jdGlvbihsKXtpZihpW3BdLnB1c2gobCksaS5ldmVyeShmdW5jdGlvbih1KXtyZXR1cm4gdS5sZW5ndGh9KSl7dmFyIGY9aS5tYXAoZnVuY3Rpb24odSl7cmV0dXJuIHUuc2hpZnQoKX0pO24ubmV4dChyP3IuYXBwbHkodm9pZCAwLEIoW10sSyhmKSkpOmYpLGkuc29tZShmdW5jdGlvbih1LGQpe3JldHVybiF1Lmxlbmd0aCYmc1tkXX0pJiZuLmNvbXBsZXRlKCl9fSxmdW5jdGlvbigpe3NbcF09ITAsIWlbcF0ubGVuZ3RoJiZuLmNvbXBsZXRlKCl9KSl9LGM9MDshbi5jbG9zZWQmJmM8by5sZW5ndGg7YysrKWEoYyk7cmV0dXJuIGZ1bmN0aW9uKCl7aT1zPW51bGx9fSk6eX1mdW5jdGlvbiBYbyhlKXtyZXR1cm4gRShmdW5jdGlvbih0LHIpe3ZhciBvPSExLG49bnVsbCxpPW51bGwscz0hMSxhPWZ1bmN0aW9uKCl7aWYoaT09bnVsbHx8aS51bnN1YnNjcmliZSgpLGk9bnVsbCxvKXtvPSExO3ZhciBwPW47bj1udWxsLHIubmV4dChwKX1zJiZyLmNvbXBsZXRlKCl9LGM9ZnVuY3Rpb24oKXtpPW51bGwscyYmci5jb21wbGV0ZSgpfTt0LnN1YnNjcmliZSh3KHIsZnVuY3Rpb24ocCl7bz0hMCxuPXAsaXx8VShlKHApKS5zdWJzY3JpYmUoaT13KHIsYSxjKSl9LGZ1bmN0aW9uKCl7cz0hMCwoIW98fCFpfHxpLmNsb3NlZCkmJnIuY29tcGxldGUoKX0pKX0pfWZ1bmN0aW9uICRlKGUsdCl7cmV0dXJuIHQ9PT12b2lkIDAmJih0PXBlKSxYbyhmdW5jdGlvbigpe3JldHVybiBIZShlLHQpfSl9ZnVuY3Rpb24gb3QoZSx0KXtyZXR1cm4gdD09PXZvaWQgMCYmKHQ9bnVsbCksdD10IT1udWxsP3Q6ZSxFKGZ1bmN0aW9uKHIsbyl7dmFyIG49W10saT0wO3Iuc3Vic2NyaWJlKHcobyxmdW5jdGlvbihzKXt2YXIgYSxjLHAsbCxmPW51bGw7aSsrJXQ9PT0wJiZuLnB1c2goW10pO3RyeXtmb3IodmFyIHU9T2UobiksZD11Lm5leHQoKTshZC5kb25lO2Q9dS5uZXh0KCkpe3ZhciB2PWQudmFsdWU7di5wdXNoKHMpLGU8PXYubGVuZ3RoJiYoZj1mIT1udWxsP2Y6W10sZi5wdXNoKHYpKX19Y2F0Y2gocmUpe2E9e2Vycm9yOnJlfX1maW5hbGx5e3RyeXtkJiYhZC5kb25lJiYoYz11LnJldHVybikmJmMuY2FsbCh1KX1maW5hbGx5e2lmKGEpdGhyb3cgYS5lcnJvcn19aWYoZil0cnl7Zm9yKHZhciBTPU9lKGYpLFg9Uy5uZXh0KCk7IVguZG9uZTtYPVMubmV4dCgpKXt2YXIgdj1YLnZhbHVlO1plKG4sdiksby5uZXh0KHYpfX1jYXRjaChyZSl7cD17ZXJyb3I6cmV9fWZpbmFsbHl7dHJ5e1gmJiFYLmRvbmUmJihsPVMucmV0dXJuKSYmbC5jYWxsKFMpfWZpbmFsbHl7aWYocCl0aHJvdyBwLmVycm9yfX19LGZ1bmN0aW9uKCl7dmFyIHMsYTt0cnl7Zm9yKHZhciBjPU9lKG4pLHA9Yy5uZXh0KCk7IXAuZG9uZTtwPWMubmV4dCgpKXt2YXIgbD1wLnZhbHVlO28ubmV4dChsKX19Y2F0Y2goZil7cz17ZXJyb3I6Zn19ZmluYWxseXt0cnl7cCYmIXAuZG9uZSYmKGE9Yy5yZXR1cm4pJiZhLmNhbGwoYyl9ZmluYWxseXtpZihzKXRocm93IHMuZXJyb3J9fW8uY29tcGxldGUoKX0sdm9pZCAwLGZ1bmN0aW9uKCl7bj1udWxsfSkpfSl9ZnVuY3Rpb24gdmUoZSl7cmV0dXJuIEUoZnVuY3Rpb24odCxyKXt2YXIgbz1udWxsLG49ITEsaTtvPXQuc3Vic2NyaWJlKHcocix2b2lkIDAsdm9pZCAwLGZ1bmN0aW9uKHMpe2k9VShlKHMsdmUoZSkodCkpKSxvPyhvLnVuc3Vic2NyaWJlKCksbz1udWxsLGkuc3Vic2NyaWJlKHIpKTpuPSEwfSkpLG4mJihvLnVuc3Vic2NyaWJlKCksbz1udWxsLGkuc3Vic2NyaWJlKHIpKX0pfWZ1bmN0aW9uIFpvKGUsdCxyLG8sbil7cmV0dXJuIGZ1bmN0aW9uKGkscyl7dmFyIGE9cixjPXQscD0wO2kuc3Vic2NyaWJlKHcocyxmdW5jdGlvbihsKXt2YXIgZj1wKys7Yz1hP2UoYyxsLGYpOihhPSEwLGwpLG8mJnMubmV4dChjKX0sbiYmKGZ1bmN0aW9uKCl7YSYmcy5uZXh0KGMpLHMuY29tcGxldGUoKX0pKSl9fWZ1bmN0aW9uIHFyKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPXB0KGUpO3JldHVybiByP0FvKHFyLmFwcGx5KHZvaWQgMCxCKFtdLEsoZSkpKSxsdChyKSk6RShmdW5jdGlvbihvLG4pe3pyKEIoW29dLEsoZHIoZSkpKSkobil9KX1mdW5jdGlvbiBQZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gcXIuYXBwbHkodm9pZCAwLEIoW10sSyhlKSkpfWZ1bmN0aW9uIGp0KGUpe3JldHVybiBFKGZ1bmN0aW9uKHQscil7dmFyIG89ITEsbj1udWxsLGk9bnVsbCxzPWZ1bmN0aW9uKCl7aWYoaT09bnVsbHx8aS51bnN1YnNjcmliZSgpLGk9bnVsbCxvKXtvPSExO3ZhciBhPW47bj1udWxsLHIubmV4dChhKX19O3Quc3Vic2NyaWJlKHcocixmdW5jdGlvbihhKXtpPT1udWxsfHxpLnVuc3Vic2NyaWJlKCksbz0hMCxuPWEsaT13KHIscyxnZSksVShlKGEpKS5zdWJzY3JpYmUoaSl9LGZ1bmN0aW9uKCl7cygpLHIuY29tcGxldGUoKX0sdm9pZCAwLGZ1bmN0aW9uKCl7bj1pPW51bGx9KSl9KX1mdW5jdGlvbiBBZShlLHQpe3JldHVybiB0PT09dm9pZCAwJiYodD1wZSksRShmdW5jdGlvbihyLG8pe3ZhciBuPW51bGwsaT1udWxsLHM9bnVsbCxhPWZ1bmN0aW9uKCl7aWYobil7bi51bnN1YnNjcmliZSgpLG49bnVsbDt2YXIgcD1pO2k9bnVsbCxvLm5leHQocCl9fTtmdW5jdGlvbiBjKCl7dmFyIHA9cytlLGw9dC5ub3coKTtpZihsPHApe249dGhpcy5zY2hlZHVsZSh2b2lkIDAscC1sKSxvLmFkZChuKTtyZXR1cm59YSgpfXIuc3Vic2NyaWJlKHcobyxmdW5jdGlvbihwKXtpPXAscz10Lm5vdygpLG58fChuPXQuc2NoZWR1bGUoYyxlKSxvLmFkZChuKSl9LGZ1bmN0aW9uKCl7YSgpLG8uY29tcGxldGUoKX0sdm9pZCAwLGZ1bmN0aW9uKCl7aT1uPW51bGx9KSl9KX1mdW5jdGlvbiBRZShlKXtyZXR1cm4gRShmdW5jdGlvbih0LHIpe3ZhciBvPSExO3Quc3Vic2NyaWJlKHcocixmdW5jdGlvbihuKXtvPSEwLHIubmV4dChuKX0sZnVuY3Rpb24oKXtvfHxyLm5leHQoZSksci5jb21wbGV0ZSgpfSkpfSl9ZnVuY3Rpb24gRWUoZSl7cmV0dXJuIGU8PTA/ZnVuY3Rpb24oKXtyZXR1cm4geX06RShmdW5jdGlvbih0LHIpe3ZhciBvPTA7dC5zdWJzY3JpYmUodyhyLGZ1bmN0aW9uKG4peysrbzw9ZSYmKHIubmV4dChuKSxlPD1vJiZyLmNvbXBsZXRlKCkpfSkpfSl9ZnVuY3Rpb24gb2UoKXtyZXR1cm4gRShmdW5jdGlvbihlLHQpe2Uuc3Vic2NyaWJlKHcodCxnZSkpfSl9ZnVuY3Rpb24gZW4oZSl7cmV0dXJuIG0oZnVuY3Rpb24oKXtyZXR1cm4gZX0pfWZ1bmN0aW9uIEtyKGUsdCl7cmV0dXJuIHQ/ZnVuY3Rpb24ocil7cmV0dXJuIEtlKHQucGlwZShFZSgxKSxvZSgpKSxyLnBpcGUoS3IoZSkpKX06SihmdW5jdGlvbihyLG8pe3JldHVybiBVKGUocixvKSkucGlwZShFZSgxKSxlbihyKSl9KX1mdW5jdGlvbiBudChlLHQpe3Q9PT12b2lkIDAmJih0PXBlKTt2YXIgcj1IZShlLHQpO3JldHVybiBLcihmdW5jdGlvbigpe3JldHVybiByfSl9ZnVuY3Rpb24gUXIoZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPW5ldyBTZXQ7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGkpe3ZhciBzPWU/ZShpKTppO24uaGFzKHMpfHwobi5hZGQocyksby5uZXh0KGkpKX0pKSx0JiZVKHQpLnN1YnNjcmliZSh3KG8sZnVuY3Rpb24oKXtyZXR1cm4gbi5jbGVhcigpfSxnZSkpfSl9ZnVuY3Rpb24gWShlLHQpe3JldHVybiB0PT09dm9pZCAwJiYodD1iZSksZT1lIT1udWxsP2U6JGEsRShmdW5jdGlvbihyLG8pe3ZhciBuLGk9ITA7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKHMpe3ZhciBhPXQocyk7KGl8fCFlKG4sYSkpJiYoaT0hMSxuPWEsby5uZXh0KHMpKX0pKX0pfWZ1bmN0aW9uICRhKGUsdCl7cmV0dXJuIGU9PT10fWZ1bmN0aW9uIG5lKGUsdCl7cmV0dXJuIFkoZnVuY3Rpb24ocixvKXtyZXR1cm4gdD90KHJbZV0sb1tlXSk6cltlXT09PW9bZV19KX1mdW5jdGlvbiB0bihlKXtyZXR1cm4gZT09PXZvaWQgMCYmKGU9UGEpLEUoZnVuY3Rpb24odCxyKXt2YXIgbz0hMTt0LnN1YnNjcmliZSh3KHIsZnVuY3Rpb24obil7bz0hMCxyLm5leHQobil9LGZ1bmN0aW9uKCl7cmV0dXJuIG8/ci5jb21wbGV0ZSgpOnIuZXJyb3IoZSgpKX0pKX0pfWZ1bmN0aW9uIFBhKCl7cmV0dXJuIG5ldyBmcn1mdW5jdGlvbiBhZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gZnVuY3Rpb24ocil7cmV0dXJuIEtlKHIsJC5hcHBseSh2b2lkIDAsQihbXSxLKGUpKSkpfX1mdW5jdGlvbiBocihlLHQpe3JldHVybiB0P2Z1bmN0aW9uKHIpe3JldHVybiByLnBpcGUoaHIoZnVuY3Rpb24obyxuKXtyZXR1cm4gVShlKG8sbikpLnBpcGUobShmdW5jdGlvbihpLHMpe3JldHVybiB0KG8saSxuLHMpfSkpfSkpfTpFKGZ1bmN0aW9uKHIsbyl7dmFyIG49MCxpPW51bGwscz0hMTtyLnN1YnNjcmliZSh3KG8sZnVuY3Rpb24oYSl7aXx8KGk9dyhvLHZvaWQgMCxmdW5jdGlvbigpe2k9bnVsbCxzJiZvLmNvbXBsZXRlKCl9KSxVKGUoYSxuKyspKS5zdWJzY3JpYmUoaSkpfSxmdW5jdGlvbigpe3M9ITAsIWkmJm8uY29tcGxldGUoKX0pKX0pfWZ1bmN0aW9uIEEoZSl7cmV0dXJuIEUoZnVuY3Rpb24odCxyKXt0cnl7dC5zdWJzY3JpYmUocil9ZmluYWxseXtyLmFkZChlKX19KX1mdW5jdGlvbiBSZShlLHQpe3ZhciByPWFyZ3VtZW50cy5sZW5ndGg+PTI7cmV0dXJuIGZ1bmN0aW9uKG8pe3JldHVybiBvLnBpcGUoZT9nKGZ1bmN0aW9uKG4saSl7cmV0dXJuIGUobixpLG8pfSk6YmUsRWUoMSkscj9RZSh0KTp0bihmdW5jdGlvbigpe3JldHVybiBuZXcgZnJ9KSl9fWZ1bmN0aW9uIFlyKGUpe3JldHVybiBlPD0wP2Z1bmN0aW9uKCl7cmV0dXJuIHl9OkUoZnVuY3Rpb24odCxyKXt2YXIgbz1bXTt0LnN1YnNjcmliZSh3KHIsZnVuY3Rpb24obil7by5wdXNoKG4pLGU8by5sZW5ndGgmJm8uc2hpZnQoKX0sZnVuY3Rpb24oKXt2YXIgbixpO3RyeXtmb3IodmFyIHM9T2UobyksYT1zLm5leHQoKTshYS5kb25lO2E9cy5uZXh0KCkpe3ZhciBjPWEudmFsdWU7ci5uZXh0KGMpfX1jYXRjaChwKXtuPXtlcnJvcjpwfX1maW5hbGx5e3RyeXthJiYhYS5kb25lJiYoaT1zLnJldHVybikmJmkuY2FsbChzKX1maW5hbGx5e2lmKG4pdGhyb3cgbi5lcnJvcn19ci5jb21wbGV0ZSgpfSx2b2lkIDAsZnVuY3Rpb24oKXtvPW51bGx9KSl9KX1mdW5jdGlvbiBybigpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTt2YXIgcj1GZShlKSxvPXJyKGUsMS8wKTtyZXR1cm4gRShmdW5jdGlvbihuLGkpe010KG8pKGZlKEIoW25dLEsoZSkpLHIpKS5zdWJzY3JpYmUoaSl9KX1mdW5jdGlvbiBWZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gcm4uYXBwbHkodm9pZCAwLEIoW10sSyhlKSkpfWZ1bmN0aW9uIHZ0KGUpe3ZhciB0LHI9MS8wLG87cmV0dXJuIGUhPW51bGwmJih0eXBlb2YgZT09Im9iamVjdCI/KHQ9ZS5jb3VudCxyPXQ9PT12b2lkIDA/MS8wOnQsbz1lLmRlbGF5KTpyPWUpLHI8PTA/ZnVuY3Rpb24oKXtyZXR1cm4geX06RShmdW5jdGlvbihuLGkpe3ZhciBzPTAsYSxjPWZ1bmN0aW9uKCl7aWYoYT09bnVsbHx8YS51bnN1YnNjcmliZSgpLGE9bnVsbCxvIT1udWxsKXt2YXIgbD10eXBlb2Ygbz09Im51bWJlciI/SGUobyk6VShvKHMpKSxmPXcoaSxmdW5jdGlvbigpe2YudW5zdWJzY3JpYmUoKSxwKCl9KTtsLnN1YnNjcmliZShmKX1lbHNlIHAoKX0scD1mdW5jdGlvbigpe3ZhciBsPSExO2E9bi5zdWJzY3JpYmUodyhpLHZvaWQgMCxmdW5jdGlvbigpeysrczxyP2E/YygpOmw9ITA6aS5jb21wbGV0ZSgpfSkpLGwmJmMoKX07cCgpfSl9ZnVuY3Rpb24gVXQoZSx0KXtyZXR1cm4gRShabyhlLHQsYXJndW1lbnRzLmxlbmd0aD49MiwhMCkpfWZ1bmN0aW9uIGxlKGUpe2U9PT12b2lkIDAmJihlPXt9KTt2YXIgdD1lLmNvbm5lY3RvcixyPXQ9PT12b2lkIDA/ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFR9OnQsbz1lLnJlc2V0T25FcnJvcixuPW89PT12b2lkIDA/ITA6byxpPWUucmVzZXRPbkNvbXBsZXRlLHM9aT09PXZvaWQgMD8hMDppLGE9ZS5yZXNldE9uUmVmQ291bnRaZXJvLGM9YT09PXZvaWQgMD8hMDphO3JldHVybiBmdW5jdGlvbihwKXt2YXIgbCxmLHUsZD0wLHY9ITEsUz0hMSxYPWZ1bmN0aW9uKCl7Zj09bnVsbHx8Zi51bnN1YnNjcmliZSgpLGY9dm9pZCAwfSxyZT1mdW5jdGlvbigpe1goKSxsPXU9dm9pZCAwLHY9Uz0hMX0sZWU9ZnVuY3Rpb24oKXt2YXIgaz1sO3JlKCksaz09bnVsbHx8ay51bnN1YnNjcmliZSgpfTtyZXR1cm4gRShmdW5jdGlvbihrLHV0KXtkKyssIVMmJiF2JiZYKCk7dmFyIGplPXU9dSE9bnVsbD91OnIoKTt1dC5hZGQoZnVuY3Rpb24oKXtkLS0sZD09PTAmJiFTJiYhdiYmKGY9QnIoZWUsYykpfSksamUuc3Vic2NyaWJlKHV0KSwhbCYmZD4wJiYobD1uZXcgYnQoe25leHQ6ZnVuY3Rpb24oUil7cmV0dXJuIGplLm5leHQoUil9LGVycm9yOmZ1bmN0aW9uKFIpe1M9ITAsWCgpLGY9QnIocmUsbixSKSxqZS5lcnJvcihSKX0sY29tcGxldGU6ZnVuY3Rpb24oKXt2PSEwLFgoKSxmPUJyKHJlLHMpLGplLmNvbXBsZXRlKCl9fSksVShrKS5zdWJzY3JpYmUobCkpfSkocCl9fWZ1bmN0aW9uIEJyKGUsdCl7Zm9yKHZhciByPVtdLG89MjtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbby0yXT1hcmd1bWVudHNbb107aWYodD09PSEwKXtlKCk7cmV0dXJufWlmKHQhPT0hMSl7dmFyIG49bmV3IGJ0KHtuZXh0OmZ1bmN0aW9uKCl7bi51bnN1YnNjcmliZSgpLGUoKX19KTtyZXR1cm4gVSh0LmFwcGx5KHZvaWQgMCxCKFtdLEsocikpKSkuc3Vic2NyaWJlKG4pfX1mdW5jdGlvbiBaKGUsdCxyKXt2YXIgbyxuLGkscyxhPSExO3JldHVybiBlJiZ0eXBlb2YgZT09Im9iamVjdCI/KG89ZS5idWZmZXJTaXplLHM9bz09PXZvaWQgMD8xLzA6byxuPWUud2luZG93VGltZSx0PW49PT12b2lkIDA/MS8wOm4saT1lLnJlZkNvdW50LGE9aT09PXZvaWQgMD8hMTppLHI9ZS5zY2hlZHVsZXIpOnM9ZSE9bnVsbD9lOjEvMCxsZSh7Y29ubmVjdG9yOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBJdChzLHQscil9LHJlc2V0T25FcnJvcjohMCxyZXNldE9uQ29tcGxldGU6ITEscmVzZXRPblJlZkNvdW50WmVybzphfSl9ZnVuY3Rpb24gSWUoZSl7cmV0dXJuIGcoZnVuY3Rpb24odCxyKXtyZXR1cm4gZTw9cn0pfWZ1bmN0aW9uIEdyKGUpe3JldHVybiBFKGZ1bmN0aW9uKHQscil7dmFyIG89ITEsbj13KHIsZnVuY3Rpb24oKXtuPT1udWxsfHxuLnVuc3Vic2NyaWJlKCksbz0hMH0sZ2UpO1UoZSkuc3Vic2NyaWJlKG4pLHQuc3Vic2NyaWJlKHcocixmdW5jdGlvbihpKXtyZXR1cm4gbyYmci5uZXh0KGkpfSkpfSl9ZnVuY3Rpb24gUSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTt2YXIgcj1GZShlKTtyZXR1cm4gRShmdW5jdGlvbihvLG4peyhyP0tlKGUsbyxyKTpLZShlLG8pKS5zdWJzY3JpYmUobil9KX1mdW5jdGlvbiBiKGUsdCl7cmV0dXJuIEUoZnVuY3Rpb24ocixvKXt2YXIgbj1udWxsLGk9MCxzPSExLGE9ZnVuY3Rpb24oKXtyZXR1cm4gcyYmIW4mJm8uY29tcGxldGUoKX07ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGMpe249PW51bGx8fG4udW5zdWJzY3JpYmUoKTt2YXIgcD0wLGw9aSsrO1UoZShjLGwpKS5zdWJzY3JpYmUobj13KG8sZnVuY3Rpb24oZil7cmV0dXJuIG8ubmV4dCh0P3QoYyxmLGwscCsrKTpmKX0sZnVuY3Rpb24oKXtuPW51bGwsYSgpfSkpfSxmdW5jdGlvbigpe3M9ITAsYSgpfSkpfSl9ZnVuY3Rpb24gVyhlKXtyZXR1cm4gRShmdW5jdGlvbih0LHIpe1UoZSkuc3Vic2NyaWJlKHcocixmdW5jdGlvbigpe3JldHVybiByLmNvbXBsZXRlKCl9LGdlKSksIXIuY2xvc2VkJiZ0LnN1YnNjcmliZShyKX0pfWZ1bmN0aW9uIEpyKGUsdCl7cmV0dXJuIHQ9PT12b2lkIDAmJih0PSExKSxFKGZ1bmN0aW9uKHIsbyl7dmFyIG49MDtyLnN1YnNjcmliZSh3KG8sZnVuY3Rpb24oaSl7dmFyIHM9ZShpLG4rKyk7KHN8fHQpJiZvLm5leHQoaSksIXMmJm8uY29tcGxldGUoKX0pKX0pfWZ1bmN0aW9uIE8oZSx0LHIpe3ZhciBvPUkoZSl8fHR8fHI/e25leHQ6ZSxlcnJvcjp0LGNvbXBsZXRlOnJ9OmU7cmV0dXJuIG8/RShmdW5jdGlvbihuLGkpe3ZhciBzOyhzPW8uc3Vic2NyaWJlKT09PW51bGx8fHM9PT12b2lkIDB8fHMuY2FsbChvKTt2YXIgYT0hMDtuLnN1YnNjcmliZSh3KGksZnVuY3Rpb24oYyl7dmFyIHA7KHA9by5uZXh0KT09PW51bGx8fHA9PT12b2lkIDB8fHAuY2FsbChvLGMpLGkubmV4dChjKX0sZnVuY3Rpb24oKXt2YXIgYzthPSExLChjPW8uY29tcGxldGUpPT09bnVsbHx8Yz09PXZvaWQgMHx8Yy5jYWxsKG8pLGkuY29tcGxldGUoKX0sZnVuY3Rpb24oYyl7dmFyIHA7YT0hMSwocD1vLmVycm9yKT09PW51bGx8fHA9PT12b2lkIDB8fHAuY2FsbChvLGMpLGkuZXJyb3IoYyl9LGZ1bmN0aW9uKCl7dmFyIGMscDthJiYoKGM9by51bnN1YnNjcmliZSk9PT1udWxsfHxjPT09dm9pZCAwfHxjLmNhbGwobykpLChwPW8uZmluYWxpemUpPT09bnVsbHx8cD09PXZvaWQgMHx8cC5jYWxsKG8pfSkpfSk6YmV9ZnVuY3Rpb24gb24oZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPXQhPW51bGw/dDp7fSxpPW4ubGVhZGluZyxzPWk9PT12b2lkIDA/ITA6aSxhPW4udHJhaWxpbmcsYz1hPT09dm9pZCAwPyExOmEscD0hMSxsPW51bGwsZj1udWxsLHU9ITEsZD1mdW5jdGlvbigpe2Y9PW51bGx8fGYudW5zdWJzY3JpYmUoKSxmPW51bGwsYyYmKFgoKSx1JiZvLmNvbXBsZXRlKCkpfSx2PWZ1bmN0aW9uKCl7Zj1udWxsLHUmJm8uY29tcGxldGUoKX0sUz1mdW5jdGlvbihyZSl7cmV0dXJuIGY9VShlKHJlKSkuc3Vic2NyaWJlKHcobyxkLHYpKX0sWD1mdW5jdGlvbigpe2lmKHApe3A9ITE7dmFyIHJlPWw7bD1udWxsLG8ubmV4dChyZSksIXUmJlMocmUpfX07ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKHJlKXtwPSEwLGw9cmUsIShmJiYhZi5jbG9zZWQpJiYocz9YKCk6UyhyZSkpfSxmdW5jdGlvbigpe3U9ITAsIShjJiZwJiZmJiYhZi5jbG9zZWQpJiZvLmNvbXBsZXRlKCl9KSl9KX1mdW5jdGlvbiBndChlLHQscil7dD09PXZvaWQgMCYmKHQ9cGUpO3ZhciBvPUhlKGUsdCk7cmV0dXJuIG9uKGZ1bmN0aW9uKCl7cmV0dXJuIG99LHIpfWZ1bmN0aW9uIHRlKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPXB0KGUpO3JldHVybiBFKGZ1bmN0aW9uKG8sbil7Zm9yKHZhciBpPWUubGVuZ3RoLHM9bmV3IEFycmF5KGkpLGE9ZS5tYXAoZnVuY3Rpb24oKXtyZXR1cm4hMX0pLGM9ITEscD1mdW5jdGlvbihmKXtVKGVbZl0pLnN1YnNjcmliZSh3KG4sZnVuY3Rpb24odSl7c1tmXT11LCFjJiYhYVtmXSYmKGFbZl09ITAsKGM9YS5ldmVyeShiZSkpJiYoYT1udWxsKSl9LGdlKSl9LGw9MDtsPGk7bCsrKXAobCk7by5zdWJzY3JpYmUodyhuLGZ1bmN0aW9uKGYpe2lmKGMpe3ZhciB1PUIoW2ZdLEsocykpO24ubmV4dChyP3IuYXBwbHkodm9pZCAwLEIoW10sSyh1KSkpOnUpfX0pKX0pfWZ1bmN0aW9uIG5uKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3JldHVybiBFKGZ1bmN0aW9uKHIsbyl7cnQuYXBwbHkodm9pZCAwLEIoW3JdLEsoZSkpKS5zdWJzY3JpYmUobyl9KX1mdW5jdGlvbiBYcigpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gbm4uYXBwbHkodm9pZCAwLEIoW10sSyhlKSkpfWZ1bmN0aW9uIGFuKCl7bGV0IGU9bmV3IEl0KDEpO3JldHVybiBoKGRvY3VtZW50LCJET01Db250ZW50TG9hZGVkIix7b25jZTohMH0pLnN1YnNjcmliZSgoKT0+ZS5uZXh0KGRvY3VtZW50KSksZX1mdW5jdGlvbiBNKGUsdD1kb2N1bWVudCl7cmV0dXJuIEFycmF5LmZyb20odC5xdWVyeVNlbGVjdG9yQWxsKGUpKX1mdW5jdGlvbiBqKGUsdD1kb2N1bWVudCl7bGV0IHI9dWUoZSx0KTtpZih0eXBlb2Ygcj09InVuZGVmaW5lZCIpdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKGBNaXNzaW5nIGVsZW1lbnQ6IGV4cGVjdGVkICIke2V9IiB0byBiZSBwcmVzZW50YCk7cmV0dXJuIHJ9ZnVuY3Rpb24gdWUoZSx0PWRvY3VtZW50KXtyZXR1cm4gdC5xdWVyeVNlbGVjdG9yKGUpfHx2b2lkIDB9ZnVuY3Rpb24gTmUoKXt2YXIgZSx0LHIsbztyZXR1cm4obz0ocj0odD0oZT1kb2N1bWVudC5hY3RpdmVFbGVtZW50KT09bnVsbD92b2lkIDA6ZS5zaGFkb3dSb290KT09bnVsbD92b2lkIDA6dC5hY3RpdmVFbGVtZW50KSE9bnVsbD9yOmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpIT1udWxsP286dm9pZCAwfXZhciBSYT1MKGgoZG9jdW1lbnQuYm9keSwiZm9jdXNpbiIpLGgoZG9jdW1lbnQuYm9keSwiZm9jdXNvdXQiKSkucGlwZShBZSgxKSxRKHZvaWQgMCksbSgoKT0+TmUoKXx8ZG9jdW1lbnQuYm9keSksWigxKSk7ZnVuY3Rpb24gWWUoZSl7cmV0dXJuIFJhLnBpcGUobSh0PT5lLmNvbnRhaW5zKHQpKSxZKCkpfWZ1bmN0aW9uIGl0KGUsdCl7cmV0dXJuIEgoKCk9PkwoaChlLCJtb3VzZWVudGVyIikucGlwZShtKCgpPT4hMCkpLGgoZSwibW91c2VsZWF2ZSIpLnBpcGUobSgoKT0+ITEpKSkucGlwZSh0P2p0KHI9PkhlKCshcip0KSk6YmUsUShlLm1hdGNoZXMoIjpob3ZlciIpKSkpfWZ1bmN0aW9uIHNuKGUsdCl7aWYodHlwZW9mIHQ9PSJzdHJpbmcifHx0eXBlb2YgdD09Im51bWJlciIpZS5pbm5lckhUTUwrPXQudG9TdHJpbmcoKTtlbHNlIGlmKHQgaW5zdGFuY2VvZiBOb2RlKWUuYXBwZW5kQ2hpbGQodCk7ZWxzZSBpZihBcnJheS5pc0FycmF5KHQpKWZvcihsZXQgciBvZiB0KXNuKGUscil9ZnVuY3Rpb24geChlLHQsLi4ucil7bGV0IG89ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChlKTtpZih0KWZvcihsZXQgbiBvZiBPYmplY3Qua2V5cyh0KSl0eXBlb2YgdFtuXSE9InVuZGVmaW5lZCImJih0eXBlb2YgdFtuXSE9ImJvb2xlYW4iP28uc2V0QXR0cmlidXRlKG4sdFtuXSk6by5zZXRBdHRyaWJ1dGUobiwiIikpO2ZvcihsZXQgbiBvZiByKXNuKG8sbik7cmV0dXJuIG99ZnVuY3Rpb24gYnIoZSl7aWYoZT45OTkpe2xldCB0PSsoKGUtOTUwKSUxZTM+OTkpO3JldHVybmAkeygoZSsxZS02KS8xZTMpLnRvRml4ZWQodCl9a2B9ZWxzZSByZXR1cm4gZS50b1N0cmluZygpfWZ1bmN0aW9uIF90KGUpe2xldCB0PXgoInNjcmlwdCIse3NyYzplfSk7cmV0dXJuIEgoKCk9Pihkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpLEwoaCh0LCJsb2FkIiksaCh0LCJlcnJvciIpLnBpcGUoYigoKT0+TnIoKCk9Pm5ldyBSZWZlcmVuY2VFcnJvcihgSW52YWxpZCBzY3JpcHQ6ICR7ZX1gKSkpKSkucGlwZShtKCgpPT57fSksQSgoKT0+ZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZCh0KSksRWUoMSkpKSl9dmFyIGNuPW5ldyBULElhPUgoKCk9PnR5cGVvZiBSZXNpemVPYnNlcnZlcj09InVuZGVmaW5lZCI/X3QoImh0dHBzOi8vdW5wa2cuY29tL3Jlc2l6ZS1vYnNlcnZlci1wb2x5ZmlsbCIpOiQodm9pZCAwKSkucGlwZShtKCgpPT5uZXcgUmVzaXplT2JzZXJ2ZXIoZT0+ZS5mb3JFYWNoKHQ9PmNuLm5leHQodCkpKSksYihlPT5MKHR0LCQoZSkpLnBpcGUoQSgoKT0+ZS5kaXNjb25uZWN0KCkpKSksWigxKSk7ZnVuY3Rpb24gZGUoZSl7cmV0dXJue3dpZHRoOmUub2Zmc2V0V2lkdGgsaGVpZ2h0OmUub2Zmc2V0SGVpZ2h0fX1mdW5jdGlvbiBMZShlKXtsZXQgdD1lO2Zvcig7dC5jbGllbnRXaWR0aD09PTAmJnQucGFyZW50RWxlbWVudDspdD10LnBhcmVudEVsZW1lbnQ7cmV0dXJuIElhLnBpcGUoTyhyPT5yLm9ic2VydmUodCkpLGIocj0+Y24ucGlwZShnKG89Pm8udGFyZ2V0PT09dCksQSgoKT0+ci51bm9ic2VydmUodCkpKSksbSgoKT0+ZGUoZSkpLFEoZGUoZSkpKX1mdW5jdGlvbiBBdChlKXtyZXR1cm57d2lkdGg6ZS5zY3JvbGxXaWR0aCxoZWlnaHQ6ZS5zY3JvbGxIZWlnaHR9fWZ1bmN0aW9uIHZyKGUpe2xldCB0PWUucGFyZW50RWxlbWVudDtmb3IoO3QmJihlLnNjcm9sbFdpZHRoPD10LnNjcm9sbFdpZHRoJiZlLnNjcm9sbEhlaWdodDw9dC5zY3JvbGxIZWlnaHQpOyl0PShlPXQpLnBhcmVudEVsZW1lbnQ7cmV0dXJuIHQ/ZTp2b2lkIDB9ZnVuY3Rpb24gcG4oZSl7bGV0IHQ9W10scj1lLnBhcmVudEVsZW1lbnQ7Zm9yKDtyOykoZS5jbGllbnRXaWR0aD5yLmNsaWVudFdpZHRofHxlLmNsaWVudEhlaWdodD5yLmNsaWVudEhlaWdodCkmJnQucHVzaChyKSxyPShlPXIpLnBhcmVudEVsZW1lbnQ7cmV0dXJuIHQubGVuZ3RoPT09MCYmdC5wdXNoKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCksdH1mdW5jdGlvbiBCZShlKXtyZXR1cm57eDplLm9mZnNldExlZnQseTplLm9mZnNldFRvcH19ZnVuY3Rpb24gbG4oZSl7bGV0IHQ9ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtyZXR1cm57eDp0Lngrd2luZG93LnNjcm9sbFgseTp0Lnkrd2luZG93LnNjcm9sbFl9fWZ1bmN0aW9uIG1uKGUpe3JldHVybiBMKGgod2luZG93LCJsb2FkIiksaCh3aW5kb3csInJlc2l6ZSIpKS5waXBlKCRlKDAseWUpLG0oKCk9PkJlKGUpKSxRKEJlKGUpKSl9ZnVuY3Rpb24gZ3IoZSl7cmV0dXJue3g6ZS5zY3JvbGxMZWZ0LHk6ZS5zY3JvbGxUb3B9fWZ1bmN0aW9uIEdlKGUpe3JldHVybiBMKGgoZSwic2Nyb2xsIiksaCh3aW5kb3csInNjcm9sbCIpLGgod2luZG93LCJyZXNpemUiKSkucGlwZSgkZSgwLHllKSxtKCgpPT5ncihlKSksUShncihlKSkpfXZhciBmbj1uZXcgVCxGYT1IKCgpPT4kKG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcihlPT57Zm9yKGxldCB0IG9mIGUpZm4ubmV4dCh0KX0se3RocmVzaG9sZDowfSkpKS5waXBlKGIoZT0+TCh0dCwkKGUpKS5waXBlKEEoKCk9PmUuZGlzY29ubmVjdCgpKSkpLFooMSkpO2Z1bmN0aW9uIG10KGUpe3JldHVybiBGYS5waXBlKE8odD0+dC5vYnNlcnZlKGUpKSxiKHQ9PmZuLnBpcGUoZygoe3RhcmdldDpyfSk9PnI9PT1lKSxBKCgpPT50LnVub2JzZXJ2ZShlKSksbSgoe2lzSW50ZXJzZWN0aW5nOnJ9KT0+cikpKSl9ZnVuY3Rpb24gdW4oZSx0PTE2KXtyZXR1cm4gR2UoZSkucGlwZShtKCh7eTpyfSk9PntsZXQgbz1kZShlKSxuPUF0KGUpO3JldHVybiByPj1uLmhlaWdodC1vLmhlaWdodC10fSksWSgpKX12YXIgeXI9e2RyYXdlcjpqKCJbZGF0YS1tZC10b2dnbGU9ZHJhd2VyXSIpLHNlYXJjaDpqKCJbZGF0YS1tZC10b2dnbGU9c2VhcmNoXSIpfTtmdW5jdGlvbiBkbihlKXtyZXR1cm4geXJbZV0uY2hlY2tlZH1mdW5jdGlvbiBhdChlLHQpe3lyW2VdLmNoZWNrZWQhPT10JiZ5cltlXS5jbGljaygpfWZ1bmN0aW9uIEplKGUpe2xldCB0PXlyW2VdO3JldHVybiBoKHQsImNoYW5nZSIpLnBpcGUobSgoKT0+dC5jaGVja2VkKSxRKHQuY2hlY2tlZCkpfWZ1bmN0aW9uIGphKGUsdCl7c3dpdGNoKGUuY29uc3RydWN0b3Ipe2Nhc2UgSFRNTElucHV0RWxlbWVudDpyZXR1cm4gZS50eXBlPT09InJhZGlvIj8vXkFycm93Ly50ZXN0KHQpOiEwO2Nhc2UgSFRNTFNlbGVjdEVsZW1lbnQ6Y2FzZSBIVE1MVGV4dEFyZWFFbGVtZW50OnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuIGUuaXNDb250ZW50RWRpdGFibGV9fWZ1bmN0aW9uIFVhKCl7cmV0dXJuIEwoaCh3aW5kb3csImNvbXBvc2l0aW9uc3RhcnQiKS5waXBlKG0oKCk9PiEwKSksaCh3aW5kb3csImNvbXBvc2l0aW9uZW5kIikucGlwZShtKCgpPT4hMSkpKS5waXBlKFEoITEpKX1mdW5jdGlvbiBobigpe2xldCBlPWgod2luZG93LCJrZXlkb3duIikucGlwZShnKHQ9PiEodC5tZXRhS2V5fHx0LmN0cmxLZXkpKSxtKHQ9Pih7bW9kZTpkbigic2VhcmNoIik/InNlYXJjaCI6Imdsb2JhbCIsdHlwZTp0LmtleSxjbGFpbSgpe3QucHJldmVudERlZmF1bHQoKSx0LnN0b3BQcm9wYWdhdGlvbigpfX0pKSxnKCh7bW9kZTp0LHR5cGU6cn0pPT57aWYodD09PSJnbG9iYWwiKXtsZXQgbz1OZSgpO2lmKHR5cGVvZiBvIT0idW5kZWZpbmVkIilyZXR1cm4hamEobyxyKX1yZXR1cm4hMH0pLGxlKCkpO3JldHVybiBVYSgpLnBpcGUoYih0PT50P3k6ZSkpfWZ1bmN0aW9uIHdlKCl7cmV0dXJuIG5ldyBVUkwobG9jYXRpb24uaHJlZil9ZnVuY3Rpb24gc3QoZSx0PSExKXtpZihWKCJuYXZpZ2F0aW9uLmluc3RhbnQiKSYmIXQpe2xldCByPXgoImEiLHtocmVmOmUuaHJlZn0pO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQociksci5jbGljaygpLHIucmVtb3ZlKCl9ZWxzZSBsb2NhdGlvbi5ocmVmPWUuaHJlZn1mdW5jdGlvbiBibigpe3JldHVybiBuZXcgVH1mdW5jdGlvbiB2bigpe3JldHVybiBsb2NhdGlvbi5oYXNoLnNsaWNlKDEpfWZ1bmN0aW9uIGduKGUpe2xldCB0PXgoImEiLHtocmVmOmV9KTt0LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIixyPT5yLnN0b3BQcm9wYWdhdGlvbigpKSx0LmNsaWNrKCl9ZnVuY3Rpb24gWnIoZSl7cmV0dXJuIEwoaCh3aW5kb3csImhhc2hjaGFuZ2UiKSxlKS5waXBlKG0odm4pLFEodm4oKSksZyh0PT50Lmxlbmd0aD4wKSxaKDEpKX1mdW5jdGlvbiB5bihlKXtyZXR1cm4gWnIoZSkucGlwZShtKHQ9PnVlKGBbaWQ9IiR7dH0iXWApKSxnKHQ9PnR5cGVvZiB0IT0idW5kZWZpbmVkIikpfWZ1bmN0aW9uIFd0KGUpe2xldCB0PW1hdGNoTWVkaWEoZSk7cmV0dXJuIHVyKHI9PnQuYWRkTGlzdGVuZXIoKCk9PnIodC5tYXRjaGVzKSkpLnBpcGUoUSh0Lm1hdGNoZXMpKX1mdW5jdGlvbiB4bigpe2xldCBlPW1hdGNoTWVkaWEoInByaW50Iik7cmV0dXJuIEwoaCh3aW5kb3csImJlZm9yZXByaW50IikucGlwZShtKCgpPT4hMCkpLGgod2luZG93LCJhZnRlcnByaW50IikucGlwZShtKCgpPT4hMSkpKS5waXBlKFEoZS5tYXRjaGVzKSl9ZnVuY3Rpb24gZW8oZSx0KXtyZXR1cm4gZS5waXBlKGIocj0+cj90KCk6eSkpfWZ1bmN0aW9uIHRvKGUsdCl7cmV0dXJuIG5ldyBGKHI9PntsZXQgbz1uZXcgWE1MSHR0cFJlcXVlc3Q7cmV0dXJuIG8ub3BlbigiR0VUIixgJHtlfWApLG8ucmVzcG9uc2VUeXBlPSJibG9iIixvLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCgpPT57by5zdGF0dXM+PTIwMCYmby5zdGF0dXM8MzAwPyhyLm5leHQoby5yZXNwb25zZSksci5jb21wbGV0ZSgpKTpyLmVycm9yKG5ldyBFcnJvcihvLnN0YXR1c1RleHQpKX0pLG8uYWRkRXZlbnRMaXN0ZW5lcigiZXJyb3IiLCgpPT57ci5lcnJvcihuZXcgRXJyb3IoIk5ldHdvcmsgZXJyb3IiKSl9KSxvLmFkZEV2ZW50TGlzdGVuZXIoImFib3J0IiwoKT0+e3IuY29tcGxldGUoKX0pLHR5cGVvZih0PT1udWxsP3ZvaWQgMDp0LnByb2dyZXNzJCkhPSJ1bmRlZmluZWQiJiYoby5hZGRFdmVudExpc3RlbmVyKCJwcm9ncmVzcyIsbj0+e3ZhciBpO2lmKG4ubGVuZ3RoQ29tcHV0YWJsZSl0LnByb2dyZXNzJC5uZXh0KG4ubG9hZGVkL24udG90YWwqMTAwKTtlbHNle2xldCBzPShpPW8uZ2V0UmVzcG9uc2VIZWFkZXIoIkNvbnRlbnQtTGVuZ3RoIikpIT1udWxsP2k6MDt0LnByb2dyZXNzJC5uZXh0KG4ubG9hZGVkLytzKjEwMCl9fSksdC5wcm9ncmVzcyQubmV4dCg1KSksby5zZW5kKCksKCk9Pm8uYWJvcnQoKX0pfWZ1bmN0aW9uIHplKGUsdCl7cmV0dXJuIHRvKGUsdCkucGlwZShiKHI9PnIudGV4dCgpKSxtKHI9PkpTT04ucGFyc2UocikpLFooMSkpfWZ1bmN0aW9uIHhyKGUsdCl7bGV0IHI9bmV3IERPTVBhcnNlcjtyZXR1cm4gdG8oZSx0KS5waXBlKGIobz0+by50ZXh0KCkpLG0obz0+ci5wYXJzZUZyb21TdHJpbmcobywidGV4dC9odG1sIikpLFooMSkpfWZ1bmN0aW9uIEVuKGUsdCl7bGV0IHI9bmV3IERPTVBhcnNlcjtyZXR1cm4gdG8oZSx0KS5waXBlKGIobz0+by50ZXh0KCkpLG0obz0+ci5wYXJzZUZyb21TdHJpbmcobywidGV4dC94bWwiKSksWigxKSl9ZnVuY3Rpb24gd24oKXtyZXR1cm57eDpNYXRoLm1heCgwLHNjcm9sbFgpLHk6TWF0aC5tYXgoMCxzY3JvbGxZKX19ZnVuY3Rpb24gVG4oKXtyZXR1cm4gTChoKHdpbmRvdywic2Nyb2xsIix7cGFzc2l2ZTohMH0pLGgod2luZG93LCJyZXNpemUiLHtwYXNzaXZlOiEwfSkpLnBpcGUobSh3biksUSh3bigpKSl9ZnVuY3Rpb24gU24oKXtyZXR1cm57d2lkdGg6aW5uZXJXaWR0aCxoZWlnaHQ6aW5uZXJIZWlnaHR9fWZ1bmN0aW9uIE9uKCl7cmV0dXJuIGgod2luZG93LCJyZXNpemUiLHtwYXNzaXZlOiEwfSkucGlwZShtKFNuKSxRKFNuKCkpKX1mdW5jdGlvbiBMbigpe3JldHVybiB6KFtUbigpLE9uKCldKS5waXBlKG0oKFtlLHRdKT0+KHtvZmZzZXQ6ZSxzaXplOnR9KSksWigxKSl9ZnVuY3Rpb24gRXIoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyfSl7bGV0IG89dC5waXBlKG5lKCJzaXplIikpLG49eihbbyxyXSkucGlwZShtKCgpPT5CZShlKSkpO3JldHVybiB6KFtyLHQsbl0pLnBpcGUobSgoW3toZWlnaHQ6aX0se29mZnNldDpzLHNpemU6YX0se3g6Yyx5OnB9XSk9Pih7b2Zmc2V0Ont4OnMueC1jLHk6cy55LXAraX0sc2l6ZTphfSkpKX1mdW5jdGlvbiBXYShlKXtyZXR1cm4gaChlLCJtZXNzYWdlIix0PT50LmRhdGEpfWZ1bmN0aW9uIERhKGUpe2xldCB0PW5ldyBUO3JldHVybiB0LnN1YnNjcmliZShyPT5lLnBvc3RNZXNzYWdlKHIpKSx0fWZ1bmN0aW9uIE1uKGUsdD1uZXcgV29ya2VyKGUpKXtsZXQgcj1XYSh0KSxvPURhKHQpLG49bmV3IFQ7bi5zdWJzY3JpYmUobyk7bGV0IGk9by5waXBlKG9lKCksYWUoITApKTtyZXR1cm4gbi5waXBlKG9lKCksVmUoci5waXBlKFcoaSkpKSxsZSgpKX12YXIgVmE9aigiI19fY29uZmlnIiksQ3Q9SlNPTi5wYXJzZShWYS50ZXh0Q29udGVudCk7Q3QuYmFzZT1gJHtuZXcgVVJMKEN0LmJhc2Usd2UoKSl9YDtmdW5jdGlvbiBUZSgpe3JldHVybiBDdH1mdW5jdGlvbiBWKGUpe3JldHVybiBDdC5mZWF0dXJlcy5pbmNsdWRlcyhlKX1mdW5jdGlvbiBNZShlLHQpe3JldHVybiB0eXBlb2YgdCE9InVuZGVmaW5lZCI/Q3QudHJhbnNsYXRpb25zW2VdLnJlcGxhY2UoIiMiLHQudG9TdHJpbmcoKSk6Q3QudHJhbnNsYXRpb25zW2VdfWZ1bmN0aW9uIENlKGUsdD1kb2N1bWVudCl7cmV0dXJuIGooYFtkYXRhLW1kLWNvbXBvbmVudD0ke2V9XWAsdCl9ZnVuY3Rpb24gbWUoZSx0PWRvY3VtZW50KXtyZXR1cm4gTShgW2RhdGEtbWQtY29tcG9uZW50PSR7ZX1dYCx0KX1mdW5jdGlvbiBOYShlKXtsZXQgdD1qKCIubWQtdHlwZXNldCA+IDpmaXJzdC1jaGlsZCIsZSk7cmV0dXJuIGgodCwiY2xpY2siLHtvbmNlOiEwfSkucGlwZShtKCgpPT5qKCIubWQtdHlwZXNldCIsZSkpLG0ocj0+KHtoYXNoOl9fbWRfaGFzaChyLmlubmVySFRNTCl9KSkpfWZ1bmN0aW9uIF9uKGUpe2lmKCFWKCJhbm5vdW5jZS5kaXNtaXNzIil8fCFlLmNoaWxkRWxlbWVudENvdW50KXJldHVybiB5O2lmKCFlLmhpZGRlbil7bGV0IHQ9aigiLm1kLXR5cGVzZXQiLGUpO19fbWRfaGFzaCh0LmlubmVySFRNTCk9PT1fX21kX2dldCgiX19hbm5vdW5jZSIpJiYoZS5oaWRkZW49ITApfXJldHVybiBIKCgpPT57bGV0IHQ9bmV3IFQ7cmV0dXJuIHQuc3Vic2NyaWJlKCh7aGFzaDpyfSk9PntlLmhpZGRlbj0hMCxfX21kX3NldCgiX19hbm5vdW5jZSIscil9KSxOYShlKS5waXBlKE8ocj0+dC5uZXh0KHIpKSxBKCgpPT50LmNvbXBsZXRlKCkpLG0ocj0+UCh7cmVmOmV9LHIpKSl9KX1mdW5jdGlvbiB6YShlLHt0YXJnZXQkOnR9KXtyZXR1cm4gdC5waXBlKG0ocj0+KHtoaWRkZW46ciE9PWV9KSkpfWZ1bmN0aW9uIEFuKGUsdCl7bGV0IHI9bmV3IFQ7cmV0dXJuIHIuc3Vic2NyaWJlKCh7aGlkZGVuOm99KT0+e2UuaGlkZGVuPW99KSx6YShlLHQpLnBpcGUoTyhvPT5yLm5leHQobykpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT5QKHtyZWY6ZX0sbykpKX1mdW5jdGlvbiBEdChlLHQpe3JldHVybiB0PT09ImlubGluZSI/eCgiZGl2Iix7Y2xhc3M6Im1kLXRvb2x0aXAgbWQtdG9vbHRpcC0taW5saW5lIixpZDplLHJvbGU6InRvb2x0aXAifSx4KCJkaXYiLHtjbGFzczoibWQtdG9vbHRpcF9faW5uZXIgbWQtdHlwZXNldCJ9KSk6eCgiZGl2Iix7Y2xhc3M6Im1kLXRvb2x0aXAiLGlkOmUscm9sZToidG9vbHRpcCJ9LHgoImRpdiIse2NsYXNzOiJtZC10b29sdGlwX19pbm5lciBtZC10eXBlc2V0In0pKX1mdW5jdGlvbiB3ciguLi5lKXtyZXR1cm4geCgiZGl2Iix7Y2xhc3M6Im1kLXRvb2x0aXAyIixyb2xlOiJkaWFsb2cifSx4KCJkaXYiLHtjbGFzczoibWQtdG9vbHRpcDJfX2lubmVyIG1kLXR5cGVzZXQifSxlKSl9ZnVuY3Rpb24gQ24oLi4uZSl7cmV0dXJuIHgoImRpdiIse2NsYXNzOiJtZC10b29sdGlwMiIscm9sZToidG9vbHRpcCJ9LHgoImRpdiIse2NsYXNzOiJtZC10b29sdGlwMl9faW5uZXIgbWQtdHlwZXNldCJ9LGUpKX1mdW5jdGlvbiBrbihlLHQpe2lmKHQ9dD9gJHt0fV9hbm5vdGF0aW9uXyR7ZX1gOnZvaWQgMCx0KXtsZXQgcj10P2AjJHt0fWA6dm9pZCAwO3JldHVybiB4KCJhc2lkZSIse2NsYXNzOiJtZC1hbm5vdGF0aW9uIix0YWJJbmRleDowfSxEdCh0KSx4KCJhIix7aHJlZjpyLGNsYXNzOiJtZC1hbm5vdGF0aW9uX19pbmRleCIsdGFiSW5kZXg6LTF9LHgoInNwYW4iLHsiZGF0YS1tZC1hbm5vdGF0aW9uLWlkIjplfSkpKX1lbHNlIHJldHVybiB4KCJhc2lkZSIse2NsYXNzOiJtZC1hbm5vdGF0aW9uIix0YWJJbmRleDowfSxEdCh0KSx4KCJzcGFuIix7Y2xhc3M6Im1kLWFubm90YXRpb25fX2luZGV4Iix0YWJJbmRleDotMX0seCgic3BhbiIseyJkYXRhLW1kLWFubm90YXRpb24taWQiOmV9KSkpfWZ1bmN0aW9uIEhuKGUpe3JldHVybiB4KCJidXR0b24iLHtjbGFzczoibWQtY29kZV9fYnV0dG9uIix0aXRsZTpNZSgiY2xpcGJvYXJkLmNvcHkiKSwiZGF0YS1jbGlwYm9hcmQtdGFyZ2V0IjpgIyR7ZX0gPiBjb2RlYCwiZGF0YS1tZC10eXBlIjoiY29weSJ9KX1mdW5jdGlvbiAkbigpe3JldHVybiB4KCJidXR0b24iLHtjbGFzczoibWQtY29kZV9fYnV0dG9uIix0aXRsZToiVG9nZ2xlIGxpbmUgc2VsZWN0aW9uIiwiZGF0YS1tZC10eXBlIjoic2VsZWN0In0pfWZ1bmN0aW9uIFBuKCl7cmV0dXJuIHgoIm5hdiIse2NsYXNzOiJtZC1jb2RlX19uYXYifSl9dmFyIEluPSR0KHJvKCkpO2Z1bmN0aW9uIG9vKGUsdCl7bGV0IHI9dCYyLG89dCYxLG49T2JqZWN0LmtleXMoZS50ZXJtcykuZmlsdGVyKGM9PiFlLnRlcm1zW2NdKS5yZWR1Y2UoKGMscCk9PlsuLi5jLHgoImRlbCIsbnVsbCwoMCxJbi5kZWZhdWx0KShwKSksIiAiXSxbXSkuc2xpY2UoMCwtMSksaT1UZSgpLHM9bmV3IFVSTChlLmxvY2F0aW9uLGkuYmFzZSk7Vigic2VhcmNoLmhpZ2hsaWdodCIpJiZzLnNlYXJjaFBhcmFtcy5zZXQoImgiLE9iamVjdC5lbnRyaWVzKGUudGVybXMpLmZpbHRlcigoWyxjXSk9PmMpLnJlZHVjZSgoYyxbcF0pPT5gJHtjfSAke3B9YC50cmltKCksIiIpKTtsZXR7dGFnczphfT1UZSgpO3JldHVybiB4KCJhIix7aHJlZjpgJHtzfWAsY2xhc3M6Im1kLXNlYXJjaC1yZXN1bHRfX2xpbmsiLHRhYkluZGV4Oi0xfSx4KCJhcnRpY2xlIix7Y2xhc3M6Im1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGUgbWQtdHlwZXNldCIsImRhdGEtbWQtc2NvcmUiOmUuc2NvcmUudG9GaXhlZCgyKX0scj4wJiZ4KCJkaXYiLHtjbGFzczoibWQtc2VhcmNoLXJlc3VsdF9faWNvbiBtZC1pY29uIn0pLHI+MCYmeCgiaDEiLG51bGwsZS50aXRsZSkscjw9MCYmeCgiaDIiLG51bGwsZS50aXRsZSksbz4wJiZlLnRleHQubGVuZ3RoPjAmJmUudGV4dCxlLnRhZ3MmJngoIm5hdiIse2NsYXNzOiJtZC10YWdzIn0sZS50YWdzLm1hcChjPT57bGV0IHA9YT9jIGluIGE/YG1kLXRhZy1pY29uIG1kLXRhZy0tJHthW2NdfWA6Im1kLXRhZy1pY29uIjoiIjtyZXR1cm4geCgic3BhbiIse2NsYXNzOmBtZC10YWcgJHtwfWB9LGMpfSkpLG8+MCYmbi5sZW5ndGg+MCYmeCgicCIse2NsYXNzOiJtZC1zZWFyY2gtcmVzdWx0X190ZXJtcyJ9LE1lKCJzZWFyY2gucmVzdWx0LnRlcm0ubWlzc2luZyIpLCI6ICIsLi4ubikpKX1mdW5jdGlvbiBGbihlKXtsZXQgdD1lWzBdLnNjb3JlLHI9Wy4uLmVdLG89VGUoKSxuPXIuZmluZEluZGV4KGw9PiFgJHtuZXcgVVJMKGwubG9jYXRpb24sby5iYXNlKX1gLmluY2x1ZGVzKCIjIikpLFtpXT1yLnNwbGljZShuLDEpLHM9ci5maW5kSW5kZXgobD0+bC5zY29yZTx0KTtzPT09LTEmJihzPXIubGVuZ3RoKTtsZXQgYT1yLnNsaWNlKDAscyksYz1yLnNsaWNlKHMpLHA9W29vKGksMnwrKCFuJiZzPT09MCkpLC4uLmEubWFwKGw9Pm9vKGwsMSkpLC4uLmMubGVuZ3RoP1t4KCJkZXRhaWxzIix7Y2xhc3M6Im1kLXNlYXJjaC1yZXN1bHRfX21vcmUifSx4KCJzdW1tYXJ5Iix7dGFiSW5kZXg6LTF9LHgoImRpdiIsbnVsbCxjLmxlbmd0aD4wJiZjLmxlbmd0aD09PTE/TWUoInNlYXJjaC5yZXN1bHQubW9yZS5vbmUiKTpNZSgic2VhcmNoLnJlc3VsdC5tb3JlLm90aGVyIixjLmxlbmd0aCkpKSwuLi5jLm1hcChsPT5vbyhsLDEpKSldOltdXTtyZXR1cm4geCgibGkiLHtjbGFzczoibWQtc2VhcmNoLXJlc3VsdF9faXRlbSJ9LHApfWZ1bmN0aW9uIGpuKGUpe3JldHVybiB4KCJ1bCIse2NsYXNzOiJtZC1zb3VyY2VfX2ZhY3RzIn0sT2JqZWN0LmVudHJpZXMoZSkubWFwKChbdCxyXSk9PngoImxpIix7Y2xhc3M6YG1kLXNvdXJjZV9fZmFjdCBtZC1zb3VyY2VfX2ZhY3QtLSR7dH1gfSx0eXBlb2Ygcj09Im51bWJlciI/YnIocik6cikpKX1mdW5jdGlvbiBubyhlKXtsZXQgdD1gdGFiYmVkLWNvbnRyb2wgdGFiYmVkLWNvbnRyb2wtLSR7ZX1gO3JldHVybiB4KCJkaXYiLHtjbGFzczp0LGhpZGRlbjohMH0seCgiYnV0dG9uIix7Y2xhc3M6InRhYmJlZC1idXR0b24iLHRhYkluZGV4Oi0xLCJhcmlhLWhpZGRlbiI6InRydWUifSkpfWZ1bmN0aW9uIFVuKGUpe3JldHVybiB4KCJkaXYiLHtjbGFzczoibWQtdHlwZXNldF9fc2Nyb2xsd3JhcCJ9LHgoImRpdiIse2NsYXNzOiJtZC10eXBlc2V0X190YWJsZSJ9LGUpKX1mdW5jdGlvbiBRYShlKXt2YXIgbztsZXQgdD1UZSgpLHI9bmV3IFVSTChgLi4vJHtlLnZlcnNpb259L2AsdC5iYXNlKTtyZXR1cm4geCgibGkiLHtjbGFzczoibWQtdmVyc2lvbl9faXRlbSJ9LHgoImEiLHtocmVmOmAke3J9YCxjbGFzczoibWQtdmVyc2lvbl9fbGluayJ9LGUudGl0bGUsKChvPXQudmVyc2lvbik9PW51bGw/dm9pZCAwOm8uYWxpYXMpJiZlLmFsaWFzZXMubGVuZ3RoPjAmJngoInNwYW4iLHtjbGFzczoibWQtdmVyc2lvbl9fYWxpYXMifSxlLmFsaWFzZXNbMF0pKSl9ZnVuY3Rpb24gV24oZSx0KXt2YXIgbztsZXQgcj1UZSgpO3JldHVybiBlPWUuZmlsdGVyKG49Pnt2YXIgaTtyZXR1cm4hKChpPW4ucHJvcGVydGllcykhPW51bGwmJmkuaGlkZGVuKX0pLHgoImRpdiIse2NsYXNzOiJtZC12ZXJzaW9uIn0seCgiYnV0dG9uIix7Y2xhc3M6Im1kLXZlcnNpb25fX2N1cnJlbnQiLCJhcmlhLWxhYmVsIjpNZSgic2VsZWN0LnZlcnNpb24iKX0sdC50aXRsZSwoKG89ci52ZXJzaW9uKT09bnVsbD92b2lkIDA6by5hbGlhcykmJnQuYWxpYXNlcy5sZW5ndGg+MCYmeCgic3BhbiIse2NsYXNzOiJtZC12ZXJzaW9uX19hbGlhcyJ9LHQuYWxpYXNlc1swXSkpLHgoInVsIix7Y2xhc3M6Im1kLXZlcnNpb25fX2xpc3QifSxlLm1hcChRYSkpKX12YXIgWWE9MDtmdW5jdGlvbiBCYShlLHQ9MjUwKXtsZXQgcj16KFtZZShlKSxpdChlLHQpXSkucGlwZShtKChbbixpXSk9Pm58fGkpLFkoKSksbz1IKCgpPT5wbihlKSkucGlwZShKKEdlKSxndCgxKSxQZShyKSxtKCgpPT5sbihlKSkpO3JldHVybiByLnBpcGUoUmUobj0+biksYigoKT0+eihbcixvXSkpLG0oKFtuLGldKT0+KHthY3RpdmU6bixvZmZzZXQ6aX0pKSxsZSgpKX1mdW5jdGlvbiBWdChlLHQscj0yNTApe2xldHtjb250ZW50JDpvLHZpZXdwb3J0JDpufT10LGk9YF9fdG9vbHRpcDJfJHtZYSsrfWA7cmV0dXJuIEgoKCk9PntsZXQgcz1uZXcgVCxhPW5ldyBqcighMSk7cy5waXBlKG9lKCksYWUoITEpKS5zdWJzY3JpYmUoYSk7bGV0IGM9YS5waXBlKGp0KGw9PkhlKCshbCoyNTAsRHIpKSxZKCksYihsPT5sP286eSksTyhsPT5sLmlkPWkpLGxlKCkpO3ooW3MucGlwZShtKCh7YWN0aXZlOmx9KT0+bCkpLGMucGlwZShiKGw9Pml0KGwsMjUwKSksUSghMSkpXSkucGlwZShtKGw9Pmwuc29tZShmPT5mKSkpLnN1YnNjcmliZShhKTtsZXQgcD1hLnBpcGUoZyhsPT5sKSx0ZShjLG4pLG0oKFtsLGYse3NpemU6dX1dKT0+e2xldCBkPWUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksdj1kLndpZHRoLzI7aWYoZi5yb2xlPT09InRvb2x0aXAiKXJldHVybnt4OnYseTo4K2QuaGVpZ2h0fTtpZihkLnk+PXUuaGVpZ2h0LzIpe2xldHtoZWlnaHQ6U309ZGUoZik7cmV0dXJue3g6dix5Oi0xNi1TfX1lbHNlIHJldHVybnt4OnYseToxNitkLmhlaWdodH19KSk7cmV0dXJuIHooW2MscyxwXSkuc3Vic2NyaWJlKChbbCx7b2Zmc2V0OmZ9LHVdKT0+e2wuc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC1ob3N0LXgiLGAke2YueH1weGApLGwuc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC1ob3N0LXkiLGAke2YueX1weGApLGwuc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC14IixgJHt1Lnh9cHhgKSxsLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAteSIsYCR7dS55fXB4YCksbC5jbGFzc0xpc3QudG9nZ2xlKCJtZC10b29sdGlwMi0tdG9wIix1Lnk8MCksbC5jbGFzc0xpc3QudG9nZ2xlKCJtZC10b29sdGlwMi0tYm90dG9tIix1Lnk+PTApfSksYS5waXBlKGcobD0+bCksdGUoYywobCxmKT0+ZiksZyhsPT5sLnJvbGU9PT0idG9vbHRpcCIpKS5zdWJzY3JpYmUobD0+e2xldCBmPWRlKGooIjpzY29wZSA+ICoiLGwpKTtsLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAtd2lkdGgiLGAke2Yud2lkdGh9cHhgKSxsLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAtdGFpbCIsIjBweCIpfSksYS5waXBlKFkoKSx4ZSh5ZSksdGUoYykpLnN1YnNjcmliZSgoW2wsZl0pPT57Zi5jbGFzc0xpc3QudG9nZ2xlKCJtZC10b29sdGlwMi0tYWN0aXZlIixsKX0pLHooW2EucGlwZShnKGw9PmwpKSxjXSkuc3Vic2NyaWJlKChbbCxmXSk9PntmLnJvbGU9PT0iZGlhbG9nIj8oZS5zZXRBdHRyaWJ1dGUoImFyaWEtY29udHJvbHMiLGkpLGUuc2V0QXR0cmlidXRlKCJhcmlhLWhhc3BvcHVwIiwiZGlhbG9nIikpOmUuc2V0QXR0cmlidXRlKCJhcmlhLWRlc2NyaWJlZGJ5IixpKX0pLGEucGlwZShnKGw9PiFsKSkuc3Vic2NyaWJlKCgpPT57ZS5yZW1vdmVBdHRyaWJ1dGUoImFyaWEtY29udHJvbHMiKSxlLnJlbW92ZUF0dHJpYnV0ZSgiYXJpYS1kZXNjcmliZWRieSIpLGUucmVtb3ZlQXR0cmlidXRlKCJhcmlhLWhhc3BvcHVwIil9KSxCYShlLHIpLnBpcGUoTyhsPT5zLm5leHQobCkpLEEoKCk9PnMuY29tcGxldGUoKSksbShsPT5QKHtyZWY6ZX0sbCkpKX0pfWZ1bmN0aW9uIFhlKGUse3ZpZXdwb3J0JDp0fSxyPWRvY3VtZW50LmJvZHkpe3JldHVybiBWdChlLHtjb250ZW50JDpuZXcgRihvPT57bGV0IG49ZS50aXRsZSxpPUNuKG4pO3JldHVybiBvLm5leHQoaSksZS5yZW1vdmVBdHRyaWJ1dGUoInRpdGxlIiksci5hcHBlbmQoaSksKCk9PntpLnJlbW92ZSgpLGUuc2V0QXR0cmlidXRlKCJ0aXRsZSIsbil9fSksdmlld3BvcnQkOnR9LDApfWZ1bmN0aW9uIEdhKGUsdCl7bGV0IHI9SCgoKT0+eihbbW4oZSksR2UodCldKSkucGlwZShtKChbe3g6byx5Om59LGldKT0+e2xldHt3aWR0aDpzLGhlaWdodDphfT1kZShlKTtyZXR1cm57eDpvLWkueCtzLzIseTpuLWkueSthLzJ9fSkpO3JldHVybiBZZShlKS5waXBlKGIobz0+ci5waXBlKG0obj0+KHthY3RpdmU6byxvZmZzZXQ6bn0pKSxFZSgrIW98fDEvMCkpKSl9ZnVuY3Rpb24gRG4oZSx0LHt0YXJnZXQkOnJ9KXtsZXRbbyxuXT1BcnJheS5mcm9tKGUuY2hpbGRyZW4pO3JldHVybiBIKCgpPT57bGV0IGk9bmV3IFQscz1pLnBpcGUob2UoKSxhZSghMCkpO3JldHVybiBpLnN1YnNjcmliZSh7bmV4dCh7b2Zmc2V0OmF9KXtlLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAteCIsYCR7YS54fXB4YCksZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXkiLGAke2EueX1weGApfSxjb21wbGV0ZSgpe2Uuc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtdG9vbHRpcC14IiksZS5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXkiKX19KSxtdChlKS5waXBlKFcocykpLnN1YnNjcmliZShhPT57ZS50b2dnbGVBdHRyaWJ1dGUoImRhdGEtbWQtdmlzaWJsZSIsYSl9KSxMKGkucGlwZShnKCh7YWN0aXZlOmF9KT0+YSkpLGkucGlwZShBZSgyNTApLGcoKHthY3RpdmU6YX0pPT4hYSkpKS5zdWJzY3JpYmUoe25leHQoe2FjdGl2ZTphfSl7YT9lLnByZXBlbmQobyk6by5yZW1vdmUoKX0sY29tcGxldGUoKXtlLnByZXBlbmQobyl9fSksaS5waXBlKCRlKDE2LHllKSkuc3Vic2NyaWJlKCh7YWN0aXZlOmF9KT0+e28uY2xhc3NMaXN0LnRvZ2dsZSgibWQtdG9vbHRpcC0tYWN0aXZlIixhKX0pLGkucGlwZShndCgxMjUseWUpLGcoKCk9PiEhZS5vZmZzZXRQYXJlbnQpLG0oKCk9PmUub2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxtKCh7eDphfSk9PmEpKS5zdWJzY3JpYmUoe25leHQoYSl7YT9lLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAtMCIsYCR7LWF9cHhgKTplLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLXRvb2x0aXAtMCIpfSxjb21wbGV0ZSgpe2Uuc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtdG9vbHRpcC0wIil9fSksaChuLCJjbGljayIpLnBpcGUoVyhzKSxnKGE9PiEoYS5tZXRhS2V5fHxhLmN0cmxLZXkpKSkuc3Vic2NyaWJlKGE9PnthLnN0b3BQcm9wYWdhdGlvbigpLGEucHJldmVudERlZmF1bHQoKX0pLGgobiwibW91c2Vkb3duIikucGlwZShXKHMpLHRlKGkpKS5zdWJzY3JpYmUoKFthLHthY3RpdmU6Y31dKT0+e3ZhciBwO2lmKGEuYnV0dG9uIT09MHx8YS5tZXRhS2V5fHxhLmN0cmxLZXkpYS5wcmV2ZW50RGVmYXVsdCgpO2Vsc2UgaWYoYyl7YS5wcmV2ZW50RGVmYXVsdCgpO2xldCBsPWUucGFyZW50RWxlbWVudC5jbG9zZXN0KCIubWQtYW5ub3RhdGlvbiIpO2wgaW5zdGFuY2VvZiBIVE1MRWxlbWVudD9sLmZvY3VzKCk6KHA9TmUoKSk9PW51bGx8fHAuYmx1cigpfX0pLHIucGlwZShXKHMpLGcoYT0+YT09PW8pLG50KDEyNSkpLnN1YnNjcmliZSgoKT0+ZS5mb2N1cygpKSxHYShlLHQpLnBpcGUoTyhhPT5pLm5leHQoYSkpLEEoKCk9PmkuY29tcGxldGUoKSksbShhPT5QKHtyZWY6ZX0sYSkpKX0pfWZ1bmN0aW9uIEphKGUpe2xldCB0PVRlKCk7aWYoZS50YWdOYW1lIT09IkNPREUiKXJldHVybltlXTtsZXQgcj1bIi5jIiwiLmMxIiwiLmNtIl07aWYodC5hbm5vdGF0ZSYmdHlwZW9mIHQuYW5ub3RhdGU9PSJvYmplY3QiKXtsZXQgbz1lLmNsb3Nlc3QoIltjbGFzc3w9bGFuZ3VhZ2VdIik7aWYobylmb3IobGV0IG4gb2YgQXJyYXkuZnJvbShvLmNsYXNzTGlzdCkpe2lmKCFuLnN0YXJ0c1dpdGgoImxhbmd1YWdlLSIpKWNvbnRpbnVlO2xldFssaV09bi5zcGxpdCgiLSIpO2kgaW4gdC5hbm5vdGF0ZSYmci5wdXNoKC4uLnQuYW5ub3RhdGVbaV0pfX1yZXR1cm4gTShyLmpvaW4oIiwgIiksZSl9ZnVuY3Rpb24gWGEoZSl7bGV0IHQ9W107Zm9yKGxldCByIG9mIEphKGUpKXtsZXQgbz1bXSxuPWRvY3VtZW50LmNyZWF0ZU5vZGVJdGVyYXRvcihyLE5vZGVGaWx0ZXIuU0hPV19URVhUKTtmb3IobGV0IGk9bi5uZXh0Tm9kZSgpO2k7aT1uLm5leHROb2RlKCkpby5wdXNoKGkpO2ZvcihsZXQgaSBvZiBvKXtsZXQgcztmb3IoO3M9LyhcKFxkK1wpKSghKT8vLmV4ZWMoaS50ZXh0Q29udGVudCk7KXtsZXRbLGEsY109cztpZih0eXBlb2YgYz09InVuZGVmaW5lZCIpe2xldCBwPWkuc3BsaXRUZXh0KHMuaW5kZXgpO2k9cC5zcGxpdFRleHQoYS5sZW5ndGgpLHQucHVzaChwKX1lbHNle2kudGV4dENvbnRlbnQ9YSx0LnB1c2goaSk7YnJlYWt9fX19cmV0dXJuIHR9ZnVuY3Rpb24gVm4oZSx0KXt0LmFwcGVuZCguLi5BcnJheS5mcm9tKGUuY2hpbGROb2RlcykpfWZ1bmN0aW9uIFRyKGUsdCx7dGFyZ2V0JDpyLHByaW50JDpvfSl7bGV0IG49dC5jbG9zZXN0KCJbaWRdIiksaT1uPT1udWxsP3ZvaWQgMDpuLmlkLHM9bmV3IE1hcDtmb3IobGV0IGEgb2YgWGEodCkpe2xldFssY109YS50ZXh0Q29udGVudC5tYXRjaCgvXCgoXGQrKVwpLyk7dWUoYDpzY29wZSA+IGxpOm50aC1jaGlsZCgke2N9KWAsZSkmJihzLnNldChjLGtuKGMsaSkpLGEucmVwbGFjZVdpdGgocy5nZXQoYykpKX1yZXR1cm4gcy5zaXplPT09MD95OkgoKCk9PntsZXQgYT1uZXcgVCxjPWEucGlwZShvZSgpLGFlKCEwKSkscD1bXTtmb3IobGV0W2wsZl1vZiBzKXAucHVzaChbaigiLm1kLXR5cGVzZXQiLGYpLGooYDpzY29wZSA+IGxpOm50aC1jaGlsZCgke2x9KWAsZSldKTtyZXR1cm4gby5waXBlKFcoYykpLnN1YnNjcmliZShsPT57ZS5oaWRkZW49IWwsZS5jbGFzc0xpc3QudG9nZ2xlKCJtZC1hbm5vdGF0aW9uLWxpc3QiLGwpO2ZvcihsZXRbZix1XW9mIHApbD9WbihmLHUpOlZuKHUsZil9KSxMKC4uLlsuLi5zXS5tYXAoKFssbF0pPT5EbihsLHQse3RhcmdldCQ6cn0pKSkucGlwZShBKCgpPT5hLmNvbXBsZXRlKCkpLGxlKCkpfSl9ZnVuY3Rpb24gTm4oZSl7aWYoZS5uZXh0RWxlbWVudFNpYmxpbmcpe2xldCB0PWUubmV4dEVsZW1lbnRTaWJsaW5nO2lmKHQudGFnTmFtZT09PSJPTCIpcmV0dXJuIHQ7aWYodC50YWdOYW1lPT09IlAiJiYhdC5jaGlsZHJlbi5sZW5ndGgpcmV0dXJuIE5uKHQpfX1mdW5jdGlvbiB6bihlLHQpe3JldHVybiBIKCgpPT57bGV0IHI9Tm4oZSk7cmV0dXJuIHR5cGVvZiByIT0idW5kZWZpbmVkIj9UcihyLGUsdCk6eX0pfXZhciBLbj0kdChhbygpKTt2YXIgWmE9MCxxbj1MKGgod2luZG93LCJrZXlkb3duIikucGlwZShtKCgpPT4hMCkpLEwoaCh3aW5kb3csImtleXVwIiksaCh3aW5kb3csImNvbnRleHRtZW51IikpLnBpcGUobSgoKT0+ITEpKSkucGlwZShRKCExKSxaKDEpKTtmdW5jdGlvbiBRbihlKXtpZihlLm5leHRFbGVtZW50U2libGluZyl7bGV0IHQ9ZS5uZXh0RWxlbWVudFNpYmxpbmc7aWYodC50YWdOYW1lPT09Ik9MIilyZXR1cm4gdDtpZih0LnRhZ05hbWU9PT0iUCImJiF0LmNoaWxkcmVuLmxlbmd0aClyZXR1cm4gUW4odCl9fWZ1bmN0aW9uIGVzKGUpe3JldHVybiBMZShlKS5waXBlKG0oKHt3aWR0aDp0fSk9Pih7c2Nyb2xsYWJsZTpBdChlKS53aWR0aD50fSkpLG5lKCJzY3JvbGxhYmxlIikpfWZ1bmN0aW9uIFluKGUsdCl7bGV0e21hdGNoZXM6cn09bWF0Y2hNZWRpYSgiKGhvdmVyKSIpLG89SCgoKT0+e2xldCBuPW5ldyBULGk9bi5waXBlKFlyKDEpKTtuLnN1YnNjcmliZSgoe3Njcm9sbGFibGU6ZH0pPT57ZCYmcj9lLnNldEF0dHJpYnV0ZSgidGFiaW5kZXgiLCIwIik6ZS5yZW1vdmVBdHRyaWJ1dGUoInRhYmluZGV4Iil9KTtsZXQgcz1bXSxhPWUuY2xvc2VzdCgicHJlIiksYz1hLmNsb3Nlc3QoIltpZF0iKSxwPWM/Yy5pZDpaYSsrO2EuaWQ9YF9fY29kZV8ke3B9YDtsZXQgbD1bXSxmPWUuY2xvc2VzdCgiLmhpZ2hsaWdodCIpO2lmKGYgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCl7bGV0IGQ9UW4oZik7aWYodHlwZW9mIGQhPSJ1bmRlZmluZWQiJiYoZi5jbGFzc0xpc3QuY29udGFpbnMoImFubm90YXRlIil8fFYoImNvbnRlbnQuY29kZS5hbm5vdGF0ZSIpKSl7bGV0IHY9VHIoZCxlLHQpO2wucHVzaChMZShmKS5waXBlKFcoaSksbSgoe3dpZHRoOlMsaGVpZ2h0Olh9KT0+UyYmWCksWSgpLGIoUz0+Uz92OnkpKSl9fWxldCB1PU0oIjpzY29wZSA+IHNwYW5baWRdIixlKTtpZih1Lmxlbmd0aCYmKGUuY2xhc3NMaXN0LmFkZCgibWQtY29kZV9fY29udGVudCIpLGUuY2xvc2VzdCgiLnNlbGVjdCIpfHxWKCJjb250ZW50LmNvZGUuc2VsZWN0IikmJiFlLmNsb3Nlc3QoIi5uby1zZWxlY3QiKSkpe2xldCBkPSt1WzBdLmlkLnNwbGl0KCItIikucG9wKCksdj0kbigpO3MucHVzaCh2KSxWKCJjb250ZW50LnRvb2x0aXBzIikmJmwucHVzaChYZSh2LHt2aWV3cG9ydCR9KSk7bGV0IFM9aCh2LCJjbGljayIpLnBpcGUoVXQoUj0+IVIsITEpLE8oKCk9PnYuYmx1cigpKSxsZSgpKTtTLnN1YnNjcmliZShSPT57di5jbGFzc0xpc3QudG9nZ2xlKCJtZC1jb2RlX19idXR0b24tLWFjdGl2ZSIsUil9KTtsZXQgWD1mZSh1KS5waXBlKEooUj0+aXQoUikucGlwZShtKHNlPT5bUixzZV0pKSkpO1MucGlwZShiKFI9PlI/WDp5KSkuc3Vic2NyaWJlKChbUixzZV0pPT57bGV0IGNlPXVlKCIuaGxsLnNlbGVjdCIsUik7aWYoY2UmJiFzZSljZS5yZXBsYWNlV2l0aCguLi5BcnJheS5mcm9tKGNlLmNoaWxkTm9kZXMpKTtlbHNlIGlmKCFjZSYmc2Upe2xldCBoZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7aGUuY2xhc3NOYW1lPSJobGwgc2VsZWN0IixoZS5hcHBlbmQoLi4uQXJyYXkuZnJvbShSLmNoaWxkTm9kZXMpLnNsaWNlKDEpKSxSLmFwcGVuZChoZSl9fSk7bGV0IHJlPWZlKHUpLnBpcGUoSihSPT5oKFIsIm1vdXNlZG93biIpLnBpcGUoTyhzZT0+c2UucHJldmVudERlZmF1bHQoKSksbSgoKT0+UikpKSksZWU9Uy5waXBlKGIoUj0+Uj9yZTp5KSx0ZShxbiksbSgoW1Isc2VdKT0+e3ZhciBoZTtsZXQgY2U9dS5pbmRleE9mKFIpK2Q7aWYoc2U9PT0hMSlyZXR1cm5bY2UsY2VdO3tsZXQgU2U9TSgiLmhsbCIsZSkubWFwKFVlPT51LmluZGV4T2YoVWUucGFyZW50RWxlbWVudCkrZCk7cmV0dXJuKGhlPXdpbmRvdy5nZXRTZWxlY3Rpb24oKSk9PW51bGx8fGhlLnJlbW92ZUFsbFJhbmdlcygpLFtNYXRoLm1pbihjZSwuLi5TZSksTWF0aC5tYXgoY2UsLi4uU2UpXX19KSksaz1acih5KS5waXBlKGcoUj0+Ui5zdGFydHNXaXRoKGBfX2NvZGVsaW5lbm8tJHtwfS1gKSkpO2suc3Vic2NyaWJlKFI9PntsZXRbLCxzZV09Ui5zcGxpdCgiLSIpLGNlPXNlLnNwbGl0KCI6IikubWFwKFNlPT4rU2UtZCsxKTtjZS5sZW5ndGg9PT0xJiZjZS5wdXNoKGNlWzBdKTtmb3IobGV0IFNlIG9mIE0oIi5obGw6bm90KC5zZWxlY3QpIixlKSlTZS5yZXBsYWNlV2l0aCguLi5BcnJheS5mcm9tKFNlLmNoaWxkTm9kZXMpKTtsZXQgaGU9dS5zbGljZShjZVswXS0xLGNlWzFdKTtmb3IobGV0IFNlIG9mIGhlKXtsZXQgVWU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpO1VlLmNsYXNzTmFtZT0iaGxsIixVZS5hcHBlbmQoLi4uQXJyYXkuZnJvbShTZS5jaGlsZE5vZGVzKS5zbGljZSgxKSksU2UuYXBwZW5kKFVlKX19KSxrLnBpcGUoRWUoMSkseGUocGUpKS5zdWJzY3JpYmUoUj0+e2lmKFIuaW5jbHVkZXMoIjoiKSl7bGV0IHNlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFIuc3BsaXQoIjoiKVswXSk7c2UmJnNldFRpbWVvdXQoKCk9PntsZXQgY2U9c2UsaGU9LTY0O2Zvcig7Y2UhPT1kb2N1bWVudC5ib2R5OyloZSs9Y2Uub2Zmc2V0VG9wLGNlPWNlLm9mZnNldFBhcmVudDt3aW5kb3cuc2Nyb2xsVG8oe3RvcDpoZX0pfSwxKX19KTtsZXQgamU9ZmUoTSgnYVtocmVmXj0iI19fY29kZWxpbmVubyJdJyxmKSkucGlwZShKKFI9PmgoUiwiY2xpY2siKS5waXBlKE8oc2U9PnNlLnByZXZlbnREZWZhdWx0KCkpLG0oKCk9PlIpKSkpLnBpcGUoVyhpKSx0ZShxbiksbSgoW1Isc2VdKT0+e2xldCBoZT0raihgW2lkPSIke1IuaGFzaC5zbGljZSgxKX0iXWApLnBhcmVudEVsZW1lbnQuaWQuc3BsaXQoIi0iKS5wb3AoKTtpZihzZT09PSExKXJldHVybltoZSxoZV07e2xldCBTZT1NKCIuaGxsIixlKS5tYXAoVWU9PitVZS5wYXJlbnRFbGVtZW50LmlkLnNwbGl0KCItIikucG9wKCkpO3JldHVybltNYXRoLm1pbihoZSwuLi5TZSksTWF0aC5tYXgoaGUsLi4uU2UpXX19KSk7TChlZSxqZSkuc3Vic2NyaWJlKFI9PntsZXQgc2U9YCNfX2NvZGVsaW5lbm8tJHtwfS1gO1JbMF09PT1SWzFdP3NlKz1SWzBdOnNlKz1gJHtSWzBdfToke1JbMV19YCxoaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwiIixzZSksd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEhhc2hDaGFuZ2VFdmVudCgiaGFzaGNoYW5nZSIse25ld1VSTDp3aW5kb3cubG9jYXRpb24ub3JpZ2luK3dpbmRvdy5sb2NhdGlvbi5wYXRobmFtZStzZSxvbGRVUkw6d2luZG93LmxvY2F0aW9uLmhyZWZ9KSl9KX1pZihLbi5kZWZhdWx0LmlzU3VwcG9ydGVkKCkmJihlLmNsb3Nlc3QoIi5jb3B5Iil8fFYoImNvbnRlbnQuY29kZS5jb3B5IikmJiFlLmNsb3Nlc3QoIi5uby1jb3B5IikpKXtsZXQgZD1IbihhLmlkKTtzLnB1c2goZCksVigiY29udGVudC50b29sdGlwcyIpJiZsLnB1c2goWGUoZCx7dmlld3BvcnQkfSkpfWlmKHMubGVuZ3RoKXtsZXQgZD1QbigpO2QuYXBwZW5kKC4uLnMpLGEuaW5zZXJ0QmVmb3JlKGQsZSl9cmV0dXJuIGVzKGUpLnBpcGUoTyhkPT5uLm5leHQoZCkpLEEoKCk9Pm4uY29tcGxldGUoKSksbShkPT5QKHtyZWY6ZX0sZCkpLFZlKEwoLi4ubCkucGlwZShXKGkpKSkpfSk7cmV0dXJuIFYoImNvbnRlbnQubGF6eSIpP210KGUpLnBpcGUoZyhuPT5uKSxFZSgxKSxiKCgpPT5vKSk6b31mdW5jdGlvbiB0cyhlLHt0YXJnZXQkOnQscHJpbnQkOnJ9KXtsZXQgbz0hMDtyZXR1cm4gTCh0LnBpcGUobShuPT5uLmNsb3Nlc3QoImRldGFpbHM6bm90KFtvcGVuXSkiKSksZyhuPT5lPT09biksbSgoKT0+KHthY3Rpb246Im9wZW4iLHJldmVhbDohMH0pKSksci5waXBlKGcobj0+bnx8IW8pLE8oKCk9Pm89ZS5vcGVuKSxtKG49Pih7YWN0aW9uOm4/Im9wZW4iOiJjbG9zZSJ9KSkpKX1mdW5jdGlvbiBCbihlLHQpe3JldHVybiBIKCgpPT57bGV0IHI9bmV3IFQ7cmV0dXJuIHIuc3Vic2NyaWJlKCh7YWN0aW9uOm8scmV2ZWFsOm59KT0+e2UudG9nZ2xlQXR0cmlidXRlKCJvcGVuIixvPT09Im9wZW4iKSxuJiZlLnNjcm9sbEludG9WaWV3KCl9KSx0cyhlLHQpLnBpcGUoTyhvPT5yLm5leHQobykpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT5QKHtyZWY6ZX0sbykpKX0pfXZhciBHbj0wO2Z1bmN0aW9uIHJzKGUpe2xldCB0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImgzIik7dC5pbm5lckhUTUw9ZS5pbm5lckhUTUw7bGV0IHI9W3RdLG89ZS5uZXh0RWxlbWVudFNpYmxpbmc7Zm9yKDtvJiYhKG8gaW5zdGFuY2VvZiBIVE1MSGVhZGluZ0VsZW1lbnQpOylyLnB1c2gobyksbz1vLm5leHRFbGVtZW50U2libGluZztyZXR1cm4gcn1mdW5jdGlvbiBvcyhlLHQpe2ZvcihsZXQgciBvZiBNKCJbaHJlZl0sIFtzcmNdIixlKSlmb3IobGV0IG8gb2ZbImhyZWYiLCJzcmMiXSl7bGV0IG49ci5nZXRBdHRyaWJ1dGUobyk7aWYobiYmIS9eKD86W2Etel0rOik/XC9cLy9pLnRlc3Qobikpe3Jbb109bmV3IFVSTChyLmdldEF0dHJpYnV0ZShvKSx0KS50b1N0cmluZygpO2JyZWFrfX1mb3IobGV0IHIgb2YgTSgiW25hbWVePV9fXSwgW2Zvcl0iLGUpKWZvcihsZXQgbyBvZlsiaWQiLCJmb3IiLCJuYW1lIl0pe2xldCBuPXIuZ2V0QXR0cmlidXRlKG8pO24mJnIuc2V0QXR0cmlidXRlKG8sYCR7bn0kcHJldmlld18ke0dufWApfXJldHVybiBHbisrLCQoZSl9ZnVuY3Rpb24gSm4oZSx0KXtsZXR7c2l0ZW1hcCQ6cn09dDtpZighKGUgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCkpcmV0dXJuIHk7aWYoIShWKCJuYXZpZ2F0aW9uLmluc3RhbnQucHJldmlldyIpfHxlLmhhc0F0dHJpYnV0ZSgiZGF0YS1wcmV2aWV3IikpKXJldHVybiB5O2UucmVtb3ZlQXR0cmlidXRlKCJ0aXRsZSIpO2xldCBvPXooW1llKGUpLGl0KGUpXSkucGlwZShtKChbaSxzXSk9Pml8fHMpLFkoKSxnKGk9PmkpKTtyZXR1cm4gcnQoW3Isb10pLnBpcGUoYigoW2ldKT0+e2xldCBzPW5ldyBVUkwoZS5ocmVmKTtyZXR1cm4gcy5zZWFyY2g9cy5oYXNoPSIiLGkuaGFzKGAke3N9YCk/JChzKTp5fSksYihpPT54cihpKS5waXBlKGIocz0+b3MocyxpKSkpKSxiKGk9PntsZXQgcz1lLmhhc2g/YGFydGljbGUgW2lkPSIke2UuaGFzaC5zbGljZSgxKX0iXWA6ImFydGljbGUgaDEiLGE9dWUocyxpKTtyZXR1cm4gdHlwZW9mIGE9PSJ1bmRlZmluZWQiP3k6JChycyhhKSl9KSkucGlwZShiKGk9PntsZXQgcz1uZXcgRihhPT57bGV0IGM9d3IoLi4uaSk7cmV0dXJuIGEubmV4dChjKSxkb2N1bWVudC5ib2R5LmFwcGVuZChjKSwoKT0+Yy5yZW1vdmUoKX0pO3JldHVybiBWdChlLFAoe2NvbnRlbnQkOnN9LHQpKX0pKX12YXIgWG49Ii5ub2RlIGNpcmNsZSwubm9kZSBlbGxpcHNlLC5ub2RlIHBhdGgsLm5vZGUgcG9seWdvbiwubm9kZSByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX1tYXJrZXJ7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpIWltcG9ydGFudH0uZWRnZUxhYmVsIC5sYWJlbCByZWN0e2ZpbGw6IzAwMDB9LmZsb3djaGFydFRpdGxlVGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpfS5sYWJlbHtjb2xvcjp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX0ubGFiZWwgZm9yZWlnbk9iamVjdHtsaW5lLWhlaWdodDpub3JtYWw7b3ZlcmZsb3c6dmlzaWJsZX0ubGFiZWwgZGl2IC5lZGdlTGFiZWx7Y29sb3I6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1mZy1jb2xvcil9LmVkZ2VMYWJlbCwuZWRnZUxhYmVsIHAsLmxhYmVsIGRpdiAuZWRnZUxhYmVse2JhY2tncm91bmQtY29sb3I6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1iZy1jb2xvcil9LmVkZ2VMYWJlbCwuZWRnZUxhYmVsIHB7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKTtjb2xvcjp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpfS5lZGdlUGF0aCAucGF0aCwuZmxvd2NoYXJ0LWxpbmt7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9LmVkZ2VQYXRoIC5hcnJvd2hlYWRQYXRoe2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKTtzdHJva2U6bm9uZX0uY2x1c3RlciByZWN0e2ZpbGw6dmFyKC0tbWQtZGVmYXVsdC1mZy1jb2xvci0tbGlnaHRlc3QpO3N0cm9rZTp2YXIoLS1tZC1kZWZhdWx0LWZnLWNvbG9yLS1saWdodGVyKX0uY2x1c3RlciBzcGFue2NvbG9yOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpO2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpfWcgI2Zsb3djaGFydC1jaXJjbGVFbmQsZyAjZmxvd2NoYXJ0LWNpcmNsZVN0YXJ0LGcgI2Zsb3djaGFydC1jcm9zc0VuZCxnICNmbG93Y2hhcnQtY3Jvc3NTdGFydCxnICNmbG93Y2hhcnQtcG9pbnRFbmQsZyAjZmxvd2NoYXJ0LXBvaW50U3RhcnR7c3Ryb2tlOm5vbmV9LmNsYXNzRGlhZ3JhbVRpdGxlVGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpfWcuY2xhc3NHcm91cCBsaW5lLGcuY2xhc3NHcm91cCByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX1nLmNsYXNzR3JvdXAgdGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpO2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpfS5jbGFzc0xhYmVsIC5ib3h7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKTtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtYmctY29sb3IpO29wYWNpdHk6MX0uY2xhc3NMYWJlbCAubGFiZWx7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX0ubm9kZSAuZGl2aWRlcntzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX0ucmVsYXRpb257c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9LmNhcmRpbmFsaXR5e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1mZy1jb2xvcik7Zm9udC1mYW1pbHk6dmFyKC0tbWQtbWVybWFpZC1mb250LWZhbWlseSl9LmNhcmRpbmFsaXR5IHRleHR7ZmlsbDppbmhlcml0IWltcG9ydGFudH1kZWZzIG1hcmtlci5tYXJrZXIuY29tcG9zaXRpb24uY2xhc3MgcGF0aCxkZWZzIG1hcmtlci5tYXJrZXIuZGVwZW5kZW5jeS5jbGFzcyBwYXRoLGRlZnMgbWFya2VyLm1hcmtlci5leHRlbnNpb24uY2xhc3MgcGF0aHtmaWxsOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcikhaW1wb3J0YW50O3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpIWltcG9ydGFudH1kZWZzIG1hcmtlci5tYXJrZXIuYWdncmVnYXRpb24uY2xhc3MgcGF0aHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtYmctY29sb3IpIWltcG9ydGFudDtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKSFpbXBvcnRhbnR9LnN0YXRlZGlhZ3JhbVRpdGxlVGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpfWcuc3RhdGVHcm91cCByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX1nLnN0YXRlR3JvdXAgLnN0YXRlLXRpdGxle2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1mZy1jb2xvcikhaW1wb3J0YW50O2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpfWcuc3RhdGVHcm91cCAuY29tcG9zaXR7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKX0ubm9kZUxhYmVsLC5ub2RlTGFiZWwgcHtjb2xvcjp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX1hIC5ub2RlTGFiZWx7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZX0ubm9kZSBjaXJjbGUuc3RhdGUtZW5kLC5ub2RlIGNpcmNsZS5zdGF0ZS1zdGFydCwuc3RhcnQtc3RhdGV7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpO3N0cm9rZTpub25lfS5lbmQtc3RhdGUtaW5uZXIsLmVuZC1zdGF0ZS1vdXRlcntmaWxsOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9LmVuZC1zdGF0ZS1pbm5lciwubm9kZSBjaXJjbGUuc3RhdGUtZW5ke3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKX0udHJhbnNpdGlvbntzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKX1baWRePXN0YXRlLWZvcmtdIHJlY3QsW2lkXj1zdGF0ZS1qb2luXSByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKSFpbXBvcnRhbnQ7c3Ryb2tlOm5vbmUhaW1wb3J0YW50fS5zdGF0ZWRpYWdyYW0tY2x1c3Rlci5zdGF0ZWRpYWdyYW0tY2x1c3RlciAuaW5uZXJ7ZmlsbDp2YXIoLS1tZC1kZWZhdWx0LWJnLWNvbG9yKX0uc3RhdGVkaWFncmFtLWNsdXN0ZXIgcmVjdHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbm9kZS1iZy1jb2xvcik7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtbm9kZS1mZy1jb2xvcil9LnN0YXRlZGlhZ3JhbS1zdGF0ZSByZWN0LmRpdmlkZXJ7ZmlsbDp2YXIoLS1tZC1kZWZhdWx0LWZnLWNvbG9yLS1saWdodGVzdCk7c3Ryb2tlOnZhcigtLW1kLWRlZmF1bHQtZmctY29sb3ItLWxpZ2h0ZXIpfWRlZnMgI3N0YXRlZGlhZ3JhbS1iYXJiRW5ke3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpfVtpZF49ZW50aXR5XSBwYXRoLFtpZF49ZW50aXR5XSByZWN0e2ZpbGw6dmFyKC0tbWQtZGVmYXVsdC1iZy1jb2xvcil9LnJlbGF0aW9uc2hpcExpbmV7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9ZGVmcyAubWFya2VyLm9uZU9yTW9yZS5lciAqLGRlZnMgLm1hcmtlci5vbmx5T25lLmVyICosZGVmcyAubWFya2VyLnplcm9Pck1vcmUuZXIgKixkZWZzIC5tYXJrZXIuemVyb09yT25lLmVyICp7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcikhaW1wb3J0YW50fXRleHQ6bm90KFtjbGFzc10pOmxhc3QtY2hpbGR7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKX0uYWN0b3J7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9yLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1hY3Rvci1ib3JkZXItY29sb3IpfXRleHQuYWN0b3I+dHNwYW57ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9yLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX1saW5le3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9yLWxpbmUtY29sb3IpfS5hY3Rvci1tYW4gY2lyY2xlLC5hY3Rvci1tYW4gbGluZXtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtYWN0b3JtYW4tYmctY29sb3IpO3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9ybWFuLWxpbmUtY29sb3IpfS5tZXNzYWdlTGluZTAsLm1lc3NhZ2VMaW5lMXtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1tZXNzYWdlLWxpbmUtY29sb3IpfS5ub3Rle2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1ub3RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1ub3RlLWJvcmRlci1jb2xvcil9Lmxvb3BUZXh0LC5sb29wVGV4dD50c3BhbiwubWVzc2FnZVRleHQsLm5vdGVUZXh0PnRzcGFue3N0cm9rZTpub25lO2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpIWltcG9ydGFudH0ubWVzc2FnZVRleHR7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLW1lc3NhZ2UtZmctY29sb3IpfS5sb29wVGV4dCwubG9vcFRleHQ+dHNwYW57ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWxvb3AtZmctY29sb3IpfS5ub3RlVGV4dD50c3BhbntmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2Utbm90ZS1mZy1jb2xvcil9I2Fycm93aGVhZCBwYXRoe2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1tZXNzYWdlLWxpbmUtY29sb3IpO3N0cm9rZTpub25lfS5sb29wTGluZXtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtbG9vcC1iZy1jb2xvcik7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtbG9vcC1ib3JkZXItY29sb3IpfS5sYWJlbEJveHtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtbGFiZWwtYmctY29sb3IpO3N0cm9rZTpub25lfS5sYWJlbFRleHQsLmxhYmVsVGV4dD5zcGFue2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1sYWJlbC1mZy1jb2xvcik7Zm9udC1mYW1pbHk6dmFyKC0tbWQtbWVybWFpZC1mb250LWZhbWlseSl9LnNlcXVlbmNlTnVtYmVye2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1udW1iZXItZmctY29sb3IpfXJlY3QucmVjdHtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtYm94LWJnLWNvbG9yKTtzdHJva2U6bm9uZX1yZWN0LnJlY3QrdGV4dC50ZXh0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1ib3gtZmctY29sb3IpfWRlZnMgI3NlcXVlbmNlbnVtYmVye2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1udW1iZXItYmctY29sb3IpIWltcG9ydGFudH0iO3ZhciBzbyxpcz0wO2Z1bmN0aW9uIGFzKCl7cmV0dXJuIHR5cGVvZiBtZXJtYWlkPT0idW5kZWZpbmVkInx8bWVybWFpZCBpbnN0YW5jZW9mIEVsZW1lbnQ/X3QoImh0dHBzOi8vdW5wa2cuY29tL21lcm1haWRAMTEvZGlzdC9tZXJtYWlkLm1pbi5qcyIpOiQodm9pZCAwKX1mdW5jdGlvbiBabihlKXtyZXR1cm4gZS5jbGFzc0xpc3QucmVtb3ZlKCJtZXJtYWlkIiksc298fChzbz1hcygpLnBpcGUoTygoKT0+bWVybWFpZC5pbml0aWFsaXplKHtzdGFydE9uTG9hZDohMSx0aGVtZUNTUzpYbixzZXF1ZW5jZTp7YWN0b3JGb250U2l6ZToiMTZweCIsbWVzc2FnZUZvbnRTaXplOiIxNnB4Iixub3RlRm9udFNpemU6IjE2cHgifX0pKSxtKCgpPT57fSksWigxKSkpLHNvLnN1YnNjcmliZSgoKT0+Z28obnVsbCxudWxsLGZ1bmN0aW9uKigpe2UuY2xhc3NMaXN0LmFkZCgibWVybWFpZCIpO2xldCB0PWBfX21lcm1haWRfJHtpcysrfWAscj14KCJkaXYiLHtjbGFzczoibWVybWFpZCJ9KSxvPWUudGV4dENvbnRlbnQse3N2ZzpuLGZuOml9PXlpZWxkIG1lcm1haWQucmVuZGVyKHQsbykscz1yLmF0dGFjaFNoYWRvdyh7bW9kZToiY2xvc2VkIn0pO3MuaW5uZXJIVE1MPW4sZS5yZXBsYWNlV2l0aChyKSxpPT1udWxsfHxpKHMpfSkpLHNvLnBpcGUobSgoKT0+KHtyZWY6ZX0pKSl9dmFyIGVpPXgoInRhYmxlIik7ZnVuY3Rpb24gdGkoZSl7cmV0dXJuIGUucmVwbGFjZVdpdGgoZWkpLGVpLnJlcGxhY2VXaXRoKFVuKGUpKSwkKHtyZWY6ZX0pfWZ1bmN0aW9uIHNzKGUpe2xldCB0PWUuZmluZChyPT5yLmNoZWNrZWQpfHxlWzBdO3JldHVybiBMKC4uLmUubWFwKHI9PmgociwiY2hhbmdlIikucGlwZShtKCgpPT5qKGBsYWJlbFtmb3I9IiR7ci5pZH0iXWApKSkpKS5waXBlKFEoaihgbGFiZWxbZm9yPSIke3QuaWR9Il1gKSksbShyPT4oe2FjdGl2ZTpyfSkpKX1mdW5jdGlvbiByaShlLHt2aWV3cG9ydCQ6dCx0YXJnZXQkOnJ9KXtsZXQgbz1qKCIudGFiYmVkLWxhYmVscyIsZSksbj1NKCI6c2NvcGUgPiBpbnB1dCIsZSksaT1ubygicHJldiIpO2UuYXBwZW5kKGkpO2xldCBzPW5vKCJuZXh0Iik7cmV0dXJuIGUuYXBwZW5kKHMpLEgoKCk9PntsZXQgYT1uZXcgVCxjPWEucGlwZShvZSgpLGFlKCEwKSk7eihbYSxMZShlKSxtdChlKV0pLnBpcGUoVyhjKSwkZSgxLHllKSkuc3Vic2NyaWJlKHtuZXh0KFt7YWN0aXZlOnB9LGxdKXtsZXQgZj1CZShwKSx7d2lkdGg6dX09ZGUocCk7ZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC1pbmRpY2F0b3IteCIsYCR7Zi54fXB4YCksZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC1pbmRpY2F0b3Itd2lkdGgiLGAke3V9cHhgKTtsZXQgZD1ncihvKTsoZi54PGQueHx8Zi54K3U+ZC54K2wud2lkdGgpJiZvLnNjcm9sbFRvKHtsZWZ0Ok1hdGgubWF4KDAsZi54LTE2KSxiZWhhdmlvcjoic21vb3RoIn0pfSxjb21wbGV0ZSgpe2Uuc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtaW5kaWNhdG9yLXgiKSxlLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLWluZGljYXRvci13aWR0aCIpfX0pLHooW0dlKG8pLExlKG8pXSkucGlwZShXKGMpKS5zdWJzY3JpYmUoKFtwLGxdKT0+e2xldCBmPUF0KG8pO2kuaGlkZGVuPXAueDwxNixzLmhpZGRlbj1wLng+Zi53aWR0aC1sLndpZHRoLTE2fSksTChoKGksImNsaWNrIikucGlwZShtKCgpPT4tMSkpLGgocywiY2xpY2siKS5waXBlKG0oKCk9PjEpKSkucGlwZShXKGMpKS5zdWJzY3JpYmUocD0+e2xldHt3aWR0aDpsfT1kZShvKTtvLnNjcm9sbEJ5KHtsZWZ0OmwqcCxiZWhhdmlvcjoic21vb3RoIn0pfSksci5waXBlKFcoYyksZyhwPT5uLmluY2x1ZGVzKHApKSkuc3Vic2NyaWJlKHA9PnAuY2xpY2soKSksby5jbGFzc0xpc3QuYWRkKCJ0YWJiZWQtbGFiZWxzLS1saW5rZWQiKTtmb3IobGV0IHAgb2Ygbil7bGV0IGw9aihgbGFiZWxbZm9yPSIke3AuaWR9Il1gKTtsLnJlcGxhY2VDaGlsZHJlbih4KCJhIix7aHJlZjpgIyR7bC5odG1sRm9yfWAsdGFiSW5kZXg6LTF9LC4uLkFycmF5LmZyb20obC5jaGlsZE5vZGVzKSkpLGgobC5maXJzdEVsZW1lbnRDaGlsZCwiY2xpY2siKS5waXBlKFcoYyksZyhmPT4hKGYubWV0YUtleXx8Zi5jdHJsS2V5KSksTyhmPT57Zi5wcmV2ZW50RGVmYXVsdCgpLGYuc3RvcFByb3BhZ2F0aW9uKCl9KSkuc3Vic2NyaWJlKCgpPT57aGlzdG9yeS5yZXBsYWNlU3RhdGUoe30sIiIsYCMke2wuaHRtbEZvcn1gKSxsLmNsaWNrKCl9KX1yZXR1cm4gVigiY29udGVudC50YWJzLmxpbmsiKSYmYS5waXBlKEllKDEpLHRlKHQpKS5zdWJzY3JpYmUoKFt7YWN0aXZlOnB9LHtvZmZzZXQ6bH1dKT0+e2xldCBmPXAuaW5uZXJUZXh0LnRyaW0oKTtpZihwLmhhc0F0dHJpYnV0ZSgiZGF0YS1tZC1zd2l0Y2hpbmciKSlwLnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1tZC1zd2l0Y2hpbmciKTtlbHNle2xldCB1PWUub2Zmc2V0VG9wLWwueTtmb3IobGV0IHYgb2YgTSgiW2RhdGEtdGFic10iKSlmb3IobGV0IFMgb2YgTSgiOnNjb3BlID4gaW5wdXQiLHYpKXtsZXQgWD1qKGBsYWJlbFtmb3I9IiR7Uy5pZH0iXWApO2lmKFghPT1wJiZYLmlubmVyVGV4dC50cmltKCk9PT1mKXtYLnNldEF0dHJpYnV0ZSgiZGF0YS1tZC1zd2l0Y2hpbmciLCIiKSxTLmNsaWNrKCk7YnJlYWt9fXdpbmRvdy5zY3JvbGxUbyh7dG9wOmUub2Zmc2V0VG9wLXV9KTtsZXQgZD1fX21kX2dldCgiX190YWJzIil8fFtdO19fbWRfc2V0KCJfX3RhYnMiLFsuLi5uZXcgU2V0KFtmLC4uLmRdKV0pfX0pLGEucGlwZShXKGMpKS5zdWJzY3JpYmUoKCk9Pntmb3IobGV0IHAgb2YgTSgiYXVkaW8sIHZpZGVvIixlKSlwLm9mZnNldFdpZHRoJiZwLmF1dG9wbGF5P3AucGxheSgpLmNhdGNoKCgpPT57fSk6cC5wYXVzZSgpfSksc3MobikucGlwZShPKHA9PmEubmV4dChwKSksQSgoKT0+YS5jb21wbGV0ZSgpKSxtKHA9PlAoe3JlZjplfSxwKSkpfSkucGlwZShldChwZSkpfWZ1bmN0aW9uIG9pKGUsdCl7bGV0e3ZpZXdwb3J0JDpyLHRhcmdldCQ6byxwcmludCQ6bn09dDtyZXR1cm4gTCguLi5NKCIuYW5ub3RhdGU6bm90KC5oaWdobGlnaHQpIixlKS5tYXAoaT0+em4oaSx7dGFyZ2V0JDpvLHByaW50JDpufSkpLC4uLk0oInByZTpub3QoLm1lcm1haWQpID4gY29kZSIsZSkubWFwKGk9PlluKGkse3RhcmdldCQ6byxwcmludCQ6bn0pKSwuLi5NKCJhIixlKS5tYXAoaT0+Sm4oaSx0KSksLi4uTSgicHJlLm1lcm1haWQiLGUpLm1hcChpPT5abihpKSksLi4uTSgidGFibGU6bm90KFtjbGFzc10pIixlKS5tYXAoaT0+dGkoaSkpLC4uLk0oImRldGFpbHMiLGUpLm1hcChpPT5CbihpLHt0YXJnZXQkOm8scHJpbnQkOm59KSksLi4uTSgiW2RhdGEtdGFic10iLGUpLm1hcChpPT5yaShpLHt2aWV3cG9ydCQ6cix0YXJnZXQkOm99KSksLi4uTSgiW3RpdGxlXTpub3QoW2RhdGEtcHJldmlld10pIixlKS5maWx0ZXIoKCk9PlYoImNvbnRlbnQudG9vbHRpcHMiKSkubWFwKGk9PlhlKGkse3ZpZXdwb3J0JDpyfSkpLC4uLk0oIi5mb290bm90ZS1yZWYiLGUpLmZpbHRlcigoKT0+VigiY29udGVudC5mb290bm90ZS50b29sdGlwcyIpKS5tYXAoaT0+VnQoaSx7Y29udGVudCQ6bmV3IEYocz0+e2xldCBhPW5ldyBVUkwoaS5ocmVmKS5oYXNoLnNsaWNlKDEpLGM9QXJyYXkuZnJvbShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5jbG9uZU5vZGUoITApLmNoaWxkcmVuKSxwPXdyKC4uLmMpO3JldHVybiBzLm5leHQocCksZG9jdW1lbnQuYm9keS5hcHBlbmQocCksKCk9PnAucmVtb3ZlKCl9KSx2aWV3cG9ydCQ6cn0pKSl9ZnVuY3Rpb24gY3MoZSx7YWxlcnQkOnR9KXtyZXR1cm4gdC5waXBlKGIocj0+TCgkKCEwKSwkKCExKS5waXBlKG50KDJlMykpKS5waXBlKG0obz0+KHttZXNzYWdlOnIsYWN0aXZlOm99KSkpKSl9ZnVuY3Rpb24gbmkoZSx0KXtsZXQgcj1qKCIubWQtdHlwZXNldCIsZSk7cmV0dXJuIEgoKCk9PntsZXQgbz1uZXcgVDtyZXR1cm4gby5zdWJzY3JpYmUoKHttZXNzYWdlOm4sYWN0aXZlOml9KT0+e2UuY2xhc3NMaXN0LnRvZ2dsZSgibWQtZGlhbG9nLS1hY3RpdmUiLGkpLHIudGV4dENvbnRlbnQ9bn0pLGNzKGUsdCkucGlwZShPKG49Pm8ubmV4dChuKSksQSgoKT0+by5jb21wbGV0ZSgpKSxtKG49PlAoe3JlZjplfSxuKSkpfSl9dmFyIHBzPTA7ZnVuY3Rpb24gbHMoZSx0KXtkb2N1bWVudC5ib2R5LmFwcGVuZChlKTtsZXR7d2lkdGg6cn09ZGUoZSk7ZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXdpZHRoIixgJHtyfXB4YCksZS5yZW1vdmUoKTtsZXQgbz12cih0KSxuPXR5cGVvZiBvIT0idW5kZWZpbmVkIj9HZShvKTokKHt4OjAseTowfSksaT1MKFllKHQpLGl0KHQpKS5waXBlKFkoKSk7cmV0dXJuIHooW2ksbl0pLnBpcGUobSgoW3MsYV0pPT57bGV0e3g6Yyx5OnB9PUJlKHQpLGw9ZGUodCksZj10LmNsb3Nlc3QoInRhYmxlIik7cmV0dXJuIGYmJnQucGFyZW50RWxlbWVudCYmKGMrPWYub2Zmc2V0TGVmdCt0LnBhcmVudEVsZW1lbnQub2Zmc2V0TGVmdCxwKz1mLm9mZnNldFRvcCt0LnBhcmVudEVsZW1lbnQub2Zmc2V0VG9wKSx7YWN0aXZlOnMsb2Zmc2V0Ont4OmMtYS54K2wud2lkdGgvMi1yLzIseTpwLWEueStsLmhlaWdodCs4fX19KSl9ZnVuY3Rpb24gaWkoZSl7bGV0IHQ9ZS50aXRsZTtpZighdC5sZW5ndGgpcmV0dXJuIHk7bGV0IHI9YF9fdG9vbHRpcF8ke3BzKyt9YCxvPUR0KHIsImlubGluZSIpLG49aigiLm1kLXR5cGVzZXQiLG8pO3JldHVybiBuLmlubmVySFRNTD10LEgoKCk9PntsZXQgaT1uZXcgVDtyZXR1cm4gaS5zdWJzY3JpYmUoe25leHQoe29mZnNldDpzfSl7by5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXgiLGAke3MueH1weGApLG8uc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC15IixgJHtzLnl9cHhgKX0sY29tcGxldGUoKXtvLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLXRvb2x0aXAteCIpLG8uc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtdG9vbHRpcC15Iil9fSksTChpLnBpcGUoZygoe2FjdGl2ZTpzfSk9PnMpKSxpLnBpcGUoQWUoMjUwKSxnKCh7YWN0aXZlOnN9KT0+IXMpKSkuc3Vic2NyaWJlKHtuZXh0KHthY3RpdmU6c30pe3M/KGUuaW5zZXJ0QWRqYWNlbnRFbGVtZW50KCJhZnRlcmVuZCIsbyksZS5zZXRBdHRyaWJ1dGUoImFyaWEtZGVzY3JpYmVkYnkiLHIpLGUucmVtb3ZlQXR0cmlidXRlKCJ0aXRsZSIpKTooby5yZW1vdmUoKSxlLnJlbW92ZUF0dHJpYnV0ZSgiYXJpYS1kZXNjcmliZWRieSIpLGUuc2V0QXR0cmlidXRlKCJ0aXRsZSIsdCkpfSxjb21wbGV0ZSgpe28ucmVtb3ZlKCksZS5yZW1vdmVBdHRyaWJ1dGUoImFyaWEtZGVzY3JpYmVkYnkiKSxlLnNldEF0dHJpYnV0ZSgidGl0bGUiLHQpfX0pLGkucGlwZSgkZSgxNix5ZSkpLnN1YnNjcmliZSgoe2FjdGl2ZTpzfSk9PntvLmNsYXNzTGlzdC50b2dnbGUoIm1kLXRvb2x0aXAtLWFjdGl2ZSIscyl9KSxpLnBpcGUoZ3QoMTI1LHllKSxnKCgpPT4hIWUub2Zmc2V0UGFyZW50KSxtKCgpPT5lLm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSksbSgoe3g6c30pPT5zKSkuc3Vic2NyaWJlKHtuZXh0KHMpe3M/by5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLTAiLGAkey1zfXB4YCk6by5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgiLS1tZC10b29sdGlwLTAiKX0sY29tcGxldGUoKXtvLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLXRvb2x0aXAtMCIpfX0pLGxzKG8sZSkucGlwZShPKHM9PmkubmV4dChzKSksQSgoKT0+aS5jb21wbGV0ZSgpKSxtKHM9PlAoe3JlZjplfSxzKSkpfSkucGlwZShldChwZSkpfWZ1bmN0aW9uIG1zKHt2aWV3cG9ydCQ6ZX0pe2lmKCFWKCJoZWFkZXIuYXV0b2hpZGUiKSlyZXR1cm4gJCghMSk7bGV0IHQ9ZS5waXBlKG0oKHtvZmZzZXQ6e3k6bn19KT0+biksb3QoMiwxKSxtKChbbixpXSk9PltuPGksaV0pLG5lKDApKSxyPXooW2UsdF0pLnBpcGUoZygoW3tvZmZzZXQ6bn0sWyxpXV0pPT5NYXRoLmFicyhpLW4ueSk+MTAwKSxtKChbLFtuXV0pPT5uKSxZKCkpLG89SmUoInNlYXJjaCIpO3JldHVybiB6KFtlLG9dKS5waXBlKG0oKFt7b2Zmc2V0Om59LGldKT0+bi55PjQwMCYmIWkpLFkoKSxiKG49Pm4/cjokKCExKSksUSghMSkpfWZ1bmN0aW9uIGFpKGUsdCl7cmV0dXJuIEgoKCk9PnooW0xlKGUpLG1zKHQpXSkpLnBpcGUobSgoW3toZWlnaHQ6cn0sb10pPT4oe2hlaWdodDpyLGhpZGRlbjpvfSkpLFkoKHIsbyk9PnIuaGVpZ2h0PT09by5oZWlnaHQmJnIuaGlkZGVuPT09by5oaWRkZW4pLFooMSkpfWZ1bmN0aW9uIHNpKGUse2hlYWRlciQ6dCxtYWluJDpyfSl7cmV0dXJuIEgoKCk9PntsZXQgbz1uZXcgVCxuPW8ucGlwZShvZSgpLGFlKCEwKSk7by5waXBlKG5lKCJhY3RpdmUiKSxQZSh0KSkuc3Vic2NyaWJlKChbe2FjdGl2ZTpzfSx7aGlkZGVuOmF9XSk9PntlLmNsYXNzTGlzdC50b2dnbGUoIm1kLWhlYWRlci0tc2hhZG93IixzJiYhYSksZS5oaWRkZW49YX0pO2xldCBpPWZlKE0oIlt0aXRsZV0iLGUpKS5waXBlKGcoKCk9PlYoImNvbnRlbnQudG9vbHRpcHMiKSksSihzPT5paShzKSkpO3JldHVybiByLnN1YnNjcmliZShvKSx0LnBpcGUoVyhuKSxtKHM9PlAoe3JlZjplfSxzKSksVmUoaS5waXBlKFcobikpKSl9KX1mdW5jdGlvbiBmcyhlLHt2aWV3cG9ydCQ6dCxoZWFkZXIkOnJ9KXtyZXR1cm4gRXIoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyfSkucGlwZShtKCh7b2Zmc2V0Ont5Om99fSk9PntsZXR7aGVpZ2h0Om59PWRlKGUpO3JldHVybnthY3RpdmU6bj4wJiZvPj1ufX0pLG5lKCJhY3RpdmUiKSl9ZnVuY3Rpb24gY2koZSx0KXtyZXR1cm4gSCgoKT0+e2xldCByPW5ldyBUO3Iuc3Vic2NyaWJlKHtuZXh0KHthY3RpdmU6bn0pe2UuY2xhc3NMaXN0LnRvZ2dsZSgibWQtaGVhZGVyX190aXRsZS0tYWN0aXZlIixuKX0sY29tcGxldGUoKXtlLmNsYXNzTGlzdC5yZW1vdmUoIm1kLWhlYWRlcl9fdGl0bGUtLWFjdGl2ZSIpfX0pO2xldCBvPXVlKCIubWQtY29udGVudCBoMSIpO3JldHVybiB0eXBlb2Ygbz09InVuZGVmaW5lZCI/eTpmcyhvLHQpLnBpcGUoTyhuPT5yLm5leHQobikpLEEoKCk9PnIuY29tcGxldGUoKSksbShuPT5QKHtyZWY6ZX0sbikpKX0pfWZ1bmN0aW9uIHBpKGUse3ZpZXdwb3J0JDp0LGhlYWRlciQ6cn0pe2xldCBvPXIucGlwZShtKCh7aGVpZ2h0Oml9KT0+aSksWSgpKSxuPW8ucGlwZShiKCgpPT5MZShlKS5waXBlKG0oKHtoZWlnaHQ6aX0pPT4oe3RvcDplLm9mZnNldFRvcCxib3R0b206ZS5vZmZzZXRUb3AraX0pKSxuZSgiYm90dG9tIikpKSk7cmV0dXJuIHooW28sbix0XSkucGlwZShtKChbaSx7dG9wOnMsYm90dG9tOmF9LHtvZmZzZXQ6e3k6Y30sc2l6ZTp7aGVpZ2h0OnB9fV0pPT4ocD1NYXRoLm1heCgwLHAtTWF0aC5tYXgoMCxzLWMsaSktTWF0aC5tYXgoMCxwK2MtYSkpLHtvZmZzZXQ6cy1pLGhlaWdodDpwLGFjdGl2ZTpzLWk8PWN9KSksWSgoaSxzKT0+aS5vZmZzZXQ9PT1zLm9mZnNldCYmaS5oZWlnaHQ9PT1zLmhlaWdodCYmaS5hY3RpdmU9PT1zLmFjdGl2ZSkpfWZ1bmN0aW9uIHVzKGUpe2xldCB0PV9fbWRfZ2V0KCJfX3BhbGV0dGUiKXx8e2luZGV4OmUuZmluZEluZGV4KG89Pm1hdGNoTWVkaWEoby5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3ItbWVkaWEiKSkubWF0Y2hlcyl9LHI9TWF0aC5tYXgoMCxNYXRoLm1pbih0LmluZGV4LGUubGVuZ3RoLTEpKTtyZXR1cm4gJCguLi5lKS5waXBlKEoobz0+aChvLCJjaGFuZ2UiKS5waXBlKG0oKCk9Pm8pKSksUShlW3JdKSxtKG89Pih7aW5kZXg6ZS5pbmRleE9mKG8pLGNvbG9yOnttZWRpYTpvLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb2xvci1tZWRpYSIpLHNjaGVtZTpvLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb2xvci1zY2hlbWUiKSxwcmltYXJ5Om8uZ2V0QXR0cmlidXRlKCJkYXRhLW1kLWNvbG9yLXByaW1hcnkiKSxhY2NlbnQ6by5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3ItYWNjZW50Iil9fSkpLFooMSkpfWZ1bmN0aW9uIGxpKGUpe2xldCB0PU0oImlucHV0IixlKSxyPXgoIm1ldGEiLHtuYW1lOiJ0aGVtZS1jb2xvciJ9KTtkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHIpO2xldCBvPXgoIm1ldGEiLHtuYW1lOiJjb2xvci1zY2hlbWUifSk7ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChvKTtsZXQgbj1XdCgiKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkiKTtyZXR1cm4gSCgoKT0+e2xldCBpPW5ldyBUO3JldHVybiBpLnN1YnNjcmliZShzPT57aWYoZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3Itc3dpdGNoaW5nIiwiIikscy5jb2xvci5tZWRpYT09PSIocHJlZmVycy1jb2xvci1zY2hlbWUpIil7bGV0IGE9bWF0Y2hNZWRpYSgiKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkiKSxjPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYS5tYXRjaGVzPyJbZGF0YS1tZC1jb2xvci1tZWRpYT0nKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCknXSI6IltkYXRhLW1kLWNvbG9yLW1lZGlhPScocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspJ10iKTtzLmNvbG9yLnNjaGVtZT1jLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb2xvci1zY2hlbWUiKSxzLmNvbG9yLnByaW1hcnk9Yy5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3ItcHJpbWFyeSIpLHMuY29sb3IuYWNjZW50PWMuZ2V0QXR0cmlidXRlKCJkYXRhLW1kLWNvbG9yLWFjY2VudCIpfWZvcihsZXRbYSxjXW9mIE9iamVjdC5lbnRyaWVzKHMuY29sb3IpKWRvY3VtZW50LmJvZHkuc2V0QXR0cmlidXRlKGBkYXRhLW1kLWNvbG9yLSR7YX1gLGMpO2ZvcihsZXQgYT0wO2E8dC5sZW5ndGg7YSsrKXtsZXQgYz10W2FdLm5leHRFbGVtZW50U2libGluZztjIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQmJihjLmhpZGRlbj1zLmluZGV4IT09YSl9X19tZF9zZXQoIl9fcGFsZXR0ZSIscyl9KSxoKGUsImtleWRvd24iKS5waXBlKGcocz0+cy5rZXk9PT0iRW50ZXIiKSx0ZShpLChzLGEpPT5hKSkuc3Vic2NyaWJlKCh7aW5kZXg6c30pPT57cz0ocysxKSV0Lmxlbmd0aCx0W3NdLmNsaWNrKCksdFtzXS5mb2N1cygpfSksaS5waXBlKG0oKCk9PntsZXQgcz1DZSgiaGVhZGVyIiksYT13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShzKTtyZXR1cm4gby5jb250ZW50PWEuY29sb3JTY2hlbWUsYS5iYWNrZ3JvdW5kQ29sb3IubWF0Y2goL1xkKy9nKS5tYXAoYz0+KCtjKS50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIiKX0pKS5zdWJzY3JpYmUocz0+ci5jb250ZW50PWAjJHtzfWApLGkucGlwZSh4ZShwZSkpLnN1YnNjcmliZSgoKT0+e2RvY3VtZW50LmJvZHkucmVtb3ZlQXR0cmlidXRlKCJkYXRhLW1kLWNvbG9yLXN3aXRjaGluZyIpfSksdXModCkucGlwZShXKG4ucGlwZShJZSgxKSkpLHZ0KCksTyhzPT5pLm5leHQocykpLEEoKCk9PmkuY29tcGxldGUoKSksbShzPT5QKHtyZWY6ZX0scykpKX0pfWZ1bmN0aW9uIG1pKGUse3Byb2dyZXNzJDp0fSl7cmV0dXJuIEgoKCk9PntsZXQgcj1uZXcgVDtyZXR1cm4gci5zdWJzY3JpYmUoKHt2YWx1ZTpvfSk9PntlLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXByb2dyZXNzLXZhbHVlIixgJHtvfWApfSksdC5waXBlKE8obz0+ci5uZXh0KHt2YWx1ZTpvfSkpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT4oe3JlZjplLHZhbHVlOm99KSkpfSl9ZnVuY3Rpb24gZmkoZSx0KXtyZXR1cm4gZS5wcm90b2NvbD10LnByb3RvY29sLGUuaG9zdG5hbWU9dC5ob3N0bmFtZSxlfWZ1bmN0aW9uIGRzKGUsdCl7bGV0IHI9bmV3IE1hcDtmb3IobGV0IG8gb2YgTSgidXJsIixlKSl7bGV0IG49aigibG9jIixvKSxpPVtmaShuZXcgVVJMKG4udGV4dENvbnRlbnQpLHQpXTtyLnNldChgJHtpWzBdfWAsaSk7Zm9yKGxldCBzIG9mIE0oIltyZWw9YWx0ZXJuYXRlXSIsbykpe2xldCBhPXMuZ2V0QXR0cmlidXRlKCJocmVmIik7YSE9bnVsbCYmaS5wdXNoKGZpKG5ldyBVUkwoYSksdCkpfX1yZXR1cm4gcn1mdW5jdGlvbiBrdChlKXtyZXR1cm4gRW4obmV3IFVSTCgic2l0ZW1hcC54bWwiLGUpKS5waXBlKG0odD0+ZHModCxuZXcgVVJMKGUpKSksdmUoKCk9PiQobmV3IE1hcCkpLGxlKCkpfWZ1bmN0aW9uIHVpKHtkb2N1bWVudCQ6ZX0pe2xldCB0PW5ldyBNYXA7ZS5waXBlKGIoKCk9Pk0oImxpbmtbcmVsPWFsdGVybmF0ZV0iKSksbShyPT5uZXcgVVJMKHIuaHJlZikpLGcocj0+IXQuaGFzKHIudG9TdHJpbmcoKSkpLEoocj0+a3QocikucGlwZShtKG89PltyLG9dKSx2ZSgoKT0+eSkpKSkuc3Vic2NyaWJlKChbcixvXSk9Pnt0LnNldChyLnRvU3RyaW5nKCkucmVwbGFjZSgvXC8kLywiIiksbyl9KSxoKGRvY3VtZW50LmJvZHksImNsaWNrIikucGlwZShnKHI9PiFyLm1ldGFLZXkmJiFyLmN0cmxLZXkpLGIocj0+e2lmKHIudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCl7bGV0IG89ci50YXJnZXQuY2xvc2VzdCgiYSIpO2lmKG8mJiFvLnRhcmdldCl7bGV0IG49Wy4uLnRdLmZpbmQoKFtmXSk9Pm8uaHJlZi5zdGFydHNXaXRoKGAke2Z9L2ApKTtpZih0eXBlb2Ygbj09InVuZGVmaW5lZCIpcmV0dXJuIHk7bGV0W2ksc109bixhPXdlKCk7aWYoYS5ocmVmLnN0YXJ0c1dpdGgoaSkpcmV0dXJuIHk7bGV0IGM9VGUoKSxwPWEuaHJlZi5yZXBsYWNlKGMuYmFzZSwiIik7cD1gJHtpfS8ke3B9YDtsZXQgbD1zLmhhcyhwLnNwbGl0KCIjIilbMF0pP25ldyBVUkwocCxjLmJhc2UpOm5ldyBVUkwoaSk7cmV0dXJuIHIucHJldmVudERlZmF1bHQoKSwkKGwpfX1yZXR1cm4geX0pKS5zdWJzY3JpYmUocj0+c3QociwhMCkpfXZhciBjbz0kdChhbygpKTtmdW5jdGlvbiBocyhlKXtlLnNldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb3B5aW5nIiwiIik7bGV0IHQ9ZS5jbG9zZXN0KCJbZGF0YS1jb3B5XSIpLHI9dD90LmdldEF0dHJpYnV0ZSgiZGF0YS1jb3B5Iik6ZS5pbm5lclRleHQ7cmV0dXJuIGUucmVtb3ZlQXR0cmlidXRlKCJkYXRhLW1kLWNvcHlpbmciKSxyLnRyaW1FbmQoKX1mdW5jdGlvbiBkaSh7YWxlcnQkOmV9KXtjby5kZWZhdWx0LmlzU3VwcG9ydGVkKCkmJm5ldyBGKHQ9PntuZXcgY28uZGVmYXVsdCgiW2RhdGEtY2xpcGJvYXJkLXRhcmdldF0sIFtkYXRhLWNsaXBib2FyZC10ZXh0XSIse3RleHQ6cj0+ci5nZXRBdHRyaWJ1dGUoImRhdGEtY2xpcGJvYXJkLXRleHQiKXx8aHMoaihyLmdldEF0dHJpYnV0ZSgiZGF0YS1jbGlwYm9hcmQtdGFyZ2V0IikpKX0pLm9uKCJzdWNjZXNzIixyPT50Lm5leHQocikpfSkucGlwZShPKHQ9Pnt0LnRyaWdnZXIuZm9jdXMoKX0pLG0oKCk9Pk1lKCJjbGlwYm9hcmQuY29waWVkIikpKS5zdWJzY3JpYmUoZSl9ZnVuY3Rpb24gaGkoZSx0KXtpZighKGUudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCkpcmV0dXJuIHk7bGV0IHI9ZS50YXJnZXQuY2xvc2VzdCgiYSIpO2lmKHI9PT1udWxsKXJldHVybiB5O2lmKHIudGFyZ2V0fHxlLm1ldGFLZXl8fGUuY3RybEtleSlyZXR1cm4geTtsZXQgbz1uZXcgVVJMKHIuaHJlZik7cmV0dXJuIG8uc2VhcmNoPW8uaGFzaD0iIix0LmhhcyhgJHtvfWApPyhlLnByZXZlbnREZWZhdWx0KCksJChyKSk6eX1mdW5jdGlvbiBiaShlKXtsZXQgdD1uZXcgTWFwO2ZvcihsZXQgciBvZiBNKCI6c2NvcGUgPiAqIixlLmhlYWQpKXQuc2V0KHIub3V0ZXJIVE1MLHIpO3JldHVybiB0fWZ1bmN0aW9uIHZpKGUpe2ZvcihsZXQgdCBvZiBNKCJbaHJlZl0sIFtzcmNdIixlKSlmb3IobGV0IHIgb2ZbImhyZWYiLCJzcmMiXSl7bGV0IG89dC5nZXRBdHRyaWJ1dGUocik7aWYobyYmIS9eKD86W2Etel0rOik/XC9cLy9pLnRlc3Qobykpe3Rbcl09dFtyXTticmVha319cmV0dXJuICQoZSl9ZnVuY3Rpb24gYnMoZSl7Zm9yKGxldCBvIG9mWyJbZGF0YS1tZC1jb21wb25lbnQ9YW5ub3VuY2VdIiwiW2RhdGEtbWQtY29tcG9uZW50PWNvbnRhaW5lcl0iLCJbZGF0YS1tZC1jb21wb25lbnQ9aGVhZGVyLXRvcGljXSIsIltkYXRhLW1kLWNvbXBvbmVudD1vdXRkYXRlZF0iLCJbZGF0YS1tZC1jb21wb25lbnQ9bG9nb10iLCJbZGF0YS1tZC1jb21wb25lbnQ9c2tpcF0iLC4uLlYoIm5hdmlnYXRpb24udGFicy5zdGlja3kiKT9bIltkYXRhLW1kLWNvbXBvbmVudD10YWJzXSJdOltdXSl7bGV0IG49dWUobyksaT11ZShvLGUpO3R5cGVvZiBuIT0idW5kZWZpbmVkIiYmdHlwZW9mIGkhPSJ1bmRlZmluZWQiJiZuLnJlcGxhY2VXaXRoKGkpfWxldCB0PWJpKGRvY3VtZW50KTtmb3IobGV0W28sbl1vZiBiaShlKSl0LmhhcyhvKT90LmRlbGV0ZShvKTpkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG4pO2ZvcihsZXQgbyBvZiB0LnZhbHVlcygpKXtsZXQgbj1vLmdldEF0dHJpYnV0ZSgibmFtZSIpO24hPT0idGhlbWUtY29sb3IiJiZuIT09ImNvbG9yLXNjaGVtZSImJm8ucmVtb3ZlKCl9bGV0IHI9Q2UoImNvbnRhaW5lciIpO3JldHVybiBLZShNKCJzY3JpcHQiLHIpKS5waXBlKGIobz0+e2xldCBuPWUuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7aWYoby5zcmMpe2ZvcihsZXQgaSBvZiBvLmdldEF0dHJpYnV0ZU5hbWVzKCkpbi5zZXRBdHRyaWJ1dGUoaSxvLmdldEF0dHJpYnV0ZShpKSk7cmV0dXJuIG8ucmVwbGFjZVdpdGgobiksbmV3IEYoaT0+e24ub25sb2FkPSgpPT5pLmNvbXBsZXRlKCl9KX1lbHNlIHJldHVybiBuLnRleHRDb250ZW50PW8udGV4dENvbnRlbnQsby5yZXBsYWNlV2l0aChuKSx5fSksb2UoKSxhZShkb2N1bWVudCkpfWZ1bmN0aW9uIGdpKHtzaXRlbWFwJDplLGxvY2F0aW9uJDp0LHZpZXdwb3J0JDpyLHByb2dyZXNzJDpvfSl7aWYobG9jYXRpb24ucHJvdG9jb2w9PT0iZmlsZToiKXJldHVybiB5OyQoZG9jdW1lbnQpLnN1YnNjcmliZSh2aSk7bGV0IG49aChkb2N1bWVudC5ib2R5LCJjbGljayIpLnBpcGUoUGUoZSksYigoW2EsY10pPT5oaShhLGMpKSxtKCh7aHJlZjphfSk9Pm5ldyBVUkwoYSkpLGxlKCkpLGk9aCh3aW5kb3csInBvcHN0YXRlIikucGlwZShtKHdlKSxsZSgpKTtuLnBpcGUodGUocikpLnN1YnNjcmliZSgoW2Ese29mZnNldDpjfV0pPT57aGlzdG9yeS5yZXBsYWNlU3RhdGUoYywiIiksaGlzdG9yeS5wdXNoU3RhdGUobnVsbCwiIixhKX0pLEwobixpKS5zdWJzY3JpYmUodCk7bGV0IHM9dC5waXBlKG5lKCJwYXRobmFtZSIpLGIoYT0+eHIoYSx7cHJvZ3Jlc3MkOm99KS5waXBlKHZlKCgpPT4oc3QoYSwhMCkseSkpKSksYih2aSksYihicyksbGUoKSk7cmV0dXJuIEwocy5waXBlKHRlKHQsKGEsYyk9PmMpKSxzLnBpcGUoYigoKT0+dCksbmUoImhhc2giKSksdC5waXBlKFkoKGEsYyk9PmEucGF0aG5hbWU9PT1jLnBhdGhuYW1lJiZhLmhhc2g9PT1jLmhhc2gpLGIoKCk9Pm4pLE8oKCk9Pmhpc3RvcnkuYmFjaygpKSkpLnN1YnNjcmliZShhPT57dmFyIGMscDtoaXN0b3J5LnN0YXRlIT09bnVsbHx8IWEuaGFzaD93aW5kb3cuc2Nyb2xsVG8oMCwocD0oYz1oaXN0b3J5LnN0YXRlKT09bnVsbD92b2lkIDA6Yy55KSE9bnVsbD9wOjApOihoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uPSJhdXRvIixnbihhLmhhc2gpLGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb249Im1hbnVhbCIpfSksdC5zdWJzY3JpYmUoKCk9PntoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uPSJtYW51YWwifSksaCh3aW5kb3csImJlZm9yZXVubG9hZCIpLnN1YnNjcmliZSgoKT0+e2hpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb249ImF1dG8ifSksci5waXBlKG5lKCJvZmZzZXQiKSxBZSgxMDApKS5zdWJzY3JpYmUoKHtvZmZzZXQ6YX0pPT57aGlzdG9yeS5yZXBsYWNlU3RhdGUoYSwiIil9KSxWKCJuYXZpZ2F0aW9uLmluc3RhbnQucHJlZmV0Y2giKSYmTChoKGRvY3VtZW50LmJvZHksIm1vdXNlbW92ZSIpLGgoZG9jdW1lbnQuYm9keSwiZm9jdXNpbiIpKS5waXBlKFBlKGUpLGIoKFthLGNdKT0+aGkoYSxjKSksQWUoMjUpLFFyKCh7aHJlZjphfSk9PmEpLGhyKGE9PntsZXQgYz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJsaW5rIik7cmV0dXJuIGMucmVsPSJwcmVmZXRjaCIsYy5ocmVmPWEudG9TdHJpbmcoKSxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGMpLGgoYywibG9hZCIpLnBpcGUobSgoKT0+YyksRWUoMSkpfSkpLnN1YnNjcmliZShhPT5hLnJlbW92ZSgpKSxzfXZhciB5aT0kdChybygpKTtmdW5jdGlvbiB4aShlKXtsZXQgdD1lLnNlcGFyYXRvci5zcGxpdCgifCIpLm1hcChuPT5uLnJlcGxhY2UoLyhcKFw/WyE9PF1bXildK1wpKS9nLCIiKS5sZW5ndGg9PT0wPyJcdUZGRkQiOm4pLmpvaW4oInwiKSxyPW5ldyBSZWdFeHAodCwiaW1nIiksbz0obixpLHMpPT5gJHtpfTxtYXJrIGRhdGEtbWQtaGlnaGxpZ2h0PiR7c308L21hcms+YDtyZXR1cm4gbj0+e249bi5yZXBsYWNlKC9bXHMqK1wtOn5eXSsvZywiICIpLnJlcGxhY2UoLyYvZywiJmFtcDsiKS50cmltKCk7bGV0IGk9bmV3IFJlZ0V4cChgKF58JHtlLnNlcGFyYXRvcn18KSgke24ucmVwbGFjZSgvW3xcXHt9KClbXF1eJCsqPy4tXS9nLCJcXCQmIikucmVwbGFjZShyLCJ8Iil9KWAsImltZyIpO3JldHVybiBzPT4oMCx5aS5kZWZhdWx0KShzKS5yZXBsYWNlKGksbykucmVwbGFjZSgvPFwvbWFyaz4oXHMrKTxtYXJrW14+XSo+L2ltZywiJDEiKX19ZnVuY3Rpb24genQoZSl7cmV0dXJuIGUudHlwZT09PTF9ZnVuY3Rpb24gU3IoZSl7cmV0dXJuIGUudHlwZT09PTN9ZnVuY3Rpb24gRWkoZSx0KXtsZXQgcj1NbihlKTtyZXR1cm4gTCgkKGxvY2F0aW9uLnByb3RvY29sIT09ImZpbGU6IiksSmUoInNlYXJjaCIpKS5waXBlKFJlKG89Pm8pLGIoKCk9PnQpKS5zdWJzY3JpYmUoKHtjb25maWc6byxkb2NzOm59KT0+ci5uZXh0KHt0eXBlOjAsZGF0YTp7Y29uZmlnOm8sZG9jczpuLG9wdGlvbnM6e3N1Z2dlc3Q6Vigic2VhcmNoLnN1Z2dlc3QiKX19fSkpLHJ9ZnVuY3Rpb24gd2koZSl7dmFyIGw7bGV0e3NlbGVjdGVkVmVyc2lvblNpdGVtYXA6dCxzZWxlY3RlZFZlcnNpb25CYXNlVVJMOnIsY3VycmVudExvY2F0aW9uOm8sY3VycmVudEJhc2VVUkw6bn09ZSxpPShsPXBvKG4pKT09bnVsbD92b2lkIDA6bC5wYXRobmFtZTtpZihpPT09dm9pZCAwKXJldHVybjtsZXQgcz15cyhvLnBhdGhuYW1lLGkpO2lmKHM9PT12b2lkIDApcmV0dXJuO2xldCBhPUVzKHQua2V5cygpKTtpZighdC5oYXMoYSkpcmV0dXJuO2xldCBjPXBvKHMsYSk7aWYoIWN8fCF0LmhhcyhjLmhyZWYpKXJldHVybjtsZXQgcD1wbyhzLHIpO2lmKHApcmV0dXJuIHAuaGFzaD1vLmhhc2gscC5zZWFyY2g9by5zZWFyY2gscH1mdW5jdGlvbiBwbyhlLHQpe3RyeXtyZXR1cm4gbmV3IFVSTChlLHQpfWNhdGNoKHIpe3JldHVybn19ZnVuY3Rpb24geXMoZSx0KXtpZihlLnN0YXJ0c1dpdGgodCkpcmV0dXJuIGUuc2xpY2UodC5sZW5ndGgpfWZ1bmN0aW9uIHhzKGUsdCl7bGV0IHI9TWF0aC5taW4oZS5sZW5ndGgsdC5sZW5ndGgpLG87Zm9yKG89MDtvPHImJmVbb109PT10W29dOysrbyk7cmV0dXJuIG99ZnVuY3Rpb24gRXMoZSl7bGV0IHQ7Zm9yKGxldCByIG9mIGUpdD09PXZvaWQgMD90PXI6dD10LnNsaWNlKDAseHModCxyKSk7cmV0dXJuIHQhPW51bGw/dDoiIn1mdW5jdGlvbiBUaSh7ZG9jdW1lbnQkOmV9KXtsZXQgdD1UZSgpLHI9emUobmV3IFVSTCgiLi4vdmVyc2lvbnMuanNvbiIsdC5iYXNlKSkucGlwZSh2ZSgoKT0+eSkpLG89ci5waXBlKG0obj0+e2xldFssaV09dC5iYXNlLm1hdGNoKC8oW14vXSspXC8/JC8pO3JldHVybiBuLmZpbmQoKHt2ZXJzaW9uOnMsYWxpYXNlczphfSk9PnM9PT1pfHxhLmluY2x1ZGVzKGkpKXx8blswXX0pKTtyLnBpcGUobShuPT5uZXcgTWFwKG4ubWFwKGk9PltgJHtuZXcgVVJMKGAuLi8ke2kudmVyc2lvbn0vYCx0LmJhc2UpfWAsaV0pKSksYihuPT5oKGRvY3VtZW50LmJvZHksImNsaWNrIikucGlwZShnKGk9PiFpLm1ldGFLZXkmJiFpLmN0cmxLZXkpLHRlKG8pLGIoKFtpLHNdKT0+e2lmKGkudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCl7bGV0IGE9aS50YXJnZXQuY2xvc2VzdCgiYSIpO2lmKGEmJiFhLnRhcmdldCYmbi5oYXMoYS5ocmVmKSl7bGV0IGM9YS5ocmVmO3JldHVybiFpLnRhcmdldC5jbG9zZXN0KCIubWQtdmVyc2lvbiIpJiZuLmdldChjKT09PXM/eTooaS5wcmV2ZW50RGVmYXVsdCgpLCQobmV3IFVSTChjKSkpfX1yZXR1cm4geX0pLGIoaT0+a3QoaSkucGlwZShtKHM9Pnt2YXIgYTtyZXR1cm4oYT13aSh7c2VsZWN0ZWRWZXJzaW9uU2l0ZW1hcDpzLHNlbGVjdGVkVmVyc2lvbkJhc2VVUkw6aSxjdXJyZW50TG9jYXRpb246d2UoKSxjdXJyZW50QmFzZVVSTDp0LmJhc2V9KSkhPW51bGw/YTppfSkpKSkpKS5zdWJzY3JpYmUobj0+c3QobiwhMCkpLHooW3Isb10pLnN1YnNjcmliZSgoW24saV0pPT57aigiLm1kLWhlYWRlcl9fdG9waWMiKS5hcHBlbmRDaGlsZChXbihuLGkpKX0pLGUucGlwZShiKCgpPT5vKSkuc3Vic2NyaWJlKG49Pnt2YXIgYTtsZXQgaT1uZXcgVVJMKHQuYmFzZSkscz1fX21kX2dldCgiX19vdXRkYXRlZCIsc2Vzc2lvblN0b3JhZ2UsaSk7aWYocz09PW51bGwpe3M9ITA7bGV0IGM9KChhPXQudmVyc2lvbik9PW51bGw/dm9pZCAwOmEuZGVmYXVsdCl8fCJsYXRlc3QiO0FycmF5LmlzQXJyYXkoYyl8fChjPVtjXSk7ZTpmb3IobGV0IHAgb2YgYylmb3IobGV0IGwgb2Ygbi5hbGlhc2VzLmNvbmNhdChuLnZlcnNpb24pKWlmKG5ldyBSZWdFeHAocCwiaSIpLnRlc3QobCkpe3M9ITE7YnJlYWsgZX1fX21kX3NldCgiX19vdXRkYXRlZCIscyxzZXNzaW9uU3RvcmFnZSxpKX1pZihzKWZvcihsZXQgYyBvZiBtZSgib3V0ZGF0ZWQiKSljLmhpZGRlbj0hMX0pfWZ1bmN0aW9uIHdzKGUse3dvcmtlciQ6dH0pe2xldHtzZWFyY2hQYXJhbXM6cn09d2UoKTtyLmhhcygicSIpJiYoYXQoInNlYXJjaCIsITApLGUudmFsdWU9ci5nZXQoInEiKSxlLmZvY3VzKCksSmUoInNlYXJjaCIpLnBpcGUoUmUoaT0+IWkpKS5zdWJzY3JpYmUoKCk9PntsZXQgaT13ZSgpO2kuc2VhcmNoUGFyYW1zLmRlbGV0ZSgicSIpLGhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCIiLGAke2l9YCl9KSk7bGV0IG89WWUoZSksbj1MKHQucGlwZShSZSh6dCkpLGgoZSwia2V5dXAiKSxvKS5waXBlKG0oKCk9PmUudmFsdWUpLFkoKSk7cmV0dXJuIHooW24sb10pLnBpcGUobSgoW2ksc10pPT4oe3ZhbHVlOmksZm9jdXM6c30pKSxaKDEpKX1mdW5jdGlvbiBTaShlLHt3b3JrZXIkOnR9KXtsZXQgcj1uZXcgVCxvPXIucGlwZShvZSgpLGFlKCEwKSk7eihbdC5waXBlKFJlKHp0KSkscl0sKGkscyk9PnMpLnBpcGUobmUoInZhbHVlIikpLnN1YnNjcmliZSgoe3ZhbHVlOml9KT0+dC5uZXh0KHt0eXBlOjIsZGF0YTppfSkpLHIucGlwZShuZSgiZm9jdXMiKSkuc3Vic2NyaWJlKCh7Zm9jdXM6aX0pPT57aSYmYXQoInNlYXJjaCIsaSl9KSxoKGUuZm9ybSwicmVzZXQiKS5waXBlKFcobykpLnN1YnNjcmliZSgoKT0+ZS5mb2N1cygpKTtsZXQgbj1qKCJoZWFkZXIgW2Zvcj1fX3NlYXJjaF0iKTtyZXR1cm4gaChuLCJjbGljayIpLnN1YnNjcmliZSgoKT0+ZS5mb2N1cygpKSx3cyhlLHt3b3JrZXIkOnR9KS5waXBlKE8oaT0+ci5uZXh0KGkpKSxBKCgpPT5yLmNvbXBsZXRlKCkpLG0oaT0+UCh7cmVmOmV9LGkpKSxaKDEpKX1mdW5jdGlvbiBPaShlLHt3b3JrZXIkOnQscXVlcnkkOnJ9KXtsZXQgbz1uZXcgVCxuPXVuKGUucGFyZW50RWxlbWVudCkucGlwZShnKEJvb2xlYW4pKSxpPWUucGFyZW50RWxlbWVudCxzPWooIjpzY29wZSA+IDpmaXJzdC1jaGlsZCIsZSksYT1qKCI6c2NvcGUgPiA6bGFzdC1jaGlsZCIsZSk7SmUoInNlYXJjaCIpLnN1YnNjcmliZShsPT57YS5zZXRBdHRyaWJ1dGUoInJvbGUiLGw/Imxpc3QiOiJwcmVzZW50YXRpb24iKSxhLmhpZGRlbj0hbH0pLG8ucGlwZSh0ZShyKSxHcih0LnBpcGUoUmUoenQpKSkpLnN1YnNjcmliZSgoW3tpdGVtczpsfSx7dmFsdWU6Zn1dKT0+e3N3aXRjaChsLmxlbmd0aCl7Y2FzZSAwOnMudGV4dENvbnRlbnQ9Zi5sZW5ndGg/TWUoInNlYXJjaC5yZXN1bHQubm9uZSIpOk1lKCJzZWFyY2gucmVzdWx0LnBsYWNlaG9sZGVyIik7YnJlYWs7Y2FzZSAxOnMudGV4dENvbnRlbnQ9TWUoInNlYXJjaC5yZXN1bHQub25lIik7YnJlYWs7ZGVmYXVsdDpsZXQgdT1icihsLmxlbmd0aCk7cy50ZXh0Q29udGVudD1NZSgic2VhcmNoLnJlc3VsdC5vdGhlciIsdSl9fSk7bGV0IGM9by5waXBlKE8oKCk9PmEuaW5uZXJIVE1MPSIiKSxiKCh7aXRlbXM6bH0pPT5MKCQoLi4ubC5zbGljZSgwLDEwKSksJCguLi5sLnNsaWNlKDEwKSkucGlwZShvdCg0KSxYcihuKSxiKChbZl0pPT5mKSkpKSxtKEZuKSxsZSgpKTtyZXR1cm4gYy5zdWJzY3JpYmUobD0+YS5hcHBlbmRDaGlsZChsKSksYy5waXBlKEoobD0+e2xldCBmPXVlKCJkZXRhaWxzIixsKTtyZXR1cm4gdHlwZW9mIGY9PSJ1bmRlZmluZWQiP3k6aChmLCJ0b2dnbGUiKS5waXBlKFcobyksbSgoKT0+ZikpfSkpLnN1YnNjcmliZShsPT57bC5vcGVuPT09ITEmJmwub2Zmc2V0VG9wPD1pLnNjcm9sbFRvcCYmaS5zY3JvbGxUbyh7dG9wOmwub2Zmc2V0VG9wfSl9KSx0LnBpcGUoZyhTciksbSgoe2RhdGE6bH0pPT5sKSkucGlwZShPKGw9Pm8ubmV4dChsKSksQSgoKT0+by5jb21wbGV0ZSgpKSxtKGw9PlAoe3JlZjplfSxsKSkpfWZ1bmN0aW9uIFRzKGUse3F1ZXJ5JDp0fSl7cmV0dXJuIHQucGlwZShtKCh7dmFsdWU6cn0pPT57bGV0IG89d2UoKTtyZXR1cm4gby5oYXNoPSIiLHI9ci5yZXBsYWNlKC9ccysvZywiKyIpLnJlcGxhY2UoLyYvZywiJTI2IikucmVwbGFjZSgvPS9nLCIlM0QiKSxvLnNlYXJjaD1gcT0ke3J9YCx7dXJsOm99fSkpfWZ1bmN0aW9uIExpKGUsdCl7bGV0IHI9bmV3IFQsbz1yLnBpcGUob2UoKSxhZSghMCkpO3JldHVybiByLnN1YnNjcmliZSgoe3VybDpufSk9PntlLnNldEF0dHJpYnV0ZSgiZGF0YS1jbGlwYm9hcmQtdGV4dCIsZS5ocmVmKSxlLmhyZWY9YCR7bn1gfSksaChlLCJjbGljayIpLnBpcGUoVyhvKSkuc3Vic2NyaWJlKG49Pm4ucHJldmVudERlZmF1bHQoKSksVHMoZSx0KS5waXBlKE8obj0+ci5uZXh0KG4pKSxBKCgpPT5yLmNvbXBsZXRlKCkpLG0obj0+UCh7cmVmOmV9LG4pKSl9ZnVuY3Rpb24gTWkoZSx7d29ya2VyJDp0LGtleWJvYXJkJDpyfSl7bGV0IG89bmV3IFQsbj1DZSgic2VhcmNoLXF1ZXJ5IiksaT1MKGgobiwia2V5ZG93biIpLGgobiwiZm9jdXMiKSkucGlwZSh4ZShwZSksbSgoKT0+bi52YWx1ZSksWSgpKTtyZXR1cm4gby5waXBlKFBlKGkpLG0oKFt7c3VnZ2VzdDphfSxjXSk9PntsZXQgcD1jLnNwbGl0KC8oW1xzLV0rKS8pO2lmKGEhPW51bGwmJmEubGVuZ3RoJiZwW3AubGVuZ3RoLTFdKXtsZXQgbD1hW2EubGVuZ3RoLTFdO2wuc3RhcnRzV2l0aChwW3AubGVuZ3RoLTFdKSYmKHBbcC5sZW5ndGgtMV09bCl9ZWxzZSBwLmxlbmd0aD0wO3JldHVybiBwfSkpLnN1YnNjcmliZShhPT5lLmlubmVySFRNTD1hLmpvaW4oIiIpLnJlcGxhY2UoL1xzL2csIiZuYnNwOyIpKSxyLnBpcGUoZygoe21vZGU6YX0pPT5hPT09InNlYXJjaCIpKS5zdWJzY3JpYmUoYT0+e2EudHlwZT09PSJBcnJvd1JpZ2h0IiYmZS5pbm5lclRleHQubGVuZ3RoJiZuLnNlbGVjdGlvblN0YXJ0PT09bi52YWx1ZS5sZW5ndGgmJihuLnZhbHVlPWUuaW5uZXJUZXh0KX0pLHQucGlwZShnKFNyKSxtKCh7ZGF0YTphfSk9PmEpKS5waXBlKE8oYT0+by5uZXh0KGEpKSxBKCgpPT5vLmNvbXBsZXRlKCkpLG0oKCk9Pih7cmVmOmV9KSkpfWZ1bmN0aW9uIF9pKGUse2luZGV4JDp0LGtleWJvYXJkJDpyfSl7bGV0IG89VGUoKTt0cnl7bGV0IG49RWkoby5zZWFyY2gsdCksaT1DZSgic2VhcmNoLXF1ZXJ5IixlKSxzPUNlKCJzZWFyY2gtcmVzdWx0IixlKTtoKGUsImNsaWNrIikucGlwZShnKCh7dGFyZ2V0OmN9KT0+YyBpbnN0YW5jZW9mIEVsZW1lbnQmJiEhYy5jbG9zZXN0KCJhIikpKS5zdWJzY3JpYmUoKCk9PmF0KCJzZWFyY2giLCExKSksci5waXBlKGcoKHttb2RlOmN9KT0+Yz09PSJzZWFyY2giKSkuc3Vic2NyaWJlKGM9PntsZXQgcD1OZSgpO3N3aXRjaChjLnR5cGUpe2Nhc2UiRW50ZXIiOmlmKHA9PT1pKXtsZXQgbD1uZXcgTWFwO2ZvcihsZXQgZiBvZiBNKCI6Zmlyc3QtY2hpbGQgW2hyZWZdIixzKSl7bGV0IHU9Zi5maXJzdEVsZW1lbnRDaGlsZDtsLnNldChmLHBhcnNlRmxvYXQodS5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtc2NvcmUiKSkpfWlmKGwuc2l6ZSl7bGV0W1tmXV09Wy4uLmxdLnNvcnQoKFssdV0sWyxkXSk9PmQtdSk7Zi5jbGljaygpfWMuY2xhaW0oKX1icmVhaztjYXNlIkVzY2FwZSI6Y2FzZSJUYWIiOmF0KCJzZWFyY2giLCExKSxpLmJsdXIoKTticmVhaztjYXNlIkFycm93VXAiOmNhc2UiQXJyb3dEb3duIjppZih0eXBlb2YgcD09InVuZGVmaW5lZCIpaS5mb2N1cygpO2Vsc2V7bGV0IGw9W2ksLi4uTSgiOm5vdChkZXRhaWxzKSA+IFtocmVmXSwgc3VtbWFyeSwgZGV0YWlsc1tvcGVuXSBbaHJlZl0iLHMpXSxmPU1hdGgubWF4KDAsKE1hdGgubWF4KDAsbC5pbmRleE9mKHApKStsLmxlbmd0aCsoYy50eXBlPT09IkFycm93VXAiPy0xOjEpKSVsLmxlbmd0aCk7bFtmXS5mb2N1cygpfWMuY2xhaW0oKTticmVhaztkZWZhdWx0OmkhPT1OZSgpJiZpLmZvY3VzKCl9fSksci5waXBlKGcoKHttb2RlOmN9KT0+Yz09PSJnbG9iYWwiKSkuc3Vic2NyaWJlKGM9Pntzd2l0Y2goYy50eXBlKXtjYXNlImYiOmNhc2UicyI6Y2FzZSIvIjppLmZvY3VzKCksaS5zZWxlY3QoKSxjLmNsYWltKCk7YnJlYWt9fSk7bGV0IGE9U2koaSx7d29ya2VyJDpufSk7cmV0dXJuIEwoYSxPaShzLHt3b3JrZXIkOm4scXVlcnkkOmF9KSkucGlwZShWZSguLi5tZSgic2VhcmNoLXNoYXJlIixlKS5tYXAoYz0+TGkoYyx7cXVlcnkkOmF9KSksLi4ubWUoInNlYXJjaC1zdWdnZXN0IixlKS5tYXAoYz0+TWkoYyx7d29ya2VyJDpuLGtleWJvYXJkJDpyfSkpKSl9Y2F0Y2gobil7cmV0dXJuIGUuaGlkZGVuPSEwLHR0fX1mdW5jdGlvbiBBaShlLHtpbmRleCQ6dCxsb2NhdGlvbiQ6cn0pe3JldHVybiB6KFt0LHIucGlwZShRKHdlKCkpLGcobz0+ISFvLnNlYXJjaFBhcmFtcy5nZXQoImgiKSkpXSkucGlwZShtKChbbyxuXSk9PnhpKG8uY29uZmlnKShuLnNlYXJjaFBhcmFtcy5nZXQoImgiKSkpLG0obz0+e3ZhciBzO2xldCBuPW5ldyBNYXAsaT1kb2N1bWVudC5jcmVhdGVOb2RlSXRlcmF0b3IoZSxOb2RlRmlsdGVyLlNIT1dfVEVYVCk7Zm9yKGxldCBhPWkubmV4dE5vZGUoKTthO2E9aS5uZXh0Tm9kZSgpKWlmKChzPWEucGFyZW50RWxlbWVudCkhPW51bGwmJnMub2Zmc2V0SGVpZ2h0KXtsZXQgYz1hLnRleHRDb250ZW50LHA9byhjKTtwLmxlbmd0aD5jLmxlbmd0aCYmbi5zZXQoYSxwKX1mb3IobGV0W2EsY11vZiBuKXtsZXR7Y2hpbGROb2RlczpwfT14KCJzcGFuIixudWxsLGMpO2EucmVwbGFjZVdpdGgoLi4uQXJyYXkuZnJvbShwKSl9cmV0dXJue3JlZjplLG5vZGVzOm59fSkpfWZ1bmN0aW9uIFNzKGUse3ZpZXdwb3J0JDp0LG1haW4kOnJ9KXtsZXQgbz1lLmNsb3Nlc3QoIi5tZC1ncmlkIiksbj1vLm9mZnNldFRvcC1vLnBhcmVudEVsZW1lbnQub2Zmc2V0VG9wO3JldHVybiB6KFtyLHRdKS5waXBlKG0oKFt7b2Zmc2V0OmksaGVpZ2h0OnN9LHtvZmZzZXQ6e3k6YX19XSk9PihzPXMrTWF0aC5taW4obixNYXRoLm1heCgwLGEtaSkpLW4se2hlaWdodDpzLGxvY2tlZDphPj1pK259KSksWSgoaSxzKT0+aS5oZWlnaHQ9PT1zLmhlaWdodCYmaS5sb2NrZWQ9PT1zLmxvY2tlZCkpfWZ1bmN0aW9uIGxvKGUsbyl7dmFyIG49byx7aGVhZGVyJDp0fT1uLHI9dm8obixbImhlYWRlciQiXSk7bGV0IGk9aigiLm1kLXNpZGViYXJfX3Njcm9sbHdyYXAiLGUpLHt5OnN9PUJlKGkpO3JldHVybiBIKCgpPT57bGV0IGE9bmV3IFQsYz1hLnBpcGUob2UoKSxhZSghMCkpLHA9YS5waXBlKCRlKDAseWUpKTtyZXR1cm4gcC5waXBlKHRlKHQpKS5zdWJzY3JpYmUoe25leHQoW3toZWlnaHQ6bH0se2hlaWdodDpmfV0pe2kuc3R5bGUuaGVpZ2h0PWAke2wtMipzfXB4YCxlLnN0eWxlLnRvcD1gJHtmfXB4YH0sY29tcGxldGUoKXtpLnN0eWxlLmhlaWdodD0iIixlLnN0eWxlLnRvcD0iIn19KSxwLnBpcGUoUmUoKSkuc3Vic2NyaWJlKCgpPT57Zm9yKGxldCBsIG9mIE0oIi5tZC1uYXZfX2xpbmstLWFjdGl2ZVtocmVmXSIsZSkpe2lmKCFsLmNsaWVudEhlaWdodCljb250aW51ZTtsZXQgZj1sLmNsb3Nlc3QoIi5tZC1zaWRlYmFyX19zY3JvbGx3cmFwIik7aWYodHlwZW9mIGYhPSJ1bmRlZmluZWQiKXtsZXQgdT1sLm9mZnNldFRvcC1mLm9mZnNldFRvcCx7aGVpZ2h0OmR9PWRlKGYpO2Yuc2Nyb2xsVG8oe3RvcDp1LWQvMn0pfX19KSxmZShNKCJsYWJlbFt0YWJpbmRleF0iLGUpKS5waXBlKEoobD0+aChsLCJjbGljayIpLnBpcGUoeGUocGUpLG0oKCk9PmwpLFcoYykpKSkuc3Vic2NyaWJlKGw9PntsZXQgZj1qKGBbaWQ9IiR7bC5odG1sRm9yfSJdYCk7aihgW2FyaWEtbGFiZWxsZWRieT0iJHtsLmlkfSJdYCkuc2V0QXR0cmlidXRlKCJhcmlhLWV4cGFuZGVkIixgJHtmLmNoZWNrZWR9YCl9KSxWKCJjb250ZW50LnRvb2x0aXBzIikmJmZlKE0oImFiYnJbdGl0bGVdIixlKSkucGlwZShKKGw9PlhlKGwse3ZpZXdwb3J0JH0pKSxXKGMpKS5zdWJzY3JpYmUoKSxTcyhlLHIpLnBpcGUoTyhsPT5hLm5leHQobCkpLEEoKCk9PmEuY29tcGxldGUoKSksbShsPT5QKHtyZWY6ZX0sbCkpKX0pfWZ1bmN0aW9uIENpKGUsdCl7aWYodHlwZW9mIHQhPSJ1bmRlZmluZWQiKXtsZXQgcj1gaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8ke2V9LyR7dH1gO3JldHVybiBydCh6ZShgJHtyfS9yZWxlYXNlcy9sYXRlc3RgKS5waXBlKHZlKCgpPT55KSxtKG89Pih7dmVyc2lvbjpvLnRhZ19uYW1lfSkpLFFlKHt9KSksemUocikucGlwZSh2ZSgoKT0+eSksbShvPT4oe3N0YXJzOm8uc3RhcmdhemVyc19jb3VudCxmb3JrczpvLmZvcmtzX2NvdW50fSkpLFFlKHt9KSkpLnBpcGUobSgoW28sbl0pPT5QKFAoe30sbyksbikpKX1lbHNle2xldCByPWBodHRwczovL2FwaS5naXRodWIuY29tL3VzZXJzLyR7ZX1gO3JldHVybiB6ZShyKS5waXBlKG0obz0+KHtyZXBvc2l0b3JpZXM6by5wdWJsaWNfcmVwb3N9KSksUWUoe30pKX19ZnVuY3Rpb24ga2koZSx0KXtsZXQgcj1gaHR0cHM6Ly8ke2V9L2FwaS92NC9wcm9qZWN0cy8ke2VuY29kZVVSSUNvbXBvbmVudCh0KX1gO3JldHVybiBydCh6ZShgJHtyfS9yZWxlYXNlcy9wZXJtYWxpbmsvbGF0ZXN0YCkucGlwZSh2ZSgoKT0+eSksbSgoe3RhZ19uYW1lOm99KT0+KHt2ZXJzaW9uOm99KSksUWUoe30pKSx6ZShyKS5waXBlKHZlKCgpPT55KSxtKCh7c3Rhcl9jb3VudDpvLGZvcmtzX2NvdW50Om59KT0+KHtzdGFyczpvLGZvcmtzOm59KSksUWUoe30pKSkucGlwZShtKChbbyxuXSk9PlAoUCh7fSxvKSxuKSkpfWZ1bmN0aW9uIEhpKGUpe2xldCB0PWUubWF0Y2goL14uK2dpdGh1YlwuY29tXC8oW14vXSspXC8/KFteL10rKT8vaSk7aWYodCl7bGV0WyxyLG9dPXQ7cmV0dXJuIENpKHIsbyl9aWYodD1lLm1hdGNoKC9eLis/KFteL10qZ2l0bGFiW14vXSspXC8oLis/KVwvPyQvaSksdCl7bGV0WyxyLG9dPXQ7cmV0dXJuIGtpKHIsbyl9cmV0dXJuIHl9dmFyIE9zO2Z1bmN0aW9uIExzKGUpe3JldHVybiBPc3x8KE9zPUgoKCk9PntsZXQgdD1fX21kX2dldCgiX19zb3VyY2UiLHNlc3Npb25TdG9yYWdlKTtpZih0KXJldHVybiAkKHQpO2lmKG1lKCJjb25zZW50IikubGVuZ3RoKXtsZXQgbz1fX21kX2dldCgiX19jb25zZW50Iik7aWYoIShvJiZvLmdpdGh1YikpcmV0dXJuIHl9cmV0dXJuIEhpKGUuaHJlZikucGlwZShPKG89Pl9fbWRfc2V0KCJfX3NvdXJjZSIsbyxzZXNzaW9uU3RvcmFnZSkpKX0pLnBpcGUodmUoKCk9PnkpLGcodD0+T2JqZWN0LmtleXModCkubGVuZ3RoPjApLG0odD0+KHtmYWN0czp0fSkpLFooMSkpKX1mdW5jdGlvbiAkaShlKXtsZXQgdD1qKCI6c2NvcGUgPiA6bGFzdC1jaGlsZCIsZSk7cmV0dXJuIEgoKCk9PntsZXQgcj1uZXcgVDtyZXR1cm4gci5zdWJzY3JpYmUoKHtmYWN0czpvfSk9Pnt0LmFwcGVuZENoaWxkKGpuKG8pKSx0LmNsYXNzTGlzdC5hZGQoIm1kLXNvdXJjZV9fcmVwb3NpdG9yeS0tYWN0aXZlIil9KSxMcyhlKS5waXBlKE8obz0+ci5uZXh0KG8pKSxBKCgpPT5yLmNvbXBsZXRlKCkpLG0obz0+UCh7cmVmOmV9LG8pKSl9KX1mdW5jdGlvbiBNcyhlLHt2aWV3cG9ydCQ6dCxoZWFkZXIkOnJ9KXtyZXR1cm4gTGUoZG9jdW1lbnQuYm9keSkucGlwZShiKCgpPT5FcihlLHtoZWFkZXIkOnIsdmlld3BvcnQkOnR9KSksbSgoe29mZnNldDp7eTpvfX0pPT4oe2hpZGRlbjpvPj0xMH0pKSxuZSgiaGlkZGVuIikpfWZ1bmN0aW9uIFBpKGUsdCl7cmV0dXJuIEgoKCk9PntsZXQgcj1uZXcgVDtyZXR1cm4gci5zdWJzY3JpYmUoe25leHQoe2hpZGRlbjpvfSl7ZS5oaWRkZW49b30sY29tcGxldGUoKXtlLmhpZGRlbj0hMX19KSwoVigibmF2aWdhdGlvbi50YWJzLnN0aWNreSIpPyQoe2hpZGRlbjohMX0pOk1zKGUsdCkpLnBpcGUoTyhvPT5yLm5leHQobykpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT5QKHtyZWY6ZX0sbykpKX0pfWZ1bmN0aW9uIF9zKGUse3ZpZXdwb3J0JDp0LGhlYWRlciQ6cn0pe2xldCBvPW5ldyBNYXAsbj1NKCIubWQtbmF2X19saW5rIixlKTtmb3IobGV0IGEgb2Ygbil7bGV0IGM9ZGVjb2RlVVJJQ29tcG9uZW50KGEuaGFzaC5zdWJzdHJpbmcoMSkpLHA9dWUoYFtpZD0iJHtjfSJdYCk7dHlwZW9mIHAhPSJ1bmRlZmluZWQiJiZvLnNldChhLHApfWxldCBpPXIucGlwZShuZSgiaGVpZ2h0IiksbSgoe2hlaWdodDphfSk9PntsZXQgYz1DZSgibWFpbiIpLHA9aigiOnNjb3BlID4gOmZpcnN0LWNoaWxkIixjKTtyZXR1cm4gYSsuOCoocC5vZmZzZXRUb3AtYy5vZmZzZXRUb3ApfSksbGUoKSk7cmV0dXJuIExlKGRvY3VtZW50LmJvZHkpLnBpcGUobmUoImhlaWdodCIpLGIoYT0+SCgoKT0+e2xldCBjPVtdO3JldHVybiAkKFsuLi5vXS5yZWR1Y2UoKHAsW2wsZl0pPT57Zm9yKDtjLmxlbmd0aCYmby5nZXQoY1tjLmxlbmd0aC0xXSkudGFnTmFtZT49Zi50YWdOYW1lOyljLnBvcCgpO2xldCB1PWYub2Zmc2V0VG9wO2Zvcig7IXUmJmYucGFyZW50RWxlbWVudDspZj1mLnBhcmVudEVsZW1lbnQsdT1mLm9mZnNldFRvcDtsZXQgZD1mLm9mZnNldFBhcmVudDtmb3IoO2Q7ZD1kLm9mZnNldFBhcmVudCl1Kz1kLm9mZnNldFRvcDtyZXR1cm4gcC5zZXQoWy4uLmM9Wy4uLmMsbF1dLnJldmVyc2UoKSx1KX0sbmV3IE1hcCkpfSkucGlwZShtKGM9Pm5ldyBNYXAoWy4uLmNdLnNvcnQoKFsscF0sWyxsXSk9PnAtbCkpKSxQZShpKSxiKChbYyxwXSk9PnQucGlwZShVdCgoW2wsZl0se29mZnNldDp7eTp1fSxzaXplOmR9KT0+e2xldCB2PXUrZC5oZWlnaHQ+PU1hdGguZmxvb3IoYS5oZWlnaHQpO2Zvcig7Zi5sZW5ndGg7KXtsZXRbLFNdPWZbMF07aWYoUy1wPHV8fHYpbD1bLi4ubCxmLnNoaWZ0KCldO2Vsc2UgYnJlYWt9Zm9yKDtsLmxlbmd0aDspe2xldFssU109bFtsLmxlbmd0aC0xXTtpZihTLXA+PXUmJiF2KWY9W2wucG9wKCksLi4uZl07ZWxzZSBicmVha31yZXR1cm5bbCxmXX0sW1tdLFsuLi5jXV0pLFkoKGwsZik9PmxbMF09PT1mWzBdJiZsWzFdPT09ZlsxXSkpKSkpKS5waXBlKG0oKFthLGNdKT0+KHtwcmV2OmEubWFwKChbcF0pPT5wKSxuZXh0OmMubWFwKChbcF0pPT5wKX0pKSxRKHtwcmV2OltdLG5leHQ6W119KSxvdCgyLDEpLG0oKFthLGNdKT0+YS5wcmV2Lmxlbmd0aDxjLnByZXYubGVuZ3RoP3twcmV2OmMucHJldi5zbGljZShNYXRoLm1heCgwLGEucHJldi5sZW5ndGgtMSksYy5wcmV2Lmxlbmd0aCksbmV4dDpbXX06e3ByZXY6Yy5wcmV2LnNsaWNlKC0xKSxuZXh0OmMubmV4dC5zbGljZSgwLGMubmV4dC5sZW5ndGgtYS5uZXh0Lmxlbmd0aCl9KSl9ZnVuY3Rpb24gUmkoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyLG1haW4kOm8sdGFyZ2V0JDpufSl7cmV0dXJuIEgoKCk9PntsZXQgaT1uZXcgVCxzPWkucGlwZShvZSgpLGFlKCEwKSk7aWYoaS5zdWJzY3JpYmUoKHtwcmV2OmEsbmV4dDpjfSk9Pntmb3IobGV0W3Bdb2YgYylwLmNsYXNzTGlzdC5yZW1vdmUoIm1kLW5hdl9fbGluay0tcGFzc2VkIikscC5jbGFzc0xpc3QucmVtb3ZlKCJtZC1uYXZfX2xpbmstLWFjdGl2ZSIpO2ZvcihsZXRbcCxbbF1db2YgYS5lbnRyaWVzKCkpbC5jbGFzc0xpc3QuYWRkKCJtZC1uYXZfX2xpbmstLXBhc3NlZCIpLGwuY2xhc3NMaXN0LnRvZ2dsZSgibWQtbmF2X19saW5rLS1hY3RpdmUiLHA9PT1hLmxlbmd0aC0xKX0pLFYoInRvYy5mb2xsb3ciKSl7bGV0IGE9TCh0LnBpcGUoQWUoMSksbSgoKT0+e30pKSx0LnBpcGUoQWUoMjUwKSxtKCgpPT4ic21vb3RoIikpKTtpLnBpcGUoZygoe3ByZXY6Y30pPT5jLmxlbmd0aD4wKSxQZShvLnBpcGUoeGUocGUpKSksdGUoYSkpLnN1YnNjcmliZSgoW1t7cHJldjpjfV0scF0pPT57bGV0W2xdPWNbYy5sZW5ndGgtMV07aWYobC5vZmZzZXRIZWlnaHQpe2xldCBmPXZyKGwpO2lmKHR5cGVvZiBmIT0idW5kZWZpbmVkIil7bGV0IHU9bC5vZmZzZXRUb3AtZi5vZmZzZXRUb3Ase2hlaWdodDpkfT1kZShmKTtmLnNjcm9sbFRvKHt0b3A6dS1kLzIsYmVoYXZpb3I6cH0pfX19KX1yZXR1cm4gVigibmF2aWdhdGlvbi50cmFja2luZyIpJiZ0LnBpcGUoVyhzKSxuZSgib2Zmc2V0IiksQWUoMjUwKSxJZSgxKSxXKG4ucGlwZShJZSgxKSkpLHZ0KHtkZWxheToyNTB9KSx0ZShpKSkuc3Vic2NyaWJlKChbLHtwcmV2OmF9XSk9PntsZXQgYz13ZSgpLHA9YVthLmxlbmd0aC0xXTtpZihwJiZwLmxlbmd0aCl7bGV0W2xdPXAse2hhc2g6Zn09bmV3IFVSTChsLmhyZWYpO2MuaGFzaCE9PWYmJihjLmhhc2g9ZixoaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwiIixgJHtjfWApKX1lbHNlIGMuaGFzaD0iIixoaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwiIixgJHtjfWApfSksX3MoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyfSkucGlwZShPKGE9PmkubmV4dChhKSksQSgoKT0+aS5jb21wbGV0ZSgpKSxtKGE9PlAoe3JlZjplfSxhKSkpfSl9ZnVuY3Rpb24gQXMoZSx7dmlld3BvcnQkOnQsbWFpbiQ6cix0YXJnZXQkOm99KXtsZXQgbj10LnBpcGUobSgoe29mZnNldDp7eTpzfX0pPT5zKSxvdCgyLDEpLG0oKFtzLGFdKT0+cz5hJiZhPjApLFkoKSksaT1yLnBpcGUobSgoe2FjdGl2ZTpzfSk9PnMpKTtyZXR1cm4geihbaSxuXSkucGlwZShtKChbcyxhXSk9PiEocyYmYSkpLFkoKSxXKG8ucGlwZShJZSgxKSkpLGFlKCEwKSx2dCh7ZGVsYXk6MjUwfSksbShzPT4oe2hpZGRlbjpzfSkpKX1mdW5jdGlvbiBJaShlLHt2aWV3cG9ydCQ6dCxoZWFkZXIkOnIsbWFpbiQ6byx0YXJnZXQkOm59KXtsZXQgaT1uZXcgVCxzPWkucGlwZShvZSgpLGFlKCEwKSk7cmV0dXJuIGkuc3Vic2NyaWJlKHtuZXh0KHtoaWRkZW46YX0pe2UuaGlkZGVuPWEsYT8oZS5zZXRBdHRyaWJ1dGUoInRhYmluZGV4IiwiLTEiKSxlLmJsdXIoKSk6ZS5yZW1vdmVBdHRyaWJ1dGUoInRhYmluZGV4Iil9LGNvbXBsZXRlKCl7ZS5zdHlsZS50b3A9IiIsZS5oaWRkZW49ITAsZS5yZW1vdmVBdHRyaWJ1dGUoInRhYmluZGV4Iil9fSksci5waXBlKFcocyksbmUoImhlaWdodCIpKS5zdWJzY3JpYmUoKHtoZWlnaHQ6YX0pPT57ZS5zdHlsZS50b3A9YCR7YSsxNn1weGB9KSxoKGUsImNsaWNrIikuc3Vic2NyaWJlKGE9PnthLnByZXZlbnREZWZhdWx0KCksd2luZG93LnNjcm9sbFRvKHt0b3A6MH0pfSksQXMoZSx7dmlld3BvcnQkOnQsbWFpbiQ6byx0YXJnZXQkOm59KS5waXBlKE8oYT0+aS5uZXh0KGEpKSxBKCgpPT5pLmNvbXBsZXRlKCkpLG0oYT0+UCh7cmVmOmV9LGEpKSl9ZnVuY3Rpb24gRmkoe2RvY3VtZW50JDplLHZpZXdwb3J0JDp0fSl7ZS5waXBlKGIoKCk9Pk0oIi5tZC1lbGxpcHNpcyIpKSxKKHI9Pm10KHIpLnBpcGUoVyhlLnBpcGUoSWUoMSkpKSxnKG89Pm8pLG0oKCk9PnIpLEVlKDEpKSksZyhyPT5yLm9mZnNldFdpZHRoPHIuc2Nyb2xsV2lkdGgpLEoocj0+e2xldCBvPXIuaW5uZXJUZXh0LG49ci5jbG9zZXN0KCJhIil8fHI7cmV0dXJuIG4udGl0bGU9byxWKCJjb250ZW50LnRvb2x0aXBzIik/WGUobix7dmlld3BvcnQkOnR9KS5waXBlKFcoZS5waXBlKEllKDEpKSksQSgoKT0+bi5yZW1vdmVBdHRyaWJ1dGUoInRpdGxlIikpKTp5fSkpLnN1YnNjcmliZSgpLFYoImNvbnRlbnQudG9vbHRpcHMiKSYmZS5waXBlKGIoKCk9Pk0oIi5tZC1zdGF0dXMiKSksSihyPT5YZShyLHt2aWV3cG9ydCQ6dH0pKSkuc3Vic2NyaWJlKCl9ZnVuY3Rpb24gamkoe2RvY3VtZW50JDplLHRhYmxldCQ6dH0pe2UucGlwZShiKCgpPT5NKCIubWQtdG9nZ2xlLS1pbmRldGVybWluYXRlIikpLE8ocj0+e3IuaW5kZXRlcm1pbmF0ZT0hMCxyLmNoZWNrZWQ9ITF9KSxKKHI9PmgociwiY2hhbmdlIikucGlwZShKcigoKT0+ci5jbGFzc0xpc3QuY29udGFpbnMoIm1kLXRvZ2dsZS0taW5kZXRlcm1pbmF0ZSIpKSxtKCgpPT5yKSkpLHRlKHQpKS5zdWJzY3JpYmUoKFtyLG9dKT0+e3IuY2xhc3NMaXN0LnJlbW92ZSgibWQtdG9nZ2xlLS1pbmRldGVybWluYXRlIiksbyYmKHIuY2hlY2tlZD0hMSl9KX1mdW5jdGlvbiBDcygpe3JldHVybi8oaVBhZHxpUGhvbmV8aVBvZCkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCl9ZnVuY3Rpb24gVWkoe2RvY3VtZW50JDplfSl7ZS5waXBlKGIoKCk9Pk0oIltkYXRhLW1kLXNjcm9sbGZpeF0iKSksTyh0PT50LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1tZC1zY3JvbGxmaXgiKSksZyhDcyksSih0PT5oKHQsInRvdWNoc3RhcnQiKS5waXBlKG0oKCk9PnQpKSkpLnN1YnNjcmliZSh0PT57bGV0IHI9dC5zY3JvbGxUb3A7cj09PTA/dC5zY3JvbGxUb3A9MTpyK3Qub2Zmc2V0SGVpZ2h0PT09dC5zY3JvbGxIZWlnaHQmJih0LnNjcm9sbFRvcD1yLTEpfSl9ZnVuY3Rpb24gV2koe3ZpZXdwb3J0JDplLHRhYmxldCQ6dH0pe3ooW0plKCJzZWFyY2giKSx0XSkucGlwZShtKChbcixvXSk9PnImJiFvKSxiKHI9PiQocikucGlwZShudChyPzQwMDoxMDApKSksdGUoZSkpLnN1YnNjcmliZSgoW3Ise29mZnNldDp7eTpvfX1dKT0+e2lmKHIpZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoImRhdGEtbWQtc2Nyb2xsbG9jayIsIiIpLGRvY3VtZW50LmJvZHkuc3R5bGUudG9wPWAtJHtvfXB4YDtlbHNle2xldCBuPS0xKnBhcnNlSW50KGRvY3VtZW50LmJvZHkuc3R5bGUudG9wLDEwKTtkb2N1bWVudC5ib2R5LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1tZC1zY3JvbGxsb2NrIiksZG9jdW1lbnQuYm9keS5zdHlsZS50b3A9IiIsbiYmd2luZG93LnNjcm9sbFRvKDAsbil9fSl9T2JqZWN0LmVudHJpZXN8fChPYmplY3QuZW50cmllcz1mdW5jdGlvbihlKXtsZXQgdD1bXTtmb3IobGV0IHIgb2YgT2JqZWN0LmtleXMoZSkpdC5wdXNoKFtyLGVbcl1dKTtyZXR1cm4gdH0pO09iamVjdC52YWx1ZXN8fChPYmplY3QudmFsdWVzPWZ1bmN0aW9uKGUpe2xldCB0PVtdO2ZvcihsZXQgciBvZiBPYmplY3Qua2V5cyhlKSl0LnB1c2goZVtyXSk7cmV0dXJuIHR9KTt0eXBlb2YgRWxlbWVudCE9InVuZGVmaW5lZCImJihFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxUb3x8KEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbFRvPWZ1bmN0aW9uKGUsdCl7dHlwZW9mIGU9PSJvYmplY3QiPyh0aGlzLnNjcm9sbExlZnQ9ZS5sZWZ0LHRoaXMuc2Nyb2xsVG9wPWUudG9wKToodGhpcy5zY3JvbGxMZWZ0PWUsdGhpcy5zY3JvbGxUb3A9dCl9KSxFbGVtZW50LnByb3RvdHlwZS5yZXBsYWNlV2l0aHx8KEVsZW1lbnQucHJvdG90eXBlLnJlcGxhY2VXaXRoPWZ1bmN0aW9uKC4uLmUpe2xldCB0PXRoaXMucGFyZW50Tm9kZTtpZih0KXtlLmxlbmd0aD09PTAmJnQucmVtb3ZlQ2hpbGQodGhpcyk7Zm9yKGxldCByPWUubGVuZ3RoLTE7cj49MDtyLS0pe2xldCBvPWVbcl07dHlwZW9mIG89PSJzdHJpbmciP289ZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobyk6by5wYXJlbnROb2RlJiZvLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobykscj90Lmluc2VydEJlZm9yZSh0aGlzLnByZXZpb3VzU2libGluZyxvKTp0LnJlcGxhY2VDaGlsZChvLHRoaXMpfX19KSk7ZnVuY3Rpb24ga3MoKXtyZXR1cm4gbG9jYXRpb24ucHJvdG9jb2w9PT0iZmlsZToiP190KGAke25ldyBVUkwoInNlYXJjaC9zZWFyY2hfaW5kZXguanMiLE9yLmJhc2UpfWApLnBpcGUobSgoKT0+X19pbmRleCksWigxKSk6emUobmV3IFVSTCgic2VhcmNoL3NlYXJjaF9pbmRleC5qc29uIixPci5iYXNlKSl9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoIm5vLWpzIik7ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoImpzIik7dmFyIGN0PWFuKCksS3Q9Ym4oKSxIdD15bihLdCksbW89aG4oKSxrZT1MbigpLExyPVd0KCIobWluLXdpZHRoOiA2MGVtKSIpLFZpPVd0KCIobWluLXdpZHRoOiA3Ni4yNWVtKSIpLE5pPXhuKCksT3I9VGUoKSx6aT1kb2N1bWVudC5mb3Jtcy5uYW1lZEl0ZW0oInNlYXJjaCIpP2tzKCk6dHQsZm89bmV3IFQ7ZGkoe2FsZXJ0JDpmb30pO3VpKHtkb2N1bWVudCQ6Y3R9KTt2YXIgdW89bmV3IFQscWk9a3QoT3IuYmFzZSk7VigibmF2aWdhdGlvbi5pbnN0YW50IikmJmdpKHtzaXRlbWFwJDpxaSxsb2NhdGlvbiQ6S3Qsdmlld3BvcnQkOmtlLHByb2dyZXNzJDp1b30pLnN1YnNjcmliZShjdCk7dmFyIERpOygoRGk9T3IudmVyc2lvbik9PW51bGw/dm9pZCAwOkRpLnByb3ZpZGVyKT09PSJtaWtlIiYmVGkoe2RvY3VtZW50JDpjdH0pO0woS3QsSHQpLnBpcGUobnQoMTI1KSkuc3Vic2NyaWJlKCgpPT57YXQoImRyYXdlciIsITEpLGF0KCJzZWFyY2giLCExKX0pO21vLnBpcGUoZygoe21vZGU6ZX0pPT5lPT09Imdsb2JhbCIpKS5zdWJzY3JpYmUoZT0+e3N3aXRjaChlLnR5cGUpe2Nhc2UicCI6Y2FzZSIsIjpsZXQgdD11ZSgibGlua1tyZWw9cHJldl0iKTt0eXBlb2YgdCE9InVuZGVmaW5lZCImJnN0KHQpO2JyZWFrO2Nhc2UibiI6Y2FzZSIuIjpsZXQgcj11ZSgibGlua1tyZWw9bmV4dF0iKTt0eXBlb2YgciE9InVuZGVmaW5lZCImJnN0KHIpO2JyZWFrO2Nhc2UiRW50ZXIiOmxldCBvPU5lKCk7byBpbnN0YW5jZW9mIEhUTUxMYWJlbEVsZW1lbnQmJm8uY2xpY2soKX19KTtGaSh7dmlld3BvcnQkOmtlLGRvY3VtZW50JDpjdH0pO2ppKHtkb2N1bWVudCQ6Y3QsdGFibGV0JDpMcn0pO1VpKHtkb2N1bWVudCQ6Y3R9KTtXaSh7dmlld3BvcnQkOmtlLHRhYmxldCQ6THJ9KTt2YXIgZnQ9YWkoQ2UoImhlYWRlciIpLHt2aWV3cG9ydCQ6a2V9KSxxdD1jdC5waXBlKG0oKCk9PkNlKCJtYWluIikpLGIoZT0+cGkoZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnR9KSksWigxKSksSHM9TCguLi5tZSgiY29uc2VudCIpLm1hcChlPT5BbihlLHt0YXJnZXQkOkh0fSkpLC4uLm1lKCJkaWFsb2ciKS5tYXAoZT0+bmkoZSx7YWxlcnQkOmZvfSkpLC4uLm1lKCJwYWxldHRlIikubWFwKGU9PmxpKGUpKSwuLi5tZSgicHJvZ3Jlc3MiKS5tYXAoZT0+bWkoZSx7cHJvZ3Jlc3MkOnVvfSkpLC4uLm1lKCJzZWFyY2giKS5tYXAoZT0+X2koZSx7aW5kZXgkOnppLGtleWJvYXJkJDptb30pKSwuLi5tZSgic291cmNlIikubWFwKGU9PiRpKGUpKSksJHM9SCgoKT0+TCguLi5tZSgiYW5ub3VuY2UiKS5tYXAoZT0+X24oZSkpLC4uLm1lKCJjb250ZW50IikubWFwKGU9Pm9pKGUse3NpdGVtYXAkOnFpLHZpZXdwb3J0JDprZSx0YXJnZXQkOkh0LHByaW50JDpOaX0pKSwuLi5tZSgiY29udGVudCIpLm1hcChlPT5WKCJzZWFyY2guaGlnaGxpZ2h0Iik/QWkoZSx7aW5kZXgkOnppLGxvY2F0aW9uJDpLdH0pOnkpLC4uLm1lKCJoZWFkZXIiKS5tYXAoZT0+c2koZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnQsbWFpbiQ6cXR9KSksLi4ubWUoImhlYWRlci10aXRsZSIpLm1hcChlPT5jaShlLHt2aWV3cG9ydCQ6a2UsaGVhZGVyJDpmdH0pKSwuLi5tZSgic2lkZWJhciIpLm1hcChlPT5lLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC10eXBlIik9PT0ibmF2aWdhdGlvbiI/ZW8oVmksKCk9PmxvKGUse3ZpZXdwb3J0JDprZSxoZWFkZXIkOmZ0LG1haW4kOnF0fSkpOmVvKExyLCgpPT5sbyhlLHt2aWV3cG9ydCQ6a2UsaGVhZGVyJDpmdCxtYWluJDpxdH0pKSksLi4ubWUoInRhYnMiKS5tYXAoZT0+UGkoZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnR9KSksLi4ubWUoInRvYyIpLm1hcChlPT5SaShlLHt2aWV3cG9ydCQ6a2UsaGVhZGVyJDpmdCxtYWluJDpxdCx0YXJnZXQkOkh0fSkpLC4uLm1lKCJ0b3AiKS5tYXAoZT0+SWkoZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnQsbWFpbiQ6cXQsdGFyZ2V0JDpIdH0pKSkpLEtpPWN0LnBpcGUoYigoKT0+JHMpLFZlKEhzKSxaKDEpKTtLaS5zdWJzY3JpYmUoKTt3aW5kb3cuZG9jdW1lbnQkPWN0O3dpbmRvdy5sb2NhdGlvbiQ9S3Q7d2luZG93LnRhcmdldCQ9SHQ7d2luZG93LmtleWJvYXJkJD1tbzt3aW5kb3cudmlld3BvcnQkPWtlO3dpbmRvdy50YWJsZXQkPUxyO3dpbmRvdy5zY3JlZW4kPVZpO3dpbmRvdy5wcmludCQ9Tmk7d2luZG93LmFsZXJ0JD1mbzt3aW5kb3cucHJvZ3Jlc3MkPXVvO3dpbmRvdy5jb21wb25lbnQkPUtpO30pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPWJ1bmRsZS43OWFlNTE5ZS5taW4uanMubWFwCgo="></script><!--URL:../assets/javascripts/bundle.79ae519e.min.js-->
|
|
<script src="data:text/javascript;base64,LyogCkphdmFzY3JpcHQgZnVuY3Rpb25zIHRvIGhlbHAgbWFrZSB0aGUgcHJpbnQgcGFnZSBtb3JlIFBERiBmcmllbmRseQoqLwoKLyoKQ29weSB0aGUgdGFibGUgb2YgY29udGVudHMgZnJvbSB0aGUgc2lkZWJhcidzLgpPbmx5IGNhbGxlZCB3aGVuIHByaW50LXNpdGUtcGx1Z2luIG9wdGlvbiAnYWRkX3RhYmxlX29mX2NvbnRlbnRzJyBpcyBzZXQgdG8gdHJ1ZQoqLwpmdW5jdGlvbiBnZW5lcmF0ZV90b2MoKSB7CiAgY29uc3Qgc2lkZWJhciA9IGRvY3VtZW50LmJvZHkuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgibWQtc2lkZWJhci0tc2Vjb25kYXJ5IilbMF0gPz8KICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0b2MtY29sbGFwc2UiKTsKCiAgY29uc3Qgc2lkZWJhclRvYyA9IHNpZGViYXIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInVsIilbMF07CgogIHZhciBjbG9uZWRUb2MgPSBzaWRlYmFyVG9jLmNsb25lTm9kZSh0cnVlKTsKICBjbG9uZWRUb2MucmVtb3ZlQXR0cmlidXRlKCJkYXRhLW1kLWNvbXBvbmVudCIpOwogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIiNwcmludC1wYWdlLXRvYyBuYXYiKVswXS5pbnNlcnRBZGphY2VudEhUTUwoImJlZm9yZWVuZCIsIGNsb25lZFRvYy5vdXRlckhUTUwpOwp9CgoKZnVuY3Rpb24gcmVtb3ZlX21hdGVyaWFsX25hdmlnYXRpb24oKSB7CiAgLy8gUmVtb3ZlIGxlZnQgc2lkZWJhciBvbiBwcmludCBwYWdlCiAgcmVtb3ZlX2VsZW1lbnRfYnlfY2xhc3NuYW1lKCJtZC1zaWRlYmFyLS1wcmltYXJ5IikKICAvLyBSZW1vdmUgdGFicyBuYXZpZ2F0aW9uIG9uIHByaW50IHBhZ2UKICByZW1vdmVfZWxlbWVudF9ieV9jbGFzc25hbWUoIm1kLXRhYnMiKQogIC8vIFJlbW92ZSBzZWFyY2gKICByZW1vdmVfZWxlbWVudF9ieV9jbGFzc25hbWUoIm1kLXNlYXJjaCIpCgp9CgpmdW5jdGlvbiByZW1vdmVfbWtkb2NzX3RoZW1lX25hdmlnYXRpb24oKSB7CiAgLy8gUmVtb3ZlIHRvcCBuYXZpZ2F0aW9uIGJhcgogIHJlbW92ZV9lbGVtZW50X2J5X2NsYXNzbmFtZSgibmF2YmFyIikKfQoKCmZ1bmN0aW9uIHJlbW92ZV9lbGVtZW50X2J5X2NsYXNzbmFtZShjbGFzc19uYW1lKSB7CiAgdmFyIGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShjbGFzc19uYW1lKTsKICBpZiggZWwubGVuZ3RoID4gMCkgewogICAgZWxbMF0uc3R5bGUuZGlzcGxheSA9ICJub25lIgogIH0KfQo="></script><!--URL:../js/print-site.js-->
|
|
<script src="data:text/javascript;base64,d2luZG93Lk1hdGhKYXggPSB7CiAgbG9hZGVyOiB7CiAgICBsb2FkOiBbImlucHV0L3RleC1mdWxsIiwgIm91dHB1dC9jaHRtbCJdCiAgfSwKICB0ZXg6IHsKICAgIHByb2Nlc3NFc2NhcGVzOiB0cnVlLAogICAgcHJvY2Vzc0Vudmlyb25tZW50czogdHJ1ZQogIH0sCiAgb3B0aW9uczogewogICAgaWdub3JlSHRtbENsYXNzOiAiLip8IiwKICAgIHByb2Nlc3NIdG1sQ2xhc3M6ICJhcml0aG1hdGV4IgogIH0KfTsKCmRvY3VtZW50JC5zdWJzY3JpYmUoKCkgPT4gewogIE1hdGhKYXgudHlwZXNldFByb21pc2U/LigKICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIi5hcml0aG1hdGV4IikKICApLmNhdGNoKChlcnJvcikgPT4gY29uc29sZS5lcnJvcihlcnJvcikpOwp9KTsK"></script><!--URL:../javascripts/mathjax.js-->
|
|
<script src="data:text/javascript;base64,IWZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO3ZhciBlPXs1MTU6ZnVuY3Rpb24oZSx0LHIpe3ZhciBuPXRoaXMmJnRoaXMuX192YWx1ZXN8fGZ1bmN0aW9uKGUpe3ZhciB0PSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5pdGVyYXRvcixyPXQmJmVbdF0sbj0wO2lmKHIpcmV0dXJuIHIuY2FsbChlKTtpZihlJiYibnVtYmVyIj09dHlwZW9mIGUubGVuZ3RoKXJldHVybntuZXh0OmZ1bmN0aW9uKCl7cmV0dXJuIGUmJm4+PWUubGVuZ3RoJiYoZT12b2lkIDApLHt2YWx1ZTplJiZlW24rK10sZG9uZTohZX19fTt0aHJvdyBuZXcgVHlwZUVycm9yKHQ/Ik9iamVjdCBpcyBub3QgaXRlcmFibGUuIjoiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpfTtmdW5jdGlvbiBvKGUpe3JldHVybiJvYmplY3QiPT10eXBlb2YgZSYmbnVsbCE9PWV9ZnVuY3Rpb24gYShlLHQpe3ZhciByLGk7dHJ5e2Zvcih2YXIgdT1uKE9iamVjdC5rZXlzKHQpKSxjPXUubmV4dCgpOyFjLmRvbmU7Yz11Lm5leHQoKSl7dmFyIHM9Yy52YWx1ZTsiX19lc01vZHVsZSIhPT1zJiYoIW8oZVtzXSl8fCFvKHRbc10pfHx0W3NdaW5zdGFuY2VvZiBQcm9taXNlP251bGwhPT10W3NdJiZ2b2lkIDAhPT10W3NdJiYoZVtzXT10W3NdKTphKGVbc10sdFtzXSkpfX1jYXRjaChlKXtyPXtlcnJvcjplfX1maW5hbGx5e3RyeXtjJiYhYy5kb25lJiYoaT11LnJldHVybikmJmkuY2FsbCh1KX1maW5hbGx5e2lmKHIpdGhyb3cgci5lcnJvcn19cmV0dXJuIGV9T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuTWF0aEpheD10LmNvbWJpbmVXaXRoTWF0aEpheD10LmNvbWJpbmVEZWZhdWx0cz10LmNvbWJpbmVDb25maWc9dC5pc09iamVjdD12b2lkIDAsdC5pc09iamVjdD1vLHQuY29tYmluZUNvbmZpZz1hLHQuY29tYmluZURlZmF1bHRzPWZ1bmN0aW9uIGUodCxyLGEpe3ZhciBpLHU7dFtyXXx8KHRbcl09e30pLHQ9dFtyXTt0cnl7Zm9yKHZhciBjPW4oT2JqZWN0LmtleXMoYSkpLHM9Yy5uZXh0KCk7IXMuZG9uZTtzPWMubmV4dCgpKXt2YXIgbD1zLnZhbHVlO28odFtsXSkmJm8oYVtsXSk/ZSh0LGwsYVtsXSk6bnVsbD09dFtsXSYmbnVsbCE9YVtsXSYmKHRbbF09YVtsXSl9fWNhdGNoKGUpe2k9e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e3MmJiFzLmRvbmUmJih1PWMucmV0dXJuKSYmdS5jYWxsKGMpfWZpbmFsbHl7aWYoaSl0aHJvdyBpLmVycm9yfX1yZXR1cm4gdH0sdC5jb21iaW5lV2l0aE1hdGhKYXg9ZnVuY3Rpb24oZSl7cmV0dXJuIGEodC5NYXRoSmF4LGUpfSx2b2lkIDA9PT1yLmcuTWF0aEpheCYmKHIuZy5NYXRoSmF4PXt9KSxyLmcuTWF0aEpheC52ZXJzaW9ufHwoci5nLk1hdGhKYXg9e3ZlcnNpb246IjMuMS40IixfOnt9LGNvbmZpZzpyLmcuTWF0aEpheH0pLHQuTWF0aEpheD1yLmcuTWF0aEpheH0sMjM1OmZ1bmN0aW9uKGUsdCxyKXt2YXIgbj10aGlzJiZ0aGlzLl9fdmFsdWVzfHxmdW5jdGlvbihlKXt2YXIgdD0iZnVuY3Rpb24iPT10eXBlb2YgU3ltYm9sJiZTeW1ib2wuaXRlcmF0b3Iscj10JiZlW3RdLG49MDtpZihyKXJldHVybiByLmNhbGwoZSk7aWYoZSYmIm51bWJlciI9PXR5cGVvZiBlLmxlbmd0aClyZXR1cm57bmV4dDpmdW5jdGlvbigpe3JldHVybiBlJiZuPj1lLmxlbmd0aCYmKGU9dm9pZCAwKSx7dmFsdWU6ZSYmZVtuKytdLGRvbmU6IWV9fX07dGhyb3cgbmV3IFR5cGVFcnJvcih0PyJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLiI6IlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC4iKX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuQ09ORklHPXQuTWF0aEpheD10LkxvYWRlcj10LlBhdGhGaWx0ZXJzPXQuUGFja2FnZUVycm9yPXQuUGFja2FnZT12b2lkIDA7dmFyIG89cig1MTUpLGE9cigyNjUpLGk9cigyNjUpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJQYWNrYWdlIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gaS5QYWNrYWdlfX0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJQYWNrYWdlRXJyb3IiLHtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiBpLlBhY2thZ2VFcnJvcn19KTt2YXIgdSxjPXIoNTI1KTt0LlBhdGhGaWx0ZXJzPXtzb3VyY2U6ZnVuY3Rpb24oZSl7cmV0dXJuIHQuQ09ORklHLnNvdXJjZS5oYXNPd25Qcm9wZXJ0eShlLm5hbWUpJiYoZS5uYW1lPXQuQ09ORklHLnNvdXJjZVtlLm5hbWVdKSwhMH0sbm9ybWFsaXplOmZ1bmN0aW9uKGUpe3ZhciB0PWUubmFtZTtyZXR1cm4gdC5tYXRjaCgvXig/OlthLXpdKzpcLyk/XC98W2Etel06XFx8XFsvaSl8fChlLm5hbWU9IlttYXRoamF4XS8iK3QucmVwbGFjZSgvXlwuXC8vLCIiKSksZS5hZGRFeHRlbnNpb24mJiF0Lm1hdGNoKC9cLlteXC9dKyQvKSYmKGUubmFtZSs9Ii5qcyIpLCEwfSxwcmVmaXg6ZnVuY3Rpb24oZSl7Zm9yKHZhciByOyhyPWUubmFtZS5tYXRjaCgvXlxbKFteXF1dKilcXS8pKSYmdC5DT05GSUcucGF0aHMuaGFzT3duUHJvcGVydHkoclsxXSk7KWUubmFtZT10LkNPTkZJRy5wYXRoc1tyWzFdXStlLm5hbWUuc3Vic3RyKHJbMF0ubGVuZ3RoKTtyZXR1cm4hMH19LGZ1bmN0aW9uKGUpe2UucmVhZHk9ZnVuY3Rpb24oKXtmb3IodmFyIGUsdCxyPVtdLG89MDtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbb109YXJndW1lbnRzW29dOzA9PT1yLmxlbmd0aCYmKHI9QXJyYXkuZnJvbShhLlBhY2thZ2UucGFja2FnZXMua2V5cygpKSk7dmFyIGk9W107dHJ5e2Zvcih2YXIgdT1uKHIpLGM9dS5uZXh0KCk7IWMuZG9uZTtjPXUubmV4dCgpKXt2YXIgcz1jLnZhbHVlLGw9YS5QYWNrYWdlLnBhY2thZ2VzLmdldChzKXx8bmV3IGEuUGFja2FnZShzLCEwKTtpLnB1c2gobC5wcm9taXNlKX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7YyYmIWMuZG9uZSYmKHQ9dS5yZXR1cm4pJiZ0LmNhbGwodSl9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fXJldHVybiBQcm9taXNlLmFsbChpKX0sZS5sb2FkPWZ1bmN0aW9uKCl7Zm9yKHZhciBlLHIsbz1bXSxpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKylvW2ldPWFyZ3VtZW50c1tpXTtpZigwPT09by5sZW5ndGgpcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO3ZhciB1PVtdO3RyeXtmb3IodmFyIGM9bihvKSxzPWMubmV4dCgpOyFzLmRvbmU7cz1jLm5leHQoKSl7dmFyIGw9cy52YWx1ZSxkPWEuUGFja2FnZS5wYWNrYWdlcy5nZXQobCk7ZHx8KGQ9bmV3IGEuUGFja2FnZShsKSkucHJvdmlkZXModC5DT05GSUcucHJvdmlkZXNbbF0pLGQuY2hlY2tOb0xvYWQoKSx1LnB1c2goZC5wcm9taXNlKX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7cyYmIXMuZG9uZSYmKHI9Yy5yZXR1cm4pJiZyLmNhbGwoYyl9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fXJldHVybiBhLlBhY2thZ2UubG9hZEFsbCgpLFByb21pc2UuYWxsKHUpfSxlLnByZUxvYWQ9ZnVuY3Rpb24oKXtmb3IodmFyIGUscixvPVtdLGk9MDtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKW9baV09YXJndW1lbnRzW2ldO3RyeXtmb3IodmFyIHU9bihvKSxjPXUubmV4dCgpOyFjLmRvbmU7Yz11Lm5leHQoKSl7dmFyIHM9Yy52YWx1ZSxsPWEuUGFja2FnZS5wYWNrYWdlcy5nZXQocyk7bHx8KGw9bmV3IGEuUGFja2FnZShzLCEwKSkucHJvdmlkZXModC5DT05GSUcucHJvdmlkZXNbc10pLGwubG9hZGVkKCl9fWNhdGNoKHQpe2U9e2Vycm9yOnR9fWZpbmFsbHl7dHJ5e2MmJiFjLmRvbmUmJihyPXUucmV0dXJuKSYmci5jYWxsKHUpfWZpbmFsbHl7aWYoZSl0aHJvdyBlLmVycm9yfX19LGUuZGVmYXVsdFJlYWR5PWZ1bmN0aW9uKCl7dm9pZCAwIT09dC5NYXRoSmF4LnN0YXJ0dXAmJnQuTWF0aEpheC5jb25maWcuc3RhcnR1cC5yZWFkeSgpfSxlLmdldFJvb3Q9ZnVuY3Rpb24oKXt2YXIgZT0iLy8uLi8uLi9lczUiO2lmKCJ1bmRlZmluZWQiIT10eXBlb2YgZG9jdW1lbnQpe3ZhciB0PWRvY3VtZW50LmN1cnJlbnRTY3JpcHR8fGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJNYXRoSmF4LXNjcmlwdCIpO3QmJihlPXQuc3JjLnJlcGxhY2UoL1wvW15cL10qJC8sIiIpKX1yZXR1cm4gZX0sZS5wYXRoRmlsdGVycz1uZXcgYy5GdW5jdGlvbkxpc3QsZS5wYXRoRmlsdGVycy5hZGQodC5QYXRoRmlsdGVycy5zb3VyY2UsMSksZS5wYXRoRmlsdGVycy5hZGQodC5QYXRoRmlsdGVycy5ub3JtYWxpemUsMiksZS5wYXRoRmlsdGVycy5hZGQodC5QYXRoRmlsdGVycy5wcmVmaXgsNSl9KHU9dC5Mb2FkZXJ8fCh0LkxvYWRlcj17fSkpLHQuTWF0aEpheD1vLk1hdGhKYXgsdm9pZCAwPT09dC5NYXRoSmF4LmxvYWRlciYmKG8uY29tYmluZURlZmF1bHRzKHQuTWF0aEpheC5jb25maWcsImxvYWRlciIse3BhdGhzOnttYXRoamF4OnUuZ2V0Um9vdCgpfSxzb3VyY2U6e30sZGVwZW5kZW5jaWVzOnt9LHByb3ZpZGVzOnt9LGxvYWQ6W10scmVhZHk6dS5kZWZhdWx0UmVhZHkuYmluZCh1KSxmYWlsZWQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGNvbnNvbGUubG9nKCJNYXRoSmF4KCIrKGUucGFja2FnZXx8Ij8iKSsiKTogIitlLm1lc3NhZ2UpfSxyZXF1aXJlOm51bGx9KSxvLmNvbWJpbmVXaXRoTWF0aEpheCh7bG9hZGVyOnV9KSksdC5DT05GSUc9dC5NYXRoSmF4LmNvbmZpZy5sb2FkZXJ9LDI2NTpmdW5jdGlvbihlLHQscil7dmFyIG4sbz10aGlzJiZ0aGlzLl9fZXh0ZW5kc3x8KG49ZnVuY3Rpb24oZSx0KXtyZXR1cm4obj1PYmplY3Quc2V0UHJvdG90eXBlT2Z8fHtfX3Byb3RvX186W119aW5zdGFuY2VvZiBBcnJheSYmZnVuY3Rpb24oZSx0KXtlLl9fcHJvdG9fXz10fXx8ZnVuY3Rpb24oZSx0KXtmb3IodmFyIHIgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxyKSYmKGVbcl09dFtyXSl9KShlLHQpfSxmdW5jdGlvbihlLHQpe2lmKCJmdW5jdGlvbiIhPXR5cGVvZiB0JiZudWxsIT09dCl0aHJvdyBuZXcgVHlwZUVycm9yKCJDbGFzcyBleHRlbmRzIHZhbHVlICIrU3RyaW5nKHQpKyIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbCIpO2Z1bmN0aW9uIHIoKXt0aGlzLmNvbnN0cnVjdG9yPWV9bihlLHQpLGUucHJvdG90eXBlPW51bGw9PT10P09iamVjdC5jcmVhdGUodCk6KHIucHJvdG90eXBlPXQucHJvdG90eXBlLG5ldyByKX0pLGE9dGhpcyYmdGhpcy5fX3ZhbHVlc3x8ZnVuY3Rpb24oZSl7dmFyIHQ9ImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmU3ltYm9sLml0ZXJhdG9yLHI9dCYmZVt0XSxuPTA7aWYocilyZXR1cm4gci5jYWxsKGUpO2lmKGUmJiJudW1iZXIiPT10eXBlb2YgZS5sZW5ndGgpcmV0dXJue25leHQ6ZnVuY3Rpb24oKXtyZXR1cm4gZSYmbj49ZS5sZW5ndGgmJihlPXZvaWQgMCkse3ZhbHVlOmUmJmVbbisrXSxkb25lOiFlfX19O3Rocm93IG5ldyBUeXBlRXJyb3IodD8iT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS4iOiJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuIil9LGk9dGhpcyYmdGhpcy5fX3JlYWR8fGZ1bmN0aW9uKGUsdCl7dmFyIHI9ImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmZVtTeW1ib2wuaXRlcmF0b3JdO2lmKCFyKXJldHVybiBlO3ZhciBuLG8sYT1yLmNhbGwoZSksaT1bXTt0cnl7Zm9yKDsodm9pZCAwPT09dHx8dC0tID4wKSYmIShuPWEubmV4dCgpKS5kb25lOylpLnB1c2gobi52YWx1ZSl9Y2F0Y2goZSl7bz17ZXJyb3I6ZX19ZmluYWxseXt0cnl7biYmIW4uZG9uZSYmKHI9YS5yZXR1cm4pJiZyLmNhbGwoYSl9ZmluYWxseXtpZihvKXRocm93IG8uZXJyb3J9fXJldHVybiBpfSx1PXRoaXMmJnRoaXMuX19zcHJlYWRBcnJheXx8ZnVuY3Rpb24oZSx0KXtmb3IodmFyIHI9MCxuPXQubGVuZ3RoLG89ZS5sZW5ndGg7cjxuO3IrKyxvKyspZVtvXT10W3JdO3JldHVybiBlfTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSksdC5QYWNrYWdlPXQuUGFja2FnZUVycm9yPXZvaWQgMDt2YXIgYz1yKDIzNSkscz1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KHQscil7dmFyIG49ZS5jYWxsKHRoaXMsdCl8fHRoaXM7cmV0dXJuIG4ucGFja2FnZT1yLG59cmV0dXJuIG8odCxlKSx0fShFcnJvcik7dC5QYWNrYWdlRXJyb3I9czt2YXIgbD1mdW5jdGlvbigpe2Z1bmN0aW9uIGUodCxyKXt2b2lkIDA9PT1yJiYocj0hMSksdGhpcy5pc0xvYWRlZD0hMSx0aGlzLmlzTG9hZGluZz0hMSx0aGlzLmhhc0ZhaWxlZD0hMSx0aGlzLmRlcGVuZGVudHM9W10sdGhpcy5kZXBlbmRlbmNpZXM9W10sdGhpcy5kZXBlbmRlbmN5Q291bnQ9MCx0aGlzLnByb3ZpZGVkPVtdLHRoaXMubmFtZT10LHRoaXMubm9Mb2FkPXIsZS5wYWNrYWdlcy5zZXQodCx0aGlzKSx0aGlzLnByb21pc2U9dGhpcy5tYWtlUHJvbWlzZSh0aGlzLm1ha2VEZXBlbmRlbmNpZXMoKSl9cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLnByb3RvdHlwZSwiY2FuTG9hZCIse2dldDpmdW5jdGlvbigpe3JldHVybiAwPT09dGhpcy5kZXBlbmRlbmN5Q291bnQmJiF0aGlzLm5vTG9hZCYmIXRoaXMuaXNMb2FkaW5nJiYhdGhpcy5oYXNGYWlsZWR9LGVudW1lcmFibGU6ITEsY29uZmlndXJhYmxlOiEwfSksZS5yZXNvbHZlUGF0aD1mdW5jdGlvbihlLHQpe3ZvaWQgMD09PXQmJih0PSEwKTt2YXIgcj17bmFtZTplLGFkZEV4dGVuc2lvbjp0fTtyZXR1cm4gYy5Mb2FkZXIucGF0aEZpbHRlcnMuZXhlY3V0ZShyKSxyLm5hbWV9LGUubG9hZEFsbD1mdW5jdGlvbigpe3ZhciBlLHQ7dHJ5e2Zvcih2YXIgcj1hKHRoaXMucGFja2FnZXMudmFsdWVzKCkpLG49ci5uZXh0KCk7IW4uZG9uZTtuPXIubmV4dCgpKXt2YXIgbz1uLnZhbHVlO28uY2FuTG9hZCYmby5sb2FkKCl9fWNhdGNoKHQpe2U9e2Vycm9yOnR9fWZpbmFsbHl7dHJ5e24mJiFuLmRvbmUmJih0PXIucmV0dXJuKSYmdC5jYWxsKHIpfWZpbmFsbHl7aWYoZSl0aHJvdyBlLmVycm9yfX19LGUucHJvdG90eXBlLm1ha2VEZXBlbmRlbmNpZXM9ZnVuY3Rpb24oKXt2YXIgdCxyLG49W10sbz1lLnBhY2thZ2VzLHM9dGhpcy5ub0xvYWQsbD10aGlzLm5hbWUsZD1bXTtjLkNPTkZJRy5kZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkobCk/ZC5wdXNoLmFwcGx5KGQsdShbXSxpKGMuQ09ORklHLmRlcGVuZGVuY2llc1tsXSkpKToiY29yZSIhPT1sJiZkLnB1c2goImNvcmUiKTt0cnl7Zm9yKHZhciBmPWEoZCksaD1mLm5leHQoKTshaC5kb25lO2g9Zi5uZXh0KCkpe3ZhciBwPWgudmFsdWUsbT1vLmdldChwKXx8bmV3IGUocCxzKTt0aGlzLmRlcGVuZGVuY2llcy5pbmRleE9mKG0pPDAmJihtLmFkZERlcGVuZGVudCh0aGlzLHMpLHRoaXMuZGVwZW5kZW5jaWVzLnB1c2gobSksbS5pc0xvYWRlZHx8KHRoaXMuZGVwZW5kZW5jeUNvdW50Kyssbi5wdXNoKG0ucHJvbWlzZSkpKX19Y2F0Y2goZSl7dD17ZXJyb3I6ZX19ZmluYWxseXt0cnl7aCYmIWguZG9uZSYmKHI9Zi5yZXR1cm4pJiZyLmNhbGwoZil9ZmluYWxseXtpZih0KXRocm93IHQuZXJyb3J9fXJldHVybiBufSxlLnByb3RvdHlwZS5tYWtlUHJvbWlzZT1mdW5jdGlvbihlKXt2YXIgdD10aGlzLHI9bmV3IFByb21pc2UoKGZ1bmN0aW9uKGUscil7dC5yZXNvbHZlPWUsdC5yZWplY3Q9cn0pKSxuPWMuQ09ORklHW3RoaXMubmFtZV18fHt9O3JldHVybiBuLnJlYWR5JiYocj1yLnRoZW4oKGZ1bmN0aW9uKGUpe3JldHVybiBuLnJlYWR5KHQubmFtZSl9KSkpLGUubGVuZ3RoJiYoZS5wdXNoKHIpLHI9UHJvbWlzZS5hbGwoZSkudGhlbigoZnVuY3Rpb24oZSl7cmV0dXJuIGUuam9pbigiLCAiKX0pKSksbi5mYWlsZWQmJnIuY2F0Y2goKGZ1bmN0aW9uKGUpe3JldHVybiBuLmZhaWxlZChuZXcgcyhlLHQubmFtZSkpfSkpLHJ9LGUucHJvdG90eXBlLmxvYWQ9ZnVuY3Rpb24oKXtpZighdGhpcy5pc0xvYWRlZCYmIXRoaXMuaXNMb2FkaW5nJiYhdGhpcy5ub0xvYWQpe3RoaXMuaXNMb2FkaW5nPSEwO3ZhciB0PWUucmVzb2x2ZVBhdGgodGhpcy5uYW1lKTtjLkNPTkZJRy5yZXF1aXJlP3RoaXMubG9hZEN1c3RvbSh0KTp0aGlzLmxvYWRTY3JpcHQodCl9fSxlLnByb3RvdHlwZS5sb2FkQ3VzdG9tPWZ1bmN0aW9uKGUpe3ZhciB0PXRoaXM7dHJ5e3ZhciByPWMuQ09ORklHLnJlcXVpcmUoZSk7ciBpbnN0YW5jZW9mIFByb21pc2U/ci50aGVuKChmdW5jdGlvbigpe3JldHVybiB0LmNoZWNrTG9hZCgpfSkpLmNhdGNoKChmdW5jdGlvbihyKXtyZXR1cm4gdC5mYWlsZWQoIkNhbid0IGxvYWQgXCIiK2UrJyJcbicrci5tZXNzYWdlLnRyaW0oKSl9KSk6dGhpcy5jaGVja0xvYWQoKX1jYXRjaChlKXt0aGlzLmZhaWxlZChlLm1lc3NhZ2UpfX0sZS5wcm90b3R5cGUubG9hZFNjcmlwdD1mdW5jdGlvbihlKXt2YXIgdD10aGlzLHI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7ci5zcmM9ZSxyLmNoYXJzZXQ9IlVURi04IixyLm9ubG9hZD1mdW5jdGlvbihlKXtyZXR1cm4gdC5jaGVja0xvYWQoKX0sci5vbmVycm9yPWZ1bmN0aW9uKHIpe3JldHVybiB0LmZhaWxlZCgiQ2FuJ3QgbG9hZCBcIiIrZSsnIicpfSxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHIpfSxlLnByb3RvdHlwZS5sb2FkZWQ9ZnVuY3Rpb24oKXt2YXIgZSx0LHIsbjt0aGlzLmlzTG9hZGVkPSEwLHRoaXMuaXNMb2FkaW5nPSExO3RyeXtmb3IodmFyIG89YSh0aGlzLmRlcGVuZGVudHMpLGk9by5uZXh0KCk7IWkuZG9uZTtpPW8ubmV4dCgpKXtpLnZhbHVlLnJlcXVpcmVtZW50U2F0aXNmaWVkKCl9fWNhdGNoKHQpe2U9e2Vycm9yOnR9fWZpbmFsbHl7dHJ5e2kmJiFpLmRvbmUmJih0PW8ucmV0dXJuKSYmdC5jYWxsKG8pfWZpbmFsbHl7aWYoZSl0aHJvdyBlLmVycm9yfX10cnl7Zm9yKHZhciB1PWEodGhpcy5wcm92aWRlZCksYz11Lm5leHQoKTshYy5kb25lO2M9dS5uZXh0KCkpe2MudmFsdWUubG9hZGVkKCl9fWNhdGNoKGUpe3I9e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e2MmJiFjLmRvbmUmJihuPXUucmV0dXJuKSYmbi5jYWxsKHUpfWZpbmFsbHl7aWYocil0aHJvdyByLmVycm9yfX10aGlzLnJlc29sdmUodGhpcy5uYW1lKX0sZS5wcm90b3R5cGUuZmFpbGVkPWZ1bmN0aW9uKGUpe3RoaXMuaGFzRmFpbGVkPSEwLHRoaXMuaXNMb2FkaW5nPSExLHRoaXMucmVqZWN0KG5ldyBzKGUsdGhpcy5uYW1lKSl9LGUucHJvdG90eXBlLmNoZWNrTG9hZD1mdW5jdGlvbigpe3ZhciBlPXRoaXM7KChjLkNPTkZJR1t0aGlzLm5hbWVdfHx7fSkuY2hlY2tSZWFkeXx8ZnVuY3Rpb24oKXtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCl9KSgpLnRoZW4oKGZ1bmN0aW9uKCl7cmV0dXJuIGUubG9hZGVkKCl9KSkuY2F0Y2goKGZ1bmN0aW9uKHQpe3JldHVybiBlLmZhaWxlZCh0KX0pKX0sZS5wcm90b3R5cGUucmVxdWlyZW1lbnRTYXRpc2ZpZWQ9ZnVuY3Rpb24oKXt0aGlzLmRlcGVuZGVuY3lDb3VudCYmKHRoaXMuZGVwZW5kZW5jeUNvdW50LS0sdGhpcy5jYW5Mb2FkJiZ0aGlzLmxvYWQoKSl9LGUucHJvdG90eXBlLnByb3ZpZGVzPWZ1bmN0aW9uKHQpe3ZhciByLG47dm9pZCAwPT09dCYmKHQ9W10pO3RyeXtmb3IodmFyIG89YSh0KSxpPW8ubmV4dCgpOyFpLmRvbmU7aT1vLm5leHQoKSl7dmFyIHU9aS52YWx1ZSxzPWUucGFja2FnZXMuZ2V0KHUpO3N8fChjLkNPTkZJRy5kZXBlbmRlbmNpZXNbdV18fChjLkNPTkZJRy5kZXBlbmRlbmNpZXNbdV09W10pLGMuQ09ORklHLmRlcGVuZGVuY2llc1t1XS5wdXNoKHUpLChzPW5ldyBlKHUsITApKS5pc0xvYWRpbmc9ITApLHRoaXMucHJvdmlkZWQucHVzaChzKX19Y2F0Y2goZSl7cj17ZXJyb3I6ZX19ZmluYWxseXt0cnl7aSYmIWkuZG9uZSYmKG49by5yZXR1cm4pJiZuLmNhbGwobyl9ZmluYWxseXtpZihyKXRocm93IHIuZXJyb3J9fX0sZS5wcm90b3R5cGUuYWRkRGVwZW5kZW50PWZ1bmN0aW9uKGUsdCl7dGhpcy5kZXBlbmRlbnRzLnB1c2goZSksdHx8dGhpcy5jaGVja05vTG9hZCgpfSxlLnByb3RvdHlwZS5jaGVja05vTG9hZD1mdW5jdGlvbigpe3ZhciBlLHQ7aWYodGhpcy5ub0xvYWQpe3RoaXMubm9Mb2FkPSExO3RyeXtmb3IodmFyIHI9YSh0aGlzLmRlcGVuZGVuY2llcyksbj1yLm5leHQoKTshbi5kb25lO249ci5uZXh0KCkpe24udmFsdWUuY2hlY2tOb0xvYWQoKX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7biYmIW4uZG9uZSYmKHQ9ci5yZXR1cm4pJiZ0LmNhbGwocil9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fX19LGUucGFja2FnZXM9bmV3IE1hcCxlfSgpO3QuUGFja2FnZT1sfSwzODg6ZnVuY3Rpb24oZSx0LHIpe3ZhciBuPXRoaXMmJnRoaXMuX19hc3NpZ258fGZ1bmN0aW9uKCl7cmV0dXJuKG49T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0LHI9MSxuPWFyZ3VtZW50cy5sZW5ndGg7cjxuO3IrKylmb3IodmFyIG8gaW4gdD1hcmd1bWVudHNbcl0pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsbykmJihlW29dPXRbb10pO3JldHVybiBlfSkuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxvPXRoaXMmJnRoaXMuX192YWx1ZXN8fGZ1bmN0aW9uKGUpe3ZhciB0PSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5pdGVyYXRvcixyPXQmJmVbdF0sbj0wO2lmKHIpcmV0dXJuIHIuY2FsbChlKTtpZihlJiYibnVtYmVyIj09dHlwZW9mIGUubGVuZ3RoKXJldHVybntuZXh0OmZ1bmN0aW9uKCl7cmV0dXJuIGUmJm4+PWUubGVuZ3RoJiYoZT12b2lkIDApLHt2YWx1ZTplJiZlW24rK10sZG9uZTohZX19fTt0aHJvdyBuZXcgVHlwZUVycm9yKHQ/Ik9iamVjdCBpcyBub3QgaXRlcmFibGUuIjoiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpfSxhPXRoaXMmJnRoaXMuX19yZWFkfHxmdW5jdGlvbihlLHQpe3ZhciByPSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJmVbU3ltYm9sLml0ZXJhdG9yXTtpZighcilyZXR1cm4gZTt2YXIgbixvLGE9ci5jYWxsKGUpLGk9W107dHJ5e2Zvcig7KHZvaWQgMD09PXR8fHQtLSA+MCkmJiEobj1hLm5leHQoKSkuZG9uZTspaS5wdXNoKG4udmFsdWUpfWNhdGNoKGUpe289e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e24mJiFuLmRvbmUmJihyPWEucmV0dXJuKSYmci5jYWxsKGEpfWZpbmFsbHl7aWYobyl0aHJvdyBvLmVycm9yfX1yZXR1cm4gaX0saT10aGlzJiZ0aGlzLl9fc3ByZWFkQXJyYXl8fGZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPTAsbj10Lmxlbmd0aCxvPWUubGVuZ3RoO3I8bjtyKyssbysrKWVbb109dFtyXTtyZXR1cm4gZX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuQ09ORklHPXQuTWF0aEpheD10LlN0YXJ0dXA9dm9pZCAwO3ZhciB1LGM9cig1MTUpLHM9cig2NjYpOyFmdW5jdGlvbihlKXt2YXIgdSxjLGQ9bmV3IHMuUHJpb3JpdGl6ZWRMaXN0O2Z1bmN0aW9uIGYodCl7cmV0dXJuIHUudmlzaXRUcmVlKHQsZS5kb2N1bWVudCl9ZnVuY3Rpb24gaCgpe3U9bmV3IHQuTWF0aEpheC5fLmNvcmUuTW1sVHJlZS5TZXJpYWxpemVkTW1sVmlzaXRvci5TZXJpYWxpemVkTW1sVmlzaXRvcixjPXQuTWF0aEpheC5fLm1hdGhqYXgubWF0aGpheCxlLmlucHV0PWcoKSxlLm91dHB1dD1iKCksZS5hZGFwdG9yPXcoKSxlLmhhbmRsZXImJmMuaGFuZGxlcnMudW5yZWdpc3RlcihlLmhhbmRsZXIpLGUuaGFuZGxlcj1PKCksZS5oYW5kbGVyJiYoYy5oYW5kbGVycy5yZWdpc3RlcihlLmhhbmRsZXIpLGUuZG9jdW1lbnQ9TSgpKX1mdW5jdGlvbiBwKCl7dmFyIHQscjtlLmlucHV0JiZlLm91dHB1dCYmbSgpO3ZhciBuPWUub3V0cHV0P2Uub3V0cHV0Lm5hbWUudG9Mb3dlckNhc2UoKToiIjt0cnl7Zm9yKHZhciBhPW8oZS5pbnB1dCksaT1hLm5leHQoKTshaS5kb25lO2k9YS5uZXh0KCkpe3ZhciB1PWkudmFsdWUsYz11Lm5hbWUudG9Mb3dlckNhc2UoKTt4KGMsdSksdihjLHUpLGUub3V0cHV0JiZ5KGMsbix1KX19Y2F0Y2goZSl7dD17ZXJyb3I6ZX19ZmluYWxseXt0cnl7aSYmIWkuZG9uZSYmKHI9YS5yZXR1cm4pJiZyLmNhbGwoYSl9ZmluYWxseXtpZih0KXRocm93IHQuZXJyb3J9fX1mdW5jdGlvbiBtKCl7dC5NYXRoSmF4LnR5cGVzZXQ9ZnVuY3Rpb24odCl7dm9pZCAwPT09dCYmKHQ9bnVsbCksZS5kb2N1bWVudC5vcHRpb25zLmVsZW1lbnRzPXQsZS5kb2N1bWVudC5yZXNldCgpLGUuZG9jdW1lbnQucmVuZGVyKCl9LHQuTWF0aEpheC50eXBlc2V0UHJvbWlzZT1mdW5jdGlvbih0KXtyZXR1cm4gdm9pZCAwPT09dCYmKHQ9bnVsbCksZS5kb2N1bWVudC5vcHRpb25zLmVsZW1lbnRzPXQsZS5kb2N1bWVudC5yZXNldCgpLGMuaGFuZGxlUmV0cmllc0ZvcigoZnVuY3Rpb24oKXtlLmRvY3VtZW50LnJlbmRlcigpfSkpfSx0Lk1hdGhKYXgudHlwZXNldENsZWFyPWZ1bmN0aW9uKHQpe3ZvaWQgMD09PXQmJih0PW51bGwpLHQ/ZS5kb2N1bWVudC5jbGVhck1hdGhJdGVtc1dpdGhpbih0KTplLmRvY3VtZW50LmNsZWFyKCl9fWZ1bmN0aW9uIHkocixuLG8pe3ZhciBhPXIrIjIiK247dC5NYXRoSmF4W2FdPWZ1bmN0aW9uKHQscil7cmV0dXJuIHZvaWQgMD09PXImJihyPXt9KSxyLmZvcm1hdD1vLm5hbWUsZS5kb2N1bWVudC5jb252ZXJ0KHQscil9LHQuTWF0aEpheFthKyJQcm9taXNlIl09ZnVuY3Rpb24odCxyKXtyZXR1cm4gdm9pZCAwPT09ciYmKHI9e30pLHIuZm9ybWF0PW8ubmFtZSxjLmhhbmRsZVJldHJpZXNGb3IoKGZ1bmN0aW9uKCl7cmV0dXJuIGUuZG9jdW1lbnQuY29udmVydCh0LHIpfSkpfSx0Lk1hdGhKYXhbbisiU3R5bGVzaGVldCJdPWZ1bmN0aW9uKCl7cmV0dXJuIGUub3V0cHV0LnN0eWxlU2hlZXQoZS5kb2N1bWVudCl9LCJnZXRNZXRyaWNzRm9yImluIGUub3V0cHV0JiYodC5NYXRoSmF4LmdldE1ldHJpY3NGb3I9ZnVuY3Rpb24odCxyKXtyZXR1cm4gZS5vdXRwdXQuZ2V0TWV0cmljc0Zvcih0LHIpfSl9ZnVuY3Rpb24geChyLG4pe3ZhciBvPXQuTWF0aEpheC5fLmNvcmUuTWF0aEl0ZW0uU1RBVEU7dC5NYXRoSmF4W3IrIjJtbWwiXT1mdW5jdGlvbih0LHIpe3JldHVybiB2b2lkIDA9PT1yJiYocj17fSksci5lbmQ9by5DT05WRVJULHIuZm9ybWF0PW4ubmFtZSxmKGUuZG9jdW1lbnQuY29udmVydCh0LHIpKX0sdC5NYXRoSmF4W3IrIjJtbWxQcm9taXNlIl09ZnVuY3Rpb24odCxyKXtyZXR1cm4gdm9pZCAwPT09ciYmKHI9e30pLHIuZW5kPW8uQ09OVkVSVCxyLmZvcm1hdD1uLm5hbWUsYy5oYW5kbGVSZXRyaWVzRm9yKChmdW5jdGlvbigpe3JldHVybiBmKGUuZG9jdW1lbnQuY29udmVydCh0LHIpKX0pKX19ZnVuY3Rpb24gdihlLHIpe3QuTWF0aEpheFtlKyJSZXNldCJdPWZ1bmN0aW9uKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3JldHVybiByLnJlc2V0LmFwcGx5KHIsaShbXSxhKGUpKSl9fWZ1bmN0aW9uIGcoKXt2YXIgcixuLGE9W107dHJ5e2Zvcih2YXIgaT1vKHQuQ09ORklHLmlucHV0KSx1PWkubmV4dCgpOyF1LmRvbmU7dT1pLm5leHQoKSl7dmFyIGM9dS52YWx1ZSxzPWUuY29uc3RydWN0b3JzW2NdO2lmKCFzKXRocm93IEVycm9yKCdJbnB1dCBKYXggIicrYysnIiBpcyBub3QgZGVmaW5lZCAoaGFzIGl0IGJlZW4gbG9hZGVkPyknKTthLnB1c2gobmV3IHModC5NYXRoSmF4LmNvbmZpZ1tjXSkpfX1jYXRjaChlKXtyPXtlcnJvcjplfX1maW5hbGx5e3RyeXt1JiYhdS5kb25lJiYobj1pLnJldHVybikmJm4uY2FsbChpKX1maW5hbGx5e2lmKHIpdGhyb3cgci5lcnJvcn19cmV0dXJuIGF9ZnVuY3Rpb24gYigpe3ZhciByPXQuQ09ORklHLm91dHB1dDtpZighcilyZXR1cm4gbnVsbDt2YXIgbj1lLmNvbnN0cnVjdG9yc1tyXTtpZighbil0aHJvdyBFcnJvcignT3V0cHV0IEpheCAiJytyKyciIGlzIG5vdCBkZWZpbmVkIChoYXMgaXQgYmVlbiBsb2FkZWQ/KScpO3JldHVybiBuZXcgbih0Lk1hdGhKYXguY29uZmlnW3JdKX1mdW5jdGlvbiB3KCl7dmFyIHI9dC5DT05GSUcuYWRhcHRvcjtpZighcnx8Im5vbmUiPT09cilyZXR1cm4gbnVsbDt2YXIgbj1lLmNvbnN0cnVjdG9yc1tyXTtpZighbil0aHJvdyBFcnJvcignRE9NQWRhcHRvciAiJytyKyciIGlzIG5vdCBkZWZpbmVkIChoYXMgaXQgYmVlbiBsb2FkZWQ/KScpO3JldHVybiBuKHQuTWF0aEpheC5jb25maWdbcl0pfWZ1bmN0aW9uIE8oKXt2YXIgcixuLGE9dC5DT05GSUcuaGFuZGxlcjtpZighYXx8Im5vbmUiPT09YXx8IWUuYWRhcHRvcilyZXR1cm4gbnVsbDt2YXIgaT1lLmNvbnN0cnVjdG9yc1thXTtpZighaSl0aHJvdyBFcnJvcignSGFuZGxlciAiJythKyciIGlzIG5vdCBkZWZpbmVkIChoYXMgaXQgYmVlbiBsb2FkZWQ/KScpO3ZhciB1PW5ldyBpKGUuYWRhcHRvciw1KTt0cnl7Zm9yKHZhciBjPW8oZCkscz1jLm5leHQoKTshcy5kb25lO3M9Yy5uZXh0KCkpe3U9cy52YWx1ZS5pdGVtKHUpfX1jYXRjaChlKXtyPXtlcnJvcjplfX1maW5hbGx5e3RyeXtzJiYhcy5kb25lJiYobj1jLnJldHVybikmJm4uY2FsbChjKX1maW5hbGx5e2lmKHIpdGhyb3cgci5lcnJvcn19cmV0dXJuIHV9ZnVuY3Rpb24gTShyKXtyZXR1cm4gdm9pZCAwPT09ciYmKHI9bnVsbCksYy5kb2N1bWVudChyfHx0LkNPTkZJRy5kb2N1bWVudCxuKG4oe30sdC5NYXRoSmF4LmNvbmZpZy5vcHRpb25zKSx7SW5wdXRKYXg6ZS5pbnB1dCxPdXRwdXRKYXg6ZS5vdXRwdXR9KSl9ZS5jb25zdHJ1Y3RvcnM9e30sZS5pbnB1dD1bXSxlLm91dHB1dD1udWxsLGUuaGFuZGxlcj1udWxsLGUuYWRhcHRvcj1udWxsLGUuZWxlbWVudHM9bnVsbCxlLmRvY3VtZW50PW51bGwsZS5wcm9taXNlPW5ldyBQcm9taXNlKChmdW5jdGlvbih0LHIpe2UucHJvbWlzZVJlc29sdmU9dCxlLnByb21pc2VSZWplY3Q9cn0pKSxlLnBhZ2VQcm9taXNlPW5ldyBQcm9taXNlKChmdW5jdGlvbihlLHQpe3ZhciBuPXIuZy5kb2N1bWVudDtpZihuJiZuLnJlYWR5U3RhdGUmJiJjb21wbGV0ZSIhPT1uLnJlYWR5U3RhdGUmJiJpbnRlcmFjdGl2ZSIhPT1uLnJlYWR5U3RhdGUpe3ZhciBvPWZ1bmN0aW9uKCl7cmV0dXJuIGUoKX07bi5kZWZhdWx0Vmlldy5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixvLCEwKSxuLmRlZmF1bHRWaWV3LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLG8sITApfWVsc2UgZSgpfSkpLGUudG9NTUw9ZixlLnJlZ2lzdGVyQ29uc3RydWN0b3I9ZnVuY3Rpb24odCxyKXtlLmNvbnN0cnVjdG9yc1t0XT1yfSxlLnVzZUhhbmRsZXI9ZnVuY3Rpb24oZSxyKXt2b2lkIDA9PT1yJiYocj0hMSksdC5DT05GSUcuaGFuZGxlciYmIXJ8fCh0LkNPTkZJRy5oYW5kbGVyPWUpfSxlLnVzZUFkYXB0b3I9ZnVuY3Rpb24oZSxyKXt2b2lkIDA9PT1yJiYocj0hMSksdC5DT05GSUcuYWRhcHRvciYmIXJ8fCh0LkNPTkZJRy5hZGFwdG9yPWUpfSxlLnVzZUlucHV0PWZ1bmN0aW9uKGUscil7dm9pZCAwPT09ciYmKHI9ITEpLGwmJiFyfHx0LkNPTkZJRy5pbnB1dC5wdXNoKGUpfSxlLnVzZU91dHB1dD1mdW5jdGlvbihlLHIpe3ZvaWQgMD09PXImJihyPSExKSx0LkNPTkZJRy5vdXRwdXQmJiFyfHwodC5DT05GSUcub3V0cHV0PWUpfSxlLmV4dGVuZEhhbmRsZXI9ZnVuY3Rpb24oZSx0KXt2b2lkIDA9PT10JiYodD0xMCksZC5hZGQoZSx0KX0sZS5kZWZhdWx0UmVhZHk9ZnVuY3Rpb24oKXtoKCkscCgpLGUucGFnZVByb21pc2UudGhlbigoZnVuY3Rpb24oKXtyZXR1cm4gdC5DT05GSUcucGFnZVJlYWR5KCl9KSkudGhlbigoZnVuY3Rpb24oKXtyZXR1cm4gZS5wcm9taXNlUmVzb2x2ZSgpfSkpLmNhdGNoKChmdW5jdGlvbih0KXtyZXR1cm4gZS5wcm9taXNlUmVqZWN0KHQpfSkpfSxlLmRlZmF1bHRQYWdlUmVhZHk9ZnVuY3Rpb24oKXtyZXR1cm4gdC5DT05GSUcudHlwZXNldCYmdC5NYXRoSmF4LnR5cGVzZXRQcm9taXNlP3QuTWF0aEpheC50eXBlc2V0UHJvbWlzZSh0LkNPTkZJRy5lbGVtZW50cyk6UHJvbWlzZS5yZXNvbHZlKCl9LGUuZ2V0Q29tcG9uZW50cz1oLGUubWFrZU1ldGhvZHM9cCxlLm1ha2VUeXBlc2V0TWV0aG9kcz1tLGUubWFrZU91dHB1dE1ldGhvZHM9eSxlLm1ha2VNbWxNZXRob2RzPXgsZS5tYWtlUmVzZXRNZXRob2Q9dixlLmdldElucHV0SmF4PWcsZS5nZXRPdXRwdXRKYXg9YixlLmdldEFkYXB0b3I9dyxlLmdldEhhbmRsZXI9TyxlLmdldERvY3VtZW50PU19KHU9dC5TdGFydHVwfHwodC5TdGFydHVwPXt9KSksdC5NYXRoSmF4PWMuTWF0aEpheCx2b2lkIDA9PT10Lk1hdGhKYXguXy5zdGFydHVwJiYoYy5jb21iaW5lRGVmYXVsdHModC5NYXRoSmF4LmNvbmZpZywic3RhcnR1cCIse2lucHV0OltdLG91dHB1dDoiIixoYW5kbGVyOm51bGwsYWRhcHRvcjpudWxsLGRvY3VtZW50OiJ1bmRlZmluZWQiPT10eXBlb2YgZG9jdW1lbnQ/IiI6ZG9jdW1lbnQsZWxlbWVudHM6bnVsbCx0eXBlc2V0OiEwLHJlYWR5OnUuZGVmYXVsdFJlYWR5LmJpbmQodSkscGFnZVJlYWR5OnUuZGVmYXVsdFBhZ2VSZWFkeS5iaW5kKHUpfSksYy5jb21iaW5lV2l0aE1hdGhKYXgoe3N0YXJ0dXA6dSxvcHRpb25zOnt9fSkpLHQuQ09ORklHPXQuTWF0aEpheC5jb25maWcuc3RhcnR1cDt2YXIgbD0wIT09dC5DT05GSUcuaW5wdXQubGVuZ3RofSw1MjU6ZnVuY3Rpb24oZSx0LHIpe3ZhciBuLG89dGhpcyYmdGhpcy5fX2V4dGVuZHN8fChuPWZ1bmN0aW9uKGUsdCl7cmV0dXJuKG49T2JqZWN0LnNldFByb3RvdHlwZU9mfHx7X19wcm90b19fOltdfWluc3RhbmNlb2YgQXJyYXkmJmZ1bmN0aW9uKGUsdCl7ZS5fX3Byb3RvX189dH18fGZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByIGluIHQpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQscikmJihlW3JdPXRbcl0pfSkoZSx0KX0sZnVuY3Rpb24oZSx0KXtpZigiZnVuY3Rpb24iIT10eXBlb2YgdCYmbnVsbCE9PXQpdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSAiK1N0cmluZyh0KSsiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGwiKTtmdW5jdGlvbiByKCl7dGhpcy5jb25zdHJ1Y3Rvcj1lfW4oZSx0KSxlLnByb3RvdHlwZT1udWxsPT09dD9PYmplY3QuY3JlYXRlKHQpOihyLnByb3RvdHlwZT10LnByb3RvdHlwZSxuZXcgcil9KSxhPXRoaXMmJnRoaXMuX192YWx1ZXN8fGZ1bmN0aW9uKGUpe3ZhciB0PSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5pdGVyYXRvcixyPXQmJmVbdF0sbj0wO2lmKHIpcmV0dXJuIHIuY2FsbChlKTtpZihlJiYibnVtYmVyIj09dHlwZW9mIGUubGVuZ3RoKXJldHVybntuZXh0OmZ1bmN0aW9uKCl7cmV0dXJuIGUmJm4+PWUubGVuZ3RoJiYoZT12b2lkIDApLHt2YWx1ZTplJiZlW24rK10sZG9uZTohZX19fTt0aHJvdyBuZXcgVHlwZUVycm9yKHQ/Ik9iamVjdCBpcyBub3QgaXRlcmFibGUuIjoiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpfSxpPXRoaXMmJnRoaXMuX19yZWFkfHxmdW5jdGlvbihlLHQpe3ZhciByPSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJmVbU3ltYm9sLml0ZXJhdG9yXTtpZighcilyZXR1cm4gZTt2YXIgbixvLGE9ci5jYWxsKGUpLGk9W107dHJ5e2Zvcig7KHZvaWQgMD09PXR8fHQtLSA+MCkmJiEobj1hLm5leHQoKSkuZG9uZTspaS5wdXNoKG4udmFsdWUpfWNhdGNoKGUpe289e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e24mJiFuLmRvbmUmJihyPWEucmV0dXJuKSYmci5jYWxsKGEpfWZpbmFsbHl7aWYobyl0aHJvdyBvLmVycm9yfX1yZXR1cm4gaX0sdT10aGlzJiZ0aGlzLl9fc3ByZWFkQXJyYXl8fGZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPTAsbj10Lmxlbmd0aCxvPWUubGVuZ3RoO3I8bjtyKyssbysrKWVbb109dFtyXTtyZXR1cm4gZX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuRnVuY3Rpb25MaXN0PXZvaWQgMDt2YXIgYz1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KCl7cmV0dXJuIG51bGwhPT1lJiZlLmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpc31yZXR1cm4gbyh0LGUpLHQucHJvdG90eXBlLmV4ZWN1dGU9ZnVuY3Rpb24oKXtmb3IodmFyIGUsdCxyPVtdLG49MDtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXJbbl09YXJndW1lbnRzW25dO3RyeXtmb3IodmFyIG89YSh0aGlzKSxjPW8ubmV4dCgpOyFjLmRvbmU7Yz1vLm5leHQoKSl7dmFyIHM9Yy52YWx1ZSxsPXMuaXRlbS5hcHBseShzLHUoW10saShyKSkpO2lmKCExPT09bClyZXR1cm4hMX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7YyYmIWMuZG9uZSYmKHQ9by5yZXR1cm4pJiZ0LmNhbGwobyl9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fXJldHVybiEwfSx0LnByb3RvdHlwZS5hc3luY0V4ZWN1dGU9ZnVuY3Rpb24oKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9LTEsbj10aGlzLml0ZW1zO3JldHVybiBuZXcgUHJvbWlzZSgoZnVuY3Rpb24odCxvKXshZnVuY3Rpb24gYSgpe2Zvcih2YXIgYzsrK3I8bi5sZW5ndGg7KXt2YXIgcz0oYz1uW3JdKS5pdGVtLmFwcGx5KGMsdShbXSxpKGUpKSk7aWYocyBpbnN0YW5jZW9mIFByb21pc2UpcmV0dXJuIHZvaWQgcy50aGVuKGEpLmNhdGNoKChmdW5jdGlvbihlKXtyZXR1cm4gbyhlKX0pKTtpZighMT09PXMpcmV0dXJuIHZvaWQgdCghMSl9dCghMCl9KCl9KSl9LHR9KHIoNjY2KS5Qcmlvcml0aXplZExpc3QpO3QuRnVuY3Rpb25MaXN0PWN9LDY2NjpmdW5jdGlvbihlLHQpe09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KSx0LlByaW9yaXRpemVkTGlzdD12b2lkIDA7dmFyIHI9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKCl7dGhpcy5pdGVtcz1bXSx0aGlzLml0ZW1zPVtdfXJldHVybiBlLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdPWZ1bmN0aW9uKCl7dmFyIGU9MCx0PXRoaXMuaXRlbXM7cmV0dXJue25leHQ6ZnVuY3Rpb24oKXtyZXR1cm57dmFsdWU6dFtlKytdLGRvbmU6ZT50Lmxlbmd0aH19fX0sZS5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQscil7dm9pZCAwPT09ciYmKHI9ZS5ERUZBVUxUUFJJT1JJVFkpO3ZhciBuPXRoaXMuaXRlbXMubGVuZ3RoO2Rve24tLX13aGlsZShuPj0wJiZyPHRoaXMuaXRlbXNbbl0ucHJpb3JpdHkpO3JldHVybiB0aGlzLml0ZW1zLnNwbGljZShuKzEsMCx7aXRlbTp0LHByaW9yaXR5OnJ9KSx0fSxlLnByb3RvdHlwZS5yZW1vdmU9ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5pdGVtcy5sZW5ndGg7ZG97dC0tfXdoaWxlKHQ+PTAmJnRoaXMuaXRlbXNbdF0uaXRlbSE9PWUpO3Q+PTAmJnRoaXMuaXRlbXMuc3BsaWNlKHQsMSl9LGUucHJvdG90eXBlLnRvQXJyYXk9ZnVuY3Rpb24oKXtyZXR1cm4gQXJyYXkuZnJvbSh0aGlzKX0sZS5ERUZBVUxUUFJJT1JJVFk9NSxlfSgpO3QuUHJpb3JpdGl6ZWRMaXN0PXJ9fSx0PXt9O2Z1bmN0aW9uIHIobil7dmFyIG89dFtuXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGE9dFtuXT17ZXhwb3J0czp7fX07cmV0dXJuIGVbbl0uY2FsbChhLmV4cG9ydHMsYSxhLmV4cG9ydHMsciksYS5leHBvcnRzfXIuZz1mdW5jdGlvbigpe2lmKCJvYmplY3QiPT10eXBlb2YgZ2xvYmFsVGhpcylyZXR1cm4gZ2xvYmFsVGhpczt0cnl7cmV0dXJuIHRoaXN8fG5ldyBGdW5jdGlvbigicmV0dXJuIHRoaXMiKSgpfWNhdGNoKGUpe2lmKCJvYmplY3QiPT10eXBlb2Ygd2luZG93KXJldHVybiB3aW5kb3d9fSgpLGZ1bmN0aW9uKCl7dmFyIGU9cig1MTUpLHQ9cigyMzUpLG49cigyNjUpLG89cigzODgpOygwLGUuY29tYmluZVdpdGhNYXRoSmF4KSh7Xzp7Y29tcG9uZW50czp7bG9hZGVyOnQscGFja2FnZTpuLHN0YXJ0dXA6b319fSk7dmFyIGEsaT17dGV4OiJbbWF0aGpheF0vaW5wdXQvdGV4L2V4dGVuc2lvbnMiLHNyZToiW21hdGhqYXhdL3NyZS8iKygidW5kZWZpbmVkIj09dHlwZW9mIHdpbmRvdz8ic3JlLW5vZGUiOiJzcmVfYnJvd3NlciIpfSx1PVsiW3RleF0vYWN0aW9uIiwiW3RleF0vYW1zIiwiW3RleF0vYW1zY2QiLCJbdGV4XS9iYm94IiwiW3RleF0vYm9sZHN5bWJvbCIsIlt0ZXhdL2JyYWtldCIsIlt0ZXhdL2J1c3Nwcm9vZnMiLCJbdGV4XS9jYW5jZWwiLCJbdGV4XS9jb2xvciIsIlt0ZXhdL2NvbmZpZ21hY3JvcyIsIlt0ZXhdL2VuY2xvc2UiLCJbdGV4XS9leHRwZmVpbCIsIlt0ZXhdL2h0bWwiLCJbdGV4XS9taGNoZW0iLCJbdGV4XS9uZXdjb21tYW5kIiwiW3RleF0vbm9lcnJvcnMiLCJbdGV4XS9ub3VuZGVmaW5lZCIsIlt0ZXhdL3BoeXNpY3MiLCJbdGV4XS9yZXF1aXJlIiwiW3RleF0vdGFnZm9ybWF0IiwiW3RleF0vdGV4dG1hY3JvcyIsIlt0ZXhdL3VuaWNvZGUiLCJbdGV4XS92ZXJiIl0sYz17c3RhcnR1cDpbImxvYWRlciJdLCJpbnB1dC90ZXgiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9hbXMiLCJbdGV4XS9uZXdjb21tYW5kIiwiW3RleF0vbm91bmRlZmluZWQiLCJbdGV4XS9yZXF1aXJlIiwiW3RleF0vYXV0b2xvYWQiLCJbdGV4XS9jb25maWdtYWNyb3MiXSwiaW5wdXQvdGV4LWZ1bGwiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9hbGwtcGFja2FnZXMiXS5jb25jYXQodSksIlt0ZXhdL2FsbC1wYWNrYWdlcyI6dX07ZnVuY3Rpb24gcyhlLHQpeyhudWxsPT10fHx0PmUubGVuZ3RoKSYmKHQ9ZS5sZW5ndGgpO2Zvcih2YXIgcj0wLG49bmV3IEFycmF5KHQpO3I8dDtyKyspbltyXT1lW3JdO3JldHVybiBufSgwLGUuY29tYmluZURlZmF1bHRzKShNYXRoSmF4LmNvbmZpZy5sb2FkZXIsImRlcGVuZGVuY2llcyIseyJhMTF5L3NlbWFudGljLWVucmljaCI6WyJpbnB1dC9tbWwiLCJbc3JlXSJdLCJhMTF5L2NvbXBsZXhpdHkiOlsiYTExeS9zZW1hbnRpYy1lbnJpY2giXSwiYTExeS9leHBsb3JlciI6WyJhMTF5L3NlbWFudGljLWVucmljaCIsInVpL21lbnUiXSwiW3RleF0vYWxsLXBhY2thZ2VzIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL2FjdGlvbiI6WyJpbnB1dC90ZXgtYmFzZSIsIlt0ZXhdL25ld2NvbW1hbmQiXSwiW3RleF0vYXV0b2xvYWQiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9yZXF1aXJlIl0sIlt0ZXhdL2FtcyI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9hbXNjZCI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9iYm94IjpbImlucHV0L3RleC1iYXNlIiwiW3RleF0vYW1zIiwiW3RleF0vbmV3Y29tbWFuZCJdLCJbdGV4XS9ib2xkc3ltYm9sIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL2JyYWtldCI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9idXNzcHJvb2ZzIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL2NhbmNlbCI6WyJpbnB1dC90ZXgtYmFzZSIsIlt0ZXhdL2VuY2xvc2UiXSwiW3RleF0vY29sb3IiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vY29sb3J2MiI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9jb25maWdtYWNyb3MiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9uZXdjb21tYW5kIl0sIlt0ZXhdL2VuY2xvc2UiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vZXh0cGZlaWwiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9uZXdjb21tYW5kIiwiW3RleF0vYW1zIl0sIlt0ZXhdL2h0bWwiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vbWhjaGVtIjpbImlucHV0L3RleC1iYXNlIiwiW3RleF0vYW1zIl0sIlt0ZXhdL25ld2NvbW1hbmQiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vbm9lcnJvcnMiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vbm91bmRlZmluZWQiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vcGh5c2ljcyI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9yZXF1aXJlIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL3RhZ2Zvcm1hdCI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS90ZXh0bWFjcm9zIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL3VuaWNvZGUiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vdmVyYiI6WyJpbnB1dC90ZXgtYmFzZSJdfSksKDAsZS5jb21iaW5lRGVmYXVsdHMpKE1hdGhKYXguY29uZmlnLmxvYWRlciwicGF0aHMiLGkpLCgwLGUuY29tYmluZURlZmF1bHRzKShNYXRoSmF4LmNvbmZpZy5sb2FkZXIsInByb3ZpZGVzIixjKSwoMCxlLmNvbWJpbmVEZWZhdWx0cykoTWF0aEpheC5jb25maWcubG9hZGVyLCJzb3VyY2UiLHsiW3RleF0vYW1zQ2QiOiJbdGV4XS9hbXNjZCIsIlt0ZXhdL2NvbG9yVjIiOiJbdGV4XS9jb2xvcnYyIiwiW3RleF0vY29uZmlnTWFjcm9zIjoiW3RleF0vY29uZmlnbWFjcm9zIiwiW3RleF0vdGFnRm9ybWF0IjoiW3RleF0vdGFnZm9ybWF0In0pLHQuTG9hZGVyLnByZUxvYWQoImxvYWRlciIpLHQuTG9hZGVyLmxvYWQuYXBwbHkodC5Mb2FkZXIsKGE9dC5DT05GSUcubG9hZCxmdW5jdGlvbihlKXtpZihBcnJheS5pc0FycmF5KGUpKXJldHVybiBzKGUpfShhKXx8ZnVuY3Rpb24oZSl7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBTeW1ib2wmJm51bGwhPWVbU3ltYm9sLml0ZXJhdG9yXXx8bnVsbCE9ZVsiQEBpdGVyYXRvciJdKXJldHVybiBBcnJheS5mcm9tKGUpfShhKXx8ZnVuY3Rpb24oZSx0KXtpZihlKXtpZigic3RyaW5nIj09dHlwZW9mIGUpcmV0dXJuIHMoZSx0KTt2YXIgcj1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZSkuc2xpY2UoOCwtMSk7cmV0dXJuIk9iamVjdCI9PT1yJiZlLmNvbnN0cnVjdG9yJiYocj1lLmNvbnN0cnVjdG9yLm5hbWUpLCJNYXAiPT09cnx8IlNldCI9PT1yP0FycmF5LmZyb20oZSk6IkFyZ3VtZW50cyI9PT1yfHwvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChyKT9zKGUsdCk6dm9pZCAwfX0oYSl8fGZ1bmN0aW9uKCl7dGhyb3cgbmV3IFR5cGVFcnJvcigiSW52YWxpZCBhdHRlbXB0IHRvIHNwcmVhZCBub24taXRlcmFibGUgaW5zdGFuY2UuXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuIil9KCkpKS50aGVuKChmdW5jdGlvbigpe3JldHVybiB0LkNPTkZJRy5yZWFkeSgpfSkpLmNhdGNoKChmdW5jdGlvbihlKXtyZXR1cm4gdC5DT05GSUcuZmFpbGVkKGUpfSkpfSgpfSgpOw=="></script><!--URL:../assets/vendor/mathjax/startup.js-->
|
|
</body>
|
|
</html><!--Generated by HTMLArk 2026-04-20 17:38:00.466093. Original URL site/print_page/index.html--> |