Wikipedia testwiki https://test.wikipedia.org/wiki/Main_Page MediaWiki 1.47.0-wmf.13 first-letter Media Special Talk User User talk Wikipedia Wikipedia talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Thread Thread talk Summary Summary talk Test namespace 1 Test namespace 1 talk Test namespace 2 Test namespace 2 talk Draft Draft talk Campaign Campaign talk TimedText TimedText talk Module Module talk SecurePoll SecurePoll talk CNBanner CNBanner talk Translations Translations talk Event Event talk Topic Newsletter Newsletter talk Wikipedia:Test 4 71460 754618 754502 2026-08-01T22:20:12Z ~2026-42828-85 75114 754618 wikitext text/x-wiki = Test = 801 Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24. 2:6 - 7:12, 157 days, (7:13+ to fill out). *7:13, 7:14, 7:15 (?) *7:16, 7:17, 7:18, 7:19, 7:20 (?) *7:21, 7:22, 7:23, 7:24, 7:25 (?) *7:26 (?) *7:27 (?) *7:28 (?) *7:29 (7:30) ''7:31'' *202 6525, Pot with Fork and Spoon, Bags with Sunglasses. *202 6526, Baskets, Tobacco Stuff or Socks. *202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others. *202 6528, Socks, Pairs of Shoes, Dressing Gowns. *202 6529, Towels, Cubes with Things. *202 6530, Cloths, Flowers Frisun or Soap. *202 6531, Food Shopping like Party Pies, Waters and Others. *202 6601, Pairs of Boots, Pillow or Podiatrist. *202 6602, Plates or Pans, Grated Cheese or Baskets. *202 6603, Forks, Pans and Other Kitchen Tools. *202 6604, Cups, Cordial Jug or Strawberry Milk. *202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce. *202 6606, Purses, Lu Papers or Paper Towels. *202 6607, Candles, Statues or Pizza Boxes. *202 6608, Cups, Blankets and Others. *202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans. *202 6610, Towels, Cloths, Soap or Containers. *202 6611, Nachos, Apple N Raspberry Codrial or Stationary. *202 6612, Basket, Electric Bed with Instructions or Paint. *202 6613, Aerobar, Birthday Cake or Packet of Candles. *202 6614, Plates, Blankets or even Vacuum Cleaner. *202 6615, Towels, Cloths or Dressing Gowns. *202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths. *202 6617, Pans, Table Spoons or Lids. *202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others. *202 6619, Chocolate Milk, Cups of Tea or Extra Mints. *202 6620, Kitkats, Pens or Domino's Pizza. *202 6621, Blankets and Pillows or Vacuum Cleaner. *202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught. *202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas. *202 6624, Staples, Socks, Hats and Others. *202 6625, Kitchen Bowls, Pans and Others. *202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop. *202 6627, Tablemats, Sunglasses or Garden Plant. *202 6628, Boots, Sleep Medicine or Pillow. *202 6629, Sewing Machine, Tobacco Stuff or Pan. *202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms. *202 6701, BBQ Chips, Biskits or Grated Cheese. *202 6702, Lighters, Plates or Cloths. *202 6703, Hot Dogs, Cola Cans or Lasagna. *202 6704, Mop, Battery Packs or Doorhandle. *202 6705, Video Cameras, Internet or McDonalds Bag?. *202 6706, Pans, Freshmint, or Hotdog Roll. *202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese. *202 6708, Ktimes, Nutrigrain or Mueslibars. *202 6709, Saladas, Socks, Vegemite or Textures. *202 6710, Baskets, Favourites or Cordial Jug. Current, 202 6711. ($#!+). *202 6712. (ALDI Stores, Australia, Worldwide). ''2026713'' 4a2f7xghnqmxwrbblnnu2688yvmsqmf 754620 754618 2026-08-01T22:20:29Z ~2026-42828-85 75114 754620 wikitext text/x-wiki = Test = 801 - Size Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24. 2:6 - 7:12, 157 days, (7:13+ to fill out). *7:13, 7:14, 7:15 (?) *7:16, 7:17, 7:18, 7:19, 7:20 (?) *7:21, 7:22, 7:23, 7:24, 7:25 (?) *7:26 (?) *7:27 (?) *7:28 (?) *7:29 (7:30) ''7:31'' *202 6525, Pot with Fork and Spoon, Bags with Sunglasses. *202 6526, Baskets, Tobacco Stuff or Socks. *202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others. *202 6528, Socks, Pairs of Shoes, Dressing Gowns. *202 6529, Towels, Cubes with Things. *202 6530, Cloths, Flowers Frisun or Soap. *202 6531, Food Shopping like Party Pies, Waters and Others. *202 6601, Pairs of Boots, Pillow or Podiatrist. *202 6602, Plates or Pans, Grated Cheese or Baskets. *202 6603, Forks, Pans and Other Kitchen Tools. *202 6604, Cups, Cordial Jug or Strawberry Milk. *202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce. *202 6606, Purses, Lu Papers or Paper Towels. *202 6607, Candles, Statues or Pizza Boxes. *202 6608, Cups, Blankets and Others. *202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans. *202 6610, Towels, Cloths, Soap or Containers. *202 6611, Nachos, Apple N Raspberry Codrial or Stationary. *202 6612, Basket, Electric Bed with Instructions or Paint. *202 6613, Aerobar, Birthday Cake or Packet of Candles. *202 6614, Plates, Blankets or even Vacuum Cleaner. *202 6615, Towels, Cloths or Dressing Gowns. *202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths. *202 6617, Pans, Table Spoons or Lids. *202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others. *202 6619, Chocolate Milk, Cups of Tea or Extra Mints. *202 6620, Kitkats, Pens or Domino's Pizza. *202 6621, Blankets and Pillows or Vacuum Cleaner. *202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught. *202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas. *202 6624, Staples, Socks, Hats and Others. *202 6625, Kitchen Bowls, Pans and Others. *202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop. *202 6627, Tablemats, Sunglasses or Garden Plant. *202 6628, Boots, Sleep Medicine or Pillow. *202 6629, Sewing Machine, Tobacco Stuff or Pan. *202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms. *202 6701, BBQ Chips, Biskits or Grated Cheese. *202 6702, Lighters, Plates or Cloths. *202 6703, Hot Dogs, Cola Cans or Lasagna. *202 6704, Mop, Battery Packs or Doorhandle. *202 6705, Video Cameras, Internet or McDonalds Bag?. *202 6706, Pans, Freshmint, or Hotdog Roll. *202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese. *202 6708, Ktimes, Nutrigrain or Mueslibars. *202 6709, Saladas, Socks, Vegemite or Textures. *202 6710, Baskets, Favourites or Cordial Jug. Current, 202 6711. ($#!+). *202 6712. (ALDI Stores, Australia, Worldwide). ''2026713'' mq78h198oo5bpg5iiukuh3r23u8zpfd 754621 754620 2026-08-01T22:20:44Z ~2026-42828-85 75114 754621 wikitext text/x-wiki = Test = 801 - Board Sizes Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24. 2:6 - 7:12, 157 days, (7:13+ to fill out). *7:13, 7:14, 7:15 (?) *7:16, 7:17, 7:18, 7:19, 7:20 (?) *7:21, 7:22, 7:23, 7:24, 7:25 (?) *7:26 (?) *7:27 (?) *7:28 (?) *7:29 (7:30) ''7:31'' *202 6525, Pot with Fork and Spoon, Bags with Sunglasses. *202 6526, Baskets, Tobacco Stuff or Socks. *202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others. *202 6528, Socks, Pairs of Shoes, Dressing Gowns. *202 6529, Towels, Cubes with Things. *202 6530, Cloths, Flowers Frisun or Soap. *202 6531, Food Shopping like Party Pies, Waters and Others. *202 6601, Pairs of Boots, Pillow or Podiatrist. *202 6602, Plates or Pans, Grated Cheese or Baskets. *202 6603, Forks, Pans and Other Kitchen Tools. *202 6604, Cups, Cordial Jug or Strawberry Milk. *202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce. *202 6606, Purses, Lu Papers or Paper Towels. *202 6607, Candles, Statues or Pizza Boxes. *202 6608, Cups, Blankets and Others. *202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans. *202 6610, Towels, Cloths, Soap or Containers. *202 6611, Nachos, Apple N Raspberry Codrial or Stationary. *202 6612, Basket, Electric Bed with Instructions or Paint. *202 6613, Aerobar, Birthday Cake or Packet of Candles. *202 6614, Plates, Blankets or even Vacuum Cleaner. *202 6615, Towels, Cloths or Dressing Gowns. *202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths. *202 6617, Pans, Table Spoons or Lids. *202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others. *202 6619, Chocolate Milk, Cups of Tea or Extra Mints. *202 6620, Kitkats, Pens or Domino's Pizza. *202 6621, Blankets and Pillows or Vacuum Cleaner. *202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught. *202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas. *202 6624, Staples, Socks, Hats and Others. *202 6625, Kitchen Bowls, Pans and Others. *202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop. *202 6627, Tablemats, Sunglasses or Garden Plant. *202 6628, Boots, Sleep Medicine or Pillow. *202 6629, Sewing Machine, Tobacco Stuff or Pan. *202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms. *202 6701, BBQ Chips, Biskits or Grated Cheese. *202 6702, Lighters, Plates or Cloths. *202 6703, Hot Dogs, Cola Cans or Lasagna. *202 6704, Mop, Battery Packs or Doorhandle. *202 6705, Video Cameras, Internet or McDonalds Bag?. *202 6706, Pans, Freshmint, or Hotdog Roll. *202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese. *202 6708, Ktimes, Nutrigrain or Mueslibars. *202 6709, Saladas, Socks, Vegemite or Textures. *202 6710, Baskets, Favourites or Cordial Jug. Current, 202 6711. ($#!+). *202 6712. (ALDI Stores, Australia, Worldwide). ''2026713'' lf2mrzu16olgqllmi6kzvo093kh9ht4 754622 754621 2026-08-01T22:21:04Z ~2026-42828-85 75114 754622 wikitext text/x-wiki = Test = 801 - Board Sizes Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24. 2:6 - 7:12, 157 days, (7:13+ to fill out). *7:13, 7:14, 7:15 (?) *7:16, 7:17, 7:18, 7:19, 7:20 (?) *7:21, 7:22, 7:23, 7:24, 7:25 (?) *7:26 (?) *7:27 (?) *7:28 (?) *7:29 (?) *7:30 (7:31) ''8:1'' *202 6525, Pot with Fork and Spoon, Bags with Sunglasses. *202 6526, Baskets, Tobacco Stuff or Socks. *202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others. *202 6528, Socks, Pairs of Shoes, Dressing Gowns. *202 6529, Towels, Cubes with Things. *202 6530, Cloths, Flowers Frisun or Soap. *202 6531, Food Shopping like Party Pies, Waters and Others. *202 6601, Pairs of Boots, Pillow or Podiatrist. *202 6602, Plates or Pans, Grated Cheese or Baskets. *202 6603, Forks, Pans and Other Kitchen Tools. *202 6604, Cups, Cordial Jug or Strawberry Milk. *202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce. *202 6606, Purses, Lu Papers or Paper Towels. *202 6607, Candles, Statues or Pizza Boxes. *202 6608, Cups, Blankets and Others. *202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans. *202 6610, Towels, Cloths, Soap or Containers. *202 6611, Nachos, Apple N Raspberry Codrial or Stationary. *202 6612, Basket, Electric Bed with Instructions or Paint. *202 6613, Aerobar, Birthday Cake or Packet of Candles. *202 6614, Plates, Blankets or even Vacuum Cleaner. *202 6615, Towels, Cloths or Dressing Gowns. *202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths. *202 6617, Pans, Table Spoons or Lids. *202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others. *202 6619, Chocolate Milk, Cups of Tea or Extra Mints. *202 6620, Kitkats, Pens or Domino's Pizza. *202 6621, Blankets and Pillows or Vacuum Cleaner. *202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught. *202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas. *202 6624, Staples, Socks, Hats and Others. *202 6625, Kitchen Bowls, Pans and Others. *202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop. *202 6627, Tablemats, Sunglasses or Garden Plant. *202 6628, Boots, Sleep Medicine or Pillow. *202 6629, Sewing Machine, Tobacco Stuff or Pan. *202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms. *202 6701, BBQ Chips, Biskits or Grated Cheese. *202 6702, Lighters, Plates or Cloths. *202 6703, Hot Dogs, Cola Cans or Lasagna. *202 6704, Mop, Battery Packs or Doorhandle. *202 6705, Video Cameras, Internet or McDonalds Bag?. *202 6706, Pans, Freshmint, or Hotdog Roll. *202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese. *202 6708, Ktimes, Nutrigrain or Mueslibars. *202 6709, Saladas, Socks, Vegemite or Textures. *202 6710, Baskets, Favourites or Cordial Jug. Current, 202 6711. ($#!+). *202 6712. (ALDI Stores, Australia, Worldwide). ''2026713'' gbimlvmy4nkyfnogqa8gy55k9cexb9b 754623 754622 2026-08-01T22:21:19Z ~2026-42828-85 75114 754623 wikitext text/x-wiki = Test = 801 - Level Board Sizes Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24. 2:6 - 7:12, 157 days, (7:13+ to fill out). *7:13, 7:14, 7:15 (?) *7:16, 7:17, 7:18, 7:19, 7:20 (?) *7:21, 7:22, 7:23, 7:24, 7:25 (?) *7:26 (?) *7:27 (?) *7:28 (?) *7:29 (?) *7:30 (7:31) ''8:1'' *202 6525, Pot with Fork and Spoon, Bags with Sunglasses. *202 6526, Baskets, Tobacco Stuff or Socks. *202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others. *202 6528, Socks, Pairs of Shoes, Dressing Gowns. *202 6529, Towels, Cubes with Things. *202 6530, Cloths, Flowers Frisun or Soap. *202 6531, Food Shopping like Party Pies, Waters and Others. *202 6601, Pairs of Boots, Pillow or Podiatrist. *202 6602, Plates or Pans, Grated Cheese or Baskets. *202 6603, Forks, Pans and Other Kitchen Tools. *202 6604, Cups, Cordial Jug or Strawberry Milk. *202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce. *202 6606, Purses, Lu Papers or Paper Towels. *202 6607, Candles, Statues or Pizza Boxes. *202 6608, Cups, Blankets and Others. *202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans. *202 6610, Towels, Cloths, Soap or Containers. *202 6611, Nachos, Apple N Raspberry Codrial or Stationary. *202 6612, Basket, Electric Bed with Instructions or Paint. *202 6613, Aerobar, Birthday Cake or Packet of Candles. *202 6614, Plates, Blankets or even Vacuum Cleaner. *202 6615, Towels, Cloths or Dressing Gowns. *202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths. *202 6617, Pans, Table Spoons or Lids. *202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others. *202 6619, Chocolate Milk, Cups of Tea or Extra Mints. *202 6620, Kitkats, Pens or Domino's Pizza. *202 6621, Blankets and Pillows or Vacuum Cleaner. *202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught. *202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas. *202 6624, Staples, Socks, Hats and Others. *202 6625, Kitchen Bowls, Pans and Others. *202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop. *202 6627, Tablemats, Sunglasses or Garden Plant. *202 6628, Boots, Sleep Medicine or Pillow. *202 6629, Sewing Machine, Tobacco Stuff or Pan. *202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms. *202 6701, BBQ Chips, Biskits or Grated Cheese. *202 6702, Lighters, Plates or Cloths. *202 6703, Hot Dogs, Cola Cans or Lasagna. *202 6704, Mop, Battery Packs or Doorhandle. *202 6705, Video Cameras, Internet or McDonalds Bag?. *202 6706, Pans, Freshmint, or Hotdog Roll. *202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese. *202 6708, Ktimes, Nutrigrain or Mueslibars. *202 6709, Saladas, Socks, Vegemite or Textures. *202 6710, Baskets, Favourites or Cordial Jug. Current, 202 6711. ($#!+). *202 6712. (ALDI Stores, Australia, Worldwide). ''2026713'' f2l18j1d146cmc3bv1ftdhnk6axxpfz User:Revi C. 2 74051 754627 622553 2026-08-01T23:37:11Z Pathoschild 469 global user pages ([[m:Synchbot|requested by Revi C.]]) 754627 wikitext text/x-wiki __NOINDEX__<div class="mw-content-ltr" lang="en" dir="ltr">{{#babel:ko|en-3|}} [[File:Revi wikimedia image.jpg|thumb|center|middle|If you are here to talk about CommonsDelinker removing a deleted image, please [[:c:User talk:Revi C.|go here]].]] Hello! I am [[:m:User:Revi C.|revi]]. I edit to [[m:SWMT|revert vandals]], do Wikidata stuff<!--(I am a Wikidata Admin! <small>([{{fullurl:wikidata:Special:ListUsers/Revi C.|limit=1}} Verify])</small>)-->, or do [[:c:COM:FR|Commons Filemoving stuff]] (I am Commons Admin too! <small>([{{fullurl:c:Special:ListUsers/Revi C.|limit=1}} Verify])</small>). Come to [[:m:User:Revi C.|my Meta userpage]] or [[:c:User:Revi C.|my Commons userpage]] for more information. Thank you.</div> s7l31vm7btg9p7hwj4hy4wj4v6hxgyh User talk:Revi C. 3 74673 754626 622552 2026-08-01T23:01:59Z Pathoschild 469 global user pages ([[m:Synchbot|requested by Revi C.]]) 754626 wikitext text/x-wiki __NOINDEX__<div class="mw-content-ltr" lang="en" dir="ltr">[[File:Revi logo (pink).png|thumb|center|<span style="color:red">PLEASE DO NOT LEAVE MESSAGE HERE!</span>]] ''' <span style="color:red"> BEFORE YOU BLOCK MY ACCOUNT: IF MY EDIT SUMMARY INCLUDE PREFIX </span>''(Script)''<span style="color:red">, DON'T BLOCK ME, JUST TELL ME TO SLOW DOWN AT COMMONS' TALK PAGE. IT IS AN AUTOMATED SCRIPT BEING USED ON COMMONS TO MOVE FILES.</span> Instead, please leave your message following site: <br /> [[File:Wikidata-logo-en.svg|45px|link=d:User talk:Revi C.]] [[d:User talk:Revi C.]] for Wikidata (Interwiki links) stuff <!--(I am {{int:Group-sysop}} there)--> <br /> [[File:Commons-logo.svg|45px|link=commons:User talk:Revi C.]] [[commons:User talk:Revi C.]] for renaming stuff or [[User:CommonsDelinker|CommonsDelinker]] action (I am {{int:Group-sysop}} there) <br /> [[File:Wikimedia Community Logo optimized.svg|45px|link=m:User talk:Revi C.]] [[meta:User talk:Revi C.]] for other stuff (User right notification, revert message, etc...) Messages left on this page may be reverted or moved without any response.</div> esxe13mcstpjlux1bt2hqwxr2v8t8mn Template:InfoNeeded 10 86720 754642 258107 2026-08-02T07:40:15Z Minorax 44057 754642 wikitext text/x-wiki [[File:Crystal Clear app help index.svg|20px|alt=|link=]]<noinclude> [[Category:Wikipedia-specific image insertion templates]] </noinclude> hkxo85r4kird0x6jq0b1s5s983nc7c7 Hi 0 92934 754567 754430 2026-08-01T20:00:34Z Enbi 72574 754567 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :D <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] ol2qslfsrsnw94096no8vg5v9plfu1f 754568 754567 2026-08-01T20:00:38Z Enbi 72574 Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754571 754568 2026-08-01T20:02:50Z Enbi 72574 754571 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :D <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] ol2qslfsrsnw94096no8vg5v9plfu1f 754572 754571 2026-08-01T20:02:53Z Enbi 72574 Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754574 754572 2026-08-01T20:04:51Z Enbi 72574 754574 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :D <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] ol2qslfsrsnw94096no8vg5v9plfu1f 754575 754574 2026-08-01T20:04:55Z Enbi 72574 Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754577 754575 2026-08-01T20:06:27Z Enbi 72574 754577 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :D <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] ol2qslfsrsnw94096no8vg5v9plfu1f 754578 754577 2026-08-01T20:06:32Z Enbi 72574 Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754581 754578 2026-08-01T20:07:25Z Enbi 72574 754581 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :3 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] 0334y4750wmyxjr0mr7pgh9wevisf8s 754582 754581 2026-08-01T20:07:29Z Enbi 72574 Reverting test edits by by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754584 754582 2026-08-01T20:08:50Z Enbi 72574 754584 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :33 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] fwurllzillhtbfo5d4yps87qf6pxffy 754585 754584 2026-08-01T20:08:58Z Enbi 72574 Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754587 754585 2026-08-01T20:09:09Z Enbi 72574 754587 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] hfcrfms10vbbc50rw2c1kcrsnsy86hd 754588 754587 2026-08-01T20:09:14Z Enbi 72574 Reverting test edits by by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754590 754588 2026-08-01T20:10:04Z Enbi 72574 754590 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] hfcrfms10vbbc50rw2c1kcrsnsy86hd 754591 754590 2026-08-01T20:10:20Z Enbi 72574 754591 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious tb27slmaiyf1skw5rwwl9l2nles70nd 754592 754591 2026-08-01T20:11:52Z Enbi 72574 Blanked the page 754592 wikitext text/x-wiki phoiac9h4m842xq45sp7s6u21eteeq1 754593 754592 2026-08-01T20:13:47Z Enbi 72574 754593 wikitext text/x-wiki sorry pvddyccdgjkb8vfzns7albocpfq8rnc 754594 754593 2026-08-01T20:14:04Z Enbi 72574 Blanked the page 754594 wikitext text/x-wiki phoiac9h4m842xq45sp7s6u21eteeq1 754595 754594 2026-08-01T20:14:07Z Enbi 72574 Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754598 754595 2026-08-01T20:17:52Z Enbi 72574 754598 wikitext text/x-wiki om]</nowiki> [[Category:Obvious Vandalism]] n3gvs1y931pro4gm60sn9q4pq61f1rp 754599 754598 2026-08-01T20:17:55Z Enbi 72574 Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754601 754599 2026-08-01T20:23:19Z Enbi 72574 Blanked the page 754601 wikitext text/x-wiki phoiac9h4m842xq45sp7s6u21eteeq1 754602 754601 2026-08-01T20:23:22Z Enbi 72574 Reverting test edits by by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754604 754602 2026-08-01T20:23:41Z Enbi 72574 Replaced content with "Vandalism]]" 754604 wikitext text/x-wiki Vandalism]] gtfmeknv6vq3ahzrhs0iueb0ljefuzo 754605 754604 2026-08-01T20:23:50Z Enbi 72574 Reverting incorrect English variants by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754607 754605 2026-08-01T21:06:42Z Enbi 72574 Blanked the page 754607 wikitext text/x-wiki phoiac9h4m842xq45sp7s6u21eteeq1 754608 754607 2026-08-01T21:06:49Z Enbi 72574 Reverting edits (Fortress-Beta) 754346 wikitext text/x-wiki {{Codeblock}} Hi is an informal greeting. It is the informal version of [[Hello]]. :0 <nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki> [[Category:Obvious Vandalism]] polq5o63cnijkcsv3wmt4ck9oesg315 754609 754608 2026-08-01T21:07:03Z Enbi 72574 Blanked the page 754609 wikitext text/x-wiki phoiac9h4m842xq45sp7s6u21eteeq1 Page 0 115230 754562 724049 2026-08-01T16:04:21Z PCendrer 75068 754562 wikitext text/x-wiki palabrotas muy feas gnly3ko230nowda83n8fc0c47tz4bu3 S 0 115236 754641 728091 2026-08-02T07:08:08Z PCendrer 75068 754641 wikitext text/x-wiki seza [[Category:Test 3]] d 4eosinif08rcfmhcow93bw5ya5ynrkd Rick Martin 0 121881 754628 690162 2026-08-02T00:06:05Z InternetArchiveBot 34092 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 754628 wikitext text/x-wiki {{Short description|Canadian ice hockey player}}{{other people}} {{Infobox ice hockey player | image = | image_size = 230px | caption = Rick Martin, Buffalo Sabres | birth_place = [[Verdun, Quebec]], Canada | birth_date = {{birth date|1951|7|26}} | death_date = {{death date and age|2011|3|13|1951|7|26}} | death_place = [[Clarence, New York]], U.S. | weight_lb = 179 | height_ft = 5 | height_in = 11 | position = [[Winger (ice hockey)|Left Wing]] | shoots = Left | played_for = [[Buffalo Sabres]]<br>[[Los Angeles Kings]] | draft = 5th overall | draft_year = 1971 | draft_team = [[Buffalo Sabres]] | career_start = 1971 | career_end = 1982 }} '''Richard Lionel Martin''' ({{IPAc-en|m|ɑːr|ˈ|t|æ|n}}; {{IPA-fr|maʁtɛ̃|lang}}; July 26, 1951{{spaced ndash}}March 13, 2011) was a [[Canadians|Canadian]] professional [[ice hockey]] [[winger (ice hockey)|winger]] who played in the [[National Hockey League|NHL]] with the [[Buffalo Sabres]] and [[Los Angeles Kings]] for 11 seasons between 1971 and 1982. He was most famous for playing on the Sabres' [[The French Connection (ice hockey)|French Connection line]] with [[Gilbert Perreault]] and [[René Robert|Rene Robert]]. ==Playing career== Martin was drafted fifth overall by the [[Buffalo Sabres]] in the [[1971 NHL Amateur Draft]] after a [[junior hockey|junior]] career with the [[Montreal Junior Canadiens]] of the [[Ontario Hockey League|Ontario Hockey Association]] (OHA). He played 685 career NHL games, scoring 384 goals and 317 assists for 701 points. His best season was the [[1974–75 NHL season]] when he scored 52 goals and 95 points in only 68 games. Martin scored at least 44 goals five times in his NHL career. Martin was selected to play in seven consecutive [[National Hockey League All-Star Game]]s ([[25th National Hockey League All-Star Game|1971–72]], through [[1978 NHL All-Star Game|1977–78]]) and was selected as the official [[NHL All-Star Team|NHL All-Star First Team]] left wing in [[1973–74 NHL season|1973–74]] and [[1974–75 NHL season|1974–75]] and the official NHL All-Star Second Team left wing in 1975–76 and 1976–77.<ref name=His>{{cite web|url=http://downloads.sabres.nhl.com/other/history.pdf|title=History|access-date=2007-07-24|year=2006|publisher=Buffalo Sabres and the National Hockey League|archive-date=2013-06-19|archive-url=https://web.archive.org/web/20130619221123/http://downloads.sabres.nhl.com/other/history.pdf|url-status=dead}} {{Webarchive|url=https://web.archive.org/web/20130619221123/http://downloads.sabres.nhl.com/other/history.pdf |date=2013-06-19 }}</ref> Martin holds the Buffalo Sabres franchise career records for [[hat trick]]s, four-goal games, 40-goal seasons, consecutive 40-goal seasons, 50-goal seasons (tied with [[Danny Gare]]), consecutive 50-goal seasons.<ref name=TRB>{{cite web|url=http://downloads.sabres.nhl.com/other/record_book.pdf|title=The Record Book|access-date=2007-07-24|year=2006|publisher=Buffalo Sabres and the National Hockey League|archive-date=2016-03-04|archive-url=https://web.archive.org/web/20160304001459/http://downloads.sabres.nhl.com/other/record_book.pdf|url-status=dead}} {{Webarchive|url=https://web.archive.org/web/20160304001459/http://downloads.sabres.nhl.com/other/record_book.pdf |date=2016-03-04 }}</ref><ref>{{cite news|title=Rick Martin, Part of Famed N.H.L. Line, Dies at 59 After Car Accident|url=https://www.nytimes.com/2011/03/16/sports/hockey/16martin.html|newspaper=[[The New York Times]]|date=March 15, 2011|access-date=March 22, 2011}}</ref> Rick Martin is #11 All Time in Career "Goals per Game" Average (.56) in NHL regular season history. Martin was involved in probably one of the three most frightening injuries on Buffalo home ice (the others being when [[Clint Malarchuk|Clint Malarchuk's]] and [[Richard Zednik|Richard Zednik's]] in separate incidents each had their [[jugular vein]] lacerated). During a 1977 game [[Dave Farrish]] of the [[New York Rangers]] hooked Martin around the neck from behind and kicked Martin's feet out from under him, causing Martin to hit his head on the ice. He was knocked unconscious, and went into convulsions. After that play, helmets became a much more common sight on the heads of his Sabre team-mates. On November 8, 1980, his career was dealt a devastating blow. In a game against the [[Washington Capitals]] in the [[Buffalo Memorial Auditorium|Aud]], Martin was racing in on a breakaway. Capitals forward [[Ryan Walter]] managed to trip Martin and no penalty was called. Capitals goalie [[Mike Palmateer]], already way out of his crease, knocked Martin back down by kicking his knee, causing severe [[cartilage]] damage that all but ended Martin's career.<ref>{{cite web|url=http://www.hockeydraftcentral.com/1971/71005.html|title=Rick Martin|access-date=2011-03-11|publisher=Hockey Draft Central}}</ref> Martin underwent surgery in Toronto and on March 10, 1981, [[Scotty Bowman]] traded Martin and [[Don Luce]] to the Kings for a pair of draft picks, one of which the Sabres used to get goalie [[Tom Barrasso]] in [[1983 NHL Entry Draft|1983]]. Martin played four games for the [[Los Angeles Kings]] before hanging up the skates. In 1989 he, along with the other two members of the French Connection, were inducted into the Buffalo Sabres Hall of Fame.<ref>{{cite web |url=http://www.sabresalumni.com/history/halloffame.php |title=Buffalo Sabres Hall of Fame |url-status=dead |access-date=20 July 2012 |archive-url=https://web.archive.org/web/20120618013818/http://www.sabresalumni.com/history/halloffame.php |archive-date=June 18, 2012 }} {{Webarchive|url=https://web.archive.org/web/20120618013818/http://www.sabresalumni.com/history/halloffame.php |date=18 June 2012 }}</ref> His number 7 was retired along with [[René Robert|Rene Robert]]'s #14 on November 15, 1995, flanking the #11 of [[Gilbert Perreault]] under a French Connection banner. On Oct. 25, 2005, Martin was inducted into the Greater Buffalo Sports Hall of Fame.<ref>{{cite news|title=Rick Martin Through the Years|url=http://galleries.buffalonews.com/photo.php?gname=gallery_1300045777.txt&item=8|newspaper=[[The Buffalo News]]|date=March 13, 2011|access-date=March 19, 2011|url-status=dead|archive-url=https://web.archive.org/web/20110317102843/http://galleries.buffalonews.com/photo.php?gname=gallery_1300045777.txt&item=8|archive-date=March 17, 2011}} {{Webarchive|url=https://web.archive.org/web/20110317102843/http://galleries.buffalonews.com/photo.php?gname=gallery_1300045777.txt&item=8 |date=March 17, 2011 }}</ref> In 2010, in commemoration of the Sabres' 40th season, ''[[The Buffalo News]]'' ranked Martin number 4 out of the top 40 Sabres of all time, while he was voted #5 by fans.<ref>{{cite news|title=Sabres Top 40 for 40 Seasons|url=http://galleries.buffalonews.com/photo.php?gname=gallery_1285003304.txt&item=4|newspaper=[[The Buffalo News]]|date=October 6, 2010|access-date=March 19, 2011|url-status=dead|archive-url=https://web.archive.org/web/20110720091737/http://galleries.buffalonews.com/photo.php?gname=gallery_1285003304.txt&item=4|archive-date=July 20, 2011}} {{Webarchive|url=https://web.archive.org/web/20110720091737/http://galleries.buffalonews.com/photo.php?gname=gallery_1285003304.txt&item=4 |date=July 20, 2011 }}</ref> After his death in 2011, the Sabres honored his memory by painting the number 7, the number Martin wore for most of his career with Buffalo, behind each goal at the [[HSBC Arena (Buffalo)|HSBC Arena]] for the remainder of the [[2010–11 Buffalo Sabres season|2010-11 season]].<ref>{{cite web|url=http://sabres.nhl.com/club/recap.htm?id=2010021071|title=Sabres 8, Thrashers 2|access-date=2011-03-22|year=2011|publisher=Buffalo Sabres|url-status=dead|archive-url=https://web.archive.org/web/20110321084925/http://sabres.nhl.com/club/recap.htm?id=2010021071|archive-date=2011-03-21}} {{Webarchive|url=https://web.archive.org/web/20110321084925/http://sabres.nhl.com/club/recap.htm?id=2010021071 |date=2011-03-21 }}</ref> ==Achievements== *1st Team All Star (1973–74) *1st Team All Star (1974–75) *2nd Team All Star (1975–76) *2nd Team All Star (1976–77) *7 Straight NHL All Star Game Appearances (1972 - 1978) *3rd All Time in Hat Tricks (21) among Left Wingers (Modern Era) *11th All Time in Career Goals Per Game Average in NHL History *Gold Championship Canada Cup 1976 (Team Canada) *5 "Top 10" finishes in Goals *2 "Top 10" finishes in Points *5 "Top 10" finishes in Even Strength Goals *3 "Top 10" finishes in Game Winning Goals *5 "Top 10" finishes in Power Play Goals *5 "Top 10" finishes in Goals Per Game Average *2 "Top 10" finishes in Points Per Game Average *6 Team Scoring Records (Buffalo Sabres) * #7 Team Jersey Retired (Buffalo Sabres) *Buffalo Sabres Hall Of Famer ==Personal life== Rick and his wife were owners of Globalquest Solutions and Globalquest Staffing Solutions in Williamsville, New York.<ref>{{cite news|title=Globalquest adding up to 10 to staff|url=http://www.bizjournals.com/albany/stories/2001/08/06/daily21.html|newspaper=The Business Review|date=August 7, 2001|access-date=March 19, 2011}}</ref> Martin owned a bar/restaurant called Slapshot on Niagara Falls Boulevard in Niagara Falls, N.Y. Rick Martin died on March 13, 2011, in [[Clarence, New York]], from a [[myocardial infarction|heart attack]] while driving, a complication of [[Hypertensive heart disease|hypertensive arteriosclerotic cardiovascular disease]].<ref name="Buffalo News story with obit">{{cite news|last=Watson|first=Stephen T.|title=Memorial plans for Martin announced by Sabres|url=http://www.buffalonews.com/sports/sabres-nhl/article366694.ece|newspaper=[[The Buffalo News]]|date=March 14, 2011|access-date=March 14, 2011}}</ref> He was 59 years old. He was survived by his wife Mikey, who has since passed on December 16, 2017, and his sons Cory, Josh, and Erick.<ref name=sabres.com>{{cite web|title=RICK MARTIN: 1951-2011|url=http://sabres.nhl.com/club/news.htm?id=555923|access-date=13 March 2011|archive-date=17 March 2011|archive-url=https://web.archive.org/web/20110317000126/http://sabres.nhl.com/club/news.htm?id=555923|url-status=dead}}</ref><ref name="Buffalo News Obituaries">{{cite web|title=Rick MARTIN Obituary: View Rick Martin's Obituary By Buffalo News|url=http://www.legacy.com/obituaries/buffalonews/obituary.aspx?n=rick-martin&pid=149347695|access-date=March 23, 2011}}</ref><ref>{{cite news|title=Video: Rick Martin memorial service|url=http://blogs.buffalonews.com/sabres/2011/03/video-rick-martin-memorial-service.html|newspaper=[[The Buffalo News]]|date=March 24, 2011|access-date=March 24, 2011|archive-date=July 20, 2011|archive-url=https://web.archive.org/web/20110720093219/http://blogs.buffalonews.com/sabres/2011/03/video-rick-martin-memorial-service.html|url-status=dead}} {{Webarchive|url=https://web.archive.org/web/20110720093219/http://blogs.buffalonews.com/sabres/2011/03/video-rick-martin-memorial-service.html |date=July 20, 2011 }}</ref> Later analysis revealed that Martin had stage 2 [[chronic traumatic encephalopathy]], a disease normally associated with [[enforcer (ice hockey)|enforcers]]; the damage was believed to stem from a severe concussion Martin sustained in 1977, and it had no effect on his cognitive abilities. Martin is the first non-enforcer to have been diagnosed with the disease, which can only be diagnosed posthumously.<ref>Golen, Jimmy (October 5, 2011). [http://www.wivb.com/dpp/sports/sabres_and_nhl/Brain-study-finds-damage-in-Rick-Martin Brain study finds damage in Rick Martin] {{Webarchive|url=https://web.archive.org/web/20111007004419/http://www.wivb.com/dpp/sports/sabres_and_nhl/Brain-study-finds-damage-in-Rick-Martin |date=2011-10-07 }}. ''Associated Press''. Retrieved October 5, 2011.</ref> ==Career statistics== ===Regular season and playoffs=== {| border="0" cellpadding="1" cellspacing="0" style="text-align:center; width:60em" |- bgcolor="#e0e0e0" ! colspan="3" bgcolor="#ffffff" | &nbsp; ! rowspan="99" bgcolor="#ffffff" | &nbsp; ! colspan="5" | [[regular season|Regular&nbsp;season]] ! rowspan="99" bgcolor="#ffffff" | &nbsp; ! colspan="5" | [[Playoffs]] |- bgcolor="#e0e0e0" ! [[Season (sports)|Season]] ! Team ! League ! GP ! [[Goal (ice hockey)|G]] ! [[Assist (ice hockey)|A]] ! [[Point (ice hockey)|Pts]] ! [[Penalty (ice hockey)|PIM]] ! GP ! G ! A ! Pts ! PIM |- | 1967–68 | Thetford Mines Canadiens | QJHL | 40 | 38 | 35 | 73 | — | 7 | 2 | 0 | 2 | 4 |- bgcolor="#f0f0f0" | [[1968–69 OHA season|1968–69]] | [[Montreal Junior Canadiens]] | [[Ontario Hockey League|OHA-Jr.]] | 52 | 22 | 21 | 43 | 27 | 14 | 3 | 0 | 3 | 2 |- | [[1969 Memorial Cup|1968–69]] | Montreal Junior Canadiens | [[Memorial Cup|M-Cup]] | — | — | — | — | — | 6 | 2 | 1 | 3 | 12 |- bgcolor="#f0f0f0" | [[1969–70 OHA season|1969–70]] | Montreal Junior Canadiens | OHA-Jr. | 34 | 23 | 32 | 55 | 10 | 16 | 14 | 20 | 34 | 12 |- | [[1970 Memorial Cup|1969–70]] | Montreal Junior Canadiens | M-Cup | — | — | — | — | — | 12 | 14 | 13 | 27 | 8 |- bgcolor="#f0f0f0" | [[1970–71 OHA season|1970–71]] | Montreal Junior Canadiens | OHA-Jr. | 60 | 71 | 50 | 121 | 106 | 11 | 17 | 7 | 24 | 10 |- | [[1971–72 NHL season|1971–72]] | [[Buffalo Sabres]] | [[National Hockey League|NHL]] | 73 | 44 | 30 | 74 | 39 | — | — | — | — | — |- bgcolor="#f0f0f0" | [[1972–73 NHL season|1972–73]] | Buffalo Sabres | NHL | 75 | 37 | 36 | 73 | 79 | 6 | 3 | 2 | 5 | 12 |- | [[1973–74 NHL season|1973–74]] | Buffalo Sabres | NHL | 78 | 52 | 34 | 86 | 38 | — | — | — | — | — |- bgcolor="#f0f0f0" | [[1974–75 NHL season|1974–75]] | Buffalo Sabres | NHL | 68 | 52 | 43 | 95 | 72 | 17 | 7 | 8 | 15 | 20 |- | [[1975–76 NHL season|1975–76]] | Buffalo Sabres | NHL | 80 | 49 | 37 | 86 | 67 | 9 | 4 | 7 | 11 | 12 |- bgcolor="#f0f0f0" | [[1976–77 NHL season|1976–77]] | Buffalo Sabres | NHL | 66 | 36 | 29 | 65 | 58 | 6 | 2 | 1 | 3 | 9 |- | [[1977–78 NHL season|1977–78]] | Buffalo Sabres | NHL | 65 | 28 | 35 | 63 | 16 | 7 | 2 | 4 | 6 | 13 |- bgcolor="#f0f0f0" | [[1978–79 NHL season|1978–79]] | Buffalo Sabres | NHL | 73 | 32 | 21 | 53 | 35 | 3 | 0 | 3 | 3 | 0 |- | [[1979–80 NHL season|1979–80]] | Buffalo Sabres | NHL | 80 | 45 | 34 | 79 | 54 | 14 | 6 | 4 | 10 | 8 |- bgcolor="#f0f0f0" | [[1980–81 NHL season|1980–81]] | Buffalo Sabres | NHL | 23 | 7 | 14 | 21 | 20 | — | — | — | — | — |- | 1980–81 | [[Los Angeles Kings]] | NHL | 1 | 1 | 1 | 2 | 0 | 1 | 0 | 0 | 0 | 0 |- bgcolor="#f0f0f0" | [[1981–82 NHL season|1981–82]] | Los Angeles Kings | NHL | 3 | 1 | 3 | 4 | 2 | — | — | — | — | — |- bgcolor="#e0e0e0" ! colspan="3" | NHL totals ! 685 ! 384 ! 317 ! 701 ! 477 ! 63 ! 24 ! 29 ! 53 ! 74 |} ===International=== {| border="0" cellpadding="1" cellspacing="0" style="text-align:center; width:50em" |- ALIGN="center" bgcolor="#e0e0e0" ! Year ! Team ! Event ! rowspan="99" bgcolor="#ffffff" | &nbsp; ! GP ! G ! A ! Pts ! PIM |- | [[1976 Canada Cup|1976]] | [[Canada men's national ice hockey team|Canada]] | [[Canada Cup|CC]] | 4 | 3 | 2 | 5 | 0 |} ==References== {{reflist}} ==External links== *{{icehockeystats|legends=13552}} *[https://web.archive.org/web/20110715184617/http://sports.rightpundits.com/?p=5976%2F Mikey Martin, Rick Martin's Wife] {{s-start}} {{succession box | before = [[Gilbert Perreault]] | title = [[List of Buffalo Sabres draft picks|Buffalo Sabres first round draft pick]] | years = [[1971 NHL Amateur Draft|1971]] | after = [[Jim Schoenfeld]]}} {{s-end}} {{DEFAULTSORT:Martin, Rick}} [[Category:1951 births]] [[Category:2011 deaths]] [[Category:Buffalo Sabres draft picks]] [[Category:Buffalo Sabres players]] [[Category:Canadian ice hockey left wingers]] [[Category:Ice hockey people from Quebec]] [[Category:Ice hockey players players with chronic traumatic encephalopathy]] [[Category:Los Angeles Kings players]] [[Category:Moncton Golden Flames players]] [[Category:Montreal Junior Canadiens players]] [[Category:National Hockey League first round draft picks]] [[Category:National Hockey League players with retired numbers]] [[Category:People from Verdun, Quebec]] [[Category:Sportspeople from Montreal]] tkuychr02iug1xgl5tlmlevhoq19qfu CAPTCHA test 0 167162 754566 750574 2026-08-01T17:59:52Z OutsideNormality 57920 this is an edit via the API 754566 wikitext text/x-wiki Hello world! oohjaetg7omy0s2yj35hjuuup48ugoy User:Novem Linguae/rater/app.js 2 168001 754651 754373 2026-08-02T10:01:49Z Novem Linguae 49714 754651 javascript text/javascript (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ module.exports={ "name": "rater", "version": "2.7.2", "description": "Wikipedia userscript that helps assess pages for WikiProjects", "homepage": "https://github.com/evad37/rater", "browser": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "lint:es5": "jshint index.js", "lint:es6": "eslint index.js \"rater-src/**\"", "lint:fix": "eslint index.js \"rater-src/**\" --fix", "lint": "npm run lint:es6 && npm run lint:es5", "build:bundle": "browserify rater-src/App.js --debug -t babelify --outfile dist/rater.js", "build:minify": "uglifyjs dist/rater.js --compress -b ascii_only=true,beautify=false --output dist/rater.min.js", "build:concat": "concat-cli -f \"comment-top.js\" dist/rater.min.js \"comment-bottom.js\" -o dist/rater.min.js", "build": "npm run lint && npm run build:bundle && npm run build:minify && npm run build:concat" }, "author": { "name": "Evad37", "url": "https://en.wikipedia.org/wiki/User:Evad37" }, "repository": { "type": "git", "url": "https://github.com/evad37/rater.git" }, "license": "(MIT OR CC-BY-4.0)", "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.0", "babelify": "^10.0.0", "browserify": "^16.5.0", "concat-cli": "^4.0.0", "eslint": "^6.8.0", "jshint": "^2.11.0", "uglify-js": "^3.8.0" } } },{}],2:[function(require,module,exports){ "use strict"; var _setup = _interopRequireDefault(require("./setup")); var _autostart = _interopRequireDefault(require("./autostart")); var _css = _interopRequireDefault(require("./css.js")); var _api = require("./api"); var _windowManager = _interopRequireDefault(require("./windowManager")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } // <nowiki> (function App() { var stylesheet; var _showMainWindow = function showMainWindow(data) { if (!data || !data.success) { return; } if (stylesheet) { stylesheet.disabled = false; } else { stylesheet = mw.util.addCSS(_css["default"]); } // Add css class to body to enable background scrolling document.getElementsByTagName("body")[0].classList.add("rater-mainWindow-open"); // Open the window _windowManager["default"].openWindow("main", data).closed.then(function (result) { // Disable/remove the css styles, so as to not interfere with other scripts/content/OOUI windows if (stylesheet) { stylesheet.disabled = true; } document.getElementsByTagName("body")[0].classList.remove("rater-mainWindow-open"); // Restart if needed if (result && result.restart) { _windowManager["default"].removeWindows(["main"]).then(_setup["default"]).then(_showMainWindow, showSetupError); return; } // Show notification when saved successfully if (result && result.success) { var $message = $("<span>").append($("<strong>").text("Ratings saved successfully.")); if (result.upgradedStub) { $message.append($("<br>"), // TODO: There should be a link that will edit the article for you $("<span>").text("Note that the article appears to be tagged as a stub.")); } mw.notify($message, { autoHide: true, autoHideSeconds: "long", tag: "Rater-saved" }); } }); }; var showSetupError = function showSetupError(code, jqxhr) { return OO.ui.alert((0, _api.makeErrorMsg)(code, jqxhr), { title: "Rater failed to open" }); }; // Invocation by portlet link mw.util.addPortletLink("p-cactions", "#", "Rater", "ca-rater", "Rate quality and importance", "5"); $("#ca-rater").click(function (event) { event.preventDefault(); (0, _setup["default"])().then(_showMainWindow, showSetupError); }); // Invocation by auto-start (do not show message on error) (0, _autostart["default"])().then(_showMainWindow); })(); // </nowiki> },{"./api":15,"./autostart":16,"./css.js":19,"./setup":22,"./windowManager":24}],3:[function(require,module,exports){ "use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports.parseTemplates = exports.getWithRedirectTo = exports.Template = void 0; var _api = _interopRequireDefault(require("./api")); var _util = require("./util"); var _config = _interopRequireDefault(require("./config")); var cache = _interopRequireWildcard(require("./cache")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // <nowiki> /** Template * * @class * Represents the wikitext of template transclusion. Used by #parseTemplates. * @prop {String} name Name of the template * @prop {String} wikitext Full wikitext of the transclusion * @prop {Object[]} parameters Parameters used in the translcusion, in order, of form: { name: {String|Number} parameter name, or position for unnamed parameters, value: {String} Wikitext passed to the parameter (whitespace trimmed), wikitext: {String} Full wikitext (including leading pipe, parameter name/equals sign (if applicable), value, and any whitespace) } * @constructor * @param {String} wikitext Wikitext of a template transclusion, starting with '{{' and ending with '}}'. */ var Template = exports.Template = function Template(wikitext) { this.wikitext = wikitext; this.parameters = []; // Spacing around pipes, equals signs, end braces (defaults) this.pipeStyle = " |"; this.equalsStyle = "="; this.endBracesStyle = "}}"; }; Template.prototype.addParam = function (name, val, wikitext) { this.parameters.push({ "name": name, "value": val, "wikitext": "|" + wikitext }); }; /** * Get a parameter data by parameter name */ Template.prototype.getParam = function (paramName) { return this.parameters.find(function (p) { return p.name == paramName; }); }; Template.prototype.setName = function (name) { this.name = name.trim(); }; Template.prototype.getTitle = function () { return mw.Title.newFromText("Template:" + this.name); }; /** * parseTemplates * * Parses templates from wikitext. * Based on SD0001's version at <https://en.wikipedia.org/wiki/User:SD0001/parseAllTemplates.js>. * Returns an array containing the template details: * var templates = parseTemplates("Hello {{foo |Bar|baz=qux |2=loremipsum|3=}} world"); * console.log(templates[0]); // --> object { name: "foo", wikitext:"{{foo |Bar|baz=qux | 2 = loremipsum |3=}}", parameters: [ { name: 1, value: 'Bar', wikitext: '|Bar' }, { name: 'baz', value: 'qux', wikitext: '|baz=qux ' }, { name: '2', value: 'loremipsum', wikitext: '| 2 = loremipsum ' }, { name: '3', value: '', wikitext: '|3=' } ], getParam: function(paramName) { return this.parameters.find(function(p) { return p.name == paramName; }); } } * * * @param {String} wikitext * @param {Boolean} recursive Set to `true` to also parse templates that occur within other templates, * rather than just top-level templates. * @return {Template[]} templates */ var _parseTemplates = exports.parseTemplates = function parseTemplates(wikitext, recursive) { /* eslint-disable no-control-regex */ if (!wikitext) { return []; } var strReplaceAt = function strReplaceAt(string, index, _char) { return string.slice(0, index) + _char + string.slice(index + 1); }; var result = []; var processTemplateText = function processTemplateText(startIdx, endIdx) { var text = wikitext.slice(startIdx, endIdx); var template = new Template("{{" + text.replace(/\x01/g, "|") + "}}"); // swap out pipe in links with \x01 control character // [[File: ]] can have multiple pipes, so might need multiple passes while (/(\[\[[^\]]*?)\|(.*?\]\])/g.test(text)) { text = text.replace(/(\[\[[^\]]*?)\|(.*?\]\])/g, "$1\x01$2"); } // Figure out most-used spacing styles for pipes/equals template.pipeStyle = (0, _util.mostFrequent)(text.match(/[\s\n]*\|[\s\n]*/g)) || " |"; template.equalsStyle = (0, _util.mostFrequent)(text.replace(/(=[^|]*)=+/g, "$1").match(/[\s\n]*=[\s\n]*/g)) || "="; // Figure out end-braces style var endSpacing = text.match(/[\s\n]*$/); template.endBracesStyle = (endSpacing ? endSpacing[0] : "") + "}}"; var chunks = text.split("|").map(function (chunk) { // change '\x01' control characters back to pipes return chunk.replace(/\x01/g, "|"); }); template.setName(chunks[0]); var parameterChunks = chunks.slice(1); var unnamedIdx = 1; parameterChunks.forEach(function (chunk) { var indexOfEqualTo = chunk.indexOf("="); var indexOfOpenBraces = chunk.indexOf("{{"); var isWithoutEquals = !chunk.includes("="); var hasBracesBeforeEquals = chunk.includes("{{") && indexOfOpenBraces < indexOfEqualTo; var isUnnamedParam = isWithoutEquals || hasBracesBeforeEquals; var pName, pNum, pVal; if (isUnnamedParam) { // Get the next number not already used by either an unnamed parameter, or by a // named parameter like `|1=val` while (template.getParam(unnamedIdx)) { unnamedIdx++; } pNum = unnamedIdx; pVal = chunk.trim(); } else { pName = chunk.slice(0, indexOfEqualTo).trim(); pVal = chunk.slice(indexOfEqualTo + 1).trim(); } template.addParam(pName || pNum, pVal, chunk); }); result.push(template); }; var n = wikitext.length; // number of unclosed braces var numUnclosed = 0; // are we inside a comment, or between nowiki tags, or in a {{{parameter}}}? var inComment = false; var inNowiki = false; var inParameter = false; var startIdx, endIdx; for (var i = 0; i < n; i++) { if (!inComment && !inNowiki && !inParameter) { if (wikitext[i] === "{" && wikitext[i + 1] === "{" && wikitext[i + 2] === "{" && wikitext[i + 3] !== "{") { inParameter = true; i += 2; } else if (wikitext[i] === "{" && wikitext[i + 1] === "{") { if (numUnclosed === 0) { startIdx = i + 2; } numUnclosed += 2; i++; } else if (wikitext[i] === "}" && wikitext[i + 1] === "}") { if (numUnclosed === 2) { endIdx = i; processTemplateText(startIdx, endIdx); } numUnclosed -= 2; i++; } else if (wikitext[i] === "|" && numUnclosed > 2) { // swap out pipes in nested templates with \x01 character wikitext = strReplaceAt(wikitext, i, "\x01"); } else if (/^<!--/.test(wikitext.slice(i, i + 4))) { inComment = true; i += 3; } else if (/^<nowiki ?>/.test(wikitext.slice(i, i + 9))) { inNowiki = true; i += 7; } } else { // we are in a comment or nowiki or {{{parameter}}} if (wikitext[i] === "|") { // swap out pipes with \x01 character wikitext = strReplaceAt(wikitext, i, "\x01"); } else if (/^-->/.test(wikitext.slice(i, i + 3))) { inComment = false; i += 2; } else if (/^<\/nowiki ?>/.test(wikitext.slice(i, i + 10))) { inNowiki = false; i += 8; } else if (wikitext[i] === "}" && wikitext[i + 1] === "}" && wikitext[i + 2] === "}") { inParameter = false; i += 2; } } } if (recursive) { var subtemplates = (0, _util.filterAndMap)(result, function (template) { return /\{\{(?:.|\n)*\}\}/.test(template.wikitext.slice(2, -2)); }, function (template) { return _parseTemplates(template.wikitext.slice(2, -2), true); }); return result.concat.apply(result, subtemplates); } return result; }; /* eslint-enable no-control-regex */ /** * @param {Template|Template[]} templates * @return {Promise<Template>|Promise<Template[]>} */ var getWithRedirectTo = exports.getWithRedirectTo = function getWithRedirectTo(templates) { var templatesArray = Array.isArray(templates) ? templates : [templates]; if (templatesArray.length === 0) { return $.Deferred().resolve([]); } return _api["default"].get({ "action": "query", "format": "json", "titles": (0, _util.filterAndMap)(templatesArray, function (template) { return template.getTitle() !== null; }, function (template) { return template.getTitle().getPrefixedText(); }), "redirects": 1 }).then(function (result) { if (!result || !result.query) { return $.Deferred().reject("Empty response"); } if (result.query.redirects) { result.query.redirects.forEach(function (redirect) { var i = templatesArray.findIndex(function (template) { var title = template.getTitle(); return title && title.getPrefixedText() === redirect.from; }); if (i !== -1) { templatesArray[i].redirectTarget = mw.Title.newFromText(redirect.to); } }); } return Array.isArray(templates) ? templatesArray : templatesArray[0]; }); }; Template.prototype.getDataForParam = function (key, paraName) { if (!this.paramData) { return null; } // If alias, switch from alias to preferred parameter name var para = this.paramAliases[paraName] || paraName; if (!this.paramData[para]) { return; } var data = this.paramData[para][key]; // Data might actually be an object with key "en" if (data && data.en && !Array.isArray(data)) { return data.en; } return data; }; Template.prototype.isShellTemplate = function () { var mainText = this.redirectTarget ? this.redirectTarget.getMainText() : this.getTitle().getMainText(); return _config["default"].shellTemplates.includes(mainText); }; Template.prototype.setParamDataAndSuggestions = function () { var self = this; var paramDataSet = $.Deferred(); if (self.paramData) { return paramDataSet.resolve(); } var prefixedText = self.redirectTarget ? self.redirectTarget.getPrefixedText() : self.getTitle().getPrefixedText(); var cachedInfo = cache.read(prefixedText + "-params"); if (cachedInfo && cachedInfo.value && cachedInfo.staleDate && cachedInfo.value.paramData != null && cachedInfo.value.parameterSuggestions != null && cachedInfo.value.paramAliases != null) { self.notemplatedata = cachedInfo.value.notemplatedata; self.paramData = cachedInfo.value.paramData; self.parameterSuggestions = cachedInfo.value.parameterSuggestions; self.paramAliases = cachedInfo.value.paramAliases; paramDataSet.resolve(); if (!(0, _util.isAfterDate)(cachedInfo.staleDate)) { // Just use the cached data return paramDataSet; } // else: Use the cache data for now, but also fetch new data from API } _api["default"].get({ action: "templatedata", titles: prefixedText, redirects: 1, includeMissingTitles: 1 }).then(function (response) { return response; }, function /*error*/ () { return null; } // Ignore errors, will use default data ).then(function (result) { // Figure out page id (beacuse action=templatedata doesn't have an indexpageids option) var id = result && $.map(result.pages, function (_value, key) { return key; }); if (!result || !result.pages[id] || result.pages[id].notemplatedata || !result.pages[id].params) { // No TemplateData, so use defaults (guesses) self.notemplatedata = true; self.templatedataApiError = !result; self.paramData = _config["default"].defaultParameterData; } else { self.paramData = result.pages[id].params; } self.paramAliases = {}; $.each(self.paramData, function (paraName, paraData) { // Extract aliases for easier reference later on if (paraData.aliases && paraData.aliases.length) { paraData.aliases.forEach(function (alias) { self.paramAliases[alias] = paraName; }); } // Extract allowed values array from description if (paraData.description && /\[.*'.+?'.*?\]/.test(paraData.description.en)) { try { var allowedVals = JSON.parse(paraData.description.en.replace(/^.*\[/, "[").replace(/"/g, "\\\"").replace(/'/g, "\"").replace(/,\s*]/, "]").replace(/].*$/, "]")); self.paramData[paraName].allowedValues = allowedVals; } catch (e) { console.warn("[Rater] Could not parse allowed values in description:\n " + paraData.description.en + "\n Check TemplateData for parameter |" + paraName + "= in " + self.getTitle().getPrefixedText()); } } }); // Make suggestions for combobox var allParamsArray = !self.notemplatedata && result.pages[id].paramOrder || $.map(self.paramData, function (_val, key) { return key; }); self.parameterSuggestions = allParamsArray.filter(function (paramName) { return paramName && paramName !== "class" && paramName !== "importance"; }).map(function (paramName) { var optionObject = { data: paramName }; var label = self.getDataForParam(label, paramName); if (label) { optionObject.label = label + " (|" + paramName + "=)"; } return optionObject; }); if (self.templatedataApiError) { // Don't save defaults/guesses to cache; return true; } cache.write(prefixedText + "-params", { notemplatedata: self.notemplatedata, paramData: self.paramData, parameterSuggestions: self.parameterSuggestions, paramAliases: self.paramAliases }, 1); return true; }).then(paramDataSet.resolve, paramDataSet.reject); return paramDataSet; }; var makeListAs = function makeListAs(subjectTitle) { var name = subjectTitle.getMainText().replace(/\s\(.*\)/, ""); if (name.indexOf(" ") === -1) { return name; } var generationalSuffix = ""; if (/ (?:[JS]r.?|[IVX]+)$/.test(name)) { generationalSuffix = name.slice(name.lastIndexOf(" ")); name = name.slice(0, name.lastIndexOf(" ")); if (name.indexOf(" ") === -1) { return name + generationalSuffix; } } var lastName = name.slice(name.lastIndexOf(" ") + 1).replace(/,$/, ""); var otherNames = name.slice(0, name.lastIndexOf(" ")); return lastName + ", " + otherNames + generationalSuffix; }; Template.prototype.addMissingParams = function () { var thisTemplate = this; // Autofill listas parameter for WP:BIO var isBiographyBanner = this.getTitle().getMainText() === "WikiProject Biography" || this.redirectTarget && this.redirectTarget.getMainText() === "WikiProject Biography"; if (isBiographyBanner && !this.getParam("listas")) { var subjectTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getSubjectPage(); this.parameters.push({ name: "listas", value: makeListAs(subjectTitle), autofilled: true }); } // Make sure required/suggested parameters are present $.each(thisTemplate.paramData, function (paraName, paraData) { if ((paraData.required || paraData.suggested) && !thisTemplate.getParam(paraName)) { // Check if already present in an alias, if any if (paraData.aliases.length) { var aliases = thisTemplate.parameters.filter(function (p) { var isAlias = paraData.aliases.includes(p.name); var isEmpty = !p.value; return isAlias && !isEmpty; }); if (aliases.length) { // At least one non-empty alias, so do nothing return; } } // No non-empty aliases, so add this to the parameters list (with // value set parameter to either the autovaule, or as null). // Also set that it was autofilled. thisTemplate.parameters.push({ name: paraName, value: paraData.autovalue || null, autofilled: true }); } }); return thisTemplate; }; Template.prototype.setClassesAndImportances = function () { var _this = this; var parsed = $.Deferred(); // Don't re-parse if already parsed; no need to parse shell templates or banners without ratings if (this.isShellTemplate()) { this.classes = _toConsumableArray(_config["default"].bannerDefaults.classes); return parsed.resolve(); } else if (this.classes && this.importances || this.withoutRatings) { return parsed.resolve(); } var mainText = this.getTitle().getMainText(); // Some projects have hardcoded values, to avoid standard classes or to prevent API issues (timeout and/or node count exceeded) var redirectTargetOrMainText = this.redirectTarget ? this.redirectTarget.getMainText() : mainText; if (_config["default"].customBanners[redirectTargetOrMainText]) { this.classes = _config["default"].customBanners[redirectTargetOrMainText].classes; this.importances = _config["default"].customBanners[redirectTargetOrMainText].importances; return parsed.resolve(); } // Otherwise try reading from cached data var cachedRatings = cache.read(mainText + "-ratings"); if (cachedRatings && cachedRatings.value && cachedRatings.staleDate && cachedRatings.value.classes != null && cachedRatings.value.importances != null) { this.classes = cachedRatings.value.classes; this.importances = cachedRatings.value.importances; parsed.resolve(); if (!(0, _util.isAfterDate)(cachedRatings.staleDate)) { // Just use the cached data return parsed; } // else: Use the cache data for now, but also fetch new data from API } var wikitextToParse = ""; _config["default"].bannerDefaults.extendedClasses.forEach(function (classname, index) { wikitextToParse += "{{" + mainText + "|class=" + classname + "|importance=" + (_config["default"].bannerDefaults.extendedImportances[index] || "") + "}}/n"; }); return _api["default"].get({ action: "parse", title: "Talk:Wikipedia", text: wikitextToParse, prop: "categorieshtml" }).then(function (result) { var catsHtml = result.parse.categorieshtml["*"]; var extendedClasses = _config["default"].bannerDefaults.extendedClasses.filter(function (cl) { return catsHtml.indexOf(cl + "-Class") !== -1; }); _this.classes = [].concat(_toConsumableArray(_config["default"].bannerDefaults.classes), _toConsumableArray(extendedClasses)); _this.importances = _config["default"].bannerDefaults.extendedImportances.filter(function (imp) { return catsHtml.indexOf(imp + "-importance") !== -1; }); cache.write(mainText + "-ratings", { classes: _this.classes, importances: _this.importances }, 1); return true; }); }; // </nowiki> },{"./api":15,"./cache":17,"./config":18,"./util":23}],4:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _config = _interopRequireDefault(require("../../config")); var _BannerWidget = _interopRequireDefault(require("./BannerWidget")); var _util = require("../../util"); var _ParameterWidget = _interopRequireDefault(require("./ParameterWidget")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } // <nowiki> var BannerListWidget = function BannerListWidget(config) { config = config || {}; // Call parent constructor BannerListWidget.parent.call(this, config); OO.ui.mixin.GroupElement.call(this, { $group: this.$element }); this.$element.addClass("rater-bannerListWidget").css({ "padding": "20px 10px 16px 10px" }); // Prefs this.preferences = config.preferences; this.oresClass = config.oresClass; this.changed = false; // Events this.aggregate({ "remove": "bannerRemove" }); this.connect(this, { "bannerRemove": "onBannerRemove" }); this.aggregate({ "changed": "bannerChanged" }); this.connect(this, { "bannerChanged": "setChanged" }); this.aggregate({ "biographyBannerChange": "biographyBannerChanged" }); this.connect(this, { "biographyBannerChanged": "syncShellTemplateWithBiographyBanner" }); this.aggregate({ "updatedSize": "bannerUpdatedSize" }); this.connect(this, { "bannerUpdatedSize": "onUpdatedSize" }); }; OO.inheritClass(BannerListWidget, OO.ui.Widget); OO.mixinClass(BannerListWidget, OO.ui.mixin.GroupElement); /* methods from mixin: - addItems( items, [index] ) : OO.ui.Element (CHAINABLE) - clearItems( ) : OO.ui.Element (CHAINABLE) - findItemFromData( data ) : OO.ui.Element|null - findItemsFromData( data ) : OO.ui.Element[] - removeItems( items ) : OO.ui.Element (CHAINABLE) */ BannerListWidget.prototype.onUpdatedSize = function () { // Emit an "updatedSize" event so the parent window can update size, if needed this.emit("updatedSize"); }; BannerListWidget.prototype.setChanged = function () { this.changed = true; }; BannerListWidget.prototype.onBannerRemove = function (banner) { this.removeItems([banner]); this.setChanged(); }; BannerListWidget.prototype.syncShellTemplateWithBiographyBanner = function (biographyBanner) { biographyBanner = biographyBanner || this.items.find(function (banner) { return banner.mainText === "WikiProject Biography" || banner.redirectTargetMainText === "WikiProject Biography"; }); if (!biographyBanner) return; var bannerShellTemplate = this.items.find(function (banner) { return banner.mainText === _config["default"].shellTemplates[0] || banner.redirectTargetMainText === _config["default"].shellTemplates[0]; }); if (!bannerShellTemplate) { return; } var paramsToSync = [{ name: "living", normalise: true }, { name: "blpo", normalise: true }, { name: "activepol", normalise: true }, { name: "listas", normalise: false }]; paramsToSync.forEach(function (paramToSync) { var _map = [biographyBanner, bannerShellTemplate].map(function (banner) { return banner.parameterList.getParameterItems().find(function (parameter) { return parameter.name === paramToSync.name || banner.paramAliases[parameter.name] === paramToSync.name; }); }), _map2 = _slicedToArray(_map, 2), biographyParam = _map2[0], shellParam = _map2[1]; if (!biographyParam) return; var paramSyncValue = paramToSync.normalise ? (0, _util.normaliseYesNo)(biographyParam.value) : biographyParam.value; biographyParam["delete"](); if (!shellParam && paramSyncValue) { var index = bannerShellTemplate.addParameterLayout.isVisible() ? -1 // Insert at the very end : bannerShellTemplate.parameterList.items.length - 1; // Insert prior to the "add parameter" button bannerShellTemplate.parameterList.addItems([new _ParameterWidget["default"]({ "name": paramToSync.name, "value": paramSyncValue, "autofilled": true }, bannerShellTemplate.paramData && bannerShellTemplate.paramData[paramToSync.name])], index); } else if (!biographyParam.autofilled && paramSyncValue) { shellParam.setValue(paramSyncValue); shellParam.setAutofilled(); } }); }; BannerListWidget.prototype.addShellTemplateIfNeeeded = function () { var _this = this; if (!this.items.some(function (banner) { return banner.isShellTemplate; })) { _BannerWidget["default"].newFromTemplateName(_config["default"].shellTemplates[0], { withoutRatings: true }, { preferences: this.preferences, isArticle: this.pageInfo.isArticle }).then(function (shellBannerWidget) { OO.ui.mixin.GroupElement.prototype.addItems.call(_this, [shellBannerWidget], 0); // Autofill ratings (if able to) _this.autofillClassRatings({ forBannerShell: true }); // emit updatedSize event _this.onUpdatedSize(); }); } return this; }; BannerListWidget.prototype.addItems = function (items, index) { if (items.length === 0) { return this; } // Call mixin method to do the adding OO.ui.mixin.GroupElement.prototype.addItems.call(this, items, index); // Autofill ratings (if able to, and if enabled in preferences) if (!this.items.some(function (banner) { return banner.isShellTemplate; })) { this.autofillClassRatings(); } this.autofillImportanceRatings(); // emit updatedSize event this.onUpdatedSize(); return this; }; BannerListWidget.prototype.autofillClassRatings = function (config) { config = config || {}; // Only autofill if set in preferences if (!this.preferences.autofillClassFromOthers && !this.preferences.autofillClassFromOres && !config.forBannerShell) { return; } // Check what banners already have var uniqueClassRatings = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.items, function (banner) { if (banner.isShellTemplate || !banner.hasClassRatings) { return false; } var classItem = banner.classDropdown.getMenu().findSelectedItem(); return classItem && classItem.getData(); }, function (banner) { return banner.classDropdown.getMenu().findSelectedItem().getData(); })); // Can't autofill if there isn't either a single value, or no value if (uniqueClassRatings.length > 1) { return; } // Determine what to autofill with var autoClass; if (uniqueClassRatings.length === 1 && (this.preferences.autofillClassFromOthers || config.forBannerShell)) { autoClass = uniqueClassRatings[0]; } else if (uniqueClassRatings.length === 0 && this.preferences.autofillClassFromOres && this.oresClass) { // Don't autofill above C-class switch (this.oresClass) { case "Stub": case "Start": case "C": case "List": autoClass = this.oresClass; } } else { // nothing to do return; } // Do the autofilling this.items.forEach(function (banner) { if (!banner.hasClassRatings && !banner.isShellTemplate) { return; } var classItem = banner.classDropdown.getMenu().findSelectedItem(); if (classItem && classItem.getData() && !config.forBannerShell) { return; } if (config.forBannerShell && !banner.isShellTemplate && classItem.getData() === autoClass) { banner.classDropdown.getMenu().selectItemByData(null); return; } banner.classDropdown.getMenu().selectItemByData(autoClass); banner.classDropdown.setAutofilled(true); }); }; BannerListWidget.prototype.autofillImportanceRatings = function () { if (!this.preferences.autofillImportance) { return; } var isRegularArticle = this.pageInfo && this.pageInfo.isArticle && !this.pageInfo.redirect && !this.pageInfo.isDisambig; if (!isRegularArticle) { return; } // TODO: Should try to find a smarter, banner-specific way of determining importance. // Maybe do something with ORES's "drafttopic" model. var autoImportance = "Low"; this.items.forEach(function (banner) { if (!banner.hasImportanceRatings) { return; } var importanceItem = banner.importanceDropdown.getMenu().findSelectedItem(); if (importanceItem && importanceItem.getData()) { return; } banner.importanceDropdown.getMenu().selectItemByData(autoImportance); banner.importanceDropdown.setAutofilled(true); }); }; BannerListWidget.prototype.setPreferences = function (prefs) { this.preferences = prefs; this.items.forEach(function (banner) { return banner.setPreferences(prefs); }); this.autofillClassRatings(); this.autofillImportanceRatings(); }; BannerListWidget.prototype.makeWikitext = function () { var bannersWikitext = (0, _util.filterAndMap)(this.items, function (banner) { return !banner.isShellTemplate; }, function (banner) { return banner.makeWikitext(); }).join("\n"); var shellTemplate = this.items.find(function (banner) { return banner.isShellTemplate; }); if (!shellTemplate) { return bannersWikitext; } var shellParam1 = new _ParameterWidget["default"]({ name: "1", value: "\n" + bannersWikitext + "\n" + (shellTemplate.nonStandardTemplates ? shellTemplate.nonStandardTemplates + "\n" : "") }); shellTemplate.parameterList.addItems([shellParam1]); var shellWikitext = shellTemplate.makeWikitext(); shellTemplate.parameterList.removeItems([shellParam1]); return shellWikitext; }; var _default = exports["default"] = BannerListWidget; // </nowiki> },{"../../config":18,"../../util":23,"./BannerWidget":5,"./ParameterWidget":9}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _ParameterListWidget = _interopRequireDefault(require("./ParameterListWidget")); var _ParameterWidget = _interopRequireDefault(require("./ParameterWidget")); var _DropdownParameterWidget = _interopRequireDefault(require("./DropdownParameterWidget")); var _SuggestionLookupTextInputWidget = _interopRequireDefault(require("./SuggestionLookupTextInputWidget")); var _util = require("../../util"); var _Template = require("../../Template"); var _HorizontalLayoutWidget = _interopRequireDefault(require("./HorizontalLayoutWidget")); var _config = _interopRequireDefault(require("../../config")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // <nowiki> function BannerWidget(template, config) { var _this = this; // Configuration initialization config = config || {}; // Call parent constructor BannerWidget["super"].call(this, config); this.$overlay = config.$overlay; /* --- PREFS --- */ this.preferences = config.preferences; /* --- PROPS --- */ this.paramData = template.paramData; this.paramAliases = template.paramAliases || {}; this.parameterSuggestions = template.parameterSuggestions; this.name = template.name; this.wikitext = template.wikitext; this.pipeStyle = template.pipeStyle; this.equalsStyle = template.equalsStyle; this.endBracesStyle = template.endBracesStyle; this.mainText = template.getTitle().getMainText(); this.redirectTargetMainText = template.redirectTarget && template.redirectTarget.getMainText(); this.isShellTemplate = template.isShellTemplate(); this.changed = template.parameters.some(function (parameter) { return parameter.autofilled; }); // initially false, unless some parameters were autofilled this.hasClassRatings = template.classes && template.classes.length; this.hasImportanceRatings = template.importances && template.importances.length; this.inactiveProject = template.inactiveProject; /* --- TITLE AND RATINGS --- */ this.removeButton = new OO.ui.ButtonWidget({ icon: "trash", label: "Remove banner", title: "Remove banner", flags: "destructive", $element: $("<div style=\"width:100%\">") }); this.clearButton = new OO.ui.ButtonWidget({ icon: "cancel", label: "Clear parameters", title: "Clear parameters", flags: "destructive", $element: $("<div style=\"width:100%\">") }); this.removeButton.$element.find("a").css("width", "100%"); this.clearButton.$element.find("a").css("width", "100%"); this.titleButtonsGroup = new OO.ui.ButtonGroupWidget({ items: [this.removeButton, this.clearButton], $element: $("<span style='width:100%;'>") }); this.mainLabelPopupButton = new OO.ui.PopupButtonWidget({ label: "{{".concat(template.getTitle().getMainText(), "}}").concat(this.inactiveProject ? " (inactive)" : ""), $element: $("<span style='display:inline-block;width:48%;margin-right:0;padding-right:8px'>"), $overlay: this.$overlay, indicator: "down", framed: false, popup: { $content: this.titleButtonsGroup.$element, width: 200, padded: false, align: "force-right", anchor: false } }); this.mainLabelPopupButton.$element.children("a").first().css({ "font-size": "110%" }).find("span.oo-ui-labelElement-label").css({ "white-space": "normal" }); // Rating dropdowns if (this.isShellTemplate) { this.classDropdown = new _DropdownParameterWidget["default"]({ label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">Class</span>"), menu: { items: [new OO.ui.MenuOptionWidget({ data: null, label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(".concat(config.isArticle ? "no class" : "auto-detect", ")</span>")) })].concat(_toConsumableArray(_config["default"].bannerDefaults.classes.map(function (classname) { return new OO.ui.MenuOptionWidget({ data: classname, label: classname }); }))) }, $overlay: this.$overlay }); var shellClassParam = template.parameters.find(function (parameter) { return parameter.name === "class"; }); this.classDropdown.getMenu().selectItemByData(shellClassParam && (0, _util.classMask)(shellClassParam.value)); } else if (this.hasClassRatings) { this.classDropdown = new _DropdownParameterWidget["default"]({ label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">Class</span>"), menu: { items: [new OO.ui.MenuOptionWidget({ data: null, label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(".concat(config.isArticle ? "inherit from shell" : "auto-detect", ")</span>")) })].concat(_toConsumableArray(template.classes.map(function (classname) { return new OO.ui.MenuOptionWidget({ data: classname, label: classname }); }))) }, $overlay: this.$overlay }); var classParam = template.parameters.find(function (parameter) { return parameter.name === "class"; }); this.classDropdown.getMenu().selectItemByData(classParam && (0, _util.classMask)(classParam.value)); } if (this.hasImportanceRatings) { this.importanceDropdown = new _DropdownParameterWidget["default"]({ label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">Importance</span>"), menu: { items: [new OO.ui.MenuOptionWidget({ data: null, label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(".concat(config.isArticle ? "no importance" : "auto-detect", ")</span>")) })].concat(_toConsumableArray(template.importances.map(function (importance) { return new OO.ui.MenuOptionWidget({ data: importance, label: importance }); }))) }, $overlay: this.$overlay }); var importanceParam = template.parameters.find(function (parameter) { return parameter.name === "importance"; }); this.importanceDropdown.getMenu().selectItemByData(importanceParam && (0, _util.importanceMask)(importanceParam.value)); } this.titleLayout = new OO.ui.HorizontalLayout({ items: [this.mainLabelPopupButton] }); if (this.hasClassRatings || this.isShellTemplate) { this.titleLayout.addItems([this.classDropdown]); } if (this.hasImportanceRatings) { this.titleLayout.addItems([this.importanceDropdown]); } /* --- PARAMETERS LIST --- */ var parameterWidgets = (0, _util.filterAndMap)(template.parameters, function (param) { if (_this.isShellTemplate) { if (param.name == "1") { _this.shellParam1Value = param.value; return false; } return param.name !== "class"; } return param.name !== "class" && param.name !== "importance"; }, function (param) { return new _ParameterWidget["default"](param, template.paramData[param.name], { $overlay: _this.$overlay }); }); this.parameterList = new _ParameterListWidget["default"]({ items: parameterWidgets, preferences: this.preferences }); /* --- ADD PARAMETER SECTION --- */ this.addParameterNameInput = new _SuggestionLookupTextInputWidget["default"]({ suggestions: template.parameterSuggestions, placeholder: "parameter name", $element: $("<div style='display:inline-block;width:40%'>"), validate: function (val) { var _this$getAddParameter = this.getAddParametersInfo(val), validName = _this$getAddParameter.validName, name = _this$getAddParameter.name, value = _this$getAddParameter.value; return !name && !value ? true : validName; }.bind(this), allowSuggestionsWhenEmpty: true, $overlay: this.$overlay }); this.updateAddParameterNameSuggestions(); this.addParameterValueInput = new _SuggestionLookupTextInputWidget["default"]({ placeholder: "parameter value", $element: $("<div style='display:inline-block;width:40%'>"), validate: function (val) { var _this$getAddParameter2 = this.getAddParametersInfo(null, val), validValue = _this$getAddParameter2.validValue, name = _this$getAddParameter2.name, value = _this$getAddParameter2.value; return !name && !value ? true : validValue; }.bind(this), allowSuggestionsWhenEmpty: true, $overlay: this.$overlay }); this.addParameterButton = new OO.ui.ButtonWidget({ label: "Add", icon: "add", flags: "progressive" }).setDisabled(true); this.addParameterControls = new _HorizontalLayoutWidget["default"]({ items: [this.addParameterNameInput, new OO.ui.LabelWidget({ label: "=" }), this.addParameterValueInput, this.addParameterButton] }); this.addParameterLayout = new OO.ui.FieldLayout(this.addParameterControls, { label: "Add parameter:", align: "top" }).toggle(false); // A hack to make messages appear on their own line this.addParameterLayout.$element.find(".oo-ui-fieldLayout-messages").css({ "clear": "both", "padding-top": 0 }); /* --- OVERALL LAYOUT/DISPLAY --- */ // Display the layout elements, and a rule this.$element.addClass("rater-bannerWidget").append(this.titleLayout.$element, this.parameterList.$element, this.addParameterLayout.$element); if (!this.isShellTemplate) { this.$element.append($("<hr>")); } if (this.isShellTemplate) { this.$element.css({ "background": "#eee", "border-radius": "10px", "padding": "0 10px 5px", "margin-bottom": "12px", "font-size": "92%" }); } /* --- EVENT HANDLING --- */ if (this.hasClassRatings) { this.classDropdown.connect(this, { "change": "onClassChange" }); } if (this.hasImportanceRatings) { this.importanceDropdown.connect(this, { "change": "onImportanceChange" }); } this.parameterList.connect(this, { "change": "onParameterChange", "addParametersButtonClick": "showAddParameterInputs", "updatedSize": "onUpdatedSize" }); this.addParameterButton.connect(this, { "click": "onParameterAdd" }); this.addParameterNameInput.connect(this, { "change": "onAddParameterNameChange", "enter": "onAddParameterNameEnter", "choose": "onAddParameterNameEnter" }); this.addParameterValueInput.connect(this, { "change": "onAddParameterValueChange", "enter": "onAddParameterValueEnter", "choose": "onAddParameterValueEnter" }); this.removeButton.connect(this, { "click": "onRemoveButtonClick" }); this.clearButton.connect(this, { "click": "onClearButtonClick" }); /* --- APPLY PREF -- */ if (this.preferences.bypassRedirects) { this.bypassRedirect(); } } OO.inheritClass(BannerWidget, OO.ui.Widget); /** * @param {String} templateName * @param {Object} [data] * @param {Boolean} data.withoutRatings * @param {Boolean} data.isWrapper * @param {Object} config * @returns {Promise<BannerWidget>} */ BannerWidget.newFromTemplateName = function (templateName, data, config) { var template = new _Template.Template(); template.name = templateName; if (data && data.withoutRatings) { template.withoutRatings = true; } return (0, _Template.getWithRedirectTo)(template).then(function (template) { return $.when(template.setClassesAndImportances(), template.setParamDataAndSuggestions()).then(function () { // Add missing required/suggested values template.addMissingParams(); // Return the now-modified template return template; }); }).then(function (template) { return new BannerWidget(template, config); }); }; BannerWidget.prototype.onUpdatedSize = function () { // Emit an "updatedSize" event so the parent window can update size, if needed this.emit("updatedSize"); }; BannerWidget.prototype.setChanged = function () { this.changed = true; this.emit("changed"); if (this.mainText === "WikiProject Biography" || this.redirectTargetMainText === "WikiProject Biography") { // Emit event so BannerListWidget can update the banner shell template (if present) this.emit("biographyBannerChange"); } }; BannerWidget.prototype.onParameterChange = function () { this.setChanged(); this.updateAddParameterNameSuggestions(); }; BannerWidget.prototype.onClassChange = function () { this.setChanged(); this.classChanged = true; var classItem = this.classDropdown.getMenu().findSelectedItem(); if (classItem && classItem.getData() == null) { // clear selection this.classDropdown.getMenu().selectItem(); } }; BannerWidget.prototype.onImportanceChange = function () { this.setChanged(); this.importanceChanged = true; var importanceItem = this.importanceDropdown.getMenu().findSelectedItem(); if (importanceItem && importanceItem.getData() == null) { // clear selection this.importanceDropdown.getMenu().selectItem(); } }; BannerWidget.prototype.showAddParameterInputs = function () { this.addParameterLayout.toggle(true); this.addParameterNameInput.focus(); this.onUpdatedSize(); }; BannerWidget.prototype.getAddParametersInfo = function (nameInputVal, valueInputVal) { var name = nameInputVal && nameInputVal.trim() || this.addParameterNameInput.getValue().trim(); var paramAlreadyIncluded = name === "class" || name === "importance" || name === "1" && this.isShellTemplate || this.parameterList.getParameterItems().some(function (paramWidget) { return paramWidget.name === name; }); var value = valueInputVal && valueInputVal.trim() || this.addParameterValueInput.getValue().trim(); var autovalue = name && this.paramData[name] && this.paramData[name].autovalue || null; return { validName: !!(name && !paramAlreadyIncluded), validValue: !!(value || autovalue), isAutovalue: !!(!value && autovalue), isAlreadyIncluded: !!(name && paramAlreadyIncluded), name: name, value: value, autovalue: autovalue }; }; BannerWidget.prototype.onAddParameterNameChange = function () { var _this$getAddParameter3 = this.getAddParametersInfo(), validName = _this$getAddParameter3.validName, validValue = _this$getAddParameter3.validValue, isAutovalue = _this$getAddParameter3.isAutovalue, isAlreadyIncluded = _this$getAddParameter3.isAlreadyIncluded, name = _this$getAddParameter3.name, autovalue = _this$getAddParameter3.autovalue; // Set value input placeholder as the autovalue this.addParameterValueInput.$input.attr("placeholder", autovalue || ""); // Set suggestions, if the parameter has a list of allowed values var allowedValues = this.paramData[name] && this.paramData[name].allowedValues && this.paramData[name].allowedValues.map(function (val) { return { data: val, label: val }; }); this.addParameterValueInput.setSuggestions(allowedValues || []); // Set button disabled state based on validity this.addParameterButton.setDisabled(!validName || !validValue); // Show notice if autovalue will be used this.addParameterLayout.setNotices(validName && isAutovalue ? ["Parameter value will be autofilled"] : []); // Show error is the banner already has the parameter set this.addParameterLayout.setErrors(isAlreadyIncluded ? ["Parameter is already present"] : []); }; BannerWidget.prototype.onAddParameterNameEnter = function () { this.addParameterValueInput.focus(); }; BannerWidget.prototype.onAddParameterValueChange = function () { var _this$getAddParameter4 = this.getAddParametersInfo(), validName = _this$getAddParameter4.validName, validValue = _this$getAddParameter4.validValue, isAutovalue = _this$getAddParameter4.isAutovalue; this.addParameterButton.setDisabled(!validName || !validValue); this.addParameterLayout.setNotices(validName && isAutovalue ? ["Parameter value will be autofilled"] : []); }; BannerWidget.prototype.onAddParameterValueEnter = function () { // Make sure button state has been updated this.onAddParameterValueChange(); // Do nothing if button is disabled (i.e. name and/or value are invalid) if (this.addParameterButton.isDisabled()) { return; } // Add parameter this.onParameterAdd(); }; BannerWidget.prototype.onParameterAdd = function () { var _this$getAddParameter5 = this.getAddParametersInfo(), validName = _this$getAddParameter5.validName, validValue = _this$getAddParameter5.validValue, name = _this$getAddParameter5.name, value = _this$getAddParameter5.value, autovalue = _this$getAddParameter5.autovalue; if (!validName || !validValue) { // Error should already be shown via onAddParameter...Change methods return; } var newParameter = new _ParameterWidget["default"]({ "name": name, "value": value || autovalue }, this.paramData[name], { $overlay: this.$overlay }); this.parameterList.addItems([newParameter]); this.addParameterNameInput.setValue(""); this.addParameterValueInput.setValue(""); this.addParameterNameInput.$input.focus(); }; BannerWidget.prototype.updateAddParameterNameSuggestions = function () { var paramsInUse = {}; this.parameterList.getParameterItems().forEach(function (paramWidget) { return paramsInUse[paramWidget.name] = true; }); this.addParameterNameInput.setSuggestions(this.parameterSuggestions.filter(function (suggestion) { return !paramsInUse[suggestion.data]; })); }; BannerWidget.prototype.onRemoveButtonClick = function () { this.emit("remove"); }; BannerWidget.prototype.onClearButtonClick = function () { this.parameterList.clearItems(this.parameterList.getParameterItems()); if (this.hasClassRatings) { this.classDropdown.getMenu().selectItem(); } if (this.hasImportanceRatings) { this.importanceDropdown.getMenu().selectItem(); } }; BannerWidget.prototype.bypassRedirect = function () { if (!this.redirectTargetMainText) { return; } // Store the bypassed name this.bypassedName = this.name; // Update title label this.mainLabelPopupButton.setLabel("{{".concat(this.redirectTargetMainText, "}}").concat(this.inactiveProject ? " (inactive)" : "")); // Update properties this.name = this.redirectTargetMainText; this.mainText = this.redirectTargetMainText; this.redirectTargetMainText = null; this.setChanged(); }; BannerWidget.prototype.makeWikitext = function () { if (!this.changed && this.wikitext) { return this.wikitext; } var pipe = this.pipeStyle; var equals = this.equalsStyle; var classItem = (this.hasClassRatings || this.isShellTemplate) && this.classDropdown.getMenu().findSelectedItem(); var classVal = classItem && classItem.getData(); var importanceItem = this.hasImportanceRatings && this.importanceDropdown.getMenu().findSelectedItem(); var importanceVal = importanceItem && importanceItem.getData(); return ("{{" + this.name + ((this.hasClassRatings || this.isShellTemplate) && classVal != null ? "".concat(pipe, "class").concat(equals).concat(classVal || "") : "") + (this.hasImportanceRatings && importanceVal != null ? "".concat(pipe, "importance").concat(equals).concat(importanceVal || "") : "") + this.parameterList.getParameterItems().map(function (parameter) { return parameter.makeWikitext(pipe, equals); }).join("") + this.endBracesStyle).replace(/\n+}}$/, "\n}}"); // avoid empty line at end like [[Special:Diff/925982142]] }; BannerWidget.prototype.setPreferences = function (prefs) { this.preferences = prefs; if (this.preferences.bypassRedirects) { this.bypassRedirect(); } this.parameterList.setPreferences(prefs); }; var _default = exports["default"] = BannerWidget; // </nowiki> },{"../../Template":3,"../../config":18,"../../util":23,"./DropdownParameterWidget":6,"./HorizontalLayoutWidget":7,"./ParameterListWidget":8,"./ParameterWidget":9,"./SuggestionLookupTextInputWidget":11}],6:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; // <nowiki> function DropdownParameterWidget(config) { // Configuration initialization config = $.extend({ $element: $("<span style='display:inline-block;width:24%'>") }, config || {}); // Call parent constructor DropdownParameterWidget["super"].call(this, config); this.$overlay = config.$overlay; this.$element.addClass("rater-dropdownParameterWidget"); // Autofilled icon this.autofilled = !!config.autofilled; this.autofilledIcon = new OO.ui.IconWidget({ icon: "robot", title: "Autofilled by Rater", flags: "progressive", $element: $("<span style='margin: 0 -5px 0 5px;min-width: 16px;width: 16px;left:unset;'>") }).toggle(this.autofilled); this.$element.find(".oo-ui-indicatorElement-indicator").before(this.autofilledIcon.$element); // Events this.menu.connect(this, { "choose": "onDropdownMenuChoose", "select": "onDropdownMenuSelect" }); } OO.inheritClass(DropdownParameterWidget, OO.ui.DropdownWidget); DropdownParameterWidget.prototype.setAutofilled = function (setAutofill) { this.autofilledIcon.toggle(!!setAutofill); this.$element.find(".oo-ui-dropdownWidget-handle").css({ "border": setAutofill ? "1px dashed #36c" : "" }); this.autofilled = !!setAutofill; }; DropdownParameterWidget.prototype.onDropdownMenuChoose = function () { this.setAutofilled(false); this.emit("change"); }; DropdownParameterWidget.prototype.onDropdownMenuSelect = function () { this.emit("change"); }; DropdownParameterWidget.prototype.getValue = function () { var selectedItem = this.menu.findSelectedItem(); return selectedItem && selectedItem.getData(); }; var _default = exports["default"] = DropdownParameterWidget; // </nowiki> },{}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // <nowiki> /** * A HorizontalLayout that is also a widget, and can thus be placed within * field layouts. * * @class * @param {*} config configuration for OO.ui.HorizontalLayout */ function HorizontalLayoutWidget(config) { // Configuration initialization config = config || {}; // Call parent constructor HorizontalLayoutWidget["super"].call(this, {}); this.layout = new OO.ui.HorizontalLayout(_objectSpread(_objectSpread({}, config), {}, { $element: this.$element })); } OO.inheritClass(HorizontalLayoutWidget, OO.ui.Widget); var _default = exports["default"] = HorizontalLayoutWidget; // </nowiki> },{}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; // <nowiki> /** * @cfg {OO.ui.Element[]} items Items to be added * @cfg {Number} displayLimit The most to show at once. If the number of items * is more than this, then only the first (displayLimit - 1) items are shown. */ var ParameterListWidget = function ParameterListWidget(config) { config = config || {}; // Call parent constructor ParameterListWidget.parent.call(this, config); OO.ui.mixin.GroupElement.call(this, { $group: this.$element }); this.addItems(config.items); this.$element.addClass("rater-parameterListWidget"); this.preferences = config.preferences; // Hide some parameters (initially), if more than set display limit -- which is the // one more than collapseParamsLowerLimit, to prevent only one param being hidden // (mostly: may occasionally occur if params were auto-filled). var displayLimit = this.preferences.collapseParamsLowerLimit + 1; if (displayLimit && this.items.length > displayLimit) { var hideFromNumber = displayLimit - 1; // One-indexed var hideFromIndex = hideFromNumber - 1; // Zero-indexed var hiddenCount = 0; for (var i = hideFromIndex; i < this.items.length; i++) { if (!this.items[i].autofilled) { // Don't hide auto-filled params this.items[i].toggle(false); hiddenCount++; } } if (hiddenCount > 0) { // Add button to show the hidden params this.showMoreParametersButton = new OO.ui.ButtonWidget({ label: "Show " + hiddenCount + " more " + (hiddenCount === 1 ? "parameter" : "parameters"), framed: false, $element: $("<span style='margin-bottom:0'>") }); this.addItems([this.showMoreParametersButton]); } } // Add the button that allows user to add more parameters this.addParametersButton = new OO.ui.ButtonWidget({ label: "Add parameter", icon: "add", framed: false, $element: $("<span style='margin-bottom:0'>") }); this.addItems([this.addParametersButton]); /* --- Events --- */ // Handle delete events from ParameterWidgets this.aggregate({ "delete": "parameterDelete" }); this.connect(this, { parameterDelete: "onParameterDelete" }); // Handle change events from ParameterWidgets this.aggregate({ change: "parameterChange" }); this.connect(this, { parameterChange: "onParameterChange" }); // Handle updatedSize events from ParameterWidgets this.aggregate({ "updatedSize": "parameterUpdatedSize" }); this.connect(this, { "parameterUpdatedSize": "onUpdatedSize" }); // Handle button clicks if (this.showMoreParametersButton) { this.showMoreParametersButton.connect(this, { "click": "onShowMoreParametersButtonClick" }); } this.addParametersButton.connect(this, { "click": "onAddParametersButtonClick" }); }; OO.inheritClass(ParameterListWidget, OO.ui.Widget); OO.mixinClass(ParameterListWidget, OO.ui.mixin.GroupElement); /* methods from mixin: - addItems( items, [index] ) : OO.ui.Element (CHAINABLE) - clearItems( ) : OO.ui.Element (CHAINABLE) - findItemFromData( data ) : OO.ui.Element|null - findItemsFromData( data ) : OO.ui.Element[] - removeItems( items ) : OO.ui.Element (CHAINABLE) */ ParameterListWidget.prototype.onUpdatedSize = function () { // Emit an "updatedSize" event so the parent window can update size, if needed this.emit("updatedSize"); }; ParameterListWidget.prototype.addItems = function (items, index) { if (items.length === 0) { return this; } // Call mixin method to do the adding OO.ui.mixin.GroupElement.prototype.addItems.call(this, items, index); // emit updatedSize event this.onUpdatedSize(); return this; }; ParameterListWidget.prototype.onParameterDelete = function (parameter) { this.removeItems([parameter]); this.emit("change"); }; ParameterListWidget.prototype.onParameterChange = function () { this.emit("change"); }; ParameterListWidget.prototype.getParameterItems = function () { return this.items.filter(function (item) { return item.constructor.name === "ParameterWidget"; }); }; ParameterListWidget.prototype.onShowMoreParametersButtonClick = function () { this.removeItems([this.showMoreParametersButton]); this.items.forEach(function (parameterWidget) { return parameterWidget.toggle(true); }); this.onUpdatedSize(); }; ParameterListWidget.prototype.onAddParametersButtonClick = function () { this.removeItems([this.addParametersButton]); this.emit("addParametersButtonClick"); }; ParameterListWidget.prototype.makeWikitext = function (pipeStyle, equalsStyle) { return this.getParameterItems().map(function (parameter) { return parameter.makeWikitext(pipeStyle, equalsStyle); }).join(""); }; ParameterListWidget.prototype.setPreferences = function (prefs) { this.preferences = prefs; var params = this.getParameterItems(); // Unhide some parameters of the collapseParamsLowerLimit has increased. // (Not hiding any if it decreased, since it's a *lower* limit of what needs to be shown.) if (params.length <= this.preferences.collapseParamsLowerLimit) { return; } var hiddenParams = params.filter(function (param) { return !param.isVisible(); }); var visibleParamsCount = params.length - hiddenParams.length; if (hiddenParams === 0 || visibleParamsCount >= this.preferences.collapseParamsLowerLimit) { return; } var numToUnhide = Math.min(this.preferences.collapseParamsLowerLimit - visibleParamsCount, hiddenParams.length); for (var i = 0; i < numToUnhide; i++) { hiddenParams[i].toggle(true); } var stillHiddenCount = hiddenParams.length - numToUnhide; if (stillHiddenCount === 0) { this.removeItems([this.showMoreParametersButton]); } else { this.showMoreParametersButton.setLabel("Show " + stillHiddenCount + " more " + (stillHiddenCount === 1 ? "paramter" : "paramters")); } }; var _default = exports["default"] = ParameterListWidget; // </nowiki> },{}],9:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _util = require("../../util"); var _HorizontalLayoutWidget = _interopRequireDefault(require("./HorizontalLayoutWidget")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } // <nowiki> function ParameterWidget(parameter, paramData, config) { // Configuration initialization config = config || {}; // Call parent constructor ParameterWidget["super"].call(this, config); this.$overlay = config.$overlay; this.name = parameter.name; this.value = parameter.value; this.autofilled = parameter.autofilled; this.isInvalid = parameter.value == null; this.paramData = paramData || {}; this.allowedValues = this.paramData.allowedValues || []; this.isRequired = this.paramData.required; this.isSuggested = this.paramData.suggested; // Make a checkbox if only 1 or 2 allowed values switch (this.allowedValues.length) { /* eslint-disable no-fallthrough */ case 1: this.allowedValues[1] = null; /* fall-through */ case 2: var isFirstAllowedVal = this.allowedValues.indexOf(parameter.value) === 0 || this.allowedValues.map(_util.normaliseYesNo).indexOf((0, _util.normaliseYesNo)(parameter.value)) === 0; var isSecondAllowedVal = this.allowedValues.indexOf(parameter.value || null) === 1 || this.allowedValues.map(_util.normaliseYesNo).indexOf(parameter.value ? (0, _util.normaliseYesNo)(parameter.value) : null) === 1; var isIndeterminate = !isFirstAllowedVal && !isSecondAllowedVal; this.checkbox = new OO.ui.CheckboxInputWidget({ selected: isIndeterminate ? undefined : isFirstAllowedVal, indeterminate: isIndeterminate ? true : undefined, $element: $("<label style='margin:0 0 0 5px'>") }); break; default: // No checkbox } /* eslint-enable no-fallthrough */ /* --- EDIT PARAMETER LAYOUT --- */ this.input = new OO.ui.ComboBoxInputWidget({ value: this.value, // label: parameter.name + " =", // labelPosition: "before", options: (0, _util.filterAndMap)(this.allowedValues, function (val) { return val !== null; }, function (val) { return { data: val, label: val }; }), $element: $("<div style='margin-bottom:0;'>"), $overlay: this.$overlay }); // Reduce the excessive whitespace/height this.input.$element.find("input").css({ "padding-top": 0, "padding-bottom": "2px", "height": "24px" }); // Fix label positioning within the reduced height this.input.$element.find("span.oo-ui-labelElement-label").css({ "line-height": "normal" }); // Also reduce height of dropdown button (if options are present) this.input.$element.find("a.oo-ui-buttonElement-button").css({ "padding-top": 0, "height": "24px", "min-height": "0" }); this.confirmButton = new OO.ui.ButtonWidget({ icon: "check", label: "Done", framed: false, flags: "progressive", $element: $("<span style='margin-right:0'>") }); this.cancelButton = new OO.ui.ButtonWidget({ icon: "undo", label: "Cancel", framed: false }); this.deleteButton = new OO.ui.ButtonWidget({ icon: this.isRequired ? "restore" : "trash", label: this.isRequired ? "Required parameter" : "Delete", framed: false, flags: "destructive", disabled: this.isRequired }); this.editButtonControls = new OO.ui.ButtonGroupWidget({ items: [this.confirmButton, this.cancelButton, this.deleteButton], $element: $("<span style='font-size:92%'>") }); this.editButtonControls.$element.find("a span:first-child").css({ "min-width": "unset", "width": "16px", "margin-right": 0 }); this.editLayoutControls = new _HorizontalLayoutWidget["default"]({ items: [this.input, this.editButtonControls] //$element: $("<div style='width: 48%;margin:0;'>") }); this.editLayout = new OO.ui.FieldLayout(this.editLayoutControls, { label: this.name + " =", align: "top", help: this.paramData.description && this.paramData.description.en || false, helpInline: true }).toggle(); this.editLayout.$element.find("label.oo-ui-inline-help").css({ "margin": "-10px 0 5px 10px" }); /* --- READ (COLLAPSED) DISPLAY OF PARAMETER --- */ this.invalidIcon = new OO.ui.IconWidget({ icon: "block", title: "Invalid parameter: no value specified!", flags: "destructive", $element: $("<span style='margin: 0 5px 0 -5px; min-width: 16px; width: 16px;'>") }).toggle(this.isInvalid); this.fullLabel = new OO.ui.LabelWidget({ label: this.name + (this.value ? " = " + this.value : " "), $element: $("<label style='margin: 0;'>") }); this.autofilledIcon = new OO.ui.IconWidget({ icon: "robot", title: "Autofilled by Rater", flags: "progressive", $element: $("<span style='margin: 0 -5px 0 5px;min-width: 16px;width: 16px;'>") }).toggle(this.autofilled); this.editButton = new OO.ui.ButtonWidget({ icon: "edit", framed: false, $element: $("<span style='margin-bottom: 0;'>") }); this.editButton.$element.find("a").css({ "border-radius": "0 10px 10px 0", "margin-left": "5px" }); this.editButton.$element.find("a span").first().css({ "min-width": "unset", "width": "16px" }); this.readLayout = new OO.ui.HorizontalLayout({ items: [this.invalidIcon, this.fullLabel, this.autofilledIcon, this.editButton], $element: $("<span style='margin:0;width:unset;'>") }); if (this.checkbox) { this.readLayout.addItems([this.checkbox], 2); } /* --- CONTAINER FOR BOTH LAYOUTS --- */ this.$element = $("<div>").addClass("rater-parameterWidget").css({ "width": "unset", "display": "inline-block", "border": this.autofilled ? "1px dashed #36c" : "1px solid #ddd", "border-radius": "10px", "padding-left": "10px", "margin": "0 8px 8px 0", "background": this.isInvalid ? "#fddd" : "#fffe" }).append(this.readLayout.$element, this.editLayout.$element); this.editButton.connect(this, { "click": "onEditClick" }); this.confirmButton.connect(this, { "click": "onConfirmClick" }); this.cancelButton.connect(this, { "click": "onCancelClick" }); this.deleteButton.connect(this, { "click": "onDeleteClick" }); if (this.checkbox) { this.checkbox.connect(this, { "change": "onCheckboxChange" }); } } OO.inheritClass(ParameterWidget, OO.ui.Widget); ParameterWidget.prototype.onUpdatedSize = function () { // Emit an "updatedSize" event so the parent window can update size, if needed this.emit("updatedSize"); }; ParameterWidget.prototype.onEditClick = function () { this.readLayout.toggle(false); this.editLayout.toggle(true); this.$element.css({ "background": "#fffe" }); this.input.focus(); this.onUpdatedSize(); }; ParameterWidget.prototype.onConfirmClick = function () { this.setValue(this.input.getValue()); this.readLayout.toggle(true); this.editLayout.toggle(false); this.onUpdatedSize(); }; ParameterWidget.prototype.onCancelClick = function () { this.input.setValue(this.value); this.readLayout.toggle(true); this.editLayout.toggle(false); this.onUpdatedSize(); }; ParameterWidget.prototype.onDeleteClick = function () { this["delete"](); }; ParameterWidget.prototype.onCheckboxChange = function (isSelected, isIndeterminate) { if (isIndeterminate) { return; } if (isSelected) { this.setValue(this.allowedValues[0]); } else { this.setValue(this.allowedValues[1]); } }; ParameterWidget.prototype["delete"] = function () { this.emit("delete"); }; ParameterWidget.prototype.setValue = function (val) { // Turn off autofill stylings/icon this.autofilled = false; this.autofilledIcon.toggle(false); this.$element.css({ "border": "1px solid #ddd" }); // Update the stored value this.value = val; // Update the input value for edit mode this.input.setValue(this.value); // Update validity this.isInvalid = this.value == null; this.invalidIcon.toggle(this.isInvalid); this.$element.css({ "background": this.isInvalid ? "#fddd" : "#fffe" }); // Updated the label for read mode this.fullLabel.setLabel(this.name + (this.value ? " = " + this.value : "")); // Update the checkbox (if there is one) if (this.checkbox) { var isFirstAllowedVal = this.allowedValues.indexOf(val) === 0 || this.allowedValues.map(_util.normaliseYesNo).indexOf((0, _util.normaliseYesNo)(val)) === 0; var isSecondAllowedVal = this.allowedValues.indexOf(val || null) === 1 || this.allowedValues.map(_util.normaliseYesNo).indexOf(val ? (0, _util.normaliseYesNo)(val) : null) === 1; var isIndeterminate = !isFirstAllowedVal && !isSecondAllowedVal; this.checkbox.setIndeterminate(isIndeterminate, true); if (!isIndeterminate) { var isSelected = isFirstAllowedVal; this.checkbox.setSelected(isSelected, true); } } // Emit a change event this.emit("change"); }; ParameterWidget.prototype.setAutofilled = function () { this.autofilled = true; this.autofilledIcon.toggle(true); this.$element.css({ "border": "1px dashed #36c" }); }; ParameterWidget.prototype.makeWikitext = function (pipeStyle, equalsStyle) { if (this.isInvalid) { return ""; } return pipeStyle + this.name + equalsStyle + (this.value || ""); }; ParameterWidget.prototype.focusInput = function () { return this.input.focus(); }; var _default = exports["default"] = ParameterWidget; // </nowiki> },{"../../util":23,"./HorizontalLayoutWidget":7}],10:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _config = _interopRequireDefault(require("../../config")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } // <nowiki> function PrefsFormWidget(config) { // Configuration initialization config = config || {}; // Call parent constructor PrefsFormWidget["super"].call(this, config); this.$element.addClass("rater-prefsFormWidget"); this.layout = new OO.ui.FieldsetLayout({ label: "Preferences", $element: this.$element }); this.preferences = { "autostart": { input: new OO.ui.ToggleSwitchWidget(), label: "Autostart Rater" }, "autostartRedirects": { input: new OO.ui.ToggleSwitchWidget(), label: "Autostart on redirects" }, "autostartNamespaces": { input: new mw.widgets.NamespacesMultiselectWidget(), label: "Autostart in these namespaces" }, "bypassRedirects": { input: new OO.ui.ToggleSwitchWidget(), label: "Bypass redirects to banners" }, "autofillClassFromOthers": { input: new OO.ui.ToggleSwitchWidget(), label: "Autofill class from other banners" }, "autofillClassFromOres": { input: new OO.ui.ToggleSwitchWidget(), label: "Autofill class based on ORES prediction" }, "autofillImportance": { input: new OO.ui.ToggleSwitchWidget(), label: "Autofill low importance" }, "collapseParamsLowerLimit": { input: new OO.ui.NumberInputWidget({ "min": 1 }), label: "Minimum number of parameters to show uncollapsed" }, "watchlist": { input: new OO.ui.ButtonSelectWidget({ items: [new OO.ui.ButtonOptionWidget({ data: "preferences", label: "Default", title: "Uses the same setting as if you manually edited the page, as per Special:Preferences" }), new OO.ui.ButtonOptionWidget({ data: "watch", label: "Always", title: "Always add pages Rater edits to your watchlist" }), new OO.ui.ButtonOptionWidget({ data: "nochange", label: "Never", title: "Never add pages Rater edit to your watchlist" })] }).selectItemByData("preferences"), label: "Add edited pages to watchlist" }, "resetCache": { input: new OO.ui.ButtonWidget({ label: "Reset cache", title: "Remove cached data, including list of WikiProjects and template parameters", flags: ["destructive"] }) } }; for (var prefName in this.preferences) { this.layout.addItems([new OO.ui.FieldLayout(this.preferences[prefName].input, { label: this.preferences[prefName].label, align: "right" })]); } this.preferences.resetCache.input.connect(this, { "click": "onResetCacheClick" }); } OO.inheritClass(PrefsFormWidget, OO.ui.Widget); PrefsFormWidget.prototype.setPrefValues = function (prefs) { var _this = this; var _loop = function _loop() { var value = prefs[prefName]; var input = _this.preferences[prefName] && _this.preferences[prefName].input; switch (input && input.constructor.name) { case "OoUiButtonSelectWidget": input.selectItemByData(value); break; case "OoUiNumberInputWidget": case "OoUiToggleSwitchWidget": input.setValue(value); break; case "MwWidgetsNamespacesMultiselectWidget": input.clearItems(); value.forEach(function (ns) { return input.addTag(ns.toString(), ns === 0 ? "(Main)" : _config["default"].mw.wgFormattedNamespaces[ns]); }); break; } }; for (var prefName in prefs) { _loop(); } }; PrefsFormWidget.prototype.getPrefs = function () { var prefs = {}; for (var prefName in this.preferences) { var input = this.preferences[prefName].input; var value = void 0; switch (input.constructor.name) { case "OoUiButtonSelectWidget": value = input.findSelectedItem().getData(); break; case "OoUiToggleSwitchWidget": value = input.getValue(); break; case "OoUiNumberInputWidget": value = Number(input.getValue()); // widget uses strings, not numbers! break; case "MwWidgetsNamespacesMultiselectWidget": value = input.getValue().map(Number); // widget uses strings, not numbers! break; } prefs[prefName] = value; } return prefs; }; PrefsFormWidget.prototype.onResetCacheClick = function () { var _this2 = this; OO.ui.confirm("After reseting cache, Rater will close and restart. Any changes made will be discarded.").then(function (confirmed) { if (confirmed) { _this2.emit("resetCache"); } }); }; var _default = exports["default"] = PrefsFormWidget; // </nowiki> },{"../../config":18}],11:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; // <nowiki> var SuggestionLookupTextInputWidget = function SuggestionLookupTextInputWidget(config) { OO.ui.TextInputWidget.call(this, config); OO.ui.mixin.LookupElement.call(this, config); this.suggestions = Array.isArray(config.suggestions) ? config.suggestions : []; this.$element.addClass("rater-suggestionLookupTextInputWidget"); }; OO.inheritClass(SuggestionLookupTextInputWidget, OO.ui.TextInputWidget); OO.mixinClass(SuggestionLookupTextInputWidget, OO.ui.mixin.LookupElement); // Set suggestion. param: Object[] with objects of the form { data: ... , label: ... } SuggestionLookupTextInputWidget.prototype.setSuggestions = function (suggestions) { if (!Array.isArray(suggestions)) { if (suggestions != null) { console.warn("[Rater] SuggestionLookupTextInputWidget.prototype.setSuggestions called with a non-array value:", suggestions); } return; } this.suggestions = suggestions; }; // Returns data, as a resolution to a promise, to be passed to #getLookupMenuOptionsFromData SuggestionLookupTextInputWidget.prototype.getLookupRequest = function () { var deferred = $.Deferred().resolve(new RegExp("\\b" + mw.util.escapeRegExp(this.getValue()), "i")); return deferred.promise({ abort: function abort() {} }); }; // ??? SuggestionLookupTextInputWidget.prototype.getLookupCacheDataFromResponse = function (response) { return response || []; }; // Is passed data from #getLookupRequest, returns an array of menu item widgets SuggestionLookupTextInputWidget.prototype.getLookupMenuOptionsFromData = function (pattern) { var labelMatchesInputVal = function labelMatchesInputVal(suggestionItem) { return pattern.test(suggestionItem.label) || !suggestionItem.label && pattern.test(suggestionItem.data); }; var makeMenuOptionWidget = function makeMenuOptionWidget(optionItem) { return new OO.ui.MenuOptionWidget({ data: optionItem.data, label: optionItem.label || optionItem.data }); }; return this.suggestions.filter(labelMatchesInputVal).map(makeMenuOptionWidget); }; // Extend onLookupMenuChoose method to emit an choose event SuggestionLookupTextInputWidget.prototype.onLookupMenuChoose = function (item) { // Get data var itemData = item.getData(); // Simplify item data if it is an object with a name property if (itemData && itemData.name) { item.setData(itemData.name); } // First blur the input, to prevent the menu popping back up this.$input.blur(); OO.ui.mixin.LookupElement.prototype.onLookupMenuChoose.call(this, item); this.emit("choose", itemData); }; var _default = exports["default"] = SuggestionLookupTextInputWidget; // </nowiki> },{}],12:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _config = _interopRequireDefault(require("../../config")); var _SuggestionLookupTextInputWidget = _interopRequireDefault(require("./SuggestionLookupTextInputWidget")); var _getBanners = require("../../getBanners"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // <nowiki> function TopBarWidget(config) { var _this = this; // Configuration initialization config = $.extend({ expanded: false, framed: false, padded: false }, config || {}); // Call parent constructor TopBarWidget["super"].call(this, config); this.$overlay = config.$overlay; // Search box this.searchBox = new _SuggestionLookupTextInputWidget["default"]({ placeholder: "Add a WikiProject...", $element: $("<div style='display:inline-block; margin:0 -1px; width:calc(100% - 55px);'>"), $overlay: this.$overlay }); (0, _getBanners.getBannerNames)().then(function (banners) { return [].concat(_toConsumableArray(banners.withRatings.map(function (bannerName) { return { label: bannerName.replace("WikiProject ", ""), data: { name: bannerName } }; })), _toConsumableArray(banners.withoutRatings.map(function (bannerName) { return { label: bannerName.replace("WikiProject ", ""), data: { name: bannerName, withoutRatings: true } }; })), _toConsumableArray(banners.wrappers.map(function (bannerName) { return { label: bannerName.replace("WikiProject ", "") + " [template wrapper]", data: { name: bannerName, wrapper: true } }; })), _toConsumableArray(banners.notWPBM.map(function (bannerName) { return { label: bannerName.replace("WikiProject ", ""), data: { name: bannerName } }; })), _toConsumableArray(banners.inactive.map(function (bannerName) { return { label: bannerName.replace("WikiProject ", "") + " [inactive]", data: { name: bannerName, withoutRatings: true } }; })), _toConsumableArray(banners.wir.map(function (bannerName) { return { label: bannerName + " [Women In Red meetup/initiative]", data: { name: bannerName, withoutRatings: true } }; }))); }).then(function (bannerOptions) { return _this.searchBox.setSuggestions(bannerOptions); }); // Add button this.addBannerButton = new OO.ui.ButtonWidget({ icon: "add", title: "Add", flags: "progressive", $element: $("<span style='float:right;margin: 0;transform: translateX(-12px);'>") }); var $searchContainer = $("<div style='display:inline-block; flex-shrink:1; flex-grow:100; min-width:250px; width:50%;'>").append(this.searchBox.$element, this.addBannerButton.$element); // Set all classes/importances // in the style of a popup button with a menu (is actually a dropdown with a hidden label, because that makes the coding easier.) this.setAllDropDown = new OO.ui.DropdownWidget({ icon: "tag", label: "Set all...", invisibleLabel: true, menu: { items: [new OO.ui.MenuSectionOptionWidget({ label: "Classes" }), new OO.ui.MenuOptionWidget({ data: { "class": null }, label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(no class)</span>") })].concat(_toConsumableArray(_config["default"].bannerDefaults.classes.map(function (classname) { return new OO.ui.MenuOptionWidget({ data: { "class": classname }, label: classname }); })), [new OO.ui.MenuSectionOptionWidget({ label: "Importances" }), new OO.ui.MenuOptionWidget({ data: { importance: null }, label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(no importance)</span>") })], _toConsumableArray(_config["default"].bannerDefaults.importances.map(function (importance) { return new OO.ui.MenuOptionWidget({ data: { importance: importance }, label: importance }); }))) }, $element: $("<span style=\"width:auto;display:inline-block;float:left;margin:0\" title='Set all...'>"), $overlay: this.$overlay }); // Remove all banners button this.removeAllButton = new OO.ui.ButtonWidget({ icon: "trash", title: "Remove all", flags: "destructive" }); // Clear all parameters button this.clearAllButton = new OO.ui.ButtonWidget({ icon: "cancel", title: "Clear all", flags: "destructive" }); // Group the buttons together this.menuButtons = new OO.ui.ButtonGroupWidget({ items: [this.removeAllButton, this.clearAllButton], $element: $("<span style='flex:1 0 auto;'>") }); // Include the dropdown in the group this.menuButtons.$element.prepend(this.setAllDropDown.$element); // Put everything into a layout this.$element.addClass("rater-topBarWidget").css({ "position": "fixed", "width": "100%", "background": "#ccc", "display": "flex", "flex-wrap": "wrap", "justify-content": "space-around", "margin": "-2px 0 0 0" }).append($searchContainer, this.menuButtons.$element); /* --- Event handling --- */ this.searchBox.connect(this, { "enter": "onSearchSelect", "choose": "onSearchSelect" }); this.addBannerButton.connect(this, { "click": "onSearchSelect" }); this.setAllDropDown.getMenu().connect(this, { "choose": "onRatingChoose" }); this.removeAllButton.connect(this, { "click": "onRemoveAllClick" }); this.clearAllButton.connect(this, { "click": "onClearAllClick" }); } OO.inheritClass(TopBarWidget, OO.ui.PanelLayout); TopBarWidget.prototype.onSearchSelect = function (data) { this.emit("searchSelect", data); }; TopBarWidget.prototype.onRatingChoose = function (item) { var data = item.getData(); if (data["class"] || data["class"] === null) { this.emit("setClasses", data["class"]); } if (data.importance || data.importance === null) { this.emit("setImportances", data.importance); } }; TopBarWidget.prototype.onRemoveAllClick = function () { this.emit("removeAll"); }; TopBarWidget.prototype.onClearAllClick = function () { this.emit("clearAll"); }; TopBarWidget.prototype.setDisabled = function (disable) { [this.searchBox, this.addBannerButton, this.setAllDropDown, this.removeAllButton, this.clearAllButton].forEach(function (widget) { return widget.setDisabled(disable); }); }; var _default = exports["default"] = TopBarWidget; // </nowiki> },{"../../config":18,"../../getBanners":20,"./SuggestionLookupTextInputWidget":11}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _api = require("../api"); function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // <nowiki> /* var incrementProgressByInterval = function() { var incrementIntervalDelay = 100; var incrementIntervalAmount = 0.1; var incrementIntervalMaxval = 98; return window.setInterval( incrementProgress, incrementIntervalDelay, incrementIntervalAmount, incrementIntervalMaxval ); }; */ var LoadDialog = function LoadDialog(config) { LoadDialog["super"].call(this, config); }; OO.inheritClass(LoadDialog, OO.ui.Dialog); LoadDialog["static"].name = "loadDialog"; LoadDialog["static"].title = "Loading Rater..."; // Customize the initialize() function: This is where to add content to the dialog body and set up event handlers. LoadDialog.prototype.initialize = function () { var _this$content$$elemen; // Call the parent method. LoadDialog["super"].prototype.initialize.call(this); // Create a layout this.content = new OO.ui.PanelLayout({ padded: true, expanded: false }); // Create content this.progressBar = new OO.ui.ProgressBarWidget({ progress: 1 }); this.setuptasks = [new OO.ui.LabelWidget({ label: "Loading your Rater preferences...", $element: $("<p style=\"display:block\">") }), new OO.ui.LabelWidget({ label: "Loading list of project banners...", $element: $("<p style=\"display:block\">") }), new OO.ui.LabelWidget({ label: "Loading talkpage wikitext...", $element: $("<p style=\"display:block\">") }), new OO.ui.LabelWidget({ label: "Parsing talkpage templates...", $element: $("<p style=\"display:block\">") }), new OO.ui.LabelWidget({ label: "Getting templates' parameter data...", $element: $("<p style=\"display:block\">") }), new OO.ui.LabelWidget({ label: "Checking subject page...", $element: $("<p style=\"display:block\">") }), new OO.ui.LabelWidget({ label: "Retrieving quality prediction...", $element: $("<p style=\"display:block\">") }).toggle()]; this.closeButton = new OO.ui.ButtonWidget({ label: "Close" }).toggle(); this.setupPromises = []; // Append content to layout (_this$content$$elemen = this.content.$element).append.apply(_this$content$$elemen, [this.progressBar.$element, new OO.ui.LabelWidget({ label: "Initialising:", $element: $("<strong style=\"display:block\">") }).$element].concat(_toConsumableArray(this.setuptasks.map(function (widget) { return widget.$element; })), [this.closeButton.$element])); // Append layout to dialog this.$body.append(this.content.$element); // Connect events to handlers this.closeButton.connect(this, { "click": "onCloseButtonClick" }); }; LoadDialog.prototype.onCloseButtonClick = function () { // Close this dialog, without passing any data this.close(); }; // Override the getBodyHeight() method to specify a custom height (or don't to use the automatically generated height). LoadDialog.prototype.getBodyHeight = function () { return this.content.$element.outerHeight(true); }; LoadDialog.prototype.incrementProgress = function (amount, maximum) { var priorProgress = this.progressBar.getProgress(); var incrementedProgress = Math.min(maximum || 100, priorProgress + amount); this.progressBar.setProgress(incrementedProgress); }; LoadDialog.prototype.addTaskPromiseHandlers = function (taskPromises) { var _this = this; var onTaskDone = function onTaskDone(index) { // Add "Done!" to label var widget = _this.setuptasks[index]; widget.setLabel(widget.getLabel() + " Done!"); // Increment status bar. Show a smooth transition by // using small steps over a short duration. var totalIncrement = 100 / _this.setuptasks.length; // percent var totalTime = 400; // milliseconds var totalSteps = 10; var incrementPerStep = totalIncrement / totalSteps; for (var step = 0; step < totalSteps; step++) { window.setTimeout(_this.incrementProgress.bind(_this), totalTime * step / totalSteps, incrementPerStep); } }; var onTaskError = function onTaskError(index, code, info) { var widget = _this.setuptasks[index]; widget.setLabel(widget.getLabel() + " Failed. " + (0, _api.makeErrorMsg)(code, info)); _this.closeButton.toggle(true); _this.updateSize(); }; taskPromises.forEach(function (promise, index) { promise.then(function () { return onTaskDone(index); }, function (code, info) { return onTaskError(index, code, info); }); }); }; // Use getSetupProcess() to set up the window with data passed to it at the time // of opening LoadDialog.prototype.getSetupProcess = function (data) { var _this2 = this; data = data || {}; return LoadDialog["super"].prototype.getSetupProcess.call(this, data).next(function () { var showOresTask = !!data.ores; _this2.setuptasks[6].toggle(showOresTask); var taskPromises = data.ores ? data.promises : data.promises.slice(0, -1); data.isOpened.then(function () { return _this2.addTaskPromiseHandlers(taskPromises); }); }, this); }; // Prevent window from closing too quickly, using getHoldProcess() LoadDialog.prototype.getHoldProcess = function (data) { data = data || {}; if (data.success) { // Wait a bit before processing the close, which happens automatically return LoadDialog["super"].prototype.getHoldProcess.call(this, data).next(800); } // No need to wait if closed manually return LoadDialog["super"].prototype.getHoldProcess.call(this, data); }; // Use the getTeardownProcess() method to perform actions whenever the dialog is closed. LoadDialog.prototype.getTeardownProcess = function (data) { var _this3 = this; return LoadDialog["super"].prototype.getTeardownProcess.call(this, data).first(function () { // Perform cleanup: reset labels _this3.setuptasks.forEach(function (setuptask) { var currentLabel = setuptask.getLabel(); setuptask.setLabel(currentLabel.slice(0, currentLabel.indexOf("...") + 3)); }); }, this); }; var _default = exports["default"] = LoadDialog; // </nowiki> },{"../api":15}],14:[function(require,module,exports){ "use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _BannerWidget = _interopRequireDefault(require("./Components/BannerWidget")); var _BannerListWidget = _interopRequireDefault(require("./Components/BannerListWidget")); var _config = _interopRequireDefault(require("../config")); var _api = _interopRequireWildcard(require("../api")); var _PrefsFormWidget = _interopRequireDefault(require("./Components/PrefsFormWidget")); var _prefs = require("../prefs"); var _Template = require("../Template"); var _TopBarWidget = _interopRequireDefault(require("./Components/TopBarWidget")); var _util = require("../util"); var cache = _interopRequireWildcard(require("../cache")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } // <nowiki> function MainWindow(config) { MainWindow["super"].call(this, config); } OO.inheritClass(MainWindow, OO.ui.ProcessDialog); MainWindow["static"].name = "main"; MainWindow["static"].title = $("<span>").css({ "font-weight": "normal" }).append($("<a>").css({ "font-weight": "bold" }).attr({ "href": mw.util.getUrl("WP:RATER"), "target": "_blank" }).text("Rater"), " (", $("<a>").attr({ "href": mw.util.getUrl("WT:RATER"), "target": "_blank" }).text("talk"), ") ", $("<span>").css({ "font-size": "90%" }).text("v" + _config["default"].script.version)); MainWindow["static"].size = "large"; MainWindow["static"].actions = [ // Primary (top right): { label: "X", // not using an icon since color becomes inverted, i.e. white on light-grey title: "Close (and discard any changes)", flags: "primary", modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs" }, // Safe (top left) { action: "showPrefs", flags: "safe", icon: "settings", title: "Preferences", modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs" }, // Others (bottom) { action: "save", accessKey: "s", label: new OO.ui.HtmlSnippet("<span style='padding:0 1em;'>Save</span>"), flags: ["primary", "progressive"], modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs" }, { action: "preview", accessKey: "p", label: "Show preview", modes: ["edit", "diff"] // available when current mode isn't "preview" or "prefs" }, { action: "changes", accessKey: "v", label: "Show changes", modes: ["edit", "preview"] // available when current mode isn't "diff" or "prefs" }, { action: "back", label: "Back", modes: ["diff", "preview"] // available when current mode is "diff" or "prefs" }, // "prefs" mode only { action: "savePrefs", label: "Update", flags: ["primary", "progressive"], modes: "prefs" }, { action: "closePrefs", label: "Cancel", flags: "safe", modes: "prefs" }]; // Customize the initialize() function: This is where to add content to the dialog body and set up event handlers. MainWindow.prototype.initialize = function () { // Call the parent method. MainWindow["super"].prototype.initialize.call(this); /* --- PREFS --- */ this.preferences = _config["default"].defaultPrefs; /* --- TOP BAR --- */ this.topBar = new _TopBarWidget["default"]({ $overlay: this.$overlay }); this.$head.css({ "height": "73px" }).append(this.topBar.$element); /* --- FOOTER --- */ this.oresLabel = new OO.ui.LabelWidget({ $element: $("<span style='float:right; padding: 10px; max-width: 50%; text-align: center;'>"), label: $("<span>").append($("<a>").attr({ "href": mw.util.getUrl("mw:ORES"), "target": "_blank" }).append($("<img>").css({ "vertical-align": "text-bottom;" }).attr({ "src": "//upload.wikimedia.org/wikipedia/commons/thumb/5/51/Objective_Revision_Evaluation_Service_logo.svg/40px-Objective_Revision_Evaluation_Service_logo.svg.png", "title": "Machine predicted quality from ORES", "alt": "ORES logo", "width": "20px", "height": "20px" })), " ", $("<span class='oresPrediction'>")) }).toggle(false); this.pagetypeLabel = new OO.ui.LabelWidget({ $element: $("<span style='float:right; padding: 10px; max-width: 33.33%; text-align: center;'>") }).toggle(false); this.$foot.prepend(this.oresLabel.$element, this.pagetypeLabel.$element); /* --- CONTENT AREA --- */ // Banners added dynamically upon opening, so just need a layout with an empty list this.bannerList = new _BannerListWidget["default"]({ preferences: this.preferences }); this.editLayout = new OO.ui.PanelLayout({ padded: false, expanded: false, $content: this.bannerList.$element }); // Preferences, filled in with current prefs upon loading. // TODO: Make this into a component, add fields and inputs this.prefsForm = new _PrefsFormWidget["default"](); this.prefsLayout = new OO.ui.PanelLayout({ padded: true, expanded: false, $content: this.prefsForm.$element }); // Preview, Show changes this.parsedContentContainer = new OO.ui.FieldsetLayout({ label: "Preview" }); this.parsedContentWidget = new OO.ui.LabelWidget({ label: "", $element: $("<div>") }); this.parsedContentContainer.addItems([new OO.ui.FieldLayout(this.parsedContentWidget, { align: "top" })]); this.parsedContentLayout = new OO.ui.PanelLayout({ padded: true, expanded: false, $content: this.parsedContentContainer.$element }); this.contentArea = new OO.ui.StackLayout({ items: [this.editLayout, this.prefsLayout, this.parsedContentLayout], padded: false, expanded: false }); this.$body.css({ "top": "73px" }).append(this.contentArea.$element); /* --- EVENT HANDLING --- */ this.topBar.connect(this, { "searchSelect": "onSearchSelect", "setClasses": "onSetClasses", "setImportances": "onSetImportances", "removeAll": "onRemoveAll", "clearAll": "onClearAll" }); this.bannerList.connect(this, { "updatedSize": "onBannerListUpdateSize" }); // Handle certain keyboard events. Requires something in the Rater window to be focused, // so add a tabindex to the body and it's parent container. this.$body.attr("tabindex", "999").parent().attr("tabindex", "999").keydown(function (event) { var scrollAmount; switch (event.which) { case 33: // page up scrollAmount = this.$body.scrollTop() - this.$body.height() * 0.9; break; case 34: // page down scrollAmount = this.$body.scrollTop() + this.$body.height() * 0.9; break; default: return; } this.$body.scrollTop(scrollAmount); event.preventDefault(); }.bind(this)); this.prefsForm.connect(this, { "resetCache": "onResetCache" }); }; MainWindow.prototype.onBannerListUpdateSize = function () { // Get the current scroll amount var scrollAmount = this.$body.scrollTop(); // Update size (which resets the scroll to 0) this.updateSize(); // Scroll to where it was before this.$body.scrollTop(scrollAmount); }; MainWindow.prototype.makeDraggable = function () { var $frameEl = this.$element.find(".oo-ui-window-frame"); var $handleEl = this.$element.find(".oo-ui-processDialog-location").css({ "cursor": "move" }); // Position for css translate transformations, relative to initial position // (which is centered on viewport when scrolled to top) var position = { x: 0, y: 0 }; var constrain = function constrain(val, minVal, maxVal) { if (val < minVal) return minVal; if (val > maxVal) return maxVal; return val; }; var constrainX = function constrainX(val) { // Don't too far horizontally (leave at least 100px visible) var limit = window.innerWidth / 2 + $frameEl.outerWidth() / 2 - 100; return constrain(val, -1 * limit, limit); }; var constrainY = function constrainY(val) { // Can't take title bar off the viewport, since it's the drag handle var minLimit = -1 * (window.innerHeight - $frameEl.outerHeight()) / 2; // Don't go too far down the page: (whole page height) - (initial position) var maxLimit = (document.documentElement || document).scrollHeight - window.innerHeight / 2; return constrain(val, minLimit, maxLimit); }; var pointerdown = false; var dragFrom = {}; var onDragStart = function onDragStart(event) { pointerdown = true; dragFrom.x = event.clientX; dragFrom.y = event.clientY; }; var onDragMove = function onDragMove(event) { if (!pointerdown || dragFrom.x == null || dragFrom.y === null) { return; } var dx = event.clientX - dragFrom.x; var dy = event.clientY - dragFrom.y; dragFrom.x = event.clientX; dragFrom.y = event.clientY; position.x = constrainX(position.x + dx); position.y = constrainY(position.y + dy); $frameEl.css("transform", "translate(".concat(position.x, "px, ").concat(position.y, "px)")); }; var onDragEnd = function onDragEnd() { pointerdown = false; delete dragFrom.x; delete dragFrom.y; // Make sure final positions are whole numbers position.x = Math.round(position.x); position.y = Math.round(position.y); $frameEl.css("transform", "translate(".concat(position.x, "px, ").concat(position.y, "px)")); }; // Use pointer events if available; otherwise use mouse events var pointer = "PointerEvent" in window ? "pointer" : "mouse"; $handleEl.on(pointer + "enter.raterMainWin", function () { return $frameEl.css("will-change", "transform"); }); // Tell browser to optimise transform $handleEl.on(pointer + "leave.raterMainWin", function () { if (!pointerdown) $frameEl.css("will-change", ""); }); // Remove optimisation if not dragging $handleEl.on(pointer + "down.raterMainWin", onDragStart); $("body").on(pointer + "move.raterMainWin", onDragMove); $("body").on(pointer + "up.raterMainWin", onDragEnd); }; // Override the getBodyHeight() method to specify a custom height MainWindow.prototype.getBodyHeight = function () { var currentlayout = this.contentArea.getCurrentItem(); var layoutHeight = currentlayout && currentlayout.$element.outerHeight(true); var contentHeight = currentlayout && currentlayout.$element.children(":first-child").outerHeight(true); return Math.max(200, layoutHeight, contentHeight); }; // Use getSetupProcess() to set up the window with data passed to it at the time // of opening MainWindow.prototype.getSetupProcess = function (data) { var _this = this; data = data || {}; return MainWindow["super"].prototype.getSetupProcess.call(this, data).next(function () { _this.makeDraggable(); // Set up preferences _this.setPreferences(data.preferences); _this.prefsForm.setPrefValues(data.preferences); // Set subject page info _this.subjectPage = data.subjectPage; _this.pageInfo = { redirect: data.redirectTarget, isDisambig: data.disambig, hasStubtag: data.stubtag, isArticle: data.isArticle }; // Set up edit mode banners _this.actions.setMode("edit"); _this.bannerList.oresClass = data.isArticle && data.isList ? "List" : data.ores && data.ores.prediction; _this.bannerList.pageInfo = _this.pageInfo; _this.bannerList.addItems(data.banners.map(function (bannerTemplate) { return new _BannerWidget["default"](bannerTemplate, { preferences: _this.preferences, $overlay: _this.$overlay, isArticle: _this.pageInfo.isArticle }); })); var shellTemplateBanner = _this.bannerList.items.find(function (banner) { return banner.isShellTemplate; }); if (shellTemplateBanner && shellTemplateBanner.shellParam1Value) { shellTemplateBanner.nonStandardTemplates = _this.bannerList.items.reduce(function (bannersList, curBanner) { return bannersList.replace(curBanner.wikitext, ""); }, shellTemplateBanner.shellParam1Value).trim().replace(/\n+/g, "\n"); } _this.bannerList.addShellTemplateIfNeeeded().syncShellTemplateWithBiographyBanner(); // Show page type, or ORES prediction, if available if (_this.pageInfo.redirect) { _this.pagetypeLabel.setLabel("Redirect page").toggle(true); } else if (_this.pageInfo.isDisambig) { _this.pagetypeLabel.setLabel("Disambiguation page").toggle(true); } else if (_this.pageInfo.isArticle && data.isGA) { _this.pagetypeLabel.setLabel("Good article").toggle(true); } else if (_this.pageInfo.isArticle && data.isFA) { _this.pagetypeLabel.setLabel("Featured article").toggle(true); } else if (_this.pageInfo.isArticle && data.isFL) { _this.pagetypeLabel.setLabel("Featured list").toggle(true); } else if (_this.pageInfo.isArticle && data.isList) { _this.pagetypeLabel.setLabel("List article").toggle(true); } else if (data.ores) { _this.oresClass = data.ores.prediction; _this.oresLabel.toggle(true).$element.find(".oresPrediction").append("Prediction: ", $("<strong>").text(data.ores.prediction), "&nbsp;(" + data.ores.probability + ")"); } else if (_this.pageInfo.isArticle) { _this.pagetypeLabel.setLabel("Article page").toggle(true); } else { _this.pagetypeLabel.setLabel(_this.subjectPage.getNamespacePrefix().slice(0, -1) + " page").toggle(true); } // Set props for use in making wikitext and edit summaries _this.talkWikitext = data.talkWikitext; _this.existingBannerNames = data.banners.map(function (bannerTemplate) { return bannerTemplate.name; }); _this.talkpage = data.talkpage; // Force a size update to ensure eveything fits okay _this.updateSize(); }, this); }; // Set up the window it is ready: attached to the DOM, and opening animation completed MainWindow.prototype.getReadyProcess = function (data) { var _this2 = this; data = data || {}; return MainWindow["super"].prototype.getReadyProcess.call(this, data).next(function () { return _this2.topBar.searchBox.focus(); }); }; // Use the getActionProcess() method to do things when actions are clicked MainWindow.prototype.getActionProcess = function (action) { var _this3 = this; if (action === "showPrefs") { this.actions.setMode("prefs"); this.contentArea.setItem(this.prefsLayout); this.topBar.setDisabled(true); this.updateSize(); } else if (action === "savePrefs") { var updatedPrefs = this.prefsForm.getPrefs(); return new OO.ui.Process().next((0, _prefs.setPrefs)(updatedPrefs).then( // Success function () { _this3.setPreferences(updatedPrefs); _this3.actions.setMode("edit"); _this3.contentArea.setItem(_this3.editLayout); _this3.topBar.setDisabled(false); _this3.updateSize(); }, // Failure function (code, err) { return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not save preferences."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err))))); })); } else if (action === "clearCache") { return new OO.ui.Process().next(function () { cache.clearAllItems(); _this3.close({ restart: true }); }); } else if (action === "closePrefs") { this.actions.setMode("edit"); this.contentArea.setItem(this.editLayout); this.topBar.setDisabled(false); this.prefsForm.setPrefValues(this.preferences); this.updateSize(); } else if (action === "save") { return new OO.ui.Process().next(_api["default"].editWithRetry(this.talkpage.getPrefixedText(), { rvsection: 0 }, function (revision) { return { section: 0, text: _this3.transformTalkWikitext(revision.content), summary: _this3.makeEditSummary(), watchlist: _this3.preferences.watchlist }; })["catch"](function (code, err) { return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not save your changes."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err))))); })).next(function () { return _this3.close({ success: true, upgradedStub: _this3.pageInfo.hasStubtag && _this3.isRatedAndNotStub() }); }); } else if (action === "preview") { return new OO.ui.Process().next(_api["default"].post({ action: "parse", contentmodel: "wikitext", text: this.transformTalkWikitext(this.talkWikitext) + "\n<hr>\n" + "'''Edit summary:''' " + this.makeEditSummary(), title: this.talkpage.getPrefixedText(), pst: 1 }).then(function (result) { if (!result || !result.parse || !result.parse.text || !result.parse.text["*"]) { return $.Deferred().reject("Empty result"); } var previewHtmlSnippet = new OO.ui.HtmlSnippet(result.parse.text["*"]); _this3.parsedContentWidget.setLabel(previewHtmlSnippet); _this3.parsedContentContainer.setLabel("Preview:"); _this3.actions.setMode("preview"); _this3.contentArea.setItem(_this3.parsedContentLayout); _this3.topBar.setDisabled(true); _this3.updateSize(); })["catch"](function (code, err) { return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not show changes."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err))))); })); } else if (action === "changes") { return new OO.ui.Process().next(_api["default"].post({ action: "compare", format: "json", fromtext: this.talkWikitext, fromcontentmodel: "wikitext", totext: this.transformTalkWikitext(this.talkWikitext), tocontentmodel: "wikitext", prop: "diff" }).then(function (result) { if (!result || !result.compare || !result.compare["*"]) { return $.Deferred().reject("Empty result"); } var $diff = $("<table>").addClass("diff").css("width", "100%").append($("<tr>").append($("<th>").attr({ "colspan": "2", "scope": "col" }).css("width", "50%").text("Latest revision"), $("<th>").attr({ "colspan": "2", "scope": "col" }).css("width", "50%").text("New text")), result.compare["*"], $("<tfoot>").append($("<tr>").append($("<td colspan='4'>").append($("<strong>").text("Edit summary: "), _this3.makeEditSummary())))); _this3.parsedContentWidget.setLabel($diff); _this3.parsedContentContainer.setLabel("Changes:"); _this3.actions.setMode("diff"); _this3.contentArea.setItem(_this3.parsedContentLayout); _this3.topBar.setDisabled(true); _this3.updateSize(); })["catch"](function (code, err) { return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not show changes."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err))))); })); } else if (action === "back") { this.actions.setMode("edit"); this.contentArea.setItem(this.editLayout); this.topBar.setDisabled(false); this.updateSize(); } else if (!action && this.bannerList.changed) { // Confirm closing of dialog if there have been changes return new OO.ui.Process().next(OO.ui.confirm("Changes made will be discarded.", { title: "Close Rater?" }).then(function (confirmed) { return confirmed ? _this3.close() : null; })); } return MainWindow["super"].prototype.getActionProcess.call(this, action); }; // Use the getTeardownProcess() method to perform actions whenever the dialog is closed. // `data` is the data passed into the window's .close() method. MainWindow.prototype.getTeardownProcess = function (data) { var _this4 = this; return MainWindow["super"].prototype.getTeardownProcess.call(this, data).first(function () { _this4.bannerList.clearItems(); _this4.topBar.searchBox.setValue(""); _this4.contentArea.setItem(_this4.editLayout); _this4.topBar.setDisabled(false); _this4.oresLabel.toggle(false).$element.find(".oresPrediction").empty(); _this4.pagetypeLabel.toggle(false).setLabel(""); _this4.$element.find(".oo-ui-window-frame").css("transform", ""); _this4.$element.find(".oo-ui-processDialog-location").off(".raterMainWin"); $("body").off(".raterMainWin"); }); }; MainWindow.prototype.setPreferences = function (prefs) { this.preferences = $.extend({}, _config["default"].defaultPrefs, prefs); // Applies preferences to existing items in the window: this.bannerList.setPreferences(this.preferences); }; MainWindow.prototype.onResetCache = function () { this.executeAction("clearCache"); }; MainWindow.prototype.onSearchSelect = function (data) { var _this5 = this; this.topBar.searchBox.pushPending(); var name = this.topBar.searchBox.getValue().trim(); if (!name) { this.topBar.searchBox.popPending().focus(); return; } var existingBanner = this.bannerList.items.find(function (banner) { return banner.mainText === name || banner.redirectTargetMainText === name; }); // Abort and show alert if banner already exists if (existingBanner) { this.topBar.searchBox.popPending(); return OO.ui.alert("There is already a {{" + name + "}} banner").then(this.searchBox.focus()); } // Confirmation required for banners missing WikiProject from name, and for uncreated disambiguation talk pages var confirmText; if (!/^[Ww](?:P|iki[Pp]roject)/.test(name)) { confirmText = new OO.ui.HtmlSnippet("{{" + mw.html.escape(name) + "}} is not a recognised WikiProject banner.<br/>Do you want to continue?"); } else if (name === "WikiProject Disambiguation" && $("#ca-talk.new").length !== 0 && this.bannerList.items.length === 0) { // eslint-disable-next-line no-useless-escape confirmText = "New talk pages shouldn't be created if they will only contain the \{\{WikiProject Disambiguation\}\} banner. Continue?"; } $.when(confirmText ? OO.ui.confirm(confirmText) : true).then(function (confirmed) { if (!confirmed) return; // Create Template object return _BannerWidget["default"].newFromTemplateName(name, data, { preferences: _this5.preferences, $overlay: _this5.$overlay, isArticle: _this5.pageInfo.isArticle }).then(function (banner) { _this5.bannerList.addItems([banner]); banner.setChanged(); _this5.updateSize(); }); }).then(function () { return _this5.topBar.searchBox.setValue("").focus().popPending(); }); }; MainWindow.prototype.onSetClasses = function (classVal) { var shellTemplate = this.bannerList.items.find(function (banner) { return banner.isShellTemplate; }); if (shellTemplate) { shellTemplate.classDropdown.getMenu().selectItemByData(classVal); shellTemplate.classDropdown.setAutofilled(false); } this.bannerList.items.forEach(function (banner) { if (banner.hasClassRatings && !banner.isShellTemplate) { banner.classDropdown.getMenu().selectItemByData(shellTemplate ? null : classVal); banner.classDropdown.setAutofilled(false); } }); }; MainWindow.prototype.onSetImportances = function (importanceVal) { this.bannerList.items.forEach(function (banner) { if (banner.hasImportanceRatings) { banner.importanceDropdown.getMenu().selectItemByData(importanceVal); banner.importanceDropdown.setAutofilled(false); } }); }; MainWindow.prototype.onRemoveAll = function () { this.bannerList.clearItems(); }; MainWindow.prototype.onClearAll = function () { this.bannerList.items.forEach(function (banner) { return banner.onClearButtonClick(); }); }; MainWindow.prototype.transformTalkWikitext = function (talkWikitext) { var _this6 = this; var bannersWikitext = this.bannerList.makeWikitext(); if (!talkWikitext) { return bannersWikitext.trim(); } // Reparse templates, in case talkpage wikitext has changed var talkTemplates = (0, _Template.parseTemplates)(talkWikitext, true); // replace existing banners wikitext with a control character talkTemplates.forEach(function (template) { if (_this6.existingBannerNames.includes(template.name)) { talkWikitext = talkWikitext.replace(template.wikitext, "\x01"); } }); // replace insertion point (first control character) with a different control character talkWikitext = talkWikitext.replace("\x01", "\x02"); // remove other control characters /* eslint-disable-next-line no-control-regex */ talkWikitext = talkWikitext.replace(/(?:\s|\n)*\x01(?:\s|\n)*/g, ""); // split into wikitext before/after the remaining control character (and trim each section) var talkWikitextSections = talkWikitext.split("\x02").map(function (t) { return t.trim(); }); if (talkWikitextSections.length === 2) { // Found the insertion point for the banners return (talkWikitextSections[0] + "\n" + bannersWikitext.trim() + "\n" + talkWikitextSections[1]).trim(); } // Check if there's anything beside templates var tempStr = talkWikitext; talkTemplates.forEach(function (template) { tempStr = tempStr.replace(template.wikitext, ""); }); if (/^#REDIRECT/i.test(talkWikitext) || !tempStr.trim()) { // Is a redirect, or everything is a template: insert at the end return talkWikitext.trim() + "\n" + bannersWikitext.trim(); } else { // There is non-template content, so insert at the start return bannersWikitext.trim() + "\n" + talkWikitext.trim(); } }; MainWindow.prototype.isRatedAndNotStub = function () { var nonStubRatinggs = this.bannerList.items.filter(function (banner) { return banner.hasClassRatings && banner.classDropdown.getValue() && banner.classDropdown.getValue() !== "Stub"; }); return nonStubRatinggs.length > 0; }; MainWindow.prototype.makeEditSummary = function () { var _this7 = this; var removedBanners = []; var editedBanners = []; var newBanners = []; var shortName = function shortName(name) { return name.replace("WikiProject ", "").replace("Subst:", ""); }; // Overall class/importance, if all the same var allClasses = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.bannerList.items, function (banner) { return banner.hasClassRatings || banner.isShellTemplate; }, function (banner) { return banner.classDropdown.getValue(); })); var overallClass = allClasses.length === 1 && allClasses[0]; var allImportances = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.bannerList.items, function (banner) { return banner.hasImportanceRatings; }, function (banner) { return banner.importanceDropdown.getValue(); })); var overallImportance = allImportances.length === 1 && allImportances[0]; // Don't use them unless some have changed var someClassesChanged = false; var someImportancesChanged = false; // removed banners: this.existingBannerNames.forEach(function (name) { var banner = _this7.bannerList.items.find(function (banner) { return banner.name === name || banner.bypassedName === name; }); if (!banner) { removedBanners.push("−" + shortName(name)); } }); // edited & new banners this.bannerList.items.forEach(function (banner) { var isNew = !banner.wikitext; // not added from wikitext on page if (!isNew && !banner.changed) { // Not changed return; } var newClass = banner.hasClassRatings && (isNew || banner.classChanged) && banner.classDropdown.getValue(); if (newClass) { someClassesChanged = true; } if (overallClass) { newClass = null; } var newImportance = banner.hasImportanceRatings && (isNew || banner.importanceChanged) && banner.importanceDropdown.getValue(); if (newImportance) { someImportancesChanged = true; } if (overallImportance) { newImportance = null; } var rating = newClass && newImportance ? newClass + "/" + newImportance : newClass || newImportance || ""; if (rating) { rating = " (" + rating + ")"; } if (isNew) { newBanners.push("+" + shortName(banner.name) + rating); } else { editedBanners.push(shortName(banner.name) + rating); } }); // overall rating var overallRating = someClassesChanged && overallClass && someImportancesChanged && overallImportance ? overallClass + "/" + overallImportance : someClassesChanged && overallClass || someImportancesChanged && overallImportance || ""; if (overallRating) { overallRating = " (" + overallRating + ")"; } return "Assessment".concat(overallRating, ": ").concat([].concat(editedBanners, newBanners, removedBanners).join(", ")).concat(_config["default"].script.advert); }; var _default = exports["default"] = MainWindow; // </nowiki> },{"../Template":3,"../api":15,"../cache":17,"../config":18,"../prefs":21,"../util":23,"./Components/BannerListWidget":4,"./Components/BannerWidget":5,"./Components/PrefsFormWidget":10,"./Components/TopBarWidget":12}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeErrorMsg = exports["default"] = void 0; var _config = _interopRequireDefault(require("./config")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } // <nowiki> var API = new mw.Api({ ajax: { headers: { "Api-User-Agent": "Rater/" + _config["default"].script.version + " ( https://en.wikipedia.org/wiki/User:Evad37/Rater )" } } }); /* ---------- API for ORES ---------------------------------------------------------------------- */ API.getORES = function (revisionID) { return $.get("https://ores.wikimedia.org/v3/scores/enwiki?models=articlequality&revids=" + revisionID); }; /* ---------- Raw wikitext ---------------------------------------------------------------------- */ API.getRaw = function (page) { return $.get("https:" + _config["default"].mw.wgServer + mw.util.getUrl(page, { action: "raw" })).then(function (data) { if (!data) { return $.Deferred().reject("ok-but-empty"); } return data; }); }; /* ---------- Edit with retry ------------------------------------------------------------------- */ /** * @param {String} title * @param {Object?} params additional params for the get request * @returns {Promise<Object, string>} page, starttime timestamp */ var getPage = function getPage(title, params) { return API.get($.extend({ "action": "query", "format": "json", "curtimestamp": 1, "titles": title, "prop": "revisions|info", "rvprop": "content|timestamp", "rvslots": "main" }, params)).then(function (response) { var page = Object.values(response.query.pages)[0]; var starttime = response.curtimestamp; return $.Deferred().resolve(page, starttime); }); }; /** * @param {Object} page details object from API * @param {string} starttime timestamp * @param {Function} transform callback that prepares the edit: * {Object} simplifiedPage => {Object|Promise<Object>} edit params * @returns {Promise<Object>} params for edit query */ var processPage = function processPage(page, starttime, transform) { var basetimestamp = page.revisions && page.revisions[0].timestamp; var simplifiedPage = { pageid: page.pageid, missing: page.missing === "", redirect: page.redirect === "", categories: page.categories, ns: page.ns, title: page.title, content: page.revisions && page.revisions[0].slots.main["*"] }; return $.when(transform(simplifiedPage)).then(function (editParams) { return $.extend({ action: "edit", title: page.title, // Protect against errors and conflicts assert: "user", basetimestamp: basetimestamp, starttimestamp: starttime }, editParams); }); }; /** editWithRetry * * Edits a page, resolving edit conflicts, and retrying edits that fail. The * tranform function may return a rejected promise if the page should not be * edited; the @returns {Promise} will will be rejected with the same rejection * values. * * Note: Unlike [mw.Api#Edit], a missing page will be created, unless the * transform callback includes the "nocreate" param. * * [mw.Api#Edit]: <https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.edit> * * @param {String} title page to be edited * @param {Object|null} getParams additional params for the get request * @param {Function} transform callback that prepares the edit: * {Object} simplifiedPage => {Object|Promise<Object>} params for API editing * @returns {Promise<object>} promise, resolved on success, rejected if * page was not edited */ API.editWithRetry = function (title, getParams, transform) { return getPage(title, getParams).then( // Succes: process the page function (page, starttime) { return processPage(page, starttime, transform); }, // Failure: try again function () { return getPage(title, getParams).then(processPage, transform); }).then(function (editParams) { return API.postWithToken("csrf", editParams)["catch"](function (errorCode) { if (errorCode === "editconflict") { // Try again, starting over return API.editWithRetry(title, getParams, transform); } // Try again return API.postWithToken("csrf", editParams); }); }); }; var makeErrorMsg = exports.makeErrorMsg = function makeErrorMsg(first, second) { var code, xhr, message; if (_typeof(first) === "object" && typeof second === "string") { // Errors from $.get being rejected (ORES & Raw wikitext) var errorObj = first.responseJSON && first.responseJSON.error; if (errorObj) { // Got an api-specific error code/message code = errorObj.code; message = errorObj.message; } else { xhr = first; } } else if (typeof first === "string" && _typeof(second) === "object") { // Errors from mw.Api object var mwErrorObj = second.error; if (mwErrorObj) { // Got an api-specific error code/message code = errorObj.code; message = errorObj.info; } else if (first === "ok-but-empty") { code = null; message = "Got an empty response from the server"; } else { xhr = second && second.xhr; } } if (code && message) { return "API error ".concat(code, ": ").concat(message); } else if (message) { return "API error: ".concat(message); } else if (xhr) { return "HTTP error ".concat(xhr.status); } else if (typeof first === "string" && first !== "error" && typeof second === "string" && second !== "error") { return "Error ".concat(first, ": ").concat(second); } else if (typeof first === "string" && first !== "error") { return "Error: ".concat(first); } else { return "Unknown API error"; } }; var _default = exports["default"] = API; // </nowiki> },{"./config":18}],16:[function(require,module,exports){ "use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _config = _interopRequireDefault(require("./config")); var _prefs = require("./prefs"); var _api = _interopRequireWildcard(require("./api")); var _setup = _interopRequireDefault(require("./setup")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } // <nowiki> var autoStart = function autoStart() { return (0, _prefs.getPrefs)().then(function (prefs) { // Check if pref is turned off if (!prefs.autostart) { return; } // Check if pref is turned off for redirects, and current page is a redirect if (!prefs.autostartRedirects && window.location.search.includes("redirect=no")) { return; } // Check if viewing diff/history/old version if (/(action|diff|oldid)/.test(window.location.search)) { return; } var subjectTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getSubjectPage(); // Check if subject page is the main page if (subjectTitle.getPrefixedText() === "Main Page") { return; } // Check subject page namespace if (prefs.autostartNamespaces && prefs.autostartNamespaces.length && !prefs.autostartNamespaces.includes(_config["default"].mw.wgNamespaceNumber)) { return; } // If talk page does not exist, can just autostart if ($("#ca-talk.new").length) { return (0, _setup["default"])(); } /* Check templates present on talk page. Fetches indirectly transcluded templates, so will find Template:WPBannerMeta (and its subtemplates). But some banners such as MILHIST don't use that meta template, so we also have to check for template titles containg 'WikiProject' */ var talkTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getTalkPage(); return _api["default"].get({ action: "query", format: "json", prop: "templates", titles: talkTitle.getPrefixedText(), tlnamespace: "10", tllimit: "500", indexpageids: 1 }).then(function (result) { var id = result.query.pageids; var templates = result.query.pages[id].templates; if (!templates) { return (0, _setup["default"])(); } var hasWikiproject = templates.some(function (template) { return /(WikiProject|WPBanner)/.test(template.title); }); if (!hasWikiproject) { return (0, _setup["default"])(); } }, function (code, jqxhr) { // Silently ignore failures (just log to console) console.warn("[Rater] Error while checking whether to autostart." + (code == null) ? "" : " " + (0, _api.makeErrorMsg)(code, jqxhr)); return $.Deferred().reject(); }); }); }; var _default = exports["default"] = autoStart; // </nowiki> },{"./api":15,"./config":18,"./prefs":21,"./setup":22}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.write = exports.read = exports.clearItemIfInvalid = exports.clearInvalidItems = exports.clearAllItems = void 0; var _util = require("./util"); // <nowiki> /** write * @param {String} key * @param {Array|Object} val * @param {Number} staleDays Number of days after which the data becomes stale (usable, but should * be updated for next time). * @param {Number} expiryDays Number of days after which the cached data may be deleted. */ var write = exports.write = function write(key, val, staleDays, expiryDays) { try { var defaultStaleDays = 1; var defaultExpiryDays = 30; var millisecondsPerDay = 24 * 60 * 60 * 1000; var staleDuration = (staleDays || defaultStaleDays) * millisecondsPerDay; var expiryDuration = (expiryDays || defaultExpiryDays) * millisecondsPerDay; var stringVal = JSON.stringify({ value: val, staleDate: new Date(Date.now() + staleDuration).toISOString(), expiryDate: new Date(Date.now() + expiryDuration).toISOString() }); localStorage.setItem("Rater-" + key, stringVal); } catch (e) {} // eslint-disable-line no-empty }; /** read * @param {String} key * @returns {Array|Object|String|Null} Cached array or object, or empty string if not yet cached, * or null if there was error. */ var read = exports.read = function read(key) { var val; try { var stringVal = localStorage.getItem("Rater-" + key); if (stringVal !== "") { val = JSON.parse(stringVal); } } catch (e) { console.log("[Rater] error reading " + key + " from localStorage cache:"); console.log("\t" + e.name + " message: " + e.message + (e.at ? " at: " + e.at : "") + (e.text ? " text: " + e.text : "")); } return val || null; }; var isRaterKey = function isRaterKey(key) { return key && key.indexOf("Rater-") === 0; }; var clearItemIfInvalid = exports.clearItemIfInvalid = function clearItemIfInvalid(key) { if (!isRaterKey(key)) { return; } var item = read(key.replace("Rater-", "")); var isInvalid = !item || !item.expiryDate || (0, _util.isAfterDate)(item.expiryDate); if (isInvalid) { localStorage.removeItem(key); } }; var clearInvalidItems = exports.clearInvalidItems = function clearInvalidItems() { // Loop backwards as localStorage length will decrease as items are removed for (var i = localStorage.length; i >= 0; i--) { setTimeout(clearItemIfInvalid, 100, localStorage.key(i)); } }; var clearAllItems = exports.clearAllItems = function clearAllItems() { // Loop backwards as localStorage length will decrease as items are removed for (var i = localStorage.length; i >= 0; i--) { var key = localStorage.key(i); if (isRaterKey(key)) { localStorage.removeItem(key); } } }; // </nowiki> },{"./util":23}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; // <nowiki> var packagejson = require("../package.json"); var version = packagejson.version; // A global object that stores all the page and user configuration and settings var config = { // Script info script: { // Advert to append to edit summaries advert: " ([[WP:RATER#".concat(version, "|Rater]])"), version: version }, // Default preferences, if user subpage raterPrefs.json does not exist defaultPrefs: { "autostart": false, "autostartRedirects": false, "autostartNamespaces": [0], "minForShell": 1, "bypassRedirects": true, "autofillClassFromOthers": true, "autofillClassFromOres": true, "autofillImportance": true, "collapseParamsLowerLimit": 6, "watchlist": "preferences" }, // MediaWiki configuration values mw: mw.config.get(["skin", "wgPageName", "wgNamespaceNumber", "wgUserName", "wgFormattedNamespaces", "wgMonthNames", "wgRevisionId", "wgScriptPath", "wgServer", "wgCategories", "wgIsMainPage"]), bannerDefaults: { classes: ["FA", "FL", "A", "GA", "B", "C", "Start", "Stub", "List"], importances: ["Top", "High", "Mid", "Low"], extendedClasses: ["Category", "Draft", "File", "FM", "Portal", "Project", "Template", "Bplus", "Future", "Current", "Disambig", "NA", "Redirect", "Book"], extendedImportances: ["Top", "High", "Mid", "Low", "Bottom", "NA"] }, customBanners: { "WikiProject Military history": { classes: ["FA", "FL", "A", "GA", "B", "C", "Start", "Stub", "List", "AL", "BL", "CL", "Category", "Draft", "File", "Portal", "Project", "Template", "Disambig", "Redirect", "Book"], importances: [] }, "WikiProject Portals": { classes: ["FPo", "Complete", "Substantial", "Basic", "Incomplete", "Meta", "List", "Category", "Draft", "File", "Project", "Template", "Disambig", "NA", "Redirect"], importances: ["Top", "High", "Mid", "Low", "Bottom", "NA"] }, "WikiProject Video games": { classes: ["FA", "FL", "FM", "GA", "B", "C", "Start", "Stub", "List", "Category", "Draft", "File", "Portal", "Project", "Template", "Disambig", "Redirect"], importances: ["Top", "High", "Mid", "Low", "NA"] } }, shellTemplates: ["WikiProject banner shell", "WikiProjectBanners", "WikiProject Banners", "WPB", "WPBS", "Wikiprojectbannershell", "WikiProject Banner Shell", "Wpb", "WPBannerShell", "Wpbs", "Wikiprojectbanners", "WP Banner Shell", "WP banner shell", "Bannershell", "Wikiproject banner shell", "WikiProject Banners Shell", "WikiProjectBanner Shell", "WikiProjectBannerShell", "WikiProject BannerShell", "WikiprojectBannerShell", "WikiProject banner shell/redirect", "WikiProject Shell", "Banner shell", "Scope shell", "Project shell", "WikiProject banner"], defaultParameterData: { "auto": { "label": { "en": "Auto-rated" }, "description": { "en": "Automatically rated by a bot. Allowed values: ['yes']." }, "autovalue": "yes" }, "listas": { "label": { "en": "List as" }, "description": { "en": "Sortkey for talk page" } }, "small": { "label": { "en": "Small?" }, "description": { "en": "Display a small version. Allowed values: ['yes']." }, "autovalue": "yes" }, "attention": { "label": { "en": "Attention required?" }, "description": { "en": "Immediate attention required. Allowed values: ['yes']." }, "autovalue": "yes" }, "needs-image": { "label": { "en": "Needs image?" }, "description": { "en": "Request that an image or photograph of the subject be added to the article. Allowed values: ['yes']." }, "aliases": ["needs-photo"], "autovalue": "yes", "suggested": true }, "needs-infobox": { "label": { "en": "Needs infobox?" }, "description": { "en": "Request that an infobox be added to the article. Allowed values: ['yes']." }, "aliases": ["needs-photo"], "autovalue": "yes", "suggested": true } } }; var _default = exports["default"] = config; // </nowiki> },{"../package.json":1}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; // <nowiki> // Attribution: Diff styles based on <https://en.wikipedia.org/wiki/Wikipedia:AutoWikiBrowser/style.css> var styles = "table.diff, td.diff-otitle, td.diff-ntitle { table-layout: auto !important;; }\ntd.diff-otitle, td.diff-ntitle { text-align: center; }\ntd.diff-marker { text-align: right; font-weight: bold; font-size: 1.25em; }\ntd.diff-lineno { font-weight: bold; }\ntd.diff-addedline, td.diff-deletedline, td.diff-context { font-size: 88%; vertical-align: top; white-space: -moz-pre-wrap; white-space: pre-wrap; }\ntd.diff-addedline, td.diff-deletedline { border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; }\ntd.diff-addedline { border-color: #a3d3ff; }\ntd.diff-deletedline { border-color: #ffe49c; }\ntd.diff-context { background: #f3f3f3; color: #333333; border-style: solid; border-width: 1px 1px 1px 4px; border-color: #e6e6e6; border-radius: 0.33em; }\n.diffchange { font-weight: bold; text-decoration: none; }\ntable.diff {\n border: none;\n width: 98%; border-spacing: 4px;\n table-layout: fixed; /* Ensures that colums are of equal width */\n}\ntd.diff-addedline .diffchange, td.diff-deletedline .diffchange { border-radius: 0.33em; padding: 0.25em 0; }\ntd.diff-addedline .diffchange {\tbackground: #d8ecff; }\ntd.diff-deletedline .diffchange { background: #feeec8; }\ntable.diff td {\tpadding: 0.33em 0.66em; }\ntable.diff col.diff-marker { width: 2%; }\ntable.diff col.diff-content { width: 48%; }\ntable.diff td div {\n /* Force-wrap very long lines such as URLs or page-widening char strings. */\n word-wrap: break-word;\n /* As fallback (FF<3.5, Opera <10.5), scrollbars will be added for very wide cells\n instead of text overflowing or widening */\n overflow: auto;\n}" + // Override OOUI window manager preventing background scrolling/interaction. // Scoped to Rater's own window manager (.rater-windowManager), so that other // OOUI dialogs (e.g. OO.ui.confirm in #mw-teleport-target) keep their default // fixed positioning and remain visible. "html body.rater-mainWindow-open {\n\tposition: unset;\n\toverflow: unset;\n}\nhtml body.rater-mainWindow-open .rater-windowManager > .oo-ui-dialog.oo-ui-window-active {\n position: static;\n padding: 0;\n}" + // Increase z-index, to be above skin menus etc; smooth transition for dragging (transform:translate) // 400 keeps Rater above Timeless sidebar dropdowns (.sidebar-inner, 350) / menus-cover (300) / // fixed header (200), but below #mw-teleport-target (450) so OO.ui.confirm dialogs stay on top. "html body.rater-mainWindow-open .rater-windowManager > .oo-ui-dialog.oo-ui-window-active > div {\n z-index: 400;\n transition: all 0.25s ease-out 0s, transform 0s !important\n}\n"; var _default = exports["default"] = styles; // </nowiki> },{}],20:[function(require,module,exports){ "use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports.getBannerNames = void 0; var _api = _interopRequireWildcard(require("./api")); var _util = require("./util"); var cache = _interopRequireWildcard(require("./cache")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } // <nowiki> var cacheBanners = function cacheBanners(banners) { cache.write("banners", banners, 2, 60); }; /** * Gets banners/options from the Api * * @returns {Promise} Resolved with: banners object, bannerOptions array */ var getListOfBannersFromApi = function getListOfBannersFromApi() { var finishedPromise = $.Deferred(); var querySkeleton = { action: "query", format: "json", list: "categorymembers", cmprop: "title", cmnamespace: "10", cmlimit: "500" }; var categories = [{ title: "Category:WikiProject banners with quality assessment", abbreviation: "withRatings", banners: [], processed: $.Deferred() }, { title: "Category:WikiProject banners without quality assessment", abbreviation: "withoutRatings", banners: [], processed: $.Deferred() }, { title: "Category:WikiProject banner wrapper templates", abbreviation: "wrappers", banners: [], processed: $.Deferred() }, { title: "Category:WikiProject banner templates not based on WPBannerMeta", abbreviation: "notWPBM", banners: [], processed: $.Deferred() }, { title: "Category:Inactive WikiProject banners", abbreviation: "inactive", banners: [], processed: $.Deferred() }, { title: "Category:Wrapper templates for WikiProject Women in Red", abbreviation: "wir", banners: [], processed: $.Deferred() }]; var processQuery = function processQuery(result, catIndex) { if (!result.query || !result.query.categorymembers) { // No results // TODO: error or warning ******** finishedPromise.reject(); return; } // Gather titles into array - excluding "Template:" prefix var resultTitles = result.query.categorymembers.map(function (info) { return info.title.slice(9); }); Array.prototype.push.apply(categories[catIndex].banners, resultTitles); // Continue query if needed if (result["continue"]) { doApiQuery($.extend(categories[catIndex].query, result["continue"]), catIndex); return; } categories[catIndex].processed.resolve(); }; var doApiQuery = function doApiQuery(q, catIndex) { _api["default"].get(q).done(function (result) { processQuery(result, catIndex); }).fail(function (code, jqxhr) { console.warn("[Rater] " + (0, _api.makeErrorMsg)(code, jqxhr, "Could not retrieve pages from [[:" + q.cmtitle + "]]")); finishedPromise.reject(); }); }; categories.forEach(function (cat, index, arr) { cat.query = $.extend({ "cmtitle": cat.title }, querySkeleton); $.when(arr[index - 1] && arr[index - 1].processed || true).then(function () { doApiQuery(cat.query, index); }); }); categories[categories.length - 1].processed.then(function () { var banners = {}; categories.forEach(function (catObject) { banners[catObject.abbreviation] = catObject.banners; }); finishedPromise.resolve(banners); }); return finishedPromise; }; /** * Gets banners from cache, if there and not too old * * @returns {Promise} Resolved with banners object */ var getBannersFromCache = function getBannersFromCache() { var cachedBanners = cache.read("banners"); if (!cachedBanners || !cachedBanners.value || !cachedBanners.staleDate) { return $.Deferred().reject(); } if ((0, _util.isAfterDate)(cachedBanners.staleDate)) { // Update in the background; still use old list until then getListOfBannersFromApi().then(cacheBanners); } return $.Deferred().resolve(cachedBanners.value); }; /** * Gets banner names, grouped by type (withRatings, withoutRatings, wrappers, notWPBM) * @returns {Promise<Object>} Object of string arrays keyed by type (withRatings, withoutRatings, wrappers, notWPBM) */ var getBannerNames = exports.getBannerNames = function getBannerNames() { return getBannersFromCache().then(function (banners) { // Ensure all keys exist if (!banners.withRatings || !banners.withoutRatings || !banners.wrappers || !banners.notWPBM || !banners.inactive || !banners.wir) { getListOfBannersFromApi().then(cacheBanners); return $.extend({ withRatings: [], withoutRatings: [], wrappers: [], notWPBM: [], inactive: [], wir: [] }, banners); } // Success: pass through return banners; })["catch"](function () { // Failure: get from Api, then cache them var bannersPromise = getListOfBannersFromApi(); bannersPromise.then(cacheBanners); return bannersPromise; }); }; // </nowiki> },{"./api":15,"./cache":17,"./util":23}],21:[function(require,module,exports){ "use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports.setPrefs = exports.getPrefs = exports["default"] = void 0; var _api = _interopRequireDefault(require("./api")); var _util = require("./util"); var _config = _interopRequireDefault(require("./config")); var cache = _interopRequireWildcard(require("./cache")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } // <nowiki> var prefsPage = "User:".concat(mw.config.get("wgUserName"), "/raterPrefs.json"); var writePrefsToCache = function writePrefsToCache(prefs) { return cache.write("prefs", prefs, 1 / 24 / 60 * 1, // 1 min 1 / 24 / 60 * 1 // 1 min ); }; var getPrefsFromApi = function getPrefsFromApi() { return _api["default"].get({ "action": "query", "format": "json", "prop": "revisions", "titles": prefsPage, "rvprop": "content", "rvslots": "main" }).then(function (response) { var page = response.query.pages[Object.keys(response.query.pages)[0]]; if (!page.pageid || page.missing === "") { return _config["default"].defaultPrefs; } var prefs; try { prefs = JSON.parse(page.revisions[0].slots.main["*"]); } catch (e) { return $.Deferred().reject("JSON-parsing-error", e); } writePrefsToCache(prefs); return prefs; }); }; var getPrefsFromCache = function getPrefsFromCache() { var cachedPrefs = cache.read("prefs"); if (!cachedPrefs || !cachedPrefs.value || !cachedPrefs.staleDate || (0, _util.isAfterDate)(cachedPrefs.staleDate)) { // No cached value, or is too old return $.Deferred().reject(); } return $.Deferred().resolve(cachedPrefs.value); }; var getPrefs = exports.getPrefs = function getPrefs() { return getPrefsFromCache().then( // Success: pass through (first param only) function (prefs) { return $.Deferred().resolve(prefs); }, // Failure: get from Api function () { return getPrefsFromApi(); }); }; /** * * @param {Object} updatedPrefs object with key:value pairs for preferences json. */ var setPrefs = exports.setPrefs = function setPrefs(updatedPrefs) { return _api["default"].editWithRetry(prefsPage, null, function () { return { "text": JSON.stringify(updatedPrefs), "summary": "Saving Rater preferences " + _config["default"].script.advert }; }).then(function () { return writePrefsToCache(updatedPrefs); }); }; var _default = exports["default"] = { get: getPrefs, set: setPrefs }; // </nowiki> },{"./api":15,"./cache":17,"./config":18,"./util":23}],22:[function(require,module,exports){ "use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _config = _interopRequireDefault(require("./config")); var _api = _interopRequireDefault(require("./api")); var _Template = require("./Template"); var _getBanners = require("./getBanners"); var cache = _interopRequireWildcard(require("./cache")); var _windowManager = _interopRequireDefault(require("./windowManager")); var _prefs = require("./prefs"); var _util = require("./util"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // <nowiki> var setupRater = function setupRater(clickEvent) { if (clickEvent) { clickEvent.preventDefault(); } var setupCompletedPromise = $.Deferred(); var currentPage = mw.Title.newFromText(_config["default"].mw.wgPageName); var talkPage = currentPage && currentPage.getTalkPage(); var subjectPage = currentPage && currentPage.getSubjectPage(); var subjectIsArticle = _config["default"].mw.wgNamespaceNumber <= 1; // Get preferences (task 0) var prefsPromise = (0, _prefs.getPrefs)(); // Get lists of all banners (task 1) var bannersPromise = (0, _getBanners.getBannerNames)(); // Load talk page (task 2) var loadTalkPromise = _api["default"].get({ action: "query", prop: "revisions", rvprop: "content", rvsection: "0", titles: talkPage.getPrefixedText(), indexpageids: 1 }).then(function (result) { var id = result.query.pageids; var wikitext = id < 0 ? "" : result.query.pages[id].revisions[0]["*"]; return wikitext; }); // Parse talk page for banners (task 3) var parseTalkPromise = loadTalkPromise.then(function (wikitext) { return (0, _Template.parseTemplates)(wikitext, true); }) // Get all templates .then(function (templates) { return templates.filter(function (template) { return template.getTitle() !== null; }); }) // Filter out invalid templates (e.g. parser functions) .then(function (templates) { return (0, _Template.getWithRedirectTo)(templates); }) // Check for redirects .then(function (templates) { return bannersPromise.then(function (allBanners) { // Get list of all banner templates return (0, _util.filterAndMap)(templates, // Filter out non-banners function (template) { if (template.isShellTemplate()) { return true; } var mainText = template.redirectTarget ? template.redirectTarget.getMainText() : template.getTitle().getMainText(); return allBanners.withRatings.includes(mainText) || allBanners.withoutRatings.includes(mainText) || allBanners.wrappers.includes(mainText) || allBanners.notWPBM.includes(mainText) || allBanners.inactive.includes(mainText) || allBanners.wir.includes(mainText); }, // Set additional properties if needed function (template) { var mainText = template.redirectTarget ? template.redirectTarget.getMainText() : template.getTitle().getMainText(); if (allBanners.wrappers.includes(mainText)) { template.redirectTarget = mw.Title.newFromText("Template:Subst:" + mainText); } if (allBanners.withoutRatings.includes(mainText) || allBanners.wir.includes(mainText)) { template.withoutRatings = true; } if (allBanners.inactive.includes(mainText)) { template.inactiveProject = true; } return template; }); }); }); // Retrieve and store classes, importances, and TemplateData (task 4) var templateDetailsPromise = parseTalkPromise.then(function (templates) { // Wait for all promises to resolve return $.when.apply(null, [].concat(_toConsumableArray(templates.map(function (template) { return template.isShellTemplate() ? null : template.setClassesAndImportances(); })), _toConsumableArray(templates.map(function (template) { return template.setParamDataAndSuggestions(); })))).then(function () { // Add missing required/suggested values templates.forEach(function (template) { return template.addMissingParams(); }); // Return the now-modified templates return templates; }); }); // Check subject page features (task 5) - but don't error out if request fails var subjectPageCheckPromise = _api["default"].get({ action: "query", format: "json", formatversion: "2", prop: "categories", titles: subjectPage.getPrefixedText(), redirects: 1, clcategories: ["Category:All disambiguation pages", "Category:All stub articles", "Category:Good articles", "Category:Featured articles", "Category:Featured lists"] }).then(function (response) { if (!response || !response.query || !response.query.pages) { return null; } var redirectTarget = response.query.redirects && response.query.redirects[0].to || false; if (redirectTarget || !subjectIsArticle) { return { redirectTarget: redirectTarget }; } var page = response.query.pages[0]; var hasCategory = function hasCategory(category) { return page.categories && page.categories.find(function (cat) { return cat.title === "Category:" + category; }); }; return { redirectTarget: redirectTarget, disambig: hasCategory("All disambiguation pages"), stubtag: hasCategory("All stub articles"), isGA: hasCategory("Good articles"), isFA: hasCategory("Featured articles"), isFL: hasCategory("Featured lists"), isList: !hasCategory("Featured lists") && /^Lists? of/.test(subjectPage.getPrefixedText()) }; })["catch"](function () { return null; }); // Failure ignored // Retrieve rating from ORES (task 6, only needed for articles) - but don't error out if request fails var shouldGetOres = subjectIsArticle; // TODO: Don't need to get ORES for redirects or disambigs if (shouldGetOres) { var latestRevIdPromise = !currentPage.isTalkPage() ? $.Deferred().resolve(_config["default"].mw.wgRevisionId) : _api["default"].get({ action: "query", format: "json", prop: "revisions", titles: subjectPage.getPrefixedText(), rvprop: "ids", indexpageids: 1 }).then(function (result) { if (result.query.redirects) { return false; } var id = result.query.pageids; var page = result.query.pages[id]; if (page.missing === "") { return false; } if (id < 0) { return $.Deferred().reject(); } return page.revisions[0].revid; }); var oresPromise = latestRevIdPromise.then(function (latestRevId) { if (!latestRevId) { return false; } return _api["default"].getORES(latestRevId).then(function (result) { var data = result.enwiki.scores[latestRevId].articlequality; if (data.error) { return $.Deferred().reject(data.error.type, data.error.message); } var prediction = data.score.prediction; var probabilities = data.score.probability; if (prediction === "FA" || prediction === "GA") { return { prediction: "B or higher", probability: ((probabilities.FA + probabilities.GA + probabilities.B) * 100).toFixed(1) + "%" }; } return { prediction: prediction, probability: (probabilities[prediction] * 100).toFixed(1) + "%" }; })["catch"](function () { return null; }); // Failure ignored; }); } // Open the load dialog var isOpenedPromise = $.Deferred(); var loadDialogWin = _windowManager["default"].openWindow("loadDialog", { promises: [bannersPromise, loadTalkPromise, parseTalkPromise, templateDetailsPromise, subjectPageCheckPromise, shouldGetOres && oresPromise], ores: shouldGetOres, isOpened: isOpenedPromise }); loadDialogWin.opened.then(isOpenedPromise.resolve); $.when(prefsPromise, loadTalkPromise, templateDetailsPromise, subjectPageCheckPromise, shouldGetOres && oresPromise).then( // All succeded function (preferences, talkWikitext, banners, subjectPageCheck, oresPredicition) { var result = { success: true, talkpage: talkPage, subjectPage: subjectPage, talkWikitext: talkWikitext, banners: banners, preferences: preferences, isArticle: subjectIsArticle }; if (subjectPageCheck) { result = _objectSpread(_objectSpread({}, result), subjectPageCheck); } if (oresPredicition && subjectPageCheck && !subjectPageCheck.isGA && !subjectPageCheck.isFA && !subjectPageCheck.isFL) { result.ores = oresPredicition; } _windowManager["default"].closeWindow("loadDialog", result); }); // Any failures are handled by the loadDialog window itself // On window closed, check data, and resolve/reject setupCompletedPromise loadDialogWin.closed.then(function (data) { if (data && data.success) { // Got everything needed: Resolve promise with this data setupCompletedPromise.resolve(data); } else if (data && data.error) { // There was an error: Reject promise with error code/info setupCompletedPromise.reject(data.error.code, data.error.info); } else { // Window closed before completion: resolve promise without any data setupCompletedPromise.resolve(null); } cache.clearInvalidItems(); }); return setupCompletedPromise; }; var _default = exports["default"] = setupRater; // </nowiki> },{"./Template":3,"./api":15,"./cache":17,"./config":18,"./getBanners":20,"./prefs":21,"./util":23,"./windowManager":24}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.classMask = classMask; exports.filterAndMap = void 0; exports.importanceMask = importanceMask; exports.isAfterDate = void 0; exports.mostFrequent = mostFrequent; exports.normaliseYesNo = void 0; exports.uniqueArray = uniqueArray; function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // <nowiki> // Various utility functions and objects that might be used in multiple places var isAfterDate = exports.isAfterDate = function isAfterDate(dateString) { return new Date(dateString) < new Date(); }; var yesWords = ["add", "added", "affirm", "affirmed", "include", "included", "on", "true", "yes", "y", "1"]; var noWords = ["decline", "declined", "exclude", "excluded", "false", "none", "not", "no", "n", "off", "omit", "omitted", "remove", "removed", "0"]; var normaliseYesNo = exports.normaliseYesNo = function normaliseYesNo(val) { if (val == null) { return val; } var trimmedLcVal = val.trim().toLowerCase(); if (yesWords.includes(trimmedLcVal)) { return "yes"; } else if (noWords.includes(trimmedLcVal)) { return "no"; } else { return trimmedLcVal; } }; /** * * @param {Array} array * @param {Function} filterPredicate (currentVal, currentIndex, array) => {boolean} * @param {Function} mapTransform (currentVal, currentIndex, array) => {any} * @returns {Array} */ var filterAndMap = exports.filterAndMap = function filterAndMap(array, filterPredicate, mapTransform) { return array.reduce(function (accumulated, currentVal, currentIndex) { if (filterPredicate(currentVal, currentIndex, array)) { return [].concat(_toConsumableArray(accumulated), [mapTransform(currentVal, currentIndex, array)]); } return accumulated; }, []); }; /** * * @param {string[]|number[]} array * @returns {string|null} item with the highest frequency * e.g. `mostFrequent(["apple", "apple", "orange"])` returns `"apple"` */ function mostFrequent(array) { if (!array || !Array.isArray(array) || array.length === 0) return null; var map = {}; var mostFreq = null; array.forEach(function (item) { map[item] = (map[item] || 0) + 1; if (mostFreq === null || map[item] > map[mostFreq]) { mostFreq = item; } }); return mostFreq; } /** * * @param {string[]|number[]} array * @returns {string[]|number[]} array with only unique values * e.g. `uniqueArray(["apple", "apple", "orange"])` returns `["apple", "orange"]` */ function uniqueArray(array) { if (!array || !Array.isArray(array) || array.length === 0) return []; var seen = {}; var unique = []; array.forEach(function (item) { if (!seen[item]) { unique.push(item); seen[item] = true; } }); return unique; } function classMask(classVal) { if (!classVal) { return classVal; } switch (classVal.toLowerCase()) { case "fa": case "fl": case "a": case "ga": case "b": case "c": case "na": case "fm": case "al": case "bl": case "cl": return classVal.toUpperCase(); case "start": case "stub": case "list": case "portal": case "project": case "draft": case "book": case "future": case "current": case "complete": case "substantial": case "basic": case "incomplete": case "meta": return classVal.slice(0, 1).toUpperCase() + classVal.slice(1).toLowerCase(); case "image": case "img": case "file": return "File"; case "category": case "cat": case "categ": return "Category"; case "disambiguation": case "disambig": case "disamb": case "dab": return "Disambig"; case "redirect": case "redir": case "red": return "Redirect"; case "template": case "temp": case "tpl": return "Template"; case "bplus": case "b+": return "Bplus"; case "fpo": return "FPo"; default: return classVal; } } function importanceMask(importance) { if (!importance) { return importance; } if (importance.toLowerCase() === "na") { return "NA"; } return importance.slice(0, 1).toUpperCase() + importance.slice(1).toLowerCase(); } // </nowiki> },{}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _LoadDialog = _interopRequireDefault(require("./Windows/LoadDialog")); var _MainWindow = _interopRequireDefault(require("./Windows/MainWindow")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } // <nowiki> var factory = new OO.Factory(); // Register window constructors with the factory. factory.register(_LoadDialog["default"]); factory.register(_MainWindow["default"]); var manager = new OO.ui.WindowManager({ "factory": factory }); // Marker class, so CSS rules can target Rater's own windows without affecting // other OOUI dialogs (e.g. OO.ui.confirm, which renders in #mw-teleport-target) manager.$element.addClass("rater-windowManager"); $(document.body).append(manager.$element); var _default = exports["default"] = manager; // </nowiki> },{"./Windows/LoadDialog":13,"./Windows/MainWindow":14}]},{},[2]) //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJwYWNrYWdlLmpzb24iLCJyYXRlci1zcmMvQXBwLmpzIiwicmF0ZXItc3JjL1RlbXBsYXRlLmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9CYW5uZXJMaXN0V2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9CYW5uZXJXaWRnZXQuanMiLCJyYXRlci1zcmMvV2luZG93cy9Db21wb25lbnRzL0Ryb3Bkb3duUGFyYW1ldGVyV2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9Ib3Jpem9udGFsTGF5b3V0V2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9QYXJhbWV0ZXJMaXN0V2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9QYXJhbWV0ZXJXaWRnZXQuanMiLCJyYXRlci1zcmMvV2luZG93cy9Db21wb25lbnRzL1ByZWZzRm9ybVdpZGdldC5qcyIsInJhdGVyLXNyYy9XaW5kb3dzL0NvbXBvbmVudHMvU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldC5qcyIsInJhdGVyLXNyYy9XaW5kb3dzL0NvbXBvbmVudHMvVG9wQmFyV2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvTG9hZERpYWxvZy5qcyIsInJhdGVyLXNyYy9XaW5kb3dzL01haW5XaW5kb3cuanMiLCJyYXRlci1zcmMvYXBpLmpzIiwicmF0ZXItc3JjL2F1dG9zdGFydC5qcyIsInJhdGVyLXNyYy9jYWNoZS5qcyIsInJhdGVyLXNyYy9jb25maWcuanMiLCJyYXRlci1zcmMvY3NzLmpzIiwicmF0ZXItc3JjL2dldEJhbm5lcnMuanMiLCJyYXRlci1zcmMvcHJlZnMuanMiLCJyYXRlci1zcmMvc2V0dXAuanMiLCJyYXRlci1zcmMvdXRpbC5qcyIsInJhdGVyLXNyYy93aW5kb3dNYW5hZ2VyLmpzIl0sIm5hbWVz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QUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsY0FBQSxFQUFBLElBQUEsQ0FBQSxnQkFBQSxFQUFBLE9BQUEsY0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsSUFBQSxDQUFBLEdBQUEsTUFBQSxDQUFBLGNBQUEsS0FBQSxNQUFBLENBQUEsd0JBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsQ0FBQSxDQUFBLEdBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsRUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxXQUFBLENBQUEsS0FBQSxDQUFBLEVBQUEsQ0FBQTtBQUFBLFNBQUEsdUJBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxHQUFBLENBQUEsZ0JBQUEsQ0FBQTtBQUFBLFNBQUEsbUJBQUEsQ0FBQSxXQUFBLGtCQUFBLENBQUEsQ0FBQSxLQUFBLGdCQUFBLENBQUEsQ0FBQSxLQUFBLDJCQUFBLENBQUEsQ0FBQSxLQUFBLGtCQUFBO0FBQUEsU0FBQSxtQkFBQSxjQUFBLFNBQUE7QUFBQSxTQUFBLDRCQUFBLENBQUEsRUFBQSxDQUFBLFFBQUEsQ0FBQSwyQkFBQSxDQUFBLFNBQUEsaUJBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQSxPQUFBLENBQUEsTUFBQSxRQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxLQUFBLDZCQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsV0FBQSxLQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsV0FBQSxDQUFBLElBQUEsYUFBQSxDQUFBLGNBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxvQkFBQSxDQUFBLCtDQUFBLElBQUEsQ0FBQSxDQUFBLElBQUEsaUJBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQTtBQUFBLFNBQUEsaUJBQUEsQ0FBQSw4QkFB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Q0FBQSxFQUFBLENBQUEsT0FBQSxDQUFBLE1BQUEsUUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsS0FBQSw2QkFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFdBQUEsS0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLFdBQUEsQ0FBQSxJQUFBLGFBQUEsQ0FBQSxjQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsb0JBQUEsQ0FBQSwrQ0FBQSxJQUFBLENBQUEsQ0FBQSxJQUFBLGlCQUFBLENBQUEsQ0FBQSxFQUFBLENBQUE7QUFBQSxTQUFBLGtCQUFBLENBQUEsRUFBQSxDQUFBLGFBQUEsQ0FBQSxJQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsTUFBQSxNQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsTUFBQSxZQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLEdBQUEsQ0FBQSxFQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxDQUFBLFVBQUEsQ0FBQTtBQUFBLFNBQUEsc0JBQUEsQ0FBQSxFQUFBLENBQUEsUUFBQSxDQUFBLFdBQUEsQ0FBQSxnQ0FBQSxNQUFBLElBQUEsQ0FBQSxDQUFBLE1BQUEsQ0FBQSxRQUFBLEtBQUEsQ0FBQSw0QkFBQSxDQUFBLFFBQUEsQ0FBQSxFQUFBLENBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLENBQUEsT0FBQSxDQUFBLE9BQUEsQ0FBQSxpQkFBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsUUFBQSxDQUFBLFFBQUEsTUFBQSxDQUFBLENBQUEsTUFBQSxDQUFBLFVBQUEsQ0FBQSx1QkFBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsTUFBQSxDQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxLQUFBLEdBQUEsQ0FBQSxDQUFBLE1BQUEsS0FBQSxDQUFBLEdBQUEs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QUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxLQUFBLEdBQUEsdUJBQUEsQ0FBQSxPQUFBO0FBQWlDLFNBQUEsd0JBQUEsQ0FBQSxFQUFBLENBQUEsNkJBQUEsT0FBQSxNQUFBLENBQUEsT0FBQSxPQUFBLElBQUEsQ0FBQSxPQUFBLE9BQUEsWUFBQSx1QkFBQSxZQUFBLHdCQUFBLENBQUEsRUFBQSxDQUFBLFNBQUEsQ0FBQSxJQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLENBQUEsS0FBQSxTQUFBLG1CQUFBLENBQUEsaUJBQUEsQ0FBQSxnQkFBQSxPQUFBLENBQUEsQ0FBQSwwQkFBQSxDQUFBLFNBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxDQUFBLEdBQUEsQ0FBQSxHQUFBLENBQUEsUUFBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsVUFBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsRUFBQSxDQUFBLGNBQUEsRUFBQSxJQUFBLENBQUEsZ0JBQUEsRUFBQSxPQUFBLGNBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsT0FBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLE1BQUEsQ0FBQSxjQUFBLEtBQUEsTUFBQSxDQUFBLHdCQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsT0FBQSxDQUFBLENBQUEsR0FBQSxJQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsQ0FBQSxDQUFBLENBQUEsRUFBQSxFQUFBLEVBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsV0FBQSxDQUFBLEtBQUEsQ0FBQSxFQUFBLENBQUE7QUFBQSxTQUFBLHVCQUFBLENBQUEsV0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFVBQUEsR0FBQSxDQUFBLGdCQUFBLENBQUE7QUFDakM7O0FBRUEsSUFBTSxTQUFTLFdBQUEsTUFBQSxDQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxD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LE9BQUEsY0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsSUFBQSxDQUFBLEdBQUEsTUFBQSxDQUFBLGNBQUEsS0FBQSxNQUFBLENBQUEsd0JBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsQ0FBQSxDQUFBLEdBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsRUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxXQUFBLENBQUEsS0FBQSxDQUFBLEVBQUEsQ0FBQTtBQUFBLFNBQUEsdUJBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxHQUFBLENBQUEsZ0JBQUEsQ0FBQTtBQUFBLFNBQUEsUUFBQSxDQUFBLEVBQUEsQ0FBQSxRQUFBLENBQUEsR0FBQSxNQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsT0FBQSxNQUFBLENBQUEscUJBQUEsUUFBQSxDQUFBLEdBQUEsTUFBQSxDQUFBLHFCQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLE1BQUEsV0FBQSxDQUFBLFdBQUEsTUFBQSxDQUFBLHdCQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsRUFBQSxVQUFBLE9BQUEsQ0FBQSxDQUFBLElBQUEsQ0FBQSxLQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsWUFBQSxDQUFBO0FBQUEsU0FBQSxjQUFBLENBQUEsYUFBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLFNBQUEsQ0FBQSxNQUFBLEVBQUEsQ0FBQSxVQUFBLENBQUEsV0FBQSxTQUFBLENBQUEsQ0FBQSxJQUFBLFNBQUEsQ0FBQSxDQUFBLFFBQUEsQ0FBQSxPQUFBLE9BQUEsQ0FBQSxNQUFBLENBQUEsQ0FBQSxPQUFBLE9BQUEsV0FBQSxDQUFBLElBQUEsZUFBQSxDQUFBLENBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxDQUFBLENBQUEsU0FBQSxNQUFBLENBQUEseUJBQUEsR0FBQSxNQUFBLENBQUEsZ0JBQUEsQ0FBQSxDQUFBLEVBQUEsTUFBQSxDQUFBLHlCQUFBLENBQUEsQ0FBQSxLQUFBLE9BQUEsQ0FBQSxNQUFBLENBQUEsQ0FBQSxHQUFBLE9BQUEsV0FBQSxDQUFBLElBQUEsTUFBQSxDQUFBLGNBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLE1BQUEsQ0FBQSx3QkFBQSxDQUFBLENBQUEsRUFBQSxDQUFBLGlCQUFBLENBQUE7QUFBQSxTQUFBLGdCQUFBLENBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxZQUFBLENBQUEsR0FBQSxjQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxNQUFBLENBQUEsY0FBQSxDQUFBLENBQUEsRUFBQSxDQUFBLElBQUEsS0FBQSxFQUFBLENBQUEsRUFBQSxVQUFBLE1BQUEsWUFBQSxNQUFBLFFBQUEsVUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSxlQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsWUFBQSxDQUFBLENBQUEsZ0NBQUEsT0FBQSxDQUFBLENBQUEsSUFBQSxDQUFBLEdBQUEsQ0FBQTtBQUFBLFNBQUEsYUFBQSxDQUFBLEVBQUEsQ0FBQSxvQkFBQSxPQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsU0FBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsV0FBQSxrQkFBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsZ0NBQUEsT0FBQSxDQUFBLENBQUEsVUFBQSxDQUFBLFlBQUEsU0FBQSx5RUFBQSxDQUFBLEdBQUEsTUFBQSxHQUFBLE1BQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSxtQkFBQSxDQUFBLFdBQUEsa0JBQUEsQ0FBQSxDQUFBLEtBQUEsZ0JBQUEsQ0FBQSxDQUFBLEtBQUEsMkJBQUEsQ0FBQSxDQUFBLEtBQUEsa0JBQUE7QUFBQSxTQUFBLG1CQUFBLGNBQUEsU0FBQTtBQUFBLFNBQUEsNEJBQUEsQ0FBQSxFQUFBLENBQUEs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OUM7O0FBRUEsSUFBSSxPQUFPLEdBQUcsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRTlCO0FBQ0EsT0FBTyxDQUFDLFFBQVEsQ0FBQyxzQkFBVSxDQUFDO0FBQzVCLE9BQU8sQ0FBQyxRQUFRLENBQUMsc0JBQVUsQ0FBQztBQUU1QixJQUFJLE9BQU8sR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFFO0VBQ3RDLFNBQVMsRUFBRTtBQUNaLENBQUUsQ0FBQztBQUNIO0FBQ0E7QUFDQSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBRSxxQkFBc0IsQ0FBQztBQUNsRCxDQUFDLENBQUUsUUFBUSxDQUFDLElBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBRSxPQUFPLENBQUMsUUFBUyxDQUFDO0FBQUMsSUFBQSxRQUFBLEdBQUEsT0FBQSxjQUUvQixPQUFPLEVBQ3RCIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm5hbWVcIjogXCJyYXRlclwiLFxuICBcInZlcnNpb25cIjogXCIyLjcuMlwiLFxuICBcImRlc2NyaXB0aW9uXCI6IFwiV2lraXBlZGlhIHVzZXJzY3JpcHQgdGhhdCBoZWxwcyBhc3Nlc3MgcGFnZXMgZm9yIFdpa2lQcm9qZWN0c1wiLFxuICBcImhvbWVwYWdlXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2V2YWQzNy9yYXRlclwiLFxuICBcImJyb3dzZXJcIjogXCJpbmRleC5qc1wiLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwidGVzdFwiOiBcImVjaG8gXFxcIkVycm9yOiBubyB0ZXN0IHNwZWNpZmllZFxcXCIgJiYgZXhpdCAxXCIsXG4gICAgXCJsaW50OmVzNVwiOiBcImpzaGludCBpbmRleC5qc1wiLFxuICAgIFwibGludDplczZcIjogXCJlc2xpbnQgaW5kZXguanMgXFxcInJhdGVyLXNyYy8qKlxcXCJcIixcbiAgICBcImxpbnQ6Zml4XCI6IFwiZXNsaW50IGluZGV4LmpzIFxcXCJyYXRlci1zcmMvKipcXFwiIC0tZml4XCIsXG4gICAgXCJsaW50XCI6IFwibnBtIHJ1biBsaW50OmVzNiAmJiBucG0gcnVuIGxpbnQ6ZXM1XCIsXG4gICAgXCJidWlsZDpidW5kbGVcIjogXCJicm93c2VyaWZ5IHJhdGVyLXNyYy9BcHAuanMgLS1kZWJ1ZyAtdCBiYWJlbGlmeSAtLW91dGZpbGUgZGlzdC9yYXRlci5qc1wiLFxuICAgIFwiYnVpbGQ6bWluaWZ5XCI6IFwidWdsaWZ5anMgZGlzdC9yYXRlci5qcyAtLWNvbXByZXNzIC1iIGFzY2lpX29ubHk9dHJ1ZSxiZWF1dGlmeT1mYWxzZSAtLW91dHB1dCBkaXN0L3JhdGVyLm1pbi5qc1wiLFxuICAgIFwiYnVpbGQ6Y29uY2F0XCI6IFwiY29uY2F0LWNsaSAtZiBcXFwiY29tbWVudC10b3AuanNcXFwiIGRpc3QvcmF0ZXIubWluLmpzIFxcXCJjb21tZW50LWJvdHRvbS5qc1xcXCIgLW8gZGlzdC9yYXRlci5taW4uanNcIixcbiAgICBcImJ1aWxkXCI6IFwibnBtIHJ1biBsaW50ICYmIG5wbSBydW4gYnVpbGQ6YnVuZGxlICYmIG5wbSBydW4gYnVpbGQ6bWluaWZ5ICYmIG5wbSBydW4gYnVpbGQ6Y29uY2F0XCJcbiAgfSxcbiAgXCJhdXRob3JcIjoge1xuICAgIFwibmFtZVwiOiBcIkV2YWQzN1wiLFxuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVXNlcjpFdmFkMzdcIlxuICB9LFxuICBcInJlcG9zaXRvcnlcIjoge1xuICAgIFwidHlwZVwiOiBcImdpdFwiLFxuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2V2YWQzNy9yYXRlci5naXRcIlxuICB9LFxuICBcImxpY2Vuc2VcIjogXCIoTUlUIE9SIENDLUJZLTQuMClcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQGJhYmVsL2NvcmVcIjogXCJeNy45LjBcIixcbiAgICBcIkBiYWJlbC9wcmVzZXQtZW52XCI6IFwiXjcuOS4wXCIsXG4gICAgXCJiYWJlbGlmeVwiOiBcIl4xMC4wLjBcIixcbiAgICBcImJyb3dzZXJpZnlcIjogXCJeMTYuNS4wXCIsXG4gICAgXCJjb25jYXQtY2xpXCI6IFwiXjQuMC4wXCIsXG4gICAgXCJlc2xpbnRcIjogXCJeNi44LjBcIixcbiAgICBcImpzaGludFwiOiBcIl4yLjExLjBcIixcbiAgICBcInVnbGlmeS1qc1wiOiBcIl4zLjguMFwiXG4gIH1cbn1cbiIsImltcG9ydCBzZXR1cFJhdGVyIGZyb20gXCIuL3NldHVwXCI7XHJcbmltcG9ydCBhdXRvU3RhcnQgZnJvbSBcIi4vYXV0b3N0YXJ0XCI7XHJcbmltcG9ydCBzdHlsZXMgZnJvbSBcIi4vY3NzLmpzXCI7XHJcbmltcG9ydCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgd2luZG93TWFuYWdlciBmcm9tIFwiLi93aW5kb3dNYW5hZ2VyXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG4oZnVuY3Rpb24gQXBwKCkge1xyXG5cdGxldCBzdHlsZXNoZWV0O1xyXG5cclxuXHRjb25zdCBzaG93TWFpbldpbmRvdyA9IGRhdGEgPT4ge1xyXG5cdFx0aWYgKCFkYXRhIHx8ICFkYXRhLnN1Y2Nlc3MpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKHN0eWxlc2hlZXQpIHtcclxuXHRcdFx0c3R5bGVzaGVldC5kaXNhYmxlZCA9IGZhbHNlO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c3R5bGVzaGVldCA9IG13LnV0aWwuYWRkQ1NTKHN0eWxlcyk7XHJcblx0XHR9XHJcblx0XHQvLyBBZGQgY3NzIGNsYXNzIHRvIGJvZHkgdG8gZW5hYmxlIGJhY2tncm91bmQgc2Nyb2xsaW5nXHJcblx0XHRkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJvZHlcIilbMF0uY2xhc3NMaXN0LmFkZChcInJhdGVyLW1haW5XaW5kb3ctb3BlblwiKTtcclxuXHRcdC8vIE9wZW4gdGhlIHdpbmRvd1xyXG5cdFx0d2luZG93TWFuYWdlci5vcGVuV2luZG93KFwibWFpblwiLCBkYXRhKVxyXG5cdFx0XHQuY2xvc2VkLnRoZW4oIHJlc3VsdCA9PiB7XHJcblx0XHRcdFx0Ly8gRGlzYWJsZS9yZW1vdmUgdGhlIGNzcyBzdHlsZXMsIHNvIGFzIHRvIG5vdCBpbnRlcmZlcmUgd2l0aCBvdGhlciBzY3JpcHRzL2NvbnRlbnQvT09VSSB3aW5kb3dzXHJcblx0XHRcdFx0aWYgKHN0eWxlc2hlZXQpIHsgc3R5bGVzaGVldC5kaXNhYmxlZCA9IHRydWU7IH1cclxuXHRcdFx0XHRkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJvZHlcIilbMF0uY2xhc3NMaXN0LnJlbW92ZShcInJhdGVyLW1haW5XaW5kb3ctb3BlblwiKTtcclxuXHRcdFx0XHQvLyBSZXN0YXJ0IGlmIG5lZWRlZFxyXG5cdFx0XHRcdGlmIChyZXN1bHQgJiYgcmVzdWx0LnJlc3RhcnQpIHtcclxuXHRcdFx0XHRcdHdpbmRvd01hbmFnZXIucmVtb3ZlV2luZG93cyhbXCJtYWluXCJdKVxyXG5cdFx0XHRcdFx0XHQudGhlbihzZXR1cFJhdGVyKVxyXG5cdFx0XHRcdFx0XHQudGhlbihzaG93TWFpbldpbmRvdywgc2hvd1NldHVwRXJyb3IpO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQvLyBTaG93IG5vdGlmaWNhdGlvbiB3aGVuIHNhdmVkIHN1Y2Nlc3NmdWxseVxyXG5cdFx0XHRcdGlmIChyZXN1bHQgJiYgcmVzdWx0LnN1Y2Nlc3MpIHtcclxuXHRcdFx0XHRcdGNvbnN0ICRtZXNzYWdlID0gJChcIjxzcGFuPlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nPlwiKS50ZXh0KFwiUmF0aW5ncyBzYXZlZCBzdWNjZXNzZnVsbHkuXCIpXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdFx0aWYgKHJlc3VsdC51cGdyYWRlZFN0dWIpIHtcclxuXHRcdFx0XHRcdFx0JG1lc3NhZ2UuYXBwZW5kKFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8YnI+XCIpLFxyXG5cdFx0XHRcdFx0XHRcdC8vIFRPRE86IFRoZXJlIHNob3VsZCBiZSBhIGxpbmsgdGhhdCB3aWxsIGVkaXQgdGhlIGFydGljbGUgZm9yIHlvdVxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3Bhbj5cIikudGV4dChcIk5vdGUgdGhhdCB0aGUgYXJ0aWNsZSBhcHBlYXJzIHRvIGJlIHRhZ2dlZCBhcyBhIHN0dWIuXCIpXHJcblx0XHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRtdy5ub3RpZnkoXHJcblx0XHRcdFx0XHRcdCRtZXNzYWdlLFxyXG5cdFx0XHRcdFx0XHR7IGF1dG9IaWRlOiB0cnVlLCBhdXRvSGlkZVNlY29uZHM6IFwibG9uZ1wiLCB0YWc6IFwiUmF0ZXItc2F2ZWRcIiB9XHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdH07XHJcblxyXG5cdGNvbnN0IHNob3dTZXR1cEVycm9yID0gKGNvZGUsIGpxeGhyKSA9PiBPTy51aS5hbGVydChcclxuXHRcdG1ha2VFcnJvck1zZyhjb2RlLCBqcXhociksXHR7XHJcblx0XHRcdHRpdGxlOiBcIlJhdGVyIGZhaWxlZCB0byBvcGVuXCJcclxuXHRcdH1cclxuXHQpO1xyXG5cclxuXHQvLyBJbnZvY2F0aW9uIGJ5IHBvcnRsZXQgbGluayBcclxuXHRtdy51dGlsLmFkZFBvcnRsZXRMaW5rKFxyXG5cdFx0XCJwLWNhY3Rpb25zXCIsXHJcblx0XHRcIiNcIixcclxuXHRcdFwiUmF0ZXJcIixcclxuXHRcdFwiY2EtcmF0ZXJcIixcclxuXHRcdFwiUmF0ZSBxdWFsaXR5IGFuZCBpbXBvcnRhbmNlXCIsXHJcblx0XHRcIjVcIlxyXG5cdCk7XHJcblx0JChcIiNjYS1yYXRlclwiKS5jbGljayhldmVudCA9PiB7XHJcblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0c2V0dXBSYXRlcigpLnRoZW4oc2hvd01haW5XaW5kb3csIHNob3dTZXR1cEVycm9yKTtcclxuXHR9KTtcclxuXHJcblx0Ly8gSW52b2NhdGlvbiBieSBhdXRvLXN0YXJ0IChkbyBub3Qgc2hvdyBtZXNzYWdlIG9uIGVycm9yKVxyXG5cdGF1dG9TdGFydCgpLnRoZW4oc2hvd01haW5XaW5kb3cpO1xyXG59KSgpO1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgQVBJIGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQge2lzQWZ0ZXJEYXRlLCBtb3N0RnJlcXVlbnQsIGZpbHRlckFuZE1hcH0gZnJvbSBcIi4vdXRpbFwiO1xyXG5pbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG5pbXBvcnQgKiBhcyBjYWNoZSBmcm9tIFwiLi9jYWNoZVwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxuLyoqIFRlbXBsYXRlXHJcbiAqXHJcbiAqIEBjbGFzc1xyXG4gKiBSZXByZXNlbnRzIHRoZSB3aWtpdGV4dCBvZiB0ZW1wbGF0ZSB0cmFuc2NsdXNpb24uIFVzZWQgYnkgI3BhcnNlVGVtcGxhdGVzLlxyXG4gKiBAcHJvcCB7U3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIHRlbXBsYXRlXHJcbiAqIEBwcm9wIHtTdHJpbmd9IHdpa2l0ZXh0IEZ1bGwgd2lraXRleHQgb2YgdGhlIHRyYW5zY2x1c2lvblxyXG4gKiBAcHJvcCB7T2JqZWN0W119IHBhcmFtZXRlcnMgUGFyYW1ldGVycyB1c2VkIGluIHRoZSB0cmFuc2xjdXNpb24sIGluIG9yZGVyLCBvZiBmb3JtOlxyXG5cdHtcclxuXHRcdG5hbWU6IHtTdHJpbmd8TnVtYmVyfSBwYXJhbWV0ZXIgbmFtZSwgb3IgcG9zaXRpb24gZm9yIHVubmFtZWQgcGFyYW1ldGVycyxcclxuXHRcdHZhbHVlOiB7U3RyaW5nfSBXaWtpdGV4dCBwYXNzZWQgdG8gdGhlIHBhcmFtZXRlciAod2hpdGVzcGFjZSB0cmltbWVkKSxcclxuXHRcdHdpa2l0ZXh0OiB7U3RyaW5nfSBGdWxsIHdpa2l0ZXh0IChpbmNsdWRpbmcgbGVhZGluZyBwaXBlLCBwYXJhbWV0ZXIgbmFtZS9lcXVhbHMgc2lnbiAoaWYgYXBwbGljYWJsZSksIHZhbHVlLCBhbmQgYW55IHdoaXRlc3BhY2UpXHJcblx0fVxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtTdHJpbmd9IHdpa2l0ZXh0IFdpa2l0ZXh0IG9mIGEgdGVtcGxhdGUgdHJhbnNjbHVzaW9uLCBzdGFydGluZyB3aXRoICd7eycgYW5kIGVuZGluZyB3aXRoICd9fScuXHJcbiAqL1xyXG52YXIgVGVtcGxhdGUgPSBmdW5jdGlvbih3aWtpdGV4dCkge1xyXG5cdHRoaXMud2lraXRleHQgPSB3aWtpdGV4dDtcclxuXHR0aGlzLnBhcmFtZXRlcnMgPSBbXTtcclxuXHQvLyBTcGFjaW5nIGFyb3VuZCBwaXBlcywgZXF1YWxzIHNpZ25zLCBlbmQgYnJhY2VzIChkZWZhdWx0cylcclxuXHR0aGlzLnBpcGVTdHlsZSA9IFwiIHxcIjtcclxuXHR0aGlzLmVxdWFsc1N0eWxlID0gXCI9XCI7XHJcblx0dGhpcy5lbmRCcmFjZXNTdHlsZSA9IFwifX1cIjtcclxufTtcclxuVGVtcGxhdGUucHJvdG90eXBlLmFkZFBhcmFtID0gZnVuY3Rpb24obmFtZSwgdmFsLCB3aWtpdGV4dCkge1xyXG5cdHRoaXMucGFyYW1ldGVycy5wdXNoKHtcclxuXHRcdFwibmFtZVwiOiBuYW1lLFxyXG5cdFx0XCJ2YWx1ZVwiOiB2YWwsIFxyXG5cdFx0XCJ3aWtpdGV4dFwiOiBcInxcIiArIHdpa2l0ZXh0XHJcblx0fSk7XHJcbn07XHJcbi8qKlxyXG4gKiBHZXQgYSBwYXJhbWV0ZXIgZGF0YSBieSBwYXJhbWV0ZXIgbmFtZVxyXG4gKi8gXHJcblRlbXBsYXRlLnByb3RvdHlwZS5nZXRQYXJhbSA9IGZ1bmN0aW9uKHBhcmFtTmFtZSkge1xyXG5cdHJldHVybiB0aGlzLnBhcmFtZXRlcnMuZmluZChmdW5jdGlvbihwKSB7IHJldHVybiBwLm5hbWUgPT0gcGFyYW1OYW1lOyB9KTtcclxufTtcclxuVGVtcGxhdGUucHJvdG90eXBlLnNldE5hbWUgPSBmdW5jdGlvbihuYW1lKSB7XHJcblx0dGhpcy5uYW1lID0gbmFtZS50cmltKCk7XHJcbn07XHJcblRlbXBsYXRlLnByb3RvdHlwZS5nZXRUaXRsZSA9IGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiBtdy5UaXRsZS5uZXdGcm9tVGV4dChcIlRlbXBsYXRlOlwiICsgdGhpcy5uYW1lKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBwYXJzZVRlbXBsYXRlc1xyXG4gKlxyXG4gKiBQYXJzZXMgdGVtcGxhdGVzIGZyb20gd2lraXRleHQuXHJcbiAqIEJhc2VkIG9uIFNEMDAwMSdzIHZlcnNpb24gYXQgPGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VzZXI6U0QwMDAxL3BhcnNlQWxsVGVtcGxhdGVzLmpzPi5cclxuICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSB0ZW1wbGF0ZSBkZXRhaWxzOlxyXG4gKiAgdmFyIHRlbXBsYXRlcyA9IHBhcnNlVGVtcGxhdGVzKFwiSGVsbG8ge3tmb28gfEJhcnxiYXo9cXV4IHwyPWxvcmVtaXBzdW18Mz19fSB3b3JsZFwiKTtcclxuICogIGNvbnNvbGUubG9nKHRlbXBsYXRlc1swXSk7IC8vIC0tPiBvYmplY3RcclxuXHR7XHJcblx0XHRuYW1lOiBcImZvb1wiLFxyXG5cdFx0d2lraXRleHQ6XCJ7e2ZvbyB8QmFyfGJhej1xdXggfCAyID0gbG9yZW1pcHN1bSAgfDM9fX1cIixcclxuXHRcdHBhcmFtZXRlcnM6IFtcclxuXHRcdFx0e1xyXG5cdFx0XHRcdG5hbWU6IDEsXHJcblx0XHRcdFx0dmFsdWU6ICdCYXInLFxyXG5cdFx0XHRcdHdpa2l0ZXh0OiAnfEJhcidcclxuXHRcdFx0fSxcclxuXHRcdFx0e1xyXG5cdFx0XHRcdG5hbWU6ICdiYXonLFxyXG5cdFx0XHRcdHZhbHVlOiAncXV4JyxcclxuXHRcdFx0XHR3aWtpdGV4dDogJ3xiYXo9cXV4ICdcclxuXHRcdFx0fSxcclxuXHRcdFx0e1xyXG5cdFx0XHRcdG5hbWU6ICcyJyxcclxuXHRcdFx0XHR2YWx1ZTogJ2xvcmVtaXBzdW0nLFxyXG5cdFx0XHRcdHdpa2l0ZXh0OiAnfCAyID0gbG9yZW1pcHN1bSAgJ1xyXG5cdFx0XHR9LFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0bmFtZTogJzMnLFxyXG5cdFx0XHRcdHZhbHVlOiAnJyxcclxuXHRcdFx0XHR3aWtpdGV4dDogJ3wzPSdcclxuXHRcdFx0fVxyXG5cdFx0XSxcclxuXHRcdGdldFBhcmFtOiBmdW5jdGlvbihwYXJhbU5hbWUpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMucGFyYW1ldGVycy5maW5kKGZ1bmN0aW9uKHApIHsgcmV0dXJuIHAubmFtZSA9PSBwYXJhbU5hbWU7IH0pO1xyXG5cdFx0fVxyXG5cdH1cclxuICogICAgXHJcbiAqIFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gd2lraXRleHRcclxuICogQHBhcmFtIHtCb29sZWFufSByZWN1cnNpdmUgU2V0IHRvIGB0cnVlYCB0byBhbHNvIHBhcnNlIHRlbXBsYXRlcyB0aGF0IG9jY3VyIHdpdGhpbiBvdGhlciB0ZW1wbGF0ZXMsXHJcbiAqICByYXRoZXIgdGhhbiBqdXN0IHRvcC1sZXZlbCB0ZW1wbGF0ZXMuIFxyXG4gKiBAcmV0dXJuIHtUZW1wbGF0ZVtdfSB0ZW1wbGF0ZXNcclxuKi9cclxudmFyIHBhcnNlVGVtcGxhdGVzID0gZnVuY3Rpb24od2lraXRleHQsIHJlY3Vyc2l2ZSkgeyAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb250cm9sLXJlZ2V4ICovXHJcblx0aWYgKCF3aWtpdGV4dCkge1xyXG5cdFx0cmV0dXJuIFtdO1xyXG5cdH1cclxuXHR2YXIgc3RyUmVwbGFjZUF0ID0gZnVuY3Rpb24oc3RyaW5nLCBpbmRleCwgY2hhcikge1xyXG5cdFx0cmV0dXJuIHN0cmluZy5zbGljZSgwLGluZGV4KSArIGNoYXIgKyBzdHJpbmcuc2xpY2UoaW5kZXggKyAxKTtcclxuXHR9O1xyXG5cclxuXHR2YXIgcmVzdWx0ID0gW107XHJcblx0XHJcblx0dmFyIHByb2Nlc3NUZW1wbGF0ZVRleHQgPSBmdW5jdGlvbiAoc3RhcnRJZHgsIGVuZElkeCkge1xyXG5cdFx0dmFyIHRleHQgPSB3aWtpdGV4dC5zbGljZShzdGFydElkeCwgZW5kSWR4KTtcclxuXHJcblx0XHR2YXIgdGVtcGxhdGUgPSBuZXcgVGVtcGxhdGUoXCJ7e1wiICsgdGV4dC5yZXBsYWNlKC9cXHgwMS9nLFwifFwiKSArIFwifX1cIik7XHJcblx0XHRcclxuXHRcdC8vIHN3YXAgb3V0IHBpcGUgaW4gbGlua3Mgd2l0aCBcXHgwMSBjb250cm9sIGNoYXJhY3RlclxyXG5cdFx0Ly8gW1tGaWxlOiBdXSBjYW4gaGF2ZSBtdWx0aXBsZSBwaXBlcywgc28gbWlnaHQgbmVlZCBtdWx0aXBsZSBwYXNzZXNcclxuXHRcdHdoaWxlICggLyhcXFtcXFtbXlxcXV0qPylcXHwoLio/XFxdXFxdKS9nLnRlc3QodGV4dCkgKSB7XHJcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UoLyhcXFtcXFtbXlxcXV0qPylcXHwoLio/XFxdXFxdKS9nLCBcIiQxXFx4MDEkMlwiKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBGaWd1cmUgb3V0IG1vc3QtdXNlZCBzcGFjaW5nIHN0eWxlcyBmb3IgcGlwZXMvZXF1YWxzXHJcblx0XHR0ZW1wbGF0ZS5waXBlU3R5bGUgPSBtb3N0RnJlcXVlbnQoIHRleHQubWF0Y2goL1tcXHNcXG5dKlxcfFtcXHNcXG5dKi9nKSApIHx8IFwiIHxcIjtcclxuXHRcdHRlbXBsYXRlLmVxdWFsc1N0eWxlID0gbW9zdEZyZXF1ZW50KCB0ZXh0LnJlcGxhY2UoLyg9W158XSopPSsvZywgXCIkMVwiKS5tYXRjaCgvW1xcc1xcbl0qPVtcXHNcXG5dKi9nKSApIHx8IFwiPVwiO1xyXG5cdFx0Ly8gRmlndXJlIG91dCBlbmQtYnJhY2VzIHN0eWxlXHJcblx0XHR2YXIgZW5kU3BhY2luZyA9IHRleHQubWF0Y2goL1tcXHNcXG5dKiQvKTtcclxuXHRcdHRlbXBsYXRlLmVuZEJyYWNlc1N0eWxlID0gKGVuZFNwYWNpbmcgPyBlbmRTcGFjaW5nWzBdIDogXCJcIikgKyBcIn19XCI7XHJcblxyXG5cdFx0dmFyIGNodW5rcyA9IHRleHQuc3BsaXQoXCJ8XCIpLm1hcChmdW5jdGlvbihjaHVuaykge1xyXG5cdFx0XHQvLyBjaGFuZ2UgJ1xceDAxJyBjb250cm9sIGNoYXJhY3RlcnMgYmFjayB0byBwaXBlc1xyXG5cdFx0XHRyZXR1cm4gY2h1bmsucmVwbGFjZSgvXFx4MDEvZyxcInxcIik7IFxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGVtcGxhdGUuc2V0TmFtZShjaHVua3NbMF0pO1xyXG5cdFx0XHJcblx0XHR2YXIgcGFyYW1ldGVyQ2h1bmtzID0gY2h1bmtzLnNsaWNlKDEpO1xyXG5cclxuXHRcdHZhciB1bm5hbWVkSWR4ID0gMTtcclxuXHRcdHBhcmFtZXRlckNodW5rcy5mb3JFYWNoKGZ1bmN0aW9uKGNodW5rKSB7XHJcblx0XHRcdHZhciBpbmRleE9mRXF1YWxUbyA9IGNodW5rLmluZGV4T2YoXCI9XCIpO1xyXG5cdFx0XHR2YXIgaW5kZXhPZk9wZW5CcmFjZXMgPSBjaHVuay5pbmRleE9mKFwie3tcIik7XHJcblx0XHRcdFxyXG5cdFx0XHR2YXIgaXNXaXRob3V0RXF1YWxzID0gIWNodW5rLmluY2x1ZGVzKFwiPVwiKTtcclxuXHRcdFx0dmFyIGhhc0JyYWNlc0JlZm9yZUVxdWFscyA9IGNodW5rLmluY2x1ZGVzKFwie3tcIikgJiYgaW5kZXhPZk9wZW5CcmFjZXMgPCBpbmRleE9mRXF1YWxUbztcdFxyXG5cdFx0XHR2YXIgaXNVbm5hbWVkUGFyYW0gPSAoIGlzV2l0aG91dEVxdWFscyB8fCBoYXNCcmFjZXNCZWZvcmVFcXVhbHMgKTtcclxuXHRcdFx0XHJcblx0XHRcdHZhciBwTmFtZSwgcE51bSwgcFZhbDtcclxuXHRcdFx0aWYgKCBpc1VubmFtZWRQYXJhbSApIHtcclxuXHRcdFx0XHQvLyBHZXQgdGhlIG5leHQgbnVtYmVyIG5vdCBhbHJlYWR5IHVzZWQgYnkgZWl0aGVyIGFuIHVubmFtZWQgcGFyYW1ldGVyLCBvciBieSBhXHJcblx0XHRcdFx0Ly8gbmFtZWQgcGFyYW1ldGVyIGxpa2UgYHwxPXZhbGBcclxuXHRcdFx0XHR3aGlsZSAoIHRlbXBsYXRlLmdldFBhcmFtKHVubmFtZWRJZHgpICkge1xyXG5cdFx0XHRcdFx0dW5uYW1lZElkeCsrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRwTnVtID0gdW5uYW1lZElkeDtcclxuXHRcdFx0XHRwVmFsID0gY2h1bmsudHJpbSgpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHBOYW1lID0gY2h1bmsuc2xpY2UoMCwgaW5kZXhPZkVxdWFsVG8pLnRyaW0oKTtcclxuXHRcdFx0XHRwVmFsID0gY2h1bmsuc2xpY2UoaW5kZXhPZkVxdWFsVG8gKyAxKS50cmltKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0dGVtcGxhdGUuYWRkUGFyYW0ocE5hbWUgfHwgcE51bSwgcFZhbCwgY2h1bmspO1xyXG5cdFx0fSk7XHJcblx0XHRcclxuXHRcdHJlc3VsdC5wdXNoKHRlbXBsYXRlKTtcclxuXHR9O1xyXG5cclxuXHRcclxuXHR2YXIgbiA9IHdpa2l0ZXh0Lmxlbmd0aDtcclxuXHRcclxuXHQvLyBudW1iZXIgb2YgdW5jbG9zZWQgYnJhY2VzXHJcblx0dmFyIG51bVVuY2xvc2VkID0gMDtcclxuXHJcblx0Ly8gYXJlIHdlIGluc2lkZSBhIGNvbW1lbnQsIG9yIGJldHdlZW4gbm93aWtpIHRhZ3MsIG9yIGluIGEge3t7cGFyYW1ldGVyfX19P1xyXG5cdHZhciBpbkNvbW1lbnQgPSBmYWxzZTtcclxuXHR2YXIgaW5Ob3dpa2kgPSBmYWxzZTtcclxuXHR2YXIgaW5QYXJhbWV0ZXIgPSBmYWxzZTtcclxuXHJcblx0dmFyIHN0YXJ0SWR4LCBlbmRJZHg7XHJcblx0XHJcblx0Zm9yICh2YXIgaT0wOyBpPG47IGkrKykge1xyXG5cdFx0XHJcblx0XHRpZiAoICFpbkNvbW1lbnQgJiYgIWluTm93aWtpICYmICFpblBhcmFtZXRlciApIHtcclxuXHJcblx0XHRcdGlmICh3aWtpdGV4dFtpXSA9PT0gXCJ7XCIgJiYgd2lraXRleHRbaSsxXSA9PT0gXCJ7XCIgJiYgd2lraXRleHRbaSsyXSA9PT0gXCJ7XCIgJiYgd2lraXRleHRbaSszXSAhPT0gXCJ7XCIpIHtcclxuXHRcdFx0XHRpblBhcmFtZXRlciA9IHRydWU7XHJcblx0XHRcdFx0aSArPSAyO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHdpa2l0ZXh0W2ldID09PSBcIntcIiAmJiB3aWtpdGV4dFtpKzFdID09PSBcIntcIikge1xyXG5cdFx0XHRcdGlmIChudW1VbmNsb3NlZCA9PT0gMCkge1xyXG5cdFx0XHRcdFx0c3RhcnRJZHggPSBpKzI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdG51bVVuY2xvc2VkICs9IDI7XHJcblx0XHRcdFx0aSsrO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHdpa2l0ZXh0W2ldID09PSBcIn1cIiAmJiB3aWtpdGV4dFtpKzFdID09PSBcIn1cIikge1xyXG5cdFx0XHRcdGlmIChudW1VbmNsb3NlZCA9PT0gMikge1xyXG5cdFx0XHRcdFx0ZW5kSWR4ID0gaTtcclxuXHRcdFx0XHRcdHByb2Nlc3NUZW1wbGF0ZVRleHQoc3RhcnRJZHgsIGVuZElkeCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdG51bVVuY2xvc2VkIC09IDI7XHJcblx0XHRcdFx0aSsrO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHdpa2l0ZXh0W2ldID09PSBcInxcIiAmJiBudW1VbmNsb3NlZCA+IDIpIHtcclxuXHRcdFx0XHQvLyBzd2FwIG91dCBwaXBlcyBpbiBuZXN0ZWQgdGVtcGxhdGVzIHdpdGggXFx4MDEgY2hhcmFjdGVyXHJcblx0XHRcdFx0d2lraXRleHQgPSBzdHJSZXBsYWNlQXQod2lraXRleHQsIGksXCJcXHgwMVwiKTtcclxuXHRcdFx0fSBlbHNlIGlmICggL148IS0tLy50ZXN0KHdpa2l0ZXh0LnNsaWNlKGksIGkgKyA0KSkgKSB7XHJcblx0XHRcdFx0aW5Db21tZW50ID0gdHJ1ZTtcclxuXHRcdFx0XHRpICs9IDM7XHJcblx0XHRcdH0gZWxzZSBpZiAoIC9ePG5vd2lraSA/Pi8udGVzdCh3aWtpdGV4dC5zbGljZShpLCBpICsgOSkpICkge1xyXG5cdFx0XHRcdGluTm93aWtpID0gdHJ1ZTtcclxuXHRcdFx0XHRpICs9IDc7XHJcblx0XHRcdH0gXHJcblxyXG5cdFx0fSBlbHNlIHsgLy8gd2UgYXJlIGluIGEgY29tbWVudCBvciBub3dpa2kgb3Ige3t7cGFyYW1ldGVyfX19XHJcblx0XHRcdGlmICh3aWtpdGV4dFtpXSA9PT0gXCJ8XCIpIHtcclxuXHRcdFx0XHQvLyBzd2FwIG91dCBwaXBlcyB3aXRoIFxceDAxIGNoYXJhY3RlclxyXG5cdFx0XHRcdHdpa2l0ZXh0ID0gc3RyUmVwbGFjZUF0KHdpa2l0ZXh0LCBpLFwiXFx4MDFcIik7XHJcblx0XHRcdH0gZWxzZSBpZiAoL14tLT4vLnRlc3Qod2lraXRleHQuc2xpY2UoaSwgaSArIDMpKSkge1xyXG5cdFx0XHRcdGluQ29tbWVudCA9IGZhbHNlO1xyXG5cdFx0XHRcdGkgKz0gMjtcclxuXHRcdFx0fSBlbHNlIGlmICgvXjxcXC9ub3dpa2kgPz4vLnRlc3Qod2lraXRleHQuc2xpY2UoaSwgaSArIDEwKSkpIHtcclxuXHRcdFx0XHRpbk5vd2lraSA9IGZhbHNlO1xyXG5cdFx0XHRcdGkgKz0gODtcclxuXHRcdFx0fSBlbHNlIGlmICh3aWtpdGV4dFtpXSA9PT0gXCJ9XCIgJiYgd2lraXRleHRbaSsxXSA9PT0gXCJ9XCIgJiYgd2lraXRleHRbaSsyXSA9PT0gXCJ9XCIpIHtcclxuXHRcdFx0XHRpblBhcmFtZXRlciA9IGZhbHNlO1xyXG5cdFx0XHRcdGkgKz0gMjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHR9XHJcblx0XHJcblx0aWYgKCByZWN1cnNpdmUgKSB7XHJcblx0XHR2YXIgc3VidGVtcGxhdGVzID0gZmlsdGVyQW5kTWFwKHJlc3VsdCxcclxuXHRcdFx0dGVtcGxhdGUgPT4gL1xce1xceyg/Oi58XFxuKSpcXH1cXH0vLnRlc3QodGVtcGxhdGUud2lraXRleHQuc2xpY2UoMiwtMikpLFxyXG5cdFx0XHR0ZW1wbGF0ZSA9PiBwYXJzZVRlbXBsYXRlcyh0ZW1wbGF0ZS53aWtpdGV4dC5zbGljZSgyLC0yKSwgdHJ1ZSlcclxuXHRcdCk7XHJcblx0XHRyZXR1cm4gcmVzdWx0LmNvbmNhdC5hcHBseShyZXN1bHQsIHN1YnRlbXBsYXRlcyk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gcmVzdWx0OyBcclxufTsgLyogZXNsaW50LWVuYWJsZSBuby1jb250cm9sLXJlZ2V4ICovXHJcblxyXG4vKipcclxuICogQHBhcmFtIHtUZW1wbGF0ZXxUZW1wbGF0ZVtdfSB0ZW1wbGF0ZXNcclxuICogQHJldHVybiB7UHJvbWlzZTxUZW1wbGF0ZT58UHJvbWlzZTxUZW1wbGF0ZVtdPn1cclxuICovXHJcbnZhciBnZXRXaXRoUmVkaXJlY3RUbyA9IGZ1bmN0aW9uKHRlbXBsYXRlcykge1xyXG5cdHZhciB0ZW1wbGF0ZXNBcnJheSA9IEFycmF5LmlzQXJyYXkodGVtcGxhdGVzKSA/IHRlbXBsYXRlcyA6IFt0ZW1wbGF0ZXNdO1xyXG5cdGlmICh0ZW1wbGF0ZXNBcnJheS5sZW5ndGggPT09IDApIHtcclxuXHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZShbXSk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gQVBJLmdldCh7XHJcblx0XHRcImFjdGlvblwiOiBcInF1ZXJ5XCIsXHJcblx0XHRcImZvcm1hdFwiOiBcImpzb25cIixcclxuXHRcdFwidGl0bGVzXCI6IGZpbHRlckFuZE1hcCh0ZW1wbGF0ZXNBcnJheSxcclxuXHRcdFx0dGVtcGxhdGUgPT4gdGVtcGxhdGUuZ2V0VGl0bGUoKSAhPT0gbnVsbCxcclxuXHRcdFx0dGVtcGxhdGUgPT4gdGVtcGxhdGUuZ2V0VGl0bGUoKS5nZXRQcmVmaXhlZFRleHQoKVxyXG5cdFx0KSxcclxuXHRcdFwicmVkaXJlY3RzXCI6IDFcclxuXHR9KS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xyXG5cdFx0aWYgKCAhcmVzdWx0IHx8ICFyZXN1bHQucXVlcnkgKSB7XHJcblx0XHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KFwiRW1wdHkgcmVzcG9uc2VcIik7XHJcblx0XHR9XHJcblx0XHRpZiAoIHJlc3VsdC5xdWVyeS5yZWRpcmVjdHMgKSB7XHJcblx0XHRcdHJlc3VsdC5xdWVyeS5yZWRpcmVjdHMuZm9yRWFjaChmdW5jdGlvbihyZWRpcmVjdCkge1xyXG5cdFx0XHRcdHZhciBpID0gdGVtcGxhdGVzQXJyYXkuZmluZEluZGV4KHRlbXBsYXRlID0+IHtcclxuXHRcdFx0XHRcdGxldCB0aXRsZSA9IHRlbXBsYXRlLmdldFRpdGxlKCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGl0bGUgJiYgdGl0bGUuZ2V0UHJlZml4ZWRUZXh0KCkgPT09IHJlZGlyZWN0LmZyb207XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdFx0aWYgKGkgIT09IC0xKSB7XHJcblx0XHRcdFx0XHR0ZW1wbGF0ZXNBcnJheVtpXS5yZWRpcmVjdFRhcmdldCA9IG13LlRpdGxlLm5ld0Zyb21UZXh0KHJlZGlyZWN0LnRvKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIEFycmF5LmlzQXJyYXkodGVtcGxhdGVzKSA/IHRlbXBsYXRlc0FycmF5IDogdGVtcGxhdGVzQXJyYXlbMF07XHJcblx0fSk7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuZ2V0RGF0YUZvclBhcmFtID0gZnVuY3Rpb24oa2V5LCBwYXJhTmFtZSkge1xyXG5cdGlmICggIXRoaXMucGFyYW1EYXRhICkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdC8vIElmIGFsaWFzLCBzd2l0Y2ggZnJvbSBhbGlhcyB0byBwcmVmZXJyZWQgcGFyYW1ldGVyIG5hbWVcclxuXHR2YXIgcGFyYSA9IHRoaXMucGFyYW1BbGlhc2VzW3BhcmFOYW1lXSB8fCBwYXJhTmFtZTtcdFxyXG5cdGlmICggIXRoaXMucGFyYW1EYXRhW3BhcmFdICkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHRcclxuXHR2YXIgZGF0YSA9IHRoaXMucGFyYW1EYXRhW3BhcmFdW2tleV07XHJcblx0Ly8gRGF0YSBtaWdodCBhY3R1YWxseSBiZSBhbiBvYmplY3Qgd2l0aCBrZXkgXCJlblwiXHJcblx0aWYgKCBkYXRhICYmIGRhdGEuZW4gJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkgKSB7XHJcblx0XHRyZXR1cm4gZGF0YS5lbjtcclxuXHR9XHJcblx0cmV0dXJuIGRhdGE7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuaXNTaGVsbFRlbXBsYXRlID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIG1haW5UZXh0ID0gdGhpcy5yZWRpcmVjdFRhcmdldFxyXG5cdFx0PyB0aGlzLnJlZGlyZWN0VGFyZ2V0LmdldE1haW5UZXh0KClcclxuXHRcdDogdGhpcy5nZXRUaXRsZSgpLmdldE1haW5UZXh0KCk7XHJcblx0cmV0dXJuIGNvbmZpZy5zaGVsbFRlbXBsYXRlcy5pbmNsdWRlcyhtYWluVGV4dCk7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuc2V0UGFyYW1EYXRhQW5kU3VnZ2VzdGlvbnMgPSBmdW5jdGlvbigpIHtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblx0dmFyIHBhcmFtRGF0YVNldCA9ICQuRGVmZXJyZWQoKTtcclxuXHRcclxuXHRpZiAoIHNlbGYucGFyYW1EYXRhICkgeyByZXR1cm4gcGFyYW1EYXRhU2V0LnJlc29sdmUoKTsgfVxyXG4gICAgXHJcblx0dmFyIHByZWZpeGVkVGV4dCA9IHNlbGYucmVkaXJlY3RUYXJnZXRcclxuXHRcdD8gc2VsZi5yZWRpcmVjdFRhcmdldC5nZXRQcmVmaXhlZFRleHQoKVxyXG5cdFx0OiBzZWxmLmdldFRpdGxlKCkuZ2V0UHJlZml4ZWRUZXh0KCk7XHJcblxyXG5cdHZhciBjYWNoZWRJbmZvID0gY2FjaGUucmVhZChwcmVmaXhlZFRleHQgKyBcIi1wYXJhbXNcIik7XHJcblx0XHJcblx0aWYgKFxyXG5cdFx0Y2FjaGVkSW5mbyAmJlxyXG5cdFx0Y2FjaGVkSW5mby52YWx1ZSAmJlxyXG5cdFx0Y2FjaGVkSW5mby5zdGFsZURhdGUgJiZcclxuXHRcdGNhY2hlZEluZm8udmFsdWUucGFyYW1EYXRhICE9IG51bGwgJiZcclxuXHRcdGNhY2hlZEluZm8udmFsdWUucGFyYW1ldGVyU3VnZ2VzdGlvbnMgIT0gbnVsbCAmJlxyXG5cdFx0Y2FjaGVkSW5mby52YWx1ZS5wYXJhbUFsaWFzZXMgIT0gbnVsbFxyXG5cdCkge1xyXG5cdFx0c2VsZi5ub3RlbXBsYXRlZGF0YSA9IGNhY2hlZEluZm8udmFsdWUubm90ZW1wbGF0ZWRhdGE7XHJcblx0XHRzZWxmLnBhcmFtRGF0YSA9IGNhY2hlZEluZm8udmFsdWUucGFyYW1EYXRhO1xyXG5cdFx0c2VsZi5wYXJhbWV0ZXJTdWdnZXN0aW9ucyA9IGNhY2hlZEluZm8udmFsdWUucGFyYW1ldGVyU3VnZ2VzdGlvbnM7XHJcblx0XHRzZWxmLnBhcmFtQWxpYXNlcyA9IGNhY2hlZEluZm8udmFsdWUucGFyYW1BbGlhc2VzO1xyXG5cdFx0XHJcblx0XHRwYXJhbURhdGFTZXQucmVzb2x2ZSgpO1xyXG5cdFx0aWYgKCAhaXNBZnRlckRhdGUoY2FjaGVkSW5mby5zdGFsZURhdGUpICkge1xyXG5cdFx0XHQvLyBKdXN0IHVzZSB0aGUgY2FjaGVkIGRhdGFcclxuXHRcdFx0cmV0dXJuIHBhcmFtRGF0YVNldDtcclxuXHRcdH0gLy8gZWxzZTogVXNlIHRoZSBjYWNoZSBkYXRhIGZvciBub3csIGJ1dCBhbHNvIGZldGNoIG5ldyBkYXRhIGZyb20gQVBJXHJcblx0fVxyXG5cdFxyXG5cdEFQSS5nZXQoe1xyXG5cdFx0YWN0aW9uOiBcInRlbXBsYXRlZGF0YVwiLFxyXG5cdFx0dGl0bGVzOiBwcmVmaXhlZFRleHQsXHJcblx0XHRyZWRpcmVjdHM6IDEsXHJcblx0XHRpbmNsdWRlTWlzc2luZ1RpdGxlczogMVxyXG5cdH0pXHJcblx0XHQudGhlbihcclxuXHRcdFx0ZnVuY3Rpb24ocmVzcG9uc2UpIHsgcmV0dXJuIHJlc3BvbnNlOyB9LFxyXG5cdFx0XHRmdW5jdGlvbigvKmVycm9yKi8pIHsgcmV0dXJuIG51bGw7IH0gLy8gSWdub3JlIGVycm9ycywgd2lsbCB1c2UgZGVmYXVsdCBkYXRhXHJcblx0XHQpXHJcblx0XHQudGhlbiggZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHQvLyBGaWd1cmUgb3V0IHBhZ2UgaWQgKGJlYWN1c2UgYWN0aW9uPXRlbXBsYXRlZGF0YSBkb2Vzbid0IGhhdmUgYW4gaW5kZXhwYWdlaWRzIG9wdGlvbilcclxuXHRcdFx0dmFyIGlkID0gcmVzdWx0ICYmICQubWFwKHJlc3VsdC5wYWdlcywgZnVuY3Rpb24oIF92YWx1ZSwga2V5ICkgeyByZXR1cm4ga2V5OyB9KTtcclxuXHRcdFxyXG5cdFx0XHRpZiAoICFyZXN1bHQgfHwgIXJlc3VsdC5wYWdlc1tpZF0gfHwgcmVzdWx0LnBhZ2VzW2lkXS5ub3RlbXBsYXRlZGF0YSB8fCAhcmVzdWx0LnBhZ2VzW2lkXS5wYXJhbXMgKSB7XHJcblx0XHRcdC8vIE5vIFRlbXBsYXRlRGF0YSwgc28gdXNlIGRlZmF1bHRzIChndWVzc2VzKVxyXG5cdFx0XHRcdHNlbGYubm90ZW1wbGF0ZWRhdGEgPSB0cnVlO1xyXG5cdFx0XHRcdHNlbGYudGVtcGxhdGVkYXRhQXBpRXJyb3IgPSAhcmVzdWx0O1xyXG5cdFx0XHRcdHNlbGYucGFyYW1EYXRhID0gY29uZmlnLmRlZmF1bHRQYXJhbWV0ZXJEYXRhO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHNlbGYucGFyYW1EYXRhID0gcmVzdWx0LnBhZ2VzW2lkXS5wYXJhbXM7XHJcblx0XHRcdH1cclxuICAgICAgICBcclxuXHRcdFx0c2VsZi5wYXJhbUFsaWFzZXMgPSB7fTtcclxuXHRcdFx0JC5lYWNoKHNlbGYucGFyYW1EYXRhLCBmdW5jdGlvbihwYXJhTmFtZSwgcGFyYURhdGEpIHtcclxuXHRcdFx0XHQvLyBFeHRyYWN0IGFsaWFzZXMgZm9yIGVhc2llciByZWZlcmVuY2UgbGF0ZXIgb25cclxuXHRcdFx0XHRpZiAoIHBhcmFEYXRhLmFsaWFzZXMgJiYgcGFyYURhdGEuYWxpYXNlcy5sZW5ndGggKSB7XHJcblx0XHRcdFx0XHRwYXJhRGF0YS5hbGlhc2VzLmZvckVhY2goZnVuY3Rpb24oYWxpYXMpe1xyXG5cdFx0XHRcdFx0XHRzZWxmLnBhcmFtQWxpYXNlc1thbGlhc10gPSBwYXJhTmFtZTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQvLyBFeHRyYWN0IGFsbG93ZWQgdmFsdWVzIGFycmF5IGZyb20gZGVzY3JpcHRpb25cclxuXHRcdFx0XHRpZiAoIHBhcmFEYXRhLmRlc2NyaXB0aW9uICYmIC9cXFsuKicuKz8nLio/XFxdLy50ZXN0KHBhcmFEYXRhLmRlc2NyaXB0aW9uLmVuKSApIHtcclxuXHRcdFx0XHRcdHRyeSB7XHJcblx0XHRcdFx0XHRcdHZhciBhbGxvd2VkVmFscyA9IEpTT04ucGFyc2UoXHJcblx0XHRcdFx0XHRcdFx0cGFyYURhdGEuZGVzY3JpcHRpb24uZW5cclxuXHRcdFx0XHRcdFx0XHRcdC5yZXBsYWNlKC9eLipcXFsvLFwiW1wiKVxyXG5cdFx0XHRcdFx0XHRcdFx0LnJlcGxhY2UoL1wiL2csIFwiXFxcXFxcXCJcIilcclxuXHRcdFx0XHRcdFx0XHRcdC5yZXBsYWNlKC8nL2csIFwiXFxcIlwiKVxyXG5cdFx0XHRcdFx0XHRcdFx0LnJlcGxhY2UoLyxcXHMqXS8sIFwiXVwiKVxyXG5cdFx0XHRcdFx0XHRcdFx0LnJlcGxhY2UoL10uKiQvLCBcIl1cIilcclxuXHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdFx0c2VsZi5wYXJhbURhdGFbcGFyYU5hbWVdLmFsbG93ZWRWYWx1ZXMgPSBhbGxvd2VkVmFscztcclxuXHRcdFx0XHRcdH0gY2F0Y2goZSkge1xyXG5cdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oXCJbUmF0ZXJdIENvdWxkIG5vdCBwYXJzZSBhbGxvd2VkIHZhbHVlcyBpbiBkZXNjcmlwdGlvbjpcXG4gIFwiK1xyXG5cdFx0XHRcdFx0cGFyYURhdGEuZGVzY3JpcHRpb24uZW4gKyBcIlxcbiBDaGVjayBUZW1wbGF0ZURhdGEgZm9yIHBhcmFtZXRlciB8XCIgKyBwYXJhTmFtZSArXHJcblx0XHRcdFx0XHRcIj0gaW4gXCIgKyBzZWxmLmdldFRpdGxlKCkuZ2V0UHJlZml4ZWRUZXh0KCkpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHRcclxuXHRcdFx0Ly8gTWFrZSBzdWdnZXN0aW9ucyBmb3IgY29tYm9ib3hcclxuXHRcdFx0dmFyIGFsbFBhcmFtc0FycmF5ID0gKCAhc2VsZi5ub3RlbXBsYXRlZGF0YSAmJiByZXN1bHQucGFnZXNbaWRdLnBhcmFtT3JkZXIgKSB8fFxyXG5cdFx0XHQkLm1hcChzZWxmLnBhcmFtRGF0YSwgZnVuY3Rpb24oX3ZhbCwga2V5KXtcclxuXHRcdFx0XHRyZXR1cm4ga2V5O1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0c2VsZi5wYXJhbWV0ZXJTdWdnZXN0aW9ucyA9IGFsbFBhcmFtc0FycmF5LmZpbHRlcihmdW5jdGlvbihwYXJhbU5hbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gKCBwYXJhbU5hbWUgJiYgcGFyYW1OYW1lICE9PSBcImNsYXNzXCIgJiYgcGFyYW1OYW1lICE9PSBcImltcG9ydGFuY2VcIiApO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHRcdC5tYXAoZnVuY3Rpb24ocGFyYW1OYW1lKSB7XHJcblx0XHRcdFx0XHR2YXIgb3B0aW9uT2JqZWN0ID0ge2RhdGE6IHBhcmFtTmFtZX07XHJcblx0XHRcdFx0XHR2YXIgbGFiZWwgPSBzZWxmLmdldERhdGFGb3JQYXJhbShsYWJlbCwgcGFyYW1OYW1lKTtcclxuXHRcdFx0XHRcdGlmICggbGFiZWwgKSB7XHJcblx0XHRcdFx0XHRcdG9wdGlvbk9iamVjdC5sYWJlbCA9IGxhYmVsICsgXCIgKHxcIiArIHBhcmFtTmFtZSArIFwiPSlcIjtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiBvcHRpb25PYmplY3Q7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcclxuXHRcdFx0aWYgKCBzZWxmLnRlbXBsYXRlZGF0YUFwaUVycm9yICkge1xyXG5cdFx0XHRcdC8vIERvbid0IHNhdmUgZGVmYXVsdHMvZ3Vlc3NlcyB0byBjYWNoZTtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHJcblx0XHRcdGNhY2hlLndyaXRlKHByZWZpeGVkVGV4dCArIFwiLXBhcmFtc1wiLCB7XHJcblx0XHRcdFx0bm90ZW1wbGF0ZWRhdGE6IHNlbGYubm90ZW1wbGF0ZWRhdGEsXHJcblx0XHRcdFx0cGFyYW1EYXRhOiBzZWxmLnBhcmFtRGF0YSxcclxuXHRcdFx0XHRwYXJhbWV0ZXJTdWdnZXN0aW9uczogc2VsZi5wYXJhbWV0ZXJTdWdnZXN0aW9ucyxcclxuXHRcdFx0XHRwYXJhbUFsaWFzZXM6IHNlbGYucGFyYW1BbGlhc2VzXHJcblx0XHRcdH0sXHQxXHJcblx0XHRcdCk7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSlcclxuXHRcdC50aGVuKFxyXG5cdFx0XHRwYXJhbURhdGFTZXQucmVzb2x2ZSxcclxuXHRcdFx0cGFyYW1EYXRhU2V0LnJlamVjdFxyXG5cdFx0KTtcclxuXHRcclxuXHRyZXR1cm4gcGFyYW1EYXRhU2V0O1x0XHJcbn07XHJcblxyXG52YXIgbWFrZUxpc3RBcyA9IGZ1bmN0aW9uKHN1YmplY3RUaXRsZSkge1xyXG5cdHZhciBuYW1lID0gc3ViamVjdFRpdGxlLmdldE1haW5UZXh0KCkucmVwbGFjZSgvXFxzXFwoLipcXCkvLCBcIlwiKTtcclxuXHRpZiAoIG5hbWUuaW5kZXhPZihcIiBcIikgPT09IC0xICkge1xyXG5cdFx0cmV0dXJuIG5hbWU7XHJcblx0fVxyXG5cdHZhciBnZW5lcmF0aW9uYWxTdWZmaXggPSBcIlwiO1xyXG5cdGlmICggLyAoPzpbSlNdci4/fFtJVlhdKykkLy50ZXN0KG5hbWUpICkge1xyXG5cdFx0Z2VuZXJhdGlvbmFsU3VmZml4ID0gbmFtZS5zbGljZShuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSk7XHJcblx0XHRuYW1lID0gbmFtZS5zbGljZSgwLCBuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSk7XHJcblx0XHRpZiAoIG5hbWUuaW5kZXhPZihcIiBcIikgPT09IC0xICkge1xyXG5cdFx0XHRyZXR1cm4gbmFtZSArIGdlbmVyYXRpb25hbFN1ZmZpeDtcclxuXHRcdH1cclxuXHR9XHJcblx0dmFyIGxhc3ROYW1lID0gbmFtZS5zbGljZShuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSsxKS5yZXBsYWNlKC8sJC8sIFwiXCIpO1xyXG5cdHZhciBvdGhlck5hbWVzID0gbmFtZS5zbGljZSgwLCBuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSk7XHJcblx0cmV0dXJuIGxhc3ROYW1lICsgXCIsIFwiICsgb3RoZXJOYW1lcyArIGdlbmVyYXRpb25hbFN1ZmZpeDtcclxufTtcclxuXHJcblRlbXBsYXRlLnByb3RvdHlwZS5hZGRNaXNzaW5nUGFyYW1zID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIHRoaXNUZW1wbGF0ZSA9IHRoaXM7XHJcblxyXG5cdC8vIEF1dG9maWxsIGxpc3RhcyBwYXJhbWV0ZXIgZm9yIFdQOkJJT1xyXG5cdHZhciBpc0Jpb2dyYXBoeUJhbm5lciA9IHRoaXMuZ2V0VGl0bGUoKS5nZXRNYWluVGV4dCgpID09PSBcIldpa2lQcm9qZWN0IEJpb2dyYXBoeVwiIHx8XHJcblx0XHQodGhpcy5yZWRpcmVjdFRhcmdldCAmJiB0aGlzLnJlZGlyZWN0VGFyZ2V0LmdldE1haW5UZXh0KCkgPT09IFwiV2lraVByb2plY3QgQmlvZ3JhcGh5XCIpO1xyXG5cclxuXHRpZiAoaXNCaW9ncmFwaHlCYW5uZXIgJiYgIXRoaXMuZ2V0UGFyYW0oXCJsaXN0YXNcIikpIHtcclxuXHRcdHZhciBzdWJqZWN0VGl0bGUgPSBtdy5UaXRsZS5uZXdGcm9tVGV4dChjb25maWcubXcud2dQYWdlTmFtZSkuZ2V0U3ViamVjdFBhZ2UoKTtcclxuXHRcdHRoaXMucGFyYW1ldGVycy5wdXNoKHtcclxuXHRcdFx0bmFtZTogXCJsaXN0YXNcIixcclxuXHRcdFx0dmFsdWU6IG1ha2VMaXN0QXMoc3ViamVjdFRpdGxlKSxcclxuXHRcdFx0YXV0b2ZpbGxlZDogdHJ1ZSxcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Ly8gTWFrZSBzdXJlIHJlcXVpcmVkL3N1Z2dlc3RlZCBwYXJhbWV0ZXJzIGFyZSBwcmVzZW50XHJcblx0JC5lYWNoKHRoaXNUZW1wbGF0ZS5wYXJhbURhdGEsIGZ1bmN0aW9uKHBhcmFOYW1lLCBwYXJhRGF0YSkge1xyXG5cdFx0aWYgKCAocGFyYURhdGEucmVxdWlyZWQgfHwgcGFyYURhdGEuc3VnZ2VzdGVkKSAmJiAhdGhpc1RlbXBsYXRlLmdldFBhcmFtKHBhcmFOYW1lKSApIHtcclxuXHRcdFx0Ly8gQ2hlY2sgaWYgYWxyZWFkeSBwcmVzZW50IGluIGFuIGFsaWFzLCBpZiBhbnlcclxuXHRcdFx0aWYgKCBwYXJhRGF0YS5hbGlhc2VzLmxlbmd0aCApIHtcclxuXHRcdFx0XHR2YXIgYWxpYXNlcyA9IHRoaXNUZW1wbGF0ZS5wYXJhbWV0ZXJzLmZpbHRlcihwID0+IHtcclxuXHRcdFx0XHRcdHZhciBpc0FsaWFzID0gcGFyYURhdGEuYWxpYXNlcy5pbmNsdWRlcyhwLm5hbWUpO1xyXG5cdFx0XHRcdFx0dmFyIGlzRW1wdHkgPSAhcC52YWx1ZTtcclxuXHRcdFx0XHRcdHJldHVybiBpc0FsaWFzICYmICFpc0VtcHR5O1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGlmICggYWxpYXNlcy5sZW5ndGggKSB7XHJcblx0XHRcdFx0Ly8gQXQgbGVhc3Qgb25lIG5vbi1lbXB0eSBhbGlhcywgc28gZG8gbm90aGluZ1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHQvLyBObyBub24tZW1wdHkgYWxpYXNlcywgc28gYWRkIHRoaXMgdG8gdGhlIHBhcmFtZXRlcnMgbGlzdCAod2l0aFxyXG5cdFx0XHQvLyB2YWx1ZSBzZXQgcGFyYW1ldGVyIHRvIGVpdGhlciB0aGUgYXV0b3ZhdWxlLCBvciBhcyBudWxsKS5cclxuXHRcdFx0Ly8gQWxzbyBzZXQgdGhhdCBpdCB3YXMgYXV0b2ZpbGxlZC5cclxuXHRcdFx0dGhpc1RlbXBsYXRlLnBhcmFtZXRlcnMucHVzaCh7XHJcblx0XHRcdFx0bmFtZTpwYXJhTmFtZSxcclxuXHRcdFx0XHR2YWx1ZTogcGFyYURhdGEuYXV0b3ZhbHVlIHx8IG51bGwsXHJcblx0XHRcdFx0YXV0b2ZpbGxlZDogdHJ1ZSxcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0fSk7XHJcblxyXG5cdHJldHVybiB0aGlzVGVtcGxhdGU7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuc2V0Q2xhc3Nlc0FuZEltcG9ydGFuY2VzID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIHBhcnNlZCA9ICQuRGVmZXJyZWQoKTtcclxuXHJcblx0Ly8gRG9uJ3QgcmUtcGFyc2UgaWYgYWxyZWFkeSBwYXJzZWQ7IG5vIG5lZWQgdG8gcGFyc2Ugc2hlbGwgdGVtcGxhdGVzIG9yIGJhbm5lcnMgd2l0aG91dCByYXRpbmdzXHJcblx0aWYgKCB0aGlzLmlzU2hlbGxUZW1wbGF0ZSgpICkge1xyXG5cdFx0dGhpcy5jbGFzc2VzID0gWy4uLmNvbmZpZy5iYW5uZXJEZWZhdWx0cy5jbGFzc2VzXTtcclxuXHRcdHJldHVybiBwYXJzZWQucmVzb2x2ZSgpO1xyXG5cdH0gZWxzZSBpZiAoICh0aGlzLmNsYXNzZXMgJiYgdGhpcy5pbXBvcnRhbmNlcykgfHwgdGhpcy53aXRob3V0UmF0aW5ncyApIHtcclxuXHRcdHJldHVybiBwYXJzZWQucmVzb2x2ZSgpO1xyXG5cdH0gXHJcblxyXG5cdHZhciBtYWluVGV4dCA9IHRoaXMuZ2V0VGl0bGUoKS5nZXRNYWluVGV4dCgpO1xyXG5cclxuXHQvLyBTb21lIHByb2plY3RzIGhhdmUgaGFyZGNvZGVkIHZhbHVlcywgdG8gYXZvaWQgc3RhbmRhcmQgY2xhc3NlcyBvciB0byBwcmV2ZW50IEFQSSBpc3N1ZXMgKHRpbWVvdXQgYW5kL29yIG5vZGUgY291bnQgZXhjZWVkZWQpXHJcblx0Y29uc3QgcmVkaXJlY3RUYXJnZXRPck1haW5UZXh0ID0gdGhpcy5yZWRpcmVjdFRhcmdldCA/IHRoaXMucmVkaXJlY3RUYXJnZXQuZ2V0TWFpblRleHQoKSA6IG1haW5UZXh0O1xyXG5cdGlmICggY29uZmlnLmN1c3RvbUJhbm5lcnNbcmVkaXJlY3RUYXJnZXRPck1haW5UZXh0XSApIHtcclxuXHRcdHRoaXMuY2xhc3NlcyA9IGNvbmZpZy5jdXN0b21CYW5uZXJzW3JlZGlyZWN0VGFyZ2V0T3JNYWluVGV4dF0uY2xhc3NlcztcclxuXHRcdHRoaXMuaW1wb3J0YW5jZXMgPSBjb25maWcuY3VzdG9tQmFubmVyc1tyZWRpcmVjdFRhcmdldE9yTWFpblRleHRdLmltcG9ydGFuY2VzO1xyXG5cdFx0cmV0dXJuIHBhcnNlZC5yZXNvbHZlKCk7XHJcblx0fVxyXG5cclxuXHQvLyBPdGhlcndpc2UgdHJ5IHJlYWRpbmcgZnJvbSBjYWNoZWQgZGF0YVxyXG5cdHZhciBjYWNoZWRSYXRpbmdzID0gY2FjaGUucmVhZChtYWluVGV4dCtcIi1yYXRpbmdzXCIpO1xyXG5cdGlmIChcclxuXHRcdGNhY2hlZFJhdGluZ3MgJiZcclxuXHRcdGNhY2hlZFJhdGluZ3MudmFsdWUgJiZcclxuXHRcdGNhY2hlZFJhdGluZ3Muc3RhbGVEYXRlICYmXHJcblx0XHRjYWNoZWRSYXRpbmdzLnZhbHVlLmNsYXNzZXMhPW51bGwgJiZcclxuXHRcdGNhY2hlZFJhdGluZ3MudmFsdWUuaW1wb3J0YW5jZXMhPW51bGxcclxuXHQpIHtcclxuXHRcdHRoaXMuY2xhc3NlcyA9IGNhY2hlZFJhdGluZ3MudmFsdWUuY2xhc3NlcztcclxuXHRcdHRoaXMuaW1wb3J0YW5jZXMgPSBjYWNoZWRSYXRpbmdzLnZhbHVlLmltcG9ydGFuY2VzO1xyXG5cdFx0cGFyc2VkLnJlc29sdmUoKTtcclxuXHRcdGlmICggIWlzQWZ0ZXJEYXRlKGNhY2hlZFJhdGluZ3Muc3RhbGVEYXRlKSApIHtcclxuXHRcdFx0Ly8gSnVzdCB1c2UgdGhlIGNhY2hlZCBkYXRhXHJcblx0XHRcdHJldHVybiBwYXJzZWQ7XHJcblx0XHR9IC8vIGVsc2U6IFVzZSB0aGUgY2FjaGUgZGF0YSBmb3Igbm93LCBidXQgYWxzbyBmZXRjaCBuZXcgZGF0YSBmcm9tIEFQSVxyXG5cdH1cclxuXHJcblx0dmFyIHdpa2l0ZXh0VG9QYXJzZSA9IFwiXCI7XHRcclxuXHRjb25maWcuYmFubmVyRGVmYXVsdHMuZXh0ZW5kZWRDbGFzc2VzLmZvckVhY2goZnVuY3Rpb24oY2xhc3NuYW1lLCBpbmRleCkge1xyXG5cdFx0d2lraXRleHRUb1BhcnNlICs9IFwie3tcIiArIG1haW5UZXh0ICsgXCJ8Y2xhc3M9XCIgKyBjbGFzc25hbWUgKyBcInxpbXBvcnRhbmNlPVwiICtcclxuXHRcdChjb25maWcuYmFubmVyRGVmYXVsdHMuZXh0ZW5kZWRJbXBvcnRhbmNlc1tpbmRleF0gfHwgXCJcIikgKyBcIn19L25cIjtcclxuXHR9KTtcclxuXHRcclxuXHRyZXR1cm4gQVBJLmdldCh7XHJcblx0XHRhY3Rpb246IFwicGFyc2VcIixcclxuXHRcdHRpdGxlOiBcIlRhbGs6V2lraXBlZGlhXCIsXHJcblx0XHR0ZXh0OiB3aWtpdGV4dFRvUGFyc2UsXHJcblx0XHRwcm9wOiBcImNhdGVnb3JpZXNodG1sXCJcclxuXHR9KVxyXG5cdFx0LnRoZW4oKHJlc3VsdCkgPT4ge1xyXG5cdFx0XHR2YXIgY2F0c0h0bWwgPSByZXN1bHQucGFyc2UuY2F0ZWdvcmllc2h0bWxbXCIqXCJdO1xyXG5cdFx0XHR2YXIgZXh0ZW5kZWRDbGFzc2VzID0gY29uZmlnLmJhbm5lckRlZmF1bHRzLmV4dGVuZGVkQ2xhc3Nlcy5maWx0ZXIoZnVuY3Rpb24oY2wpIHtcclxuXHRcdFx0XHRyZXR1cm4gY2F0c0h0bWwuaW5kZXhPZihjbCtcIi1DbGFzc1wiKSAhPT0gLTE7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHR0aGlzLmNsYXNzZXMgPSBbLi4uY29uZmlnLmJhbm5lckRlZmF1bHRzLmNsYXNzZXMsIC4uLmV4dGVuZGVkQ2xhc3Nlc107XHJcblx0XHRcdHRoaXMuaW1wb3J0YW5jZXMgPSBjb25maWcuYmFubmVyRGVmYXVsdHMuZXh0ZW5kZWRJbXBvcnRhbmNlcy5maWx0ZXIoZnVuY3Rpb24oaW1wKSB7XHJcblx0XHRcdFx0cmV0dXJuIGNhdHNIdG1sLmluZGV4T2YoaW1wK1wiLWltcG9ydGFuY2VcIikgIT09IC0xO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0Y2FjaGUud3JpdGUobWFpblRleHQrXCItcmF0aW5nc1wiLFxyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGNsYXNzZXM6IHRoaXMuY2xhc3NlcyxcclxuXHRcdFx0XHRcdGltcG9ydGFuY2VzOiB0aGlzLmltcG9ydGFuY2VzXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHQxXHJcblx0XHRcdCk7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSk7XHJcbn07XHJcblxyXG5leHBvcnQge1RlbXBsYXRlLCBwYXJzZVRlbXBsYXRlcywgZ2V0V2l0aFJlZGlyZWN0VG99O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgY29uZmlnIGZyb20gXCIuLi8uLi9jb25maWdcIjtcclxuaW1wb3J0IEJhbm5lcldpZGdldCBmcm9tIFwiLi9CYW5uZXJXaWRnZXRcIjtcclxuaW1wb3J0IHsgbm9ybWFsaXNlWWVzTm8sIGZpbHRlckFuZE1hcCwgdW5pcXVlQXJyYXkgfSBmcm9tIFwiLi4vLi4vdXRpbFwiO1xyXG5pbXBvcnQgUGFyYW1ldGVyV2lkZ2V0IGZyb20gXCIuL1BhcmFtZXRlcldpZGdldFwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxudmFyIEJhbm5lckxpc3RXaWRnZXQgPSBmdW5jdGlvbiBCYW5uZXJMaXN0V2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Y29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG5cclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdEJhbm5lckxpc3RXaWRnZXQucGFyZW50LmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG5cdE9PLnVpLm1peGluLkdyb3VwRWxlbWVudC5jYWxsKCB0aGlzLCB7XHJcblx0XHQkZ3JvdXA6IHRoaXMuJGVsZW1lbnRcclxuXHR9ICk7XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLWJhbm5lckxpc3RXaWRnZXRcIikuY3NzKHtcInBhZGRpbmdcIjpcIjIwcHggMTBweCAxNnB4IDEwcHhcIn0pO1xyXG5cclxuXHQvLyBQcmVmc1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSBjb25maWcucHJlZmVyZW5jZXM7XHJcblx0XHJcblx0dGhpcy5vcmVzQ2xhc3MgPSBjb25maWcub3Jlc0NsYXNzO1xyXG5cdFxyXG5cdHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuXHQvLyBFdmVudHNcclxuXHR0aGlzLmFnZ3JlZ2F0ZSgge1wicmVtb3ZlXCI6IFwiYmFubmVyUmVtb3ZlXCJ9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7XCJiYW5uZXJSZW1vdmVcIjogXCJvbkJhbm5lclJlbW92ZVwifSApO1xyXG5cclxuXHR0aGlzLmFnZ3JlZ2F0ZSgge1wiY2hhbmdlZFwiOiBcImJhbm5lckNoYW5nZWRcIn0gKTtcclxuXHR0aGlzLmNvbm5lY3QoIHRoaXMsIHtcImJhbm5lckNoYW5nZWRcIjogXCJzZXRDaGFuZ2VkXCJ9ICk7XHJcblxyXG5cdHRoaXMuYWdncmVnYXRlKCB7XCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VcIjogXCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VkXCJ9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7XCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VkXCI6IFwic3luY1NoZWxsVGVtcGxhdGVXaXRoQmlvZ3JhcGh5QmFubmVyXCJ9ICk7XHJcblxyXG5cdHRoaXMuYWdncmVnYXRlKCB7XCJ1cGRhdGVkU2l6ZVwiOiBcImJhbm5lclVwZGF0ZWRTaXplXCJ9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7XCJiYW5uZXJVcGRhdGVkU2l6ZVwiOiBcIm9uVXBkYXRlZFNpemVcIn0gKTtcclxufTtcclxuXHJcbk9PLmluaGVyaXRDbGFzcyggQmFubmVyTGlzdFdpZGdldCwgT08udWkuV2lkZ2V0ICk7XHJcbk9PLm1peGluQ2xhc3MoIEJhbm5lckxpc3RXaWRnZXQsIE9PLnVpLm1peGluLkdyb3VwRWxlbWVudCApO1xyXG4vKlxyXG5tZXRob2RzIGZyb20gbWl4aW46XHJcbiAtIGFkZEl0ZW1zKCBpdGVtcywgW2luZGV4XSApIDogT08udWkuRWxlbWVudCAgKENIQUlOQUJMRSlcclxuIC0gY2xlYXJJdGVtcyggKSA6IE9PLnVpLkVsZW1lbnQgIChDSEFJTkFCTEUpXHJcbiAtIGZpbmRJdGVtRnJvbURhdGEoIGRhdGEgKSA6IE9PLnVpLkVsZW1lbnR8bnVsbFxyXG4gLSBmaW5kSXRlbXNGcm9tRGF0YSggZGF0YSApIDogT08udWkuRWxlbWVudFtdXHJcbiAtIHJlbW92ZUl0ZW1zKCBpdGVtcyApIDogT08udWkuRWxlbWVudCAgKENIQUlOQUJMRSlcclxuKi9cclxuXHJcbkJhbm5lckxpc3RXaWRnZXQucHJvdG90eXBlLm9uVXBkYXRlZFNpemUgPSBmdW5jdGlvbigpIHtcclxuXHQvLyBFbWl0IGFuIFwidXBkYXRlZFNpemVcIiBldmVudCBzbyB0aGUgcGFyZW50IHdpbmRvdyBjYW4gdXBkYXRlIHNpemUsIGlmIG5lZWRlZFxyXG5cdHRoaXMuZW1pdChcInVwZGF0ZWRTaXplXCIpO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuc2V0Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuY2hhbmdlZCA9IHRydWU7XHJcbn07XHJcblxyXG5CYW5uZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vbkJhbm5lclJlbW92ZSA9IGZ1bmN0aW9uICggYmFubmVyICkge1xyXG5cdHRoaXMucmVtb3ZlSXRlbXMoW2Jhbm5lcl0pO1xyXG5cdHRoaXMuc2V0Q2hhbmdlZCgpO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuc3luY1NoZWxsVGVtcGxhdGVXaXRoQmlvZ3JhcGh5QmFubmVyID0gZnVuY3Rpb24oIGJpb2dyYXBoeUJhbm5lciApIHtcclxuXHRiaW9ncmFwaHlCYW5uZXIgPSBiaW9ncmFwaHlCYW5uZXIgfHwgdGhpcy5pdGVtcy5maW5kKFxyXG5cdFx0YmFubmVyID0+IGJhbm5lci5tYWluVGV4dCA9PT0gXCJXaWtpUHJvamVjdCBCaW9ncmFwaHlcIiB8fCBiYW5uZXIucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9PT0gXCJXaWtpUHJvamVjdCBCaW9ncmFwaHlcIlxyXG5cdCk7XHJcblx0aWYgKCFiaW9ncmFwaHlCYW5uZXIpIHJldHVybjtcclxuXHJcblx0Y29uc3QgYmFubmVyU2hlbGxUZW1wbGF0ZSA9IHRoaXMuaXRlbXMuZmluZChcclxuXHRcdGJhbm5lciA9PiBiYW5uZXIubWFpblRleHQgPT09IGNvbmZpZy5zaGVsbFRlbXBsYXRlc1swXSB8fCBiYW5uZXIucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9PT0gY29uZmlnLnNoZWxsVGVtcGxhdGVzWzBdXHJcblx0KTtcclxuXHRpZiAoIWJhbm5lclNoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblxyXG5cdGNvbnN0IHBhcmFtc1RvU3luYyA9IFtcclxuXHRcdHsgbmFtZTogXCJsaXZpbmdcIiwgbm9ybWFsaXNlOiB0cnVlIH0sXHJcblx0XHR7IG5hbWU6IFwiYmxwb1wiLCBub3JtYWxpc2U6IHRydWUgfSxcclxuXHRcdHsgbmFtZTogXCJhY3RpdmVwb2xcIiwgbm9ybWFsaXNlOiB0cnVlIH0sXHJcblx0XHR7IG5hbWU6IFwibGlzdGFzXCIsIG5vcm1hbGlzZTogZmFsc2UgfSxcclxuXHRdO1xyXG5cdHBhcmFtc1RvU3luYy5mb3JFYWNoKHBhcmFtVG9TeW5jID0+IHtcclxuXHRcdGNvbnN0IFtiaW9ncmFwaHlQYXJhbSwgc2hlbGxQYXJhbV0gPSBbYmlvZ3JhcGh5QmFubmVyLCBiYW5uZXJTaGVsbFRlbXBsYXRlXS5tYXAoYmFubmVyID0+XHJcblx0XHRcdGJhbm5lci5wYXJhbWV0ZXJMaXN0LmdldFBhcmFtZXRlckl0ZW1zKClcclxuXHRcdFx0XHQuZmluZChwYXJhbWV0ZXIgPT5cclxuXHRcdFx0XHRcdHBhcmFtZXRlci5uYW1lID09PSBwYXJhbVRvU3luYy5uYW1lIHx8XHJcblx0XHRcdFx0XHRiYW5uZXIucGFyYW1BbGlhc2VzW3BhcmFtZXRlci5uYW1lXSA9PT0gcGFyYW1Ub1N5bmMubmFtZVxyXG5cdFx0XHRcdClcclxuXHRcdCk7XHJcblx0XHRpZiAoIWJpb2dyYXBoeVBhcmFtKSByZXR1cm47XHJcblxyXG5cdFx0Y29uc3QgcGFyYW1TeW5jVmFsdWUgPSBwYXJhbVRvU3luYy5ub3JtYWxpc2UgPyBub3JtYWxpc2VZZXNObyhiaW9ncmFwaHlQYXJhbS52YWx1ZSkgOiBiaW9ncmFwaHlQYXJhbS52YWx1ZTtcclxuXHRcdGJpb2dyYXBoeVBhcmFtLmRlbGV0ZSgpO1xyXG5cclxuXHRcdGlmICghc2hlbGxQYXJhbSAmJiBwYXJhbVN5bmNWYWx1ZSkge1xyXG5cdFx0XHRjb25zdCBpbmRleCA9IGJhbm5lclNoZWxsVGVtcGxhdGUuYWRkUGFyYW1ldGVyTGF5b3V0LmlzVmlzaWJsZSgpXHJcblx0XHRcdFx0PyAtMSAvLyBJbnNlcnQgYXQgdGhlIHZlcnkgZW5kXHJcblx0XHRcdFx0OiBiYW5uZXJTaGVsbFRlbXBsYXRlLnBhcmFtZXRlckxpc3QuaXRlbXMubGVuZ3RoLTE7IC8vIEluc2VydCBwcmlvciB0byB0aGUgXCJhZGQgcGFyYW1ldGVyXCIgYnV0dG9uXHJcblx0XHRcdGJhbm5lclNoZWxsVGVtcGxhdGUucGFyYW1ldGVyTGlzdC5hZGRJdGVtcyhbXHJcblx0XHRcdFx0bmV3IFBhcmFtZXRlcldpZGdldCgge1xyXG5cdFx0XHRcdFx0XCJuYW1lXCI6IHBhcmFtVG9TeW5jLm5hbWUsXHJcblx0XHRcdFx0XHRcInZhbHVlXCI6IHBhcmFtU3luY1ZhbHVlLFxyXG5cdFx0XHRcdFx0XCJhdXRvZmlsbGVkXCI6IHRydWVcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdGJhbm5lclNoZWxsVGVtcGxhdGUucGFyYW1EYXRhICYmIGJhbm5lclNoZWxsVGVtcGxhdGUucGFyYW1EYXRhW3BhcmFtVG9TeW5jLm5hbWVdXHJcblx0XHRcdFx0KVxyXG5cdFx0XHRdLCBpbmRleCk7XHJcblx0XHR9IGVsc2UgaWYgKCFiaW9ncmFwaHlQYXJhbS5hdXRvZmlsbGVkICYmIHBhcmFtU3luY1ZhbHVlKSB7XHJcblx0XHRcdHNoZWxsUGFyYW0uc2V0VmFsdWUoIHBhcmFtU3luY1ZhbHVlICk7XHJcblx0XHRcdHNoZWxsUGFyYW0uc2V0QXV0b2ZpbGxlZCgpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuYWRkU2hlbGxUZW1wbGF0ZUlmTmVlZWRlZCA9IGZ1bmN0aW9uICgpIHtcclxuXHRpZiAoXHJcblx0XHQhdGhpcy5pdGVtcy5zb21lKGJhbm5lciA9PiBiYW5uZXIuaXNTaGVsbFRlbXBsYXRlKVxyXG5cdCkge1xyXG5cdFx0QmFubmVyV2lkZ2V0Lm5ld0Zyb21UZW1wbGF0ZU5hbWUoXHJcblx0XHRcdGNvbmZpZy5zaGVsbFRlbXBsYXRlc1swXSxcclxuXHRcdFx0e3dpdGhvdXRSYXRpbmdzOiB0cnVlfSxcclxuXHRcdFx0e3ByZWZlcmVuY2VzOiB0aGlzLnByZWZlcmVuY2VzLCBpc0FydGljbGU6IHRoaXMucGFnZUluZm8uaXNBcnRpY2xlfVxyXG5cdFx0KS50aGVuKHNoZWxsQmFubmVyV2lkZ2V0ID0+IHtcclxuXHRcdFx0T08udWkubWl4aW4uR3JvdXBFbGVtZW50LnByb3RvdHlwZS5hZGRJdGVtcy5jYWxsKCB0aGlzLCBbc2hlbGxCYW5uZXJXaWRnZXRdLCAwICk7XHJcblx0XHRcdC8vIEF1dG9maWxsIHJhdGluZ3MgKGlmIGFibGUgdG8pXHJcblx0XHRcdHRoaXMuYXV0b2ZpbGxDbGFzc1JhdGluZ3Moe2ZvckJhbm5lclNoZWxsOiB0cnVlfSk7XHJcblx0XHRcdC8vIGVtaXQgdXBkYXRlZFNpemUgZXZlbnQgXHJcblx0XHRcdHRoaXMub25VcGRhdGVkU2l6ZSgpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblxyXG5CYW5uZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5hZGRJdGVtcyA9IGZ1bmN0aW9uICggaXRlbXMsIGluZGV4ICkge1xyXG5cclxuXHRpZiAoIGl0ZW1zLmxlbmd0aCA9PT0gMCApIHtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0Ly8gQ2FsbCBtaXhpbiBtZXRob2QgdG8gZG8gdGhlIGFkZGluZ1xyXG5cdE9PLnVpLm1peGluLkdyb3VwRWxlbWVudC5wcm90b3R5cGUuYWRkSXRlbXMuY2FsbCggdGhpcywgaXRlbXMsIGluZGV4ICk7XHJcblxyXG5cdC8vIEF1dG9maWxsIHJhdGluZ3MgKGlmIGFibGUgdG8sIGFuZCBpZiBlbmFibGVkIGluIHByZWZlcmVuY2VzKVxyXG5cdGlmICghdGhpcy5pdGVtcy5zb21lKGJhbm5lciA9PiBiYW5uZXIuaXNTaGVsbFRlbXBsYXRlKSkge1xyXG5cdFx0dGhpcy5hdXRvZmlsbENsYXNzUmF0aW5ncygpO1xyXG5cdH1cclxuXHR0aGlzLmF1dG9maWxsSW1wb3J0YW5jZVJhdGluZ3MoKTtcclxuXHJcblx0Ly8gZW1pdCB1cGRhdGVkU2l6ZSBldmVudCBcclxuXHR0aGlzLm9uVXBkYXRlZFNpemUoKTtcclxuXHJcblx0cmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5CYW5uZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5hdXRvZmlsbENsYXNzUmF0aW5ncyA9IGZ1bmN0aW9uKGNvbmZpZykge1xyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBPbmx5IGF1dG9maWxsIGlmIHNldCBpbiBwcmVmZXJlbmNlc1xyXG5cdGlmICghdGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbENsYXNzRnJvbU90aGVycyAmJiAhdGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbENsYXNzRnJvbU9yZXMgJiYgIWNvbmZpZy5mb3JCYW5uZXJTaGVsbCkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBDaGVjayB3aGF0IGJhbm5lcnMgYWxyZWFkeSBoYXZlXHJcblx0Y29uc3QgdW5pcXVlQ2xhc3NSYXRpbmdzID0gdW5pcXVlQXJyYXkoIGZpbHRlckFuZE1hcChcclxuXHRcdHRoaXMuaXRlbXMsXHJcblx0XHRiYW5uZXIgPT4ge1xyXG5cdFx0XHRpZiAoYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSB8fCAhYmFubmVyLmhhc0NsYXNzUmF0aW5ncykge1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjb25zdCBjbGFzc0l0ZW0gPSBiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdFx0XHRyZXR1cm4gY2xhc3NJdGVtICYmIGNsYXNzSXRlbS5nZXREYXRhKCk7XHJcblx0XHR9LFxyXG5cdFx0YmFubmVyID0+IGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5maW5kU2VsZWN0ZWRJdGVtKCkuZ2V0RGF0YSgpXHJcblx0KSk7XHJcblx0Ly8gQ2FuJ3QgYXV0b2ZpbGwgaWYgdGhlcmUgaXNuJ3QgZWl0aGVyIGEgc2luZ2xlIHZhbHVlLCBvciBubyB2YWx1ZVxyXG5cdGlmICh1bmlxdWVDbGFzc1JhdGluZ3MubGVuZ3RoID4gMSkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBEZXRlcm1pbmUgd2hhdCB0byBhdXRvZmlsbCB3aXRoXHJcblx0bGV0IGF1dG9DbGFzcztcclxuXHRpZiAodW5pcXVlQ2xhc3NSYXRpbmdzLmxlbmd0aCA9PT0gMSAmJiAodGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbENsYXNzRnJvbU90aGVycyB8fCBjb25maWcuZm9yQmFubmVyU2hlbGwpKSB7XHJcblx0XHRhdXRvQ2xhc3MgPSB1bmlxdWVDbGFzc1JhdGluZ3NbMF07XHJcblx0fSBlbHNlIGlmICh1bmlxdWVDbGFzc1JhdGluZ3MubGVuZ3RoID09PSAwICYmIHRoaXMucHJlZmVyZW5jZXMuYXV0b2ZpbGxDbGFzc0Zyb21PcmVzICYmIHRoaXMub3Jlc0NsYXNzKSB7XHJcblx0XHQvLyBEb24ndCBhdXRvZmlsbCBhYm92ZSBDLWNsYXNzXHJcblx0XHRzd2l0Y2godGhpcy5vcmVzQ2xhc3MpIHtcclxuXHRcdGNhc2UgXCJTdHViXCI6IGNhc2UgXCJTdGFydFwiOiBjYXNlIFwiQ1wiOiBjYXNlIFwiTGlzdFwiOlxyXG5cdFx0XHRhdXRvQ2xhc3MgPSB0aGlzLm9yZXNDbGFzcztcclxuXHRcdH1cclxuXHR9IGVsc2Uge1xyXG5cdFx0Ly8gbm90aGluZyB0byBkb1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBEbyB0aGUgYXV0b2ZpbGxpbmdcclxuXHR0aGlzLml0ZW1zLmZvckVhY2goYmFubmVyID0+IHtcclxuXHRcdGlmICghYmFubmVyLmhhc0NsYXNzUmF0aW5ncyAmJiAhYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRjb25zdCBjbGFzc0l0ZW0gPSBiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdFx0aWYgKGNsYXNzSXRlbSAmJiBjbGFzc0l0ZW0uZ2V0RGF0YSgpICYmICFjb25maWcuZm9yQmFubmVyU2hlbGwpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKGNvbmZpZy5mb3JCYW5uZXJTaGVsbCAmJiAhYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSAmJiBjbGFzc0l0ZW0uZ2V0RGF0YSgpID09PSBhdXRvQ2xhc3MpIHtcclxuXHRcdFx0YmFubmVyLmNsYXNzRHJvcGRvd24uZ2V0TWVudSgpLnNlbGVjdEl0ZW1CeURhdGEobnVsbCk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5zZWxlY3RJdGVtQnlEYXRhKGF1dG9DbGFzcyk7XHJcblx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5zZXRBdXRvZmlsbGVkKHRydWUpO1xyXG5cdH0pO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuYXV0b2ZpbGxJbXBvcnRhbmNlUmF0aW5ncyA9IGZ1bmN0aW9uKCkge1xyXG5cdGlmICghdGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbEltcG9ydGFuY2UpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Y29uc3QgaXNSZWd1bGFyQXJ0aWNsZSA9IHRoaXMucGFnZUluZm8gJiYgdGhpcy5wYWdlSW5mby5pc0FydGljbGUgJiYgIXRoaXMucGFnZUluZm8ucmVkaXJlY3QgJiYgIXRoaXMucGFnZUluZm8uaXNEaXNhbWJpZztcclxuXHRpZiAoIWlzUmVndWxhckFydGljbGUpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Ly8gVE9ETzogU2hvdWxkIHRyeSB0byBmaW5kIGEgc21hcnRlciwgYmFubmVyLXNwZWNpZmljIHdheSBvZiBkZXRlcm1pbmluZyBpbXBvcnRhbmNlLlxyXG5cdC8vIE1heWJlIGRvIHNvbWV0aGluZyB3aXRoICBPUkVTJ3MgXCJkcmFmdHRvcGljXCIgbW9kZWwuXHJcblx0Y29uc3QgYXV0b0ltcG9ydGFuY2UgPSBcIkxvd1wiO1xyXG5cdHRoaXMuaXRlbXMuZm9yRWFjaChiYW5uZXIgPT4ge1xyXG5cdFx0aWYgKCFiYW5uZXIuaGFzSW1wb3J0YW5jZVJhdGluZ3MpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgaW1wb3J0YW5jZUl0ZW0gPSBiYW5uZXIuaW1wb3J0YW5jZURyb3Bkb3duLmdldE1lbnUoKS5maW5kU2VsZWN0ZWRJdGVtKCk7XHJcblx0XHRpZiAoaW1wb3J0YW5jZUl0ZW0gJiYgaW1wb3J0YW5jZUl0ZW0uZ2V0RGF0YSgpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGJhbm5lci5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0TWVudSgpLnNlbGVjdEl0ZW1CeURhdGEoYXV0b0ltcG9ydGFuY2UpO1xyXG5cdFx0YmFubmVyLmltcG9ydGFuY2VEcm9wZG93bi5zZXRBdXRvZmlsbGVkKHRydWUpO1xyXG5cdH0pO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuc2V0UHJlZmVyZW5jZXMgPSBmdW5jdGlvbihwcmVmcykge1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSBwcmVmcztcclxuXHR0aGlzLml0ZW1zLmZvckVhY2goYmFubmVyID0+IGJhbm5lci5zZXRQcmVmZXJlbmNlcyhwcmVmcykpO1xyXG5cdHRoaXMuYXV0b2ZpbGxDbGFzc1JhdGluZ3MoKTtcclxuXHR0aGlzLmF1dG9maWxsSW1wb3J0YW5jZVJhdGluZ3MoKTtcclxufTtcclxuXHJcbkJhbm5lckxpc3RXaWRnZXQucHJvdG90eXBlLm1ha2VXaWtpdGV4dCA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBiYW5uZXJzV2lraXRleHQgPSBmaWx0ZXJBbmRNYXAoXHJcblx0XHR0aGlzLml0ZW1zLFxyXG5cdFx0YmFubmVyID0+ICFiYW5uZXIuaXNTaGVsbFRlbXBsYXRlLFxyXG5cdFx0YmFubmVyID0+IGJhbm5lci5tYWtlV2lraXRleHQoKVxyXG5cdCkuam9pbihcIlxcblwiKTtcclxuXHR2YXIgc2hlbGxUZW1wbGF0ZSA9IHRoaXMuaXRlbXMuZmluZChiYW5uZXIgPT4gYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSk7XHJcblx0aWYgKCFzaGVsbFRlbXBsYXRlKSB7XHJcblx0XHRyZXR1cm4gYmFubmVyc1dpa2l0ZXh0O1xyXG5cdH1cclxuXHR2YXIgc2hlbGxQYXJhbTEgPSBuZXcgUGFyYW1ldGVyV2lkZ2V0KHtcclxuXHRcdG5hbWU6XCIxXCIsXHJcblx0XHR2YWx1ZTogXCJcXG5cIiArIGJhbm5lcnNXaWtpdGV4dCArIFwiXFxuXCIgK1xyXG5cdFx0XHQoc2hlbGxUZW1wbGF0ZS5ub25TdGFuZGFyZFRlbXBsYXRlc1x0PyBzaGVsbFRlbXBsYXRlLm5vblN0YW5kYXJkVGVtcGxhdGVzICsgXCJcXG5cIiA6IFwiXCIpXHJcblx0fSk7XHJcblx0c2hlbGxUZW1wbGF0ZS5wYXJhbWV0ZXJMaXN0LmFkZEl0ZW1zKFsgc2hlbGxQYXJhbTEgXSk7XHJcblx0dmFyIHNoZWxsV2lraXRleHQgPSBzaGVsbFRlbXBsYXRlLm1ha2VXaWtpdGV4dCgpO1xyXG5cdHNoZWxsVGVtcGxhdGUucGFyYW1ldGVyTGlzdC5yZW1vdmVJdGVtcyhbIHNoZWxsUGFyYW0xIF0pO1xyXG5cdHJldHVybiBzaGVsbFdpa2l0ZXh0O1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQmFubmVyTGlzdFdpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IFBhcmFtZXRlckxpc3RXaWRnZXQgZnJvbSBcIi4vUGFyYW1ldGVyTGlzdFdpZGdldFwiO1xyXG5pbXBvcnQgUGFyYW1ldGVyV2lkZ2V0IGZyb20gXCIuL1BhcmFtZXRlcldpZGdldFwiO1xyXG5pbXBvcnQgRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQgZnJvbSBcIi4vRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXRcIjtcclxuaW1wb3J0IFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQgZnJvbSBcIi4vU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldFwiO1xyXG5pbXBvcnQgeyBmaWx0ZXJBbmRNYXAsIGNsYXNzTWFzaywgaW1wb3J0YW5jZU1hc2sgfSBmcm9tIFwiLi4vLi4vdXRpbFwiO1xyXG5pbXBvcnQge1RlbXBsYXRlLCBnZXRXaXRoUmVkaXJlY3RUb30gZnJvbSBcIi4uLy4uL1RlbXBsYXRlXCI7XHJcbmltcG9ydCBIb3Jpem9udGFsTGF5b3V0V2lkZ2V0IGZyb20gXCIuL0hvcml6b250YWxMYXlvdXRXaWRnZXRcIjtcclxuaW1wb3J0IGdsb2JhbENvbmZpZyBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG5mdW5jdGlvbiBCYW5uZXJXaWRnZXQoIHRlbXBsYXRlLCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdEJhbm5lcldpZGdldC5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLiRvdmVybGF5ID0gY29uZmlnLiRvdmVybGF5O1xyXG5cclxuXHQvKiAtLS0gUFJFRlMgLS0tICovXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IGNvbmZpZy5wcmVmZXJlbmNlcztcclxuXHRcclxuXHQvKiAtLS0gUFJPUFMgLS0tICovXHJcblx0dGhpcy5wYXJhbURhdGEgPSB0ZW1wbGF0ZS5wYXJhbURhdGE7XHJcblx0dGhpcy5wYXJhbUFsaWFzZXMgPSB0ZW1wbGF0ZS5wYXJhbUFsaWFzZXMgfHwge307XHJcblx0dGhpcy5wYXJhbWV0ZXJTdWdnZXN0aW9ucyA9IHRlbXBsYXRlLnBhcmFtZXRlclN1Z2dlc3Rpb25zO1xyXG5cdHRoaXMubmFtZSA9IHRlbXBsYXRlLm5hbWU7XHJcblx0dGhpcy53aWtpdGV4dCA9IHRlbXBsYXRlLndpa2l0ZXh0O1xyXG5cdHRoaXMucGlwZVN0eWxlID0gdGVtcGxhdGUucGlwZVN0eWxlO1xyXG5cdHRoaXMuZXF1YWxzU3R5bGUgPSB0ZW1wbGF0ZS5lcXVhbHNTdHlsZTtcclxuXHR0aGlzLmVuZEJyYWNlc1N0eWxlID0gdGVtcGxhdGUuZW5kQnJhY2VzU3R5bGU7XHJcblx0dGhpcy5tYWluVGV4dCA9IHRlbXBsYXRlLmdldFRpdGxlKCkuZ2V0TWFpblRleHQoKTtcclxuXHR0aGlzLnJlZGlyZWN0VGFyZ2V0TWFpblRleHQgPSB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldCAmJiB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldC5nZXRNYWluVGV4dCgpO1xyXG5cdHRoaXMuaXNTaGVsbFRlbXBsYXRlID0gdGVtcGxhdGUuaXNTaGVsbFRlbXBsYXRlKCk7XHJcblx0dGhpcy5jaGFuZ2VkID0gdGVtcGxhdGUucGFyYW1ldGVycy5zb21lKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIuYXV0b2ZpbGxlZCk7IC8vIGluaXRpYWxseSBmYWxzZSwgdW5sZXNzIHNvbWUgcGFyYW1ldGVycyB3ZXJlIGF1dG9maWxsZWRcclxuXHR0aGlzLmhhc0NsYXNzUmF0aW5ncyA9IHRlbXBsYXRlLmNsYXNzZXMgJiYgdGVtcGxhdGUuY2xhc3Nlcy5sZW5ndGg7XHJcblx0dGhpcy5oYXNJbXBvcnRhbmNlUmF0aW5ncyA9IHRlbXBsYXRlLmltcG9ydGFuY2VzICYmIHRlbXBsYXRlLmltcG9ydGFuY2VzLmxlbmd0aDtcclxuXHR0aGlzLmluYWN0aXZlUHJvamVjdCA9IHRlbXBsYXRlLmluYWN0aXZlUHJvamVjdDtcclxuXHJcblx0LyogLS0tIFRJVExFIEFORCBSQVRJTkdTIC0tLSAqL1xyXG5cclxuXHR0aGlzLnJlbW92ZUJ1dHRvbiA9IG5ldyBPTy51aS5CdXR0b25XaWRnZXQoIHtcclxuXHRcdGljb246IFwidHJhc2hcIixcclxuXHRcdGxhYmVsOiBcIlJlbW92ZSBiYW5uZXJcIixcclxuXHRcdHRpdGxlOiBcIlJlbW92ZSBiYW5uZXJcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxkaXYgc3R5bGU9XFxcIndpZHRoOjEwMCVcXFwiPlwiKVxyXG5cdH0gKTtcclxuXHR0aGlzLmNsZWFyQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCgge1xyXG5cdFx0aWNvbjogXCJjYW5jZWxcIixcclxuXHRcdGxhYmVsOiBcIkNsZWFyIHBhcmFtZXRlcnNcIixcclxuXHRcdHRpdGxlOiBcIkNsZWFyIHBhcmFtZXRlcnNcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxkaXYgc3R5bGU9XFxcIndpZHRoOjEwMCVcXFwiPlwiKVxyXG5cdH0gKTtcclxuXHR0aGlzLnJlbW92ZUJ1dHRvbi4kZWxlbWVudC5maW5kKFwiYVwiKS5jc3MoXCJ3aWR0aFwiLFwiMTAwJVwiKTtcclxuXHR0aGlzLmNsZWFyQnV0dG9uLiRlbGVtZW50LmZpbmQoXCJhXCIpLmNzcyhcIndpZHRoXCIsXCIxMDAlXCIpO1xyXG5cclxuXHR0aGlzLnRpdGxlQnV0dG9uc0dyb3VwID0gbmV3IE9PLnVpLkJ1dHRvbkdyb3VwV2lkZ2V0KCB7XHJcblx0XHRpdGVtczogWyB0aGlzLnJlbW92ZUJ1dHRvbixcdHRoaXMuY2xlYXJCdXR0b24gXSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J3dpZHRoOjEwMCU7Jz5cIiksXHJcblx0fSApO1xyXG5cclxuXHR0aGlzLm1haW5MYWJlbFBvcHVwQnV0dG9uID0gbmV3IE9PLnVpLlBvcHVwQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRsYWJlbDogYHt7JHt0ZW1wbGF0ZS5nZXRUaXRsZSgpLmdldE1haW5UZXh0KCl9fX0ke3RoaXMuaW5hY3RpdmVQcm9qZWN0ID8gXCIgKGluYWN0aXZlKVwiIDogXCJcIn1gLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NDglO21hcmdpbi1yaWdodDowO3BhZGRpbmctcmlnaHQ6OHB4Jz5cIiksXHJcblx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdGluZGljYXRvcjpcImRvd25cIixcclxuXHRcdGZyYW1lZDpmYWxzZSxcclxuXHRcdHBvcHVwOiB7XHJcblx0XHRcdCRjb250ZW50OiB0aGlzLnRpdGxlQnV0dG9uc0dyb3VwLiRlbGVtZW50LFxyXG5cdFx0XHR3aWR0aDogMjAwLFxyXG5cdFx0XHRwYWRkZWQ6IGZhbHNlLFxyXG5cdFx0XHRhbGlnbjogXCJmb3JjZS1yaWdodFwiLFxyXG5cdFx0XHRhbmNob3I6IGZhbHNlXHJcblx0XHR9XHJcblx0fSApO1xyXG5cdHRoaXMubWFpbkxhYmVsUG9wdXBCdXR0b24uJGVsZW1lbnRcclxuXHRcdC5jaGlsZHJlbihcImFcIikuZmlyc3QoKS5jc3Moe1wiZm9udC1zaXplXCI6XCIxMTAlXCJ9KVxyXG5cdFx0LmZpbmQoXCJzcGFuLm9vLXVpLWxhYmVsRWxlbWVudC1sYWJlbFwiKS5jc3Moe1wid2hpdGUtc3BhY2VcIjpcIm5vcm1hbFwifSk7XHJcblxyXG5cdC8vIFJhdGluZyBkcm9wZG93bnNcclxuXHRpZiAodGhpcy5pc1NoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93biA9IG5ldyBEcm9wZG93blBhcmFtZXRlcldpZGdldCgge1xyXG5cdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFwiPHNwYW4gc3R5bGU9XFxcImNvbG9yOiM3NzdcXFwiPkNsYXNzPC9zcGFuPlwiKSxcclxuXHRcdFx0bWVudToge1xyXG5cdFx0XHRcdGl0ZW1zOiBbXHJcblx0XHRcdFx0XHRuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0XHRkYXRhOiBudWxsLFxyXG5cdFx0XHRcdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KGA8c3BhbiBzdHlsZT1cImNvbG9yOiM3NzdcIj4oJHtjb25maWcuaXNBcnRpY2xlID8gXCJubyBjbGFzc1wiIDogXCJhdXRvLWRldGVjdFwifSk8L3NwYW4+YClcclxuXHRcdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRcdC4uLmdsb2JhbENvbmZpZy5iYW5uZXJEZWZhdWx0cy5jbGFzc2VzLm1hcCggY2xhc3NuYW1lID0+XHJcblx0XHRcdFx0XHRcdG5ldyBPTy51aS5NZW51T3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdFx0ZGF0YTogY2xhc3NuYW1lLFxyXG5cdFx0XHRcdFx0XHRcdGxhYmVsOiBjbGFzc25hbWVcclxuXHRcdFx0XHRcdFx0fSApXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XSxcclxuXHRcdFx0fSxcclxuXHRcdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXksXHJcblx0XHR9ICk7XHJcblx0XHR2YXIgc2hlbGxDbGFzc1BhcmFtID0gdGVtcGxhdGUucGFyYW1ldGVycy5maW5kKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubmFtZSA9PT0gXCJjbGFzc1wiKTtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YSggc2hlbGxDbGFzc1BhcmFtICYmIGNsYXNzTWFzayhzaGVsbENsYXNzUGFyYW0udmFsdWUpICk7XHJcblx0fSBlbHNlIGlmICh0aGlzLmhhc0NsYXNzUmF0aW5ncykge1xyXG5cdFx0dGhpcy5jbGFzc0Ryb3Bkb3duID0gbmV3IERyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBuZXcgT08udWkuSHRtbFNuaXBwZXQoXCI8c3BhbiBzdHlsZT1cXFwiY29sb3I6Izc3N1xcXCI+Q2xhc3M8L3NwYW4+XCIpLFxyXG5cdFx0XHRtZW51OiB7XHJcblx0XHRcdFx0aXRlbXM6IFtcclxuXHRcdFx0XHRcdG5ldyBPTy51aS5NZW51T3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdGRhdGE6IG51bGwsXHJcblx0XHRcdFx0XHRcdGxhYmVsOiBuZXcgT08udWkuSHRtbFNuaXBwZXQoYDxzcGFuIHN0eWxlPVwiY29sb3I6Izc3N1wiPigke2NvbmZpZy5pc0FydGljbGUgPyBcImluaGVyaXQgZnJvbSBzaGVsbFwiIDogXCJhdXRvLWRldGVjdFwifSk8L3NwYW4+YClcclxuXHRcdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRcdC4uLnRlbXBsYXRlLmNsYXNzZXMubWFwKCBjbGFzc25hbWUgPT5cclxuXHRcdFx0XHRcdFx0bmV3IE9PLnVpLk1lbnVPcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdFx0XHRkYXRhOiBjbGFzc25hbWUsXHJcblx0XHRcdFx0XHRcdFx0bGFiZWw6IGNsYXNzbmFtZVxyXG5cdFx0XHRcdFx0XHR9IClcclxuXHRcdFx0XHRcdClcclxuXHRcdFx0XHRdLFxyXG5cdFx0XHR9LFxyXG5cdFx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdH0gKTtcclxuXHRcdHZhciBjbGFzc1BhcmFtID0gdGVtcGxhdGUucGFyYW1ldGVycy5maW5kKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubmFtZSA9PT0gXCJjbGFzc1wiKTtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YSggY2xhc3NQYXJhbSAmJiBjbGFzc01hc2soY2xhc3NQYXJhbS52YWx1ZSkgKTtcclxuXHR9XHJcblxyXG5cdGlmICh0aGlzLmhhc0ltcG9ydGFuY2VSYXRpbmdzKSB7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93biA9IG5ldyBEcm9wZG93blBhcmFtZXRlcldpZGdldCgge1xyXG5cdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFwiPHNwYW4gc3R5bGU9XFxcImNvbG9yOiM3NzdcXFwiPkltcG9ydGFuY2U8L3NwYW4+XCIpLFxyXG5cdFx0XHRtZW51OiB7XHJcblx0XHRcdFx0aXRlbXM6IFtcclxuXHRcdFx0XHRcdG5ldyBPTy51aS5NZW51T3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdGRhdGE6IG51bGwsIGxhYmVsOiBuZXcgT08udWkuSHRtbFNuaXBwZXQoYDxzcGFuIHN0eWxlPVwiY29sb3I6Izc3N1wiPigke2NvbmZpZy5pc0FydGljbGUgPyBcIm5vIGltcG9ydGFuY2VcIiA6IFwiYXV0by1kZXRlY3RcIn0pPC9zcGFuPmApXHJcblx0XHRcdFx0XHR9ICksXHJcblx0XHRcdFx0XHQuLi50ZW1wbGF0ZS5pbXBvcnRhbmNlcy5tYXAoaW1wb3J0YW5jZSA9PlxyXG5cdFx0XHRcdFx0XHRuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0XHRcdGRhdGE6IGltcG9ydGFuY2UsXHJcblx0XHRcdFx0XHRcdFx0bGFiZWw6IGltcG9ydGFuY2VcclxuXHRcdFx0XHRcdFx0fSApXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XVxyXG5cdFx0XHR9LFxyXG5cdFx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdH0gKTtcclxuXHRcdHZhciBpbXBvcnRhbmNlUGFyYW0gPSB0ZW1wbGF0ZS5wYXJhbWV0ZXJzLmZpbmQocGFyYW1ldGVyID0+IHBhcmFtZXRlci5uYW1lID09PSBcImltcG9ydGFuY2VcIik7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YSggaW1wb3J0YW5jZVBhcmFtICYmIGltcG9ydGFuY2VNYXNrKGltcG9ydGFuY2VQYXJhbS52YWx1ZSkgKTtcclxuXHR9XHJcblxyXG5cdHRoaXMudGl0bGVMYXlvdXQgPSBuZXcgT08udWkuSG9yaXpvbnRhbExheW91dCgge1xyXG5cdFx0aXRlbXM6IFsgdGhpcy5tYWluTGFiZWxQb3B1cEJ1dHRvbiBdXHJcblx0fSApO1xyXG5cdGlmICh0aGlzLmhhc0NsYXNzUmF0aW5ncyB8fCB0aGlzLmlzU2hlbGxUZW1wbGF0ZSkge1xyXG5cdFx0dGhpcy50aXRsZUxheW91dC5hZGRJdGVtcyhbIHRoaXMuY2xhc3NEcm9wZG93biBdKTtcclxuXHR9XHJcblx0aWYgKHRoaXMuaGFzSW1wb3J0YW5jZVJhdGluZ3MpIHtcclxuXHRcdHRoaXMudGl0bGVMYXlvdXQuYWRkSXRlbXMoWyB0aGlzLmltcG9ydGFuY2VEcm9wZG93biBdKTtcclxuXHR9XHJcblxyXG5cdC8qIC0tLSBQQVJBTUVURVJTIExJU1QgLS0tICovXHJcblxyXG5cdHZhciBwYXJhbWV0ZXJXaWRnZXRzID0gZmlsdGVyQW5kTWFwKFxyXG5cdFx0dGVtcGxhdGUucGFyYW1ldGVycyxcclxuXHRcdHBhcmFtID0+IHtcclxuXHRcdFx0aWYgKCB0aGlzLmlzU2hlbGxUZW1wbGF0ZSApIHtcclxuXHRcdFx0XHRpZiAocGFyYW0ubmFtZSA9PSBcIjFcIikge1xyXG5cdFx0XHRcdFx0dGhpcy5zaGVsbFBhcmFtMVZhbHVlID0gcGFyYW0udmFsdWU7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiBwYXJhbS5uYW1lICE9PSBcImNsYXNzXCI7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHBhcmFtLm5hbWUgIT09IFwiY2xhc3NcIiAmJiBwYXJhbS5uYW1lICE9PSBcImltcG9ydGFuY2VcIjtcclxuXHRcdH0sXHJcblx0XHRwYXJhbSA9PiBuZXcgUGFyYW1ldGVyV2lkZ2V0KHBhcmFtLCB0ZW1wbGF0ZS5wYXJhbURhdGFbcGFyYW0ubmFtZV0sIHskb3ZlcmxheTogdGhpcy4kb3ZlcmxheX0pXHJcblx0KTtcclxuXHJcblx0dGhpcy5wYXJhbWV0ZXJMaXN0ID0gbmV3IFBhcmFtZXRlckxpc3RXaWRnZXQoIHtcclxuXHRcdGl0ZW1zOiBwYXJhbWV0ZXJXaWRnZXRzLFxyXG5cdFx0cHJlZmVyZW5jZXM6IHRoaXMucHJlZmVyZW5jZXNcclxuXHR9ICk7XHJcblxyXG5cdC8qIC0tLSBBREQgUEFSQU1FVEVSIFNFQ1RJT04gLS0tICovXHJcblxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0ID0gbmV3IFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQoe1xyXG5cdFx0c3VnZ2VzdGlvbnM6IHRlbXBsYXRlLnBhcmFtZXRlclN1Z2dlc3Rpb25zLFxyXG5cdFx0cGxhY2Vob2xkZXI6IFwicGFyYW1ldGVyIG5hbWVcIixcclxuXHRcdCRlbGVtZW50OiAkKFwiPGRpdiBzdHlsZT0nZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NDAlJz5cIiksXHJcblx0XHR2YWxpZGF0ZTogZnVuY3Rpb24odmFsKSB7XHJcblx0XHRcdGxldCB7dmFsaWROYW1lLCBuYW1lLCB2YWx1ZX0gPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKHZhbCk7XHJcblx0XHRcdHJldHVybiAoIW5hbWUgJiYgIXZhbHVlKSA/IHRydWUgOiB2YWxpZE5hbWU7XHJcblx0XHR9LmJpbmQodGhpcyksXHJcblx0XHRhbGxvd1N1Z2dlc3Rpb25zV2hlbkVtcHR5OiB0cnVlLFxyXG5cdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXlcclxuXHR9KTtcclxuXHR0aGlzLnVwZGF0ZUFkZFBhcmFtZXRlck5hbWVTdWdnZXN0aW9ucygpO1xyXG5cdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWVJbnB1dCA9IG5ldyBTdWdnZXN0aW9uTG9va3VwVGV4dElucHV0V2lkZ2V0KHtcclxuXHRcdHBsYWNlaG9sZGVyOiBcInBhcmFtZXRlciB2YWx1ZVwiLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8ZGl2IHN0eWxlPSdkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDo0MCUnPlwiKSxcclxuXHRcdHZhbGlkYXRlOiBmdW5jdGlvbih2YWwpIHtcclxuXHRcdFx0bGV0IHt2YWxpZFZhbHVlLCBuYW1lLCB2YWx1ZX0gPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKG51bGwsIHZhbCk7XHJcblx0XHRcdHJldHVybiAoIW5hbWUgJiYgIXZhbHVlKSA/IHRydWUgOiB2YWxpZFZhbHVlO1xyXG5cdFx0fS5iaW5kKHRoaXMpLFxyXG5cdFx0YWxsb3dTdWdnZXN0aW9uc1doZW5FbXB0eTogdHJ1ZSxcclxuXHRcdCRvdmVybGF5OiB0aGlzLiRvdmVybGF5XHJcblx0fSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGxhYmVsOiBcIkFkZFwiLFxyXG5cdFx0aWNvbjogXCJhZGRcIixcclxuXHRcdGZsYWdzOiBcInByb2dyZXNzaXZlXCJcclxuXHR9KS5zZXREaXNhYmxlZCh0cnVlKTtcclxuXHR0aGlzLmFkZFBhcmFtZXRlckNvbnRyb2xzID0gbmV3IEhvcml6b250YWxMYXlvdXRXaWRnZXQoIHtcclxuXHRcdGl0ZW1zOiBbXHJcblx0XHRcdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LFxyXG5cdFx0XHRuZXcgT08udWkuTGFiZWxXaWRnZXQoe2xhYmVsOlwiPVwifSksXHJcblx0XHRcdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWVJbnB1dCxcclxuXHRcdFx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b25cclxuXHRcdF1cclxuXHR9ICk7XHJcblxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTGF5b3V0ID0gbmV3IE9PLnVpLkZpZWxkTGF5b3V0KHRoaXMuYWRkUGFyYW1ldGVyQ29udHJvbHMsIHtcclxuXHRcdGxhYmVsOiBcIkFkZCBwYXJhbWV0ZXI6XCIsXHJcblx0XHRhbGlnbjogXCJ0b3BcIlxyXG5cdH0pLnRvZ2dsZShmYWxzZSk7XHJcblx0Ly8gQSBoYWNrIHRvIG1ha2UgbWVzc2FnZXMgYXBwZWFyIG9uIHRoZWlyIG93biBsaW5lXHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJMYXlvdXQuJGVsZW1lbnQuZmluZChcIi5vby11aS1maWVsZExheW91dC1tZXNzYWdlc1wiKS5jc3Moe1xyXG5cdFx0XCJjbGVhclwiOiBcImJvdGhcIixcclxuXHRcdFwicGFkZGluZy10b3BcIjogMFxyXG5cdH0pO1xyXG5cclxuXHQvKiAtLS0gT1ZFUkFMTCBMQVlPVVQvRElTUExBWSAtLS0gKi9cclxuXHJcblx0Ly8gRGlzcGxheSB0aGUgbGF5b3V0IGVsZW1lbnRzLCBhbmQgYSBydWxlXHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLWJhbm5lcldpZGdldFwiKS5hcHBlbmQoXHJcblx0XHR0aGlzLnRpdGxlTGF5b3V0LiRlbGVtZW50LFxyXG5cdFx0dGhpcy5wYXJhbWV0ZXJMaXN0LiRlbGVtZW50LFxyXG5cdFx0dGhpcy5hZGRQYXJhbWV0ZXJMYXlvdXQuJGVsZW1lbnRcclxuXHQpO1xyXG5cdGlmICghdGhpcy5pc1NoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHRoaXMuJGVsZW1lbnQuYXBwZW5kKCAkKFwiPGhyPlwiKSApO1xyXG5cdH1cclxuXHJcblx0aWYgKHRoaXMuaXNTaGVsbFRlbXBsYXRlKSB7XHJcblx0XHR0aGlzLiRlbGVtZW50LmNzcyh7XHJcblx0XHRcdFwiYmFja2dyb3VuZFwiOiBcIiNlZWVcIixcclxuXHRcdFx0XCJib3JkZXItcmFkaXVzXCI6IFwiMTBweFwiLFxyXG5cdFx0XHRcInBhZGRpbmdcIjogXCIwIDEwcHggNXB4XCIsXHJcblx0XHRcdFwibWFyZ2luLWJvdHRvbVwiOiBcIjEycHhcIixcclxuXHRcdFx0XCJmb250LXNpemVcIjogXCI5MiVcIlx0XHRcdFxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvKiAtLS0gRVZFTlQgSEFORExJTkcgLS0tICovXHJcblxyXG5cdGlmICh0aGlzLmhhc0NsYXNzUmF0aW5ncykge1xyXG5cdFx0dGhpcy5jbGFzc0Ryb3Bkb3duLmNvbm5lY3QoIHRoaXMsIHtcImNoYW5nZVwiOiBcIm9uQ2xhc3NDaGFuZ2VcIiB9ICk7XHJcblx0fVxyXG5cdGlmICh0aGlzLmhhc0ltcG9ydGFuY2VSYXRpbmdzKSB7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5jb25uZWN0KCB0aGlzLCB7XCJjaGFuZ2VcIjogXCJvbkltcG9ydGFuY2VDaGFuZ2VcIiB9ICk7XHJcblx0fVxyXG5cdHRoaXMucGFyYW1ldGVyTGlzdC5jb25uZWN0KCB0aGlzLCB7XHJcblx0XHRcImNoYW5nZVwiOiBcIm9uUGFyYW1ldGVyQ2hhbmdlXCIsXHJcblx0XHRcImFkZFBhcmFtZXRlcnNCdXR0b25DbGlja1wiOiBcInNob3dBZGRQYXJhbWV0ZXJJbnB1dHNcIixcclxuXHRcdFwidXBkYXRlZFNpemVcIjogXCJvblVwZGF0ZWRTaXplXCJcclxuXHR9ICk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b24uY29ubmVjdCh0aGlzLCB7IFwiY2xpY2tcIjogXCJvblBhcmFtZXRlckFkZFwiIH0pO1xyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LmNvbm5lY3QodGhpcywge1xyXG5cdFx0XCJjaGFuZ2VcIjogXCJvbkFkZFBhcmFtZXRlck5hbWVDaGFuZ2VcIixcclxuXHRcdFwiZW50ZXJcIjogXCJvbkFkZFBhcmFtZXRlck5hbWVFbnRlclwiLFxyXG5cdFx0XCJjaG9vc2VcIjogXCJvbkFkZFBhcmFtZXRlck5hbWVFbnRlclwiXHJcblx0fSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZUlucHV0LmNvbm5lY3QodGhpcywge1xyXG5cdFx0XCJjaGFuZ2VcIjogXCJvbkFkZFBhcmFtZXRlclZhbHVlQ2hhbmdlXCIsXHJcblx0XHRcImVudGVyXCI6IFwib25BZGRQYXJhbWV0ZXJWYWx1ZUVudGVyXCIsXHJcblx0XHRcImNob29zZVwiOiBcIm9uQWRkUGFyYW1ldGVyVmFsdWVFbnRlclwiXHJcblx0fSk7XHJcblx0dGhpcy5yZW1vdmVCdXR0b24uY29ubmVjdCh0aGlzLCB7XCJjbGlja1wiOiBcIm9uUmVtb3ZlQnV0dG9uQ2xpY2tcIn0sICk7XHJcblx0dGhpcy5jbGVhckJ1dHRvbi5jb25uZWN0KCB0aGlzLCB7XCJjbGlja1wiOiBcIm9uQ2xlYXJCdXR0b25DbGlja1wifSApO1xyXG5cclxuXHQvKiAtLS0gQVBQTFkgUFJFRiAtLSAqL1xyXG5cdGlmICh0aGlzLnByZWZlcmVuY2VzLmJ5cGFzc1JlZGlyZWN0cykge1xyXG5cdFx0dGhpcy5ieXBhc3NSZWRpcmVjdCgpO1xyXG5cdH1cclxuXHJcbn1cclxuT08uaW5oZXJpdENsYXNzKCBCYW5uZXJXaWRnZXQsIE9PLnVpLldpZGdldCApO1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZW1wbGF0ZU5hbWVcclxuICogQHBhcmFtIHtPYmplY3R9IFtkYXRhXVxyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRhdGEud2l0aG91dFJhdGluZ3NcclxuICogQHBhcmFtIHtCb29sZWFufSBkYXRhLmlzV3JhcHBlclxyXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPEJhbm5lcldpZGdldD59XHJcbiAqL1xyXG5CYW5uZXJXaWRnZXQubmV3RnJvbVRlbXBsYXRlTmFtZSA9IGZ1bmN0aW9uKHRlbXBsYXRlTmFtZSwgZGF0YSwgY29uZmlnKSB7XHJcblx0dmFyIHRlbXBsYXRlID0gbmV3IFRlbXBsYXRlKCk7XHJcblx0dGVtcGxhdGUubmFtZSA9IHRlbXBsYXRlTmFtZTtcclxuXHRpZiAoZGF0YSAmJiBkYXRhLndpdGhvdXRSYXRpbmdzKSB7XHJcblx0XHR0ZW1wbGF0ZS53aXRob3V0UmF0aW5ncyA9IHRydWU7XHJcblx0fVxyXG5cdHJldHVybiBnZXRXaXRoUmVkaXJlY3RUbyh0ZW1wbGF0ZSlcclxuXHRcdC50aGVuKGZ1bmN0aW9uKHRlbXBsYXRlKSB7XHJcblx0XHRcdHJldHVybiAkLndoZW4oXHJcblx0XHRcdFx0dGVtcGxhdGUuc2V0Q2xhc3Nlc0FuZEltcG9ydGFuY2VzKCksXHJcblx0XHRcdFx0dGVtcGxhdGUuc2V0UGFyYW1EYXRhQW5kU3VnZ2VzdGlvbnMoKVxyXG5cdFx0XHQpLnRoZW4oKCkgPT4ge1xyXG5cdFx0XHRcdC8vIEFkZCBtaXNzaW5nIHJlcXVpcmVkL3N1Z2dlc3RlZCB2YWx1ZXNcclxuXHRcdFx0XHR0ZW1wbGF0ZS5hZGRNaXNzaW5nUGFyYW1zKCk7XHJcblx0XHRcdFx0Ly8gUmV0dXJuIHRoZSBub3ctbW9kaWZpZWQgdGVtcGxhdGVcclxuXHRcdFx0XHRyZXR1cm4gdGVtcGxhdGU7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSlcclxuXHRcdC50aGVuKHRlbXBsYXRlID0+IG5ldyBCYW5uZXJXaWRnZXQodGVtcGxhdGUsIGNvbmZpZykpO1xyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vblVwZGF0ZWRTaXplID0gZnVuY3Rpb24oKSB7XHJcblx0Ly8gRW1pdCBhbiBcInVwZGF0ZWRTaXplXCIgZXZlbnQgc28gdGhlIHBhcmVudCB3aW5kb3cgY2FuIHVwZGF0ZSBzaXplLCBpZiBuZWVkZWRcclxuXHR0aGlzLmVtaXQoXCJ1cGRhdGVkU2l6ZVwiKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuc2V0Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuY2hhbmdlZCA9IHRydWU7XHJcblx0dGhpcy5lbWl0KFwiY2hhbmdlZFwiKTtcclxuXHRpZiAodGhpcy5tYWluVGV4dCA9PT0gXCJXaWtpUHJvamVjdCBCaW9ncmFwaHlcIiB8fCB0aGlzLnJlZGlyZWN0VGFyZ2V0TWFpblRleHQgPT09IFwiV2lraVByb2plY3QgQmlvZ3JhcGh5XCIpIHtcclxuXHRcdC8vIEVtaXQgZXZlbnQgc28gQmFubmVyTGlzdFdpZGdldCBjYW4gdXBkYXRlIHRoZSBiYW5uZXIgc2hlbGwgdGVtcGxhdGUgKGlmIHByZXNlbnQpXHJcblx0XHR0aGlzLmVtaXQoXCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VcIik7XHRcdFxyXG5cdH1cclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25QYXJhbWV0ZXJDaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnNldENoYW5nZWQoKTtcclxuXHR0aGlzLnVwZGF0ZUFkZFBhcmFtZXRlck5hbWVTdWdnZXN0aW9ucygpO1xyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vbkNsYXNzQ2hhbmdlID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5zZXRDaGFuZ2VkKCk7XHJcblx0dGhpcy5jbGFzc0NoYW5nZWQgPSB0cnVlO1xyXG5cdHZhciBjbGFzc0l0ZW0gPSB0aGlzLmNsYXNzRHJvcGRvd24uZ2V0TWVudSgpLmZpbmRTZWxlY3RlZEl0ZW0oKTtcclxuXHRpZiAoY2xhc3NJdGVtICYmIGNsYXNzSXRlbS5nZXREYXRhKCkgPT0gbnVsbCApIHtcclxuXHRcdC8vIGNsZWFyIHNlbGVjdGlvblxyXG5cdFx0dGhpcy5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5zZWxlY3RJdGVtKCk7XHJcblx0fVxyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vbkltcG9ydGFuY2VDaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnNldENoYW5nZWQoKTtcclxuXHR0aGlzLmltcG9ydGFuY2VDaGFuZ2VkID0gdHJ1ZTtcclxuXHR2YXIgaW1wb3J0YW5jZUl0ZW0gPSB0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdGlmIChpbXBvcnRhbmNlSXRlbSAmJiBpbXBvcnRhbmNlSXRlbS5nZXREYXRhKCkgPT0gbnVsbCApIHtcclxuXHRcdC8vIGNsZWFyIHNlbGVjdGlvblxyXG5cdFx0dGhpcy5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0TWVudSgpLnNlbGVjdEl0ZW0oKTtcclxuXHR9XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLnNob3dBZGRQYXJhbWV0ZXJJbnB1dHMgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmFkZFBhcmFtZXRlckxheW91dC50b2dnbGUodHJ1ZSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJOYW1lSW5wdXQuZm9jdXMoKTtcclxuXHR0aGlzLm9uVXBkYXRlZFNpemUoKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuZ2V0QWRkUGFyYW1ldGVyc0luZm8gPSBmdW5jdGlvbihuYW1lSW5wdXRWYWwsIHZhbHVlSW5wdXRWYWwpIHtcclxuXHR2YXIgbmFtZSA9IG5hbWVJbnB1dFZhbCAmJiBuYW1lSW5wdXRWYWwudHJpbSgpIHx8IHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LmdldFZhbHVlKCkudHJpbSgpO1xyXG5cdHZhciBwYXJhbUFscmVhZHlJbmNsdWRlZCA9IG5hbWUgPT09IFwiY2xhc3NcIiB8fFxyXG5cdFx0bmFtZSA9PT0gXCJpbXBvcnRhbmNlXCIgfHxcclxuXHRcdChuYW1lID09PSBcIjFcIiAmJiB0aGlzLmlzU2hlbGxUZW1wbGF0ZSkgfHxcclxuXHRcdHRoaXMucGFyYW1ldGVyTGlzdC5nZXRQYXJhbWV0ZXJJdGVtcygpLnNvbWUocGFyYW1XaWRnZXQgPT4gcGFyYW1XaWRnZXQubmFtZSA9PT0gbmFtZSk7XHJcblx0dmFyIHZhbHVlID0gdmFsdWVJbnB1dFZhbCAmJiB2YWx1ZUlucHV0VmFsLnRyaW0oKSB8fCB0aGlzLmFkZFBhcmFtZXRlclZhbHVlSW5wdXQuZ2V0VmFsdWUoKS50cmltKCk7XHJcblx0dmFyIGF1dG92YWx1ZSA9IG5hbWUgJiYgdGhpcy5wYXJhbURhdGFbbmFtZV0gJiYgdGhpcy5wYXJhbURhdGFbbmFtZV0uYXV0b3ZhbHVlIHx8IG51bGw7XHJcblx0cmV0dXJuIHtcclxuXHRcdHZhbGlkTmFtZTogISEobmFtZSAmJiAhcGFyYW1BbHJlYWR5SW5jbHVkZWQpLFxyXG5cdFx0dmFsaWRWYWx1ZTogISEodmFsdWUgfHwgYXV0b3ZhbHVlKSxcclxuXHRcdGlzQXV0b3ZhbHVlOiAhISghdmFsdWUgJiYgYXV0b3ZhbHVlKSxcclxuXHRcdGlzQWxyZWFkeUluY2x1ZGVkOiAhIShuYW1lICYmIHBhcmFtQWxyZWFkeUluY2x1ZGVkKSxcclxuXHRcdG5hbWUsXHJcblx0XHR2YWx1ZSxcclxuXHRcdGF1dG92YWx1ZVxyXG5cdH07XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm9uQWRkUGFyYW1ldGVyTmFtZUNoYW5nZSA9IGZ1bmN0aW9uKCkge1xyXG5cdGxldCB7IHZhbGlkTmFtZSwgdmFsaWRWYWx1ZSwgaXNBdXRvdmFsdWUsIGlzQWxyZWFkeUluY2x1ZGVkLCBuYW1lLCBhdXRvdmFsdWUgfSA9IHRoaXMuZ2V0QWRkUGFyYW1ldGVyc0luZm8oKTtcclxuXHQvLyBTZXQgdmFsdWUgaW5wdXQgcGxhY2Vob2xkZXIgYXMgdGhlIGF1dG92YWx1ZVxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWVJbnB1dC4kaW5wdXQuYXR0ciggXCJwbGFjZWhvbGRlclwiLCAgYXV0b3ZhbHVlIHx8IFwiXCIgKTtcclxuXHQvLyBTZXQgc3VnZ2VzdGlvbnMsIGlmIHRoZSBwYXJhbWV0ZXIgaGFzIGEgbGlzdCBvZiBhbGxvd2VkIHZhbHVlc1xyXG5cdHZhciBhbGxvd2VkVmFsdWVzID0gdGhpcy5wYXJhbURhdGFbbmFtZV0gJiZcclxuXHRcdHRoaXMucGFyYW1EYXRhW25hbWVdLmFsbG93ZWRWYWx1ZXMgJiYgXHJcblx0XHR0aGlzLnBhcmFtRGF0YVtuYW1lXS5hbGxvd2VkVmFsdWVzLm1hcCh2YWwgPT4ge3JldHVybiB7ZGF0YTogdmFsLCBsYWJlbDp2YWx9OyB9KTtcclxuXHR0aGlzLmFkZFBhcmFtZXRlclZhbHVlSW5wdXQuc2V0U3VnZ2VzdGlvbnMoYWxsb3dlZFZhbHVlcyB8fCBbXSk7XHJcblx0Ly8gU2V0IGJ1dHRvbiBkaXNhYmxlZCBzdGF0ZSBiYXNlZCBvbiB2YWxpZGl0eVxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyQnV0dG9uLnNldERpc2FibGVkKCF2YWxpZE5hbWUgfHwgIXZhbGlkVmFsdWUpO1xyXG5cdC8vIFNob3cgbm90aWNlIGlmIGF1dG92YWx1ZSB3aWxsIGJlIHVzZWRcclxuXHR0aGlzLmFkZFBhcmFtZXRlckxheW91dC5zZXROb3RpY2VzKCB2YWxpZE5hbWUgJiYgaXNBdXRvdmFsdWUgPyBbXCJQYXJhbWV0ZXIgdmFsdWUgd2lsbCBiZSBhdXRvZmlsbGVkXCJdIDogW10gKTtcclxuXHQvLyBTaG93IGVycm9yIGlzIHRoZSBiYW5uZXIgYWxyZWFkeSBoYXMgdGhlIHBhcmFtZXRlciBzZXRcclxuXHR0aGlzLmFkZFBhcmFtZXRlckxheW91dC5zZXRFcnJvcnMoIGlzQWxyZWFkeUluY2x1ZGVkID8gW1wiUGFyYW1ldGVyIGlzIGFscmVhZHkgcHJlc2VudFwiXSA6IFtdICk7XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm9uQWRkUGFyYW1ldGVyTmFtZUVudGVyID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZUlucHV0LmZvY3VzKCk7XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm9uQWRkUGFyYW1ldGVyVmFsdWVDaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHRsZXQgeyB2YWxpZE5hbWUsIHZhbGlkVmFsdWUsIGlzQXV0b3ZhbHVlIH0gPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKCk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b24uc2V0RGlzYWJsZWQoIXZhbGlkTmFtZSB8fCAhdmFsaWRWYWx1ZSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJMYXlvdXQuc2V0Tm90aWNlcyggdmFsaWROYW1lICYmIGlzQXV0b3ZhbHVlID8gW1wiUGFyYW1ldGVyIHZhbHVlIHdpbGwgYmUgYXV0b2ZpbGxlZFwiXSA6IFtdICk7IFxyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vbkFkZFBhcmFtZXRlclZhbHVlRW50ZXIgPSBmdW5jdGlvbigpIHtcclxuXHQvLyBNYWtlIHN1cmUgYnV0dG9uIHN0YXRlIGhhcyBiZWVuIHVwZGF0ZWRcclxuXHR0aGlzLm9uQWRkUGFyYW1ldGVyVmFsdWVDaGFuZ2UoKTtcclxuXHQvLyBEbyBub3RoaW5nIGlmIGJ1dHRvbiBpcyBkaXNhYmxlZCAoaS5lLiBuYW1lIGFuZC9vciB2YWx1ZSBhcmUgaW52YWxpZClcclxuXHRpZiAoIHRoaXMuYWRkUGFyYW1ldGVyQnV0dG9uLmlzRGlzYWJsZWQoKSApIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Ly8gQWRkIHBhcmFtZXRlclxyXG5cdHRoaXMub25QYXJhbWV0ZXJBZGQoKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25QYXJhbWV0ZXJBZGQgPSBmdW5jdGlvbigpIHtcclxuXHRsZXQgeyB2YWxpZE5hbWUsIHZhbGlkVmFsdWUsIG5hbWUsIHZhbHVlLCBhdXRvdmFsdWUgfSAgPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKCk7XHJcblx0aWYgKCF2YWxpZE5hbWUgfHwgIXZhbGlkVmFsdWUpIHtcclxuXHRcdC8vIEVycm9yIHNob3VsZCBhbHJlYWR5IGJlIHNob3duIHZpYSBvbkFkZFBhcmFtZXRlci4uLkNoYW5nZSBtZXRob2RzXHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdHZhciBuZXdQYXJhbWV0ZXIgPSBuZXcgUGFyYW1ldGVyV2lkZ2V0KFxyXG5cdFx0e1xyXG5cdFx0XHRcIm5hbWVcIjogbmFtZSxcclxuXHRcdFx0XCJ2YWx1ZVwiOiB2YWx1ZSB8fCBhdXRvdmFsdWVcclxuXHRcdH0sXHJcblx0XHR0aGlzLnBhcmFtRGF0YVtuYW1lXSxcclxuXHRcdHskb3ZlcmxheTogdGhpcy4kb3ZlcmxheX1cclxuXHQpO1xyXG5cdHRoaXMucGFyYW1ldGVyTGlzdC5hZGRJdGVtcyhbbmV3UGFyYW1ldGVyXSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJOYW1lSW5wdXQuc2V0VmFsdWUoXCJcIik7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZUlucHV0LnNldFZhbHVlKFwiXCIpO1xyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LiRpbnB1dC5mb2N1cygpO1xyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS51cGRhdGVBZGRQYXJhbWV0ZXJOYW1lU3VnZ2VzdGlvbnMgPSBmdW5jdGlvbigpIHtcclxuXHRsZXQgcGFyYW1zSW5Vc2UgPSB7fTtcclxuXHR0aGlzLnBhcmFtZXRlckxpc3QuZ2V0UGFyYW1ldGVySXRlbXMoKS5mb3JFYWNoKFxyXG5cdFx0cGFyYW1XaWRnZXQgPT4gcGFyYW1zSW5Vc2VbcGFyYW1XaWRnZXQubmFtZV0gPSB0cnVlXHJcblx0KTtcclxuXHR0aGlzLmFkZFBhcmFtZXRlck5hbWVJbnB1dC5zZXRTdWdnZXN0aW9ucyhcclxuXHRcdHRoaXMucGFyYW1ldGVyU3VnZ2VzdGlvbnMuZmlsdGVyKFxyXG5cdFx0XHRzdWdnZXN0aW9uID0+ICFwYXJhbXNJblVzZVtzdWdnZXN0aW9uLmRhdGFdXHJcblx0XHQpXHJcblx0KTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25SZW1vdmVCdXR0b25DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuZW1pdChcInJlbW92ZVwiKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25DbGVhckJ1dHRvbkNsaWNrID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5wYXJhbWV0ZXJMaXN0LmNsZWFySXRlbXMoXHJcblx0XHR0aGlzLnBhcmFtZXRlckxpc3QuZ2V0UGFyYW1ldGVySXRlbXMoKVxyXG5cdCk7XHJcblx0aWYgKCB0aGlzLmhhc0NsYXNzUmF0aW5ncyApIHtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbSgpO1xyXG5cdH1cclxuXHRpZiAoIHRoaXMuaGFzSW1wb3J0YW5jZVJhdGluZ3MgKSB7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbSgpO1xyXG5cdH1cclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuYnlwYXNzUmVkaXJlY3QgPSBmdW5jdGlvbigpIHtcclxuXHRpZiAoIXRoaXMucmVkaXJlY3RUYXJnZXRNYWluVGV4dCkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBTdG9yZSB0aGUgYnlwYXNzZWQgbmFtZVxyXG5cdHRoaXMuYnlwYXNzZWROYW1lID0gdGhpcy5uYW1lO1xyXG5cdC8vIFVwZGF0ZSB0aXRsZSBsYWJlbFxyXG5cdHRoaXMubWFpbkxhYmVsUG9wdXBCdXR0b24uc2V0TGFiZWwoYHt7JHt0aGlzLnJlZGlyZWN0VGFyZ2V0TWFpblRleHR9fX0ke3RoaXMuaW5hY3RpdmVQcm9qZWN0ID8gXCIgKGluYWN0aXZlKVwiIDogXCJcIn1gKTtcclxuXHQvLyBVcGRhdGUgcHJvcGVydGllc1xyXG5cdHRoaXMubmFtZSA9IHRoaXMucmVkaXJlY3RUYXJnZXRNYWluVGV4dDtcclxuXHR0aGlzLm1haW5UZXh0ID0gdGhpcy5yZWRpcmVjdFRhcmdldE1haW5UZXh0O1xyXG5cdHRoaXMucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9IG51bGw7XHJcblx0dGhpcy5zZXRDaGFuZ2VkKCk7XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm1ha2VXaWtpdGV4dCA9IGZ1bmN0aW9uKCkge1xyXG5cdGlmICghdGhpcy5jaGFuZ2VkICYmIHRoaXMud2lraXRleHQpIHtcclxuXHRcdHJldHVybiB0aGlzLndpa2l0ZXh0O1xyXG5cdH1cclxuXHR2YXIgcGlwZSA9IHRoaXMucGlwZVN0eWxlO1xyXG5cdHZhciBlcXVhbHMgPSB0aGlzLmVxdWFsc1N0eWxlO1xyXG5cdHZhciBjbGFzc0l0ZW0gPSAodGhpcy5oYXNDbGFzc1JhdGluZ3MgfHwgdGhpcy5pc1NoZWxsVGVtcGxhdGUpICYmIHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdHZhciBjbGFzc1ZhbCA9IGNsYXNzSXRlbSAmJiBjbGFzc0l0ZW0uZ2V0RGF0YSgpO1xyXG5cdHZhciBpbXBvcnRhbmNlSXRlbSA9IHRoaXMuaGFzSW1wb3J0YW5jZVJhdGluZ3MgJiYgdGhpcy5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0TWVudSgpLmZpbmRTZWxlY3RlZEl0ZW0oKTtcclxuXHR2YXIgaW1wb3J0YW5jZVZhbCA9IGltcG9ydGFuY2VJdGVtICYmIGltcG9ydGFuY2VJdGVtLmdldERhdGEoKTtcclxuXHJcblx0cmV0dXJuIChcInt7XCIgK1xyXG5cdFx0dGhpcy5uYW1lICtcclxuXHRcdCggKHRoaXMuaGFzQ2xhc3NSYXRpbmdzIHx8IHRoaXMuaXNTaGVsbFRlbXBsYXRlKSAmJiBjbGFzc1ZhbCE9bnVsbCA/IGAke3BpcGV9Y2xhc3Mke2VxdWFsc30ke2NsYXNzVmFsfHxcIlwifWAgOiBcIlwiICkgK1xyXG5cdFx0KCB0aGlzLmhhc0ltcG9ydGFuY2VSYXRpbmdzICYmIGltcG9ydGFuY2VWYWwhPW51bGwgPyBgJHtwaXBlfWltcG9ydGFuY2Uke2VxdWFsc30ke2ltcG9ydGFuY2VWYWx8fFwiXCJ9YCA6IFwiXCIgKSArXHJcblx0XHR0aGlzLnBhcmFtZXRlckxpc3QuZ2V0UGFyYW1ldGVySXRlbXMoKVxyXG5cdFx0XHQubWFwKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubWFrZVdpa2l0ZXh0KHBpcGUsIGVxdWFscykpXHJcblx0XHRcdC5qb2luKFwiXCIpICtcclxuXHRcdHRoaXMuZW5kQnJhY2VzU3R5bGUpXHJcblx0XHQucmVwbGFjZSgvXFxuK319JC8sIFwiXFxufX1cIik7IC8vIGF2b2lkIGVtcHR5IGxpbmUgYXQgZW5kIGxpa2UgW1tTcGVjaWFsOkRpZmYvOTI1OTgyMTQyXV1cclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuc2V0UHJlZmVyZW5jZXMgPSBmdW5jdGlvbihwcmVmcykge1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSBwcmVmcztcclxuXHRpZiAodGhpcy5wcmVmZXJlbmNlcy5ieXBhc3NSZWRpcmVjdHMpIHtcclxuXHRcdHRoaXMuYnlwYXNzUmVkaXJlY3QoKTtcclxuXHR9XHJcblx0dGhpcy5wYXJhbWV0ZXJMaXN0LnNldFByZWZlcmVuY2VzKHByZWZzKTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEJhbm5lcldpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiLy8gPG5vd2lraT5cclxuXHJcbmZ1bmN0aW9uIERyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9ICQuZXh0ZW5kKHtcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjI0JSc+XCIpXHJcblx0fSwgY29uZmlnIHx8IHt9ICk7XHJcblxyXG5cdC8vIENhbGwgcGFyZW50IGNvbnN0cnVjdG9yXHJcblx0RHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQuc3VwZXIuY2FsbCggdGhpcywgY29uZmlnICk7XHJcblxyXG5cdHRoaXMuJG92ZXJsYXkgPSBjb25maWcuJG92ZXJsYXk7XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLWRyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0XCIpO1xyXG4gICAgXHJcblx0Ly8gQXV0b2ZpbGxlZCBpY29uXHJcblx0dGhpcy5hdXRvZmlsbGVkID0gISFjb25maWcuYXV0b2ZpbGxlZDtcclxuXHR0aGlzLmF1dG9maWxsZWRJY29uID0gbmV3IE9PLnVpLkljb25XaWRnZXQoIHtcclxuXHRcdGljb246IFwicm9ib3RcIixcclxuXHRcdHRpdGxlOiBcIkF1dG9maWxsZWQgYnkgUmF0ZXJcIixcclxuXHRcdGZsYWdzOiBcInByb2dyZXNzaXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPSdtYXJnaW46IDAgLTVweCAwIDVweDttaW4td2lkdGg6IDE2cHg7d2lkdGg6IDE2cHg7bGVmdDp1bnNldDsnPlwiKVxyXG5cdH0gKS50b2dnbGUodGhpcy5hdXRvZmlsbGVkKTtcclxuXHR0aGlzLiRlbGVtZW50LmZpbmQoXCIub28tdWktaW5kaWNhdG9yRWxlbWVudC1pbmRpY2F0b3JcIikuYmVmb3JlKFxyXG5cdFx0dGhpcy5hdXRvZmlsbGVkSWNvbi4kZWxlbWVudFxyXG5cdCk7XHJcblxyXG5cdC8vIEV2ZW50c1xyXG5cdHRoaXMubWVudS5jb25uZWN0KHRoaXMsIHtcclxuXHRcdFwiY2hvb3NlXCI6IFwib25Ecm9wZG93bk1lbnVDaG9vc2VcIixcclxuXHRcdFwic2VsZWN0XCI6IFwib25Ecm9wZG93bk1lbnVTZWxlY3RcIlxyXG5cdH0pO1xyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQsIE9PLnVpLkRyb3Bkb3duV2lkZ2V0ICk7XHJcblxyXG5Ecm9wZG93blBhcmFtZXRlcldpZGdldC5wcm90b3R5cGUuc2V0QXV0b2ZpbGxlZCA9IGZ1bmN0aW9uKHNldEF1dG9maWxsKSB7XHJcblx0dGhpcy5hdXRvZmlsbGVkSWNvbi50b2dnbGUoISFzZXRBdXRvZmlsbCk7XHJcblx0dGhpcy4kZWxlbWVudC5maW5kKFwiLm9vLXVpLWRyb3Bkb3duV2lkZ2V0LWhhbmRsZVwiKS5jc3Moe1xyXG5cdFx0XCJib3JkZXJcIjogc2V0QXV0b2ZpbGwgPyBcIjFweCBkYXNoZWQgIzM2Y1wiIDogXCJcIlxyXG5cdH0pO1xyXG5cdHRoaXMuYXV0b2ZpbGxlZCA9ICEhc2V0QXV0b2ZpbGw7XHJcbn07XHJcblxyXG5Ecm9wZG93blBhcmFtZXRlcldpZGdldC5wcm90b3R5cGUub25Ecm9wZG93bk1lbnVDaG9vc2UgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnNldEF1dG9maWxsZWQoZmFsc2UpO1xyXG5cdHRoaXMuZW1pdChcImNoYW5nZVwiKTtcclxufTtcclxuXHJcbkRyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vbkRyb3Bkb3duTWVudVNlbGVjdCA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuZW1pdChcImNoYW5nZVwiKTtcclxufTtcclxuXHJcbkRyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdGNvbnN0IHNlbGVjdGVkSXRlbSA9IHRoaXMubWVudS5maW5kU2VsZWN0ZWRJdGVtKCk7XHJcblx0cmV0dXJuIHNlbGVjdGVkSXRlbSAmJiBzZWxlY3RlZEl0ZW0uZ2V0RGF0YSgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsIi8vIDxub3dpa2k+XHJcblxyXG4vKipcclxuICogQSBIb3Jpem9udGFsTGF5b3V0IHRoYXQgaXMgYWxzbyBhIHdpZGdldCwgYW5kIGNhbiB0aHVzIGJlIHBsYWNlZCB3aXRoaW5cclxuICogZmllbGQgbGF5b3V0cy5cclxuICogXHJcbiAqIEBjbGFzc1xyXG4gKiBAcGFyYW0geyp9IGNvbmZpZyBjb25maWd1cmF0aW9uIGZvciBPTy51aS5Ib3Jpem9udGFsTGF5b3V0XHJcbiAqL1xyXG5mdW5jdGlvbiBIb3Jpem9udGFsTGF5b3V0V2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdEhvcml6b250YWxMYXlvdXRXaWRnZXQuc3VwZXIuY2FsbCggdGhpcywge30gKTtcclxuICAgIFxyXG5cdHRoaXMubGF5b3V0ID0gbmV3IE9PLnVpLkhvcml6b250YWxMYXlvdXQoIHtcclxuXHRcdC4uLmNvbmZpZyxcclxuXHRcdCRlbGVtZW50OiB0aGlzLiRlbGVtZW50XHJcblx0fSk7XHJcblxyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggSG9yaXpvbnRhbExheW91dFdpZGdldCwgT08udWkuV2lkZ2V0ICk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBIb3Jpem9udGFsTGF5b3V0V2lkZ2V0O1xyXG4vLyA8L25vd2lraT4iLCIvLyA8bm93aWtpPlxyXG5cclxuLyoqXHJcbiAqIEBjZmcge09PLnVpLkVsZW1lbnRbXX0gaXRlbXMgSXRlbXMgdG8gYmUgYWRkZWRcclxuICogQGNmZyB7TnVtYmVyfSBkaXNwbGF5TGltaXQgVGhlIG1vc3QgdG8gc2hvdyBhdCBvbmNlLiBJZiB0aGUgbnVtYmVyIG9mIGl0ZW1zXHJcbiAqICBpcyBtb3JlIHRoYW4gdGhpcywgdGhlbiBvbmx5IHRoZSBmaXJzdCAoZGlzcGxheUxpbWl0IC0gMSkgaXRlbXMgYXJlIHNob3duLlxyXG4gKi9cclxudmFyIFBhcmFtZXRlckxpc3RXaWRnZXQgPSBmdW5jdGlvbiBQYXJhbWV0ZXJMaXN0V2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Y29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG5cclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdFBhcmFtZXRlckxpc3RXaWRnZXQucGFyZW50LmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG5cdE9PLnVpLm1peGluLkdyb3VwRWxlbWVudC5jYWxsKCB0aGlzLCB7XHJcblx0XHQkZ3JvdXA6IHRoaXMuJGVsZW1lbnRcclxuXHR9ICk7XHJcblx0dGhpcy5hZGRJdGVtcyggY29uZmlnLml0ZW1zICk7XHJcblxyXG5cdHRoaXMuJGVsZW1lbnQuYWRkQ2xhc3MoXCJyYXRlci1wYXJhbWV0ZXJMaXN0V2lkZ2V0XCIpO1xyXG4gICAgXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IGNvbmZpZy5wcmVmZXJlbmNlcztcclxuICAgXHJcblx0Ly8gSGlkZSBzb21lIHBhcmFtZXRlcnMgKGluaXRpYWxseSksIGlmIG1vcmUgdGhhbiBzZXQgZGlzcGxheSBsaW1pdCAtLSB3aGljaCBpcyB0aGUgXHJcblx0Ly8gb25lIG1vcmUgdGhhbiBjb2xsYXBzZVBhcmFtc0xvd2VyTGltaXQsIHRvIHByZXZlbnQgb25seSBvbmUgcGFyYW0gYmVpbmcgaGlkZGVuXHJcblx0Ly8gKG1vc3RseTogbWF5IG9jY2FzaW9uYWxseSBvY2N1ciBpZiBwYXJhbXMgd2VyZSBhdXRvLWZpbGxlZCkuXHJcblx0bGV0IGRpc3BsYXlMaW1pdCA9IHRoaXMucHJlZmVyZW5jZXMuY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0ICsgMTtcclxuXHRpZiAoZGlzcGxheUxpbWl0ICYmIHRoaXMuaXRlbXMubGVuZ3RoID4gZGlzcGxheUxpbWl0ICkge1xyXG5cdFx0dmFyIGhpZGVGcm9tTnVtYmVyID0gZGlzcGxheUxpbWl0IC0gMTsgLy8gT25lLWluZGV4ZWRcclxuXHRcdHZhciBoaWRlRnJvbUluZGV4ID0gaGlkZUZyb21OdW1iZXIgLSAxOyAvLyBaZXJvLWluZGV4ZWRcclxuXHRcdHZhciBoaWRkZW5Db3VudCA9IDA7XHJcblx0XHRmb3IgKGxldCBpID0gaGlkZUZyb21JbmRleDsgaSA8IHRoaXMuaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0aWYgKCF0aGlzLml0ZW1zW2ldLmF1dG9maWxsZWQpIHsgLy8gRG9uJ3QgaGlkZSBhdXRvLWZpbGxlZCBwYXJhbXNcclxuXHRcdFx0XHR0aGlzLml0ZW1zW2ldLnRvZ2dsZShmYWxzZSk7XHJcblx0XHRcdFx0aGlkZGVuQ291bnQrKztcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0aWYgKGhpZGRlbkNvdW50PjApIHtcclxuXHRcdFx0Ly8gQWRkIGJ1dHRvbiB0byBzaG93IHRoZSBoaWRkZW4gcGFyYW1zXHJcblx0XHRcdHRoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCh7XHJcblx0XHRcdFx0bGFiZWw6IFwiU2hvdyBcIiArIGhpZGRlbkNvdW50ICsgXCIgbW9yZSBcIiArIChoaWRkZW5Db3VudD09PTEgPyBcInBhcmFtZXRlclwiIDogXCJwYXJhbWV0ZXJzXCIpLFxyXG5cdFx0XHRcdGZyYW1lZDogZmFsc2UsXHJcblx0XHRcdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nbWFyZ2luLWJvdHRvbTowJz5cIilcclxuXHRcdFx0fSk7XHJcblx0XHRcdHRoaXMuYWRkSXRlbXMoW3RoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uXSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBBZGQgdGhlIGJ1dHRvbiB0aGF0IGFsbG93cyB1c2VyIHRvIGFkZCBtb3JlIHBhcmFtZXRlcnNcclxuXHR0aGlzLmFkZFBhcmFtZXRlcnNCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGxhYmVsOiBcIkFkZCBwYXJhbWV0ZXJcIixcclxuXHRcdGljb246IFwiYWRkXCIsXHJcblx0XHRmcmFtZWQ6IGZhbHNlLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nbWFyZ2luLWJvdHRvbTowJz5cIilcclxuXHR9KTtcclxuXHR0aGlzLmFkZEl0ZW1zKFt0aGlzLmFkZFBhcmFtZXRlcnNCdXR0b25dKTtcclxuXHJcblx0LyogLS0tIEV2ZW50cyAtLS0gKi9cclxuXHJcblx0Ly8gSGFuZGxlIGRlbGV0ZSBldmVudHMgZnJvbSBQYXJhbWV0ZXJXaWRnZXRzXHJcblx0dGhpcy5hZ2dyZWdhdGUoIHsgZGVsZXRlOiBcInBhcmFtZXRlckRlbGV0ZVwiXHR9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7IHBhcmFtZXRlckRlbGV0ZTogXCJvblBhcmFtZXRlckRlbGV0ZVwiIH0gKTtcclxuICAgIFxyXG5cdC8vIEhhbmRsZSBjaGFuZ2UgZXZlbnRzIGZyb20gUGFyYW1ldGVyV2lkZ2V0c1xyXG5cdHRoaXMuYWdncmVnYXRlKCB7IGNoYW5nZTogXCJwYXJhbWV0ZXJDaGFuZ2VcIlx0fSApO1xyXG5cdHRoaXMuY29ubmVjdCggdGhpcywgeyBwYXJhbWV0ZXJDaGFuZ2U6IFwib25QYXJhbWV0ZXJDaGFuZ2VcIiB9ICk7XHJcblxyXG5cdC8vIEhhbmRsZSB1cGRhdGVkU2l6ZSBldmVudHMgZnJvbSBQYXJhbWV0ZXJXaWRnZXRzXHJcblx0dGhpcy5hZ2dyZWdhdGUoIHtcInVwZGF0ZWRTaXplXCI6IFwicGFyYW1ldGVyVXBkYXRlZFNpemVcIn0gKTtcclxuXHR0aGlzLmNvbm5lY3QoIHRoaXMsIHtcInBhcmFtZXRlclVwZGF0ZWRTaXplXCI6IFwib25VcGRhdGVkU2l6ZVwifSApO1xyXG4gICAgXHJcblx0Ly8gSGFuZGxlIGJ1dHRvbiBjbGlja3NcclxuXHRpZiAodGhpcy5zaG93TW9yZVBhcmFtZXRlcnNCdXR0b24gKSB7XHJcblx0XHR0aGlzLnNob3dNb3JlUGFyYW1ldGVyc0J1dHRvbi5jb25uZWN0KCB0aGlzLCB7IFwiY2xpY2tcIjogXCJvblNob3dNb3JlUGFyYW1ldGVyc0J1dHRvbkNsaWNrXCIgfSApO1xyXG5cdH1cclxuXHR0aGlzLmFkZFBhcmFtZXRlcnNCdXR0b24uY29ubmVjdCggdGhpcywgeyBcImNsaWNrXCI6IFwib25BZGRQYXJhbWV0ZXJzQnV0dG9uQ2xpY2tcIiB9ICk7XHJcbn07XHJcblxyXG5PTy5pbmhlcml0Q2xhc3MoIFBhcmFtZXRlckxpc3RXaWRnZXQsIE9PLnVpLldpZGdldCApO1xyXG5PTy5taXhpbkNsYXNzKCBQYXJhbWV0ZXJMaXN0V2lkZ2V0LCBPTy51aS5taXhpbi5Hcm91cEVsZW1lbnQgKTtcclxuLypcclxubWV0aG9kcyBmcm9tIG1peGluOlxyXG4gLSBhZGRJdGVtcyggaXRlbXMsIFtpbmRleF0gKSA6IE9PLnVpLkVsZW1lbnQgIChDSEFJTkFCTEUpXHJcbiAtIGNsZWFySXRlbXMoICkgOiBPTy51aS5FbGVtZW50ICAoQ0hBSU5BQkxFKVxyXG4gLSBmaW5kSXRlbUZyb21EYXRhKCBkYXRhICkgOiBPTy51aS5FbGVtZW50fG51bGxcclxuIC0gZmluZEl0ZW1zRnJvbURhdGEoIGRhdGEgKSA6IE9PLnVpLkVsZW1lbnRbXVxyXG4gLSByZW1vdmVJdGVtcyggaXRlbXMgKSA6IE9PLnVpLkVsZW1lbnQgIChDSEFJTkFCTEUpXHJcbiovXHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vblVwZGF0ZWRTaXplID0gZnVuY3Rpb24oKSB7XHJcblx0Ly8gRW1pdCBhbiBcInVwZGF0ZWRTaXplXCIgZXZlbnQgc28gdGhlIHBhcmVudCB3aW5kb3cgY2FuIHVwZGF0ZSBzaXplLCBpZiBuZWVkZWRcclxuXHR0aGlzLmVtaXQoXCJ1cGRhdGVkU2l6ZVwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLmFkZEl0ZW1zID0gZnVuY3Rpb24gKCBpdGVtcywgaW5kZXggKSB7XHJcblx0aWYgKCBpdGVtcy5sZW5ndGggPT09IDAgKSB7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblxyXG5cdC8vIENhbGwgbWl4aW4gbWV0aG9kIHRvIGRvIHRoZSBhZGRpbmdcclxuXHRPTy51aS5taXhpbi5Hcm91cEVsZW1lbnQucHJvdG90eXBlLmFkZEl0ZW1zLmNhbGwoIHRoaXMsIGl0ZW1zLCBpbmRleCApO1xyXG5cclxuXHQvLyBlbWl0IHVwZGF0ZWRTaXplIGV2ZW50IFxyXG5cdHRoaXMub25VcGRhdGVkU2l6ZSgpO1xyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcdFxyXG5cclxuUGFyYW1ldGVyTGlzdFdpZGdldC5wcm90b3R5cGUub25QYXJhbWV0ZXJEZWxldGUgPSBmdW5jdGlvbihwYXJhbWV0ZXIpIHtcclxuXHR0aGlzLnJlbW92ZUl0ZW1zKFtwYXJhbWV0ZXJdKTtcclxuXHR0aGlzLmVtaXQoXCJjaGFuZ2VcIik7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vblBhcmFtZXRlckNoYW5nZSA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuZW1pdChcImNoYW5nZVwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLmdldFBhcmFtZXRlckl0ZW1zID0gZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHRoaXMuaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbS5jb25zdHJ1Y3Rvci5uYW1lID09PSBcIlBhcmFtZXRlcldpZGdldFwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLm9uU2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnJlbW92ZUl0ZW1zKFt0aGlzLnNob3dNb3JlUGFyYW1ldGVyc0J1dHRvbl0pO1xyXG5cdHRoaXMuaXRlbXMuZm9yRWFjaChwYXJhbWV0ZXJXaWRnZXQgPT4gcGFyYW1ldGVyV2lkZ2V0LnRvZ2dsZSh0cnVlKSk7XHJcblx0dGhpcy5vblVwZGF0ZWRTaXplKCk7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vbkFkZFBhcmFtZXRlcnNCdXR0b25DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMucmVtb3ZlSXRlbXMoW3RoaXMuYWRkUGFyYW1ldGVyc0J1dHRvbl0pO1xyXG5cdHRoaXMuZW1pdChcImFkZFBhcmFtZXRlcnNCdXR0b25DbGlja1wiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLm1ha2VXaWtpdGV4dCA9IGZ1bmN0aW9uKHBpcGVTdHlsZSwgZXF1YWxzU3R5bGUpIHtcclxuXHRyZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXJJdGVtcygpXHJcblx0XHQubWFwKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubWFrZVdpa2l0ZXh0KHBpcGVTdHlsZSwgZXF1YWxzU3R5bGUpKVxyXG5cdFx0LmpvaW4oXCJcIik7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5zZXRQcmVmZXJlbmNlcyA9IGZ1bmN0aW9uKHByZWZzKSB7XHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IHByZWZzO1xyXG5cdHZhciBwYXJhbXMgPSB0aGlzLmdldFBhcmFtZXRlckl0ZW1zKCk7XHJcblx0Ly8gVW5oaWRlIHNvbWUgcGFyYW1ldGVycyBvZiB0aGUgY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0IGhhcyBpbmNyZWFzZWQuXHJcblx0Ly8gKE5vdCBoaWRpbmcgYW55IGlmIGl0IGRlY3JlYXNlZCwgc2luY2UgaXQncyBhICpsb3dlciogbGltaXQgb2Ygd2hhdCBuZWVkcyB0byBiZSBzaG93bi4pXHJcblx0aWYgKCBwYXJhbXMubGVuZ3RoIDw9IHRoaXMucHJlZmVyZW5jZXMuY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0ICkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHR2YXIgaGlkZGVuUGFyYW1zID0gcGFyYW1zLmZpbHRlcihwYXJhbSA9PiAhcGFyYW0uaXNWaXNpYmxlKCkpO1xyXG5cdHZhciB2aXNpYmxlUGFyYW1zQ291bnQgPSBwYXJhbXMubGVuZ3RoIC0gaGlkZGVuUGFyYW1zLmxlbmd0aDtcclxuXHRpZiAoXHJcblx0XHRoaWRkZW5QYXJhbXMgPT09IDAgfHxcclxuICAgICAgICB2aXNpYmxlUGFyYW1zQ291bnQgPj0gdGhpcy5wcmVmZXJlbmNlcy5jb2xsYXBzZVBhcmFtc0xvd2VyTGltaXRcclxuXHQpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0dmFyIG51bVRvVW5oaWRlID0gTWF0aC5taW4oXHJcblx0XHR0aGlzLnByZWZlcmVuY2VzLmNvbGxhcHNlUGFyYW1zTG93ZXJMaW1pdCAtIHZpc2libGVQYXJhbXNDb3VudCxcclxuXHRcdGhpZGRlblBhcmFtcy5sZW5ndGhcclxuXHQpO1xyXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgbnVtVG9VbmhpZGU7IGkrKykge1xyXG5cdFx0aGlkZGVuUGFyYW1zW2ldLnRvZ2dsZSh0cnVlKTtcclxuXHR9XHJcblx0dmFyIHN0aWxsSGlkZGVuQ291bnQgPSBoaWRkZW5QYXJhbXMubGVuZ3RoIC0gbnVtVG9VbmhpZGU7XHJcblx0aWYgKHN0aWxsSGlkZGVuQ291bnQgPT09IDApIHtcclxuXHRcdHRoaXMucmVtb3ZlSXRlbXMoW3RoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uXSk7XHJcblx0fSBlbHNlIHtcclxuXHRcdHRoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uLnNldExhYmVsKFxyXG5cdFx0XHRcIlNob3cgXCIgKyBzdGlsbEhpZGRlbkNvdW50ICsgXCIgbW9yZSBcIiArIChzdGlsbEhpZGRlbkNvdW50PT09MSA/IFwicGFyYW10ZXJcIiA6IFwicGFyYW10ZXJzXCIpXHJcblx0XHQpO1xyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFBhcmFtZXRlckxpc3RXaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCB7IG5vcm1hbGlzZVllc05vLCBmaWx0ZXJBbmRNYXAgfSBmcm9tIFwiLi4vLi4vdXRpbFwiO1xyXG5pbXBvcnQgSG9yaXpvbnRhbExheW91dFdpZGdldCBmcm9tIFwiLi9Ib3Jpem9udGFsTGF5b3V0V2lkZ2V0XCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG5mdW5jdGlvbiBQYXJhbWV0ZXJXaWRnZXQoIHBhcmFtZXRlciwgcGFyYW1EYXRhLCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdFBhcmFtZXRlcldpZGdldC5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLiRvdmVybGF5ID0gY29uZmlnLiRvdmVybGF5O1xyXG4gICAgXHJcblx0dGhpcy5uYW1lID0gcGFyYW1ldGVyLm5hbWU7XHJcblx0dGhpcy52YWx1ZSA9IHBhcmFtZXRlci52YWx1ZTtcclxuXHR0aGlzLmF1dG9maWxsZWQgPSBwYXJhbWV0ZXIuYXV0b2ZpbGxlZDtcclxuXHR0aGlzLmlzSW52YWxpZCA9IHBhcmFtZXRlci52YWx1ZSA9PSBudWxsO1xyXG5cdHRoaXMucGFyYW1EYXRhID0gcGFyYW1EYXRhIHx8IHt9O1xyXG5cdHRoaXMuYWxsb3dlZFZhbHVlcyA9IHRoaXMucGFyYW1EYXRhLmFsbG93ZWRWYWx1ZXMgfHwgW107XHJcblx0dGhpcy5pc1JlcXVpcmVkID0gdGhpcy5wYXJhbURhdGEucmVxdWlyZWQ7XHJcblx0dGhpcy5pc1N1Z2dlc3RlZCA9IHRoaXMucGFyYW1EYXRhLnN1Z2dlc3RlZDtcclxuXHJcblx0Ly8gTWFrZSBhIGNoZWNrYm94IGlmIG9ubHkgMSBvciAyIGFsbG93ZWQgdmFsdWVzXHJcblx0c3dpdGNoKHRoaXMuYWxsb3dlZFZhbHVlcy5sZW5ndGgpIHtcdC8qIGVzbGludC1kaXNhYmxlIG5vLWZhbGx0aHJvdWdoICovXHJcblx0Y2FzZSAxOlxyXG5cdFx0dGhpcy5hbGxvd2VkVmFsdWVzWzFdID0gbnVsbDtcclxuXHRcdC8qIGZhbGwtdGhyb3VnaCAqL1xyXG5cdGNhc2UgMjpcclxuXHRcdHZhciBpc0ZpcnN0QWxsb3dlZFZhbCA9IChcclxuXHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLmluZGV4T2YoIHBhcmFtZXRlci52YWx1ZSApID09PSAwIHx8XHJcblx0XHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLm1hcChub3JtYWxpc2VZZXNObykuaW5kZXhPZiggbm9ybWFsaXNlWWVzTm8ocGFyYW1ldGVyLnZhbHVlKSApID09PSAwXHJcblx0XHQpO1xyXG5cdFx0dmFyIGlzU2Vjb25kQWxsb3dlZFZhbCA9IChcclxuXHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLmluZGV4T2YoIHBhcmFtZXRlci52YWx1ZSB8fCBudWxsICkgPT09IDEgfHxcclxuXHRcdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMubWFwKG5vcm1hbGlzZVllc05vKS5pbmRleE9mKCBwYXJhbWV0ZXIudmFsdWUgPyBub3JtYWxpc2VZZXNObyhwYXJhbWV0ZXIudmFsdWUpIDogbnVsbCkgPT09IDFcclxuXHRcdCk7XHJcblx0XHR2YXIgaXNJbmRldGVybWluYXRlID0gIWlzRmlyc3RBbGxvd2VkVmFsICYmICFpc1NlY29uZEFsbG93ZWRWYWw7XHJcblx0XHR0aGlzLmNoZWNrYm94ID0gbmV3IE9PLnVpLkNoZWNrYm94SW5wdXRXaWRnZXQoIHtcclxuXHRcdFx0c2VsZWN0ZWQ6IGlzSW5kZXRlcm1pbmF0ZSA/IHVuZGVmaW5lZCA6IGlzRmlyc3RBbGxvd2VkVmFsLFxyXG5cdFx0XHRpbmRldGVybWluYXRlOiBpc0luZGV0ZXJtaW5hdGUgPyB0cnVlIDogdW5kZWZpbmVkLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxsYWJlbCBzdHlsZT0nbWFyZ2luOjAgMCAwIDVweCc+XCIpXHJcblx0XHR9ICk7XHJcblx0XHRicmVhaztcclxuXHRkZWZhdWx0OlxyXG5cdFx0XHQvLyBObyBjaGVja2JveFxyXG5cdH0gLyogZXNsaW50LWVuYWJsZSBuby1mYWxsdGhyb3VnaCAqL1xyXG5cclxuXHQvKiAtLS0gRURJVCBQQVJBTUVURVIgTEFZT1VUIC0tLSAqL1xyXG5cclxuXHR0aGlzLmlucHV0ID0gbmV3IE9PLnVpLkNvbWJvQm94SW5wdXRXaWRnZXQoIHtcclxuXHRcdHZhbHVlOiB0aGlzLnZhbHVlLFxyXG5cdFx0Ly8gbGFiZWw6IHBhcmFtZXRlci5uYW1lICsgXCIgPVwiLFxyXG5cdFx0Ly8gbGFiZWxQb3NpdGlvbjogXCJiZWZvcmVcIixcclxuXHRcdG9wdGlvbnM6IGZpbHRlckFuZE1hcChcclxuXHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLFxyXG5cdFx0XHR2YWwgPT4gdmFsIT09bnVsbCxcclxuXHRcdFx0dmFsID0+ICh7ZGF0YTogdmFsLCBsYWJlbDp2YWx9KVxyXG5cdFx0KSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPGRpdiBzdHlsZT0nbWFyZ2luLWJvdHRvbTowOyc+XCIpLFxyXG5cdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXlcclxuXHR9ICk7XHJcblx0Ly8gUmVkdWNlIHRoZSBleGNlc3NpdmUgd2hpdGVzcGFjZS9oZWlnaHRcclxuXHR0aGlzLmlucHV0LiRlbGVtZW50LmZpbmQoXCJpbnB1dFwiKS5jc3Moe1xyXG5cdFx0XCJwYWRkaW5nLXRvcFwiOiAwLFxyXG5cdFx0XCJwYWRkaW5nLWJvdHRvbVwiOiBcIjJweFwiLFxyXG5cdFx0XCJoZWlnaHRcIjogXCIyNHB4XCJcclxuXHR9KTtcclxuXHQvLyBGaXggbGFiZWwgcG9zaXRpb25pbmcgd2l0aGluIHRoZSByZWR1Y2VkIGhlaWdodFxyXG5cdHRoaXMuaW5wdXQuJGVsZW1lbnQuZmluZChcInNwYW4ub28tdWktbGFiZWxFbGVtZW50LWxhYmVsXCIpLmNzcyh7XCJsaW5lLWhlaWdodFwiOiBcIm5vcm1hbFwifSk7XHJcblx0Ly8gQWxzbyByZWR1Y2UgaGVpZ2h0IG9mIGRyb3Bkb3duIGJ1dHRvbiAoaWYgb3B0aW9ucyBhcmUgcHJlc2VudClcclxuXHR0aGlzLmlucHV0LiRlbGVtZW50LmZpbmQoXCJhLm9vLXVpLWJ1dHRvbkVsZW1lbnQtYnV0dG9uXCIpLmNzcyh7XHJcblx0XHRcInBhZGRpbmctdG9wXCI6IDAsXHJcblx0XHRcImhlaWdodFwiOiBcIjI0cHhcIixcclxuXHRcdFwibWluLWhlaWdodFwiOiBcIjBcIlxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmNvbmZpcm1CdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGljb246IFwiY2hlY2tcIixcclxuXHRcdGxhYmVsOiBcIkRvbmVcIixcclxuXHRcdGZyYW1lZDogZmFsc2UsXHJcblx0XHRmbGFnczogXCJwcm9ncmVzc2l2ZVwiLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nbWFyZ2luLXJpZ2h0OjAnPlwiKVxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmNhbmNlbEJ1dHRvbiA9IG5ldyBPTy51aS5CdXR0b25XaWRnZXQoe1xyXG5cdFx0aWNvbjogXCJ1bmRvXCIsXHJcblx0XHRsYWJlbDogXCJDYW5jZWxcIixcclxuXHRcdGZyYW1lZDogZmFsc2UsXHJcblx0fSk7XHJcblxyXG5cdHRoaXMuZGVsZXRlQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCh7XHJcblx0XHRpY29uOiB0aGlzLmlzUmVxdWlyZWQgPyBcInJlc3RvcmVcIiA6IFwidHJhc2hcIixcclxuXHRcdGxhYmVsOiB0aGlzLmlzUmVxdWlyZWQgPyBcIlJlcXVpcmVkIHBhcmFtZXRlclwiIDogXCJEZWxldGVcIixcclxuXHRcdGZyYW1lZDogZmFsc2UsXHJcblx0XHRmbGFnczogXCJkZXN0cnVjdGl2ZVwiLFxyXG5cdFx0ZGlzYWJsZWQ6IHRoaXMuaXNSZXF1aXJlZFxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmVkaXRCdXR0b25Db250cm9scyA9IG5ldyBPTy51aS5CdXR0b25Hcm91cFdpZGdldCh7XHJcblx0XHRpdGVtczogW1xyXG5cdFx0XHR0aGlzLmNvbmZpcm1CdXR0b24sXHJcblx0XHRcdHRoaXMuY2FuY2VsQnV0dG9uLFxyXG5cdFx0XHR0aGlzLmRlbGV0ZUJ1dHRvblxyXG5cdFx0XSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J2ZvbnQtc2l6ZTo5MiUnPlwiKVxyXG5cdH0pO1xyXG5cdHRoaXMuZWRpdEJ1dHRvbkNvbnRyb2xzLiRlbGVtZW50LmZpbmQoXCJhIHNwYW46Zmlyc3QtY2hpbGRcIikuY3NzKHtcclxuXHRcdFwibWluLXdpZHRoXCI6IFwidW5zZXRcIixcclxuXHRcdFwid2lkdGhcIjogXCIxNnB4XCIsXHJcblx0XHRcIm1hcmdpbi1yaWdodFwiOiAwXHJcblx0fSk7XHJcblxyXG5cdHRoaXMuZWRpdExheW91dENvbnRyb2xzID0gbmV3IEhvcml6b250YWxMYXlvdXRXaWRnZXQoe1xyXG5cdFx0aXRlbXM6IFtcclxuXHRcdFx0dGhpcy5pbnB1dCxcclxuXHRcdFx0dGhpcy5lZGl0QnV0dG9uQ29udHJvbHNcclxuXHRcdF0sXHJcblx0XHQvLyRlbGVtZW50OiAkKFwiPGRpdiBzdHlsZT0nd2lkdGg6IDQ4JTttYXJnaW46MDsnPlwiKVxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmVkaXRMYXlvdXQgPSBuZXcgT08udWkuRmllbGRMYXlvdXQoIHRoaXMuZWRpdExheW91dENvbnRyb2xzLCB7XHJcblx0XHRsYWJlbDogdGhpcy5uYW1lICsgXCIgPVwiLFxyXG5cdFx0YWxpZ246IFwidG9wXCIsXHJcblx0XHRoZWxwOiB0aGlzLnBhcmFtRGF0YS5kZXNjcmlwdGlvbiAmJiB0aGlzLnBhcmFtRGF0YS5kZXNjcmlwdGlvbi5lbiB8fCBmYWxzZSxcclxuXHRcdGhlbHBJbmxpbmU6IHRydWVcclxuXHR9KS50b2dnbGUoKTtcclxuXHR0aGlzLmVkaXRMYXlvdXQuJGVsZW1lbnQuZmluZChcImxhYmVsLm9vLXVpLWlubGluZS1oZWxwXCIpLmNzcyh7XCJtYXJnaW5cIjogXCItMTBweCAwIDVweCAxMHB4XCJ9KTtcclxuXHJcblx0LyogLS0tIFJFQUQgKENPTExBUFNFRCkgRElTUExBWSBPRiBQQVJBTUVURVIgLS0tICovXHJcblxyXG5cdHRoaXMuaW52YWxpZEljb24gPSBuZXcgT08udWkuSWNvbldpZGdldCgge1xyXG5cdFx0aWNvbjogXCJibG9ja1wiLFxyXG5cdFx0dGl0bGU6IFwiSW52YWxpZCBwYXJhbWV0ZXI6IG5vIHZhbHVlIHNwZWNpZmllZCFcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPSdtYXJnaW46IDAgNXB4IDAgLTVweDsgbWluLXdpZHRoOiAxNnB4OyB3aWR0aDogMTZweDsnPlwiKVxyXG5cdH0gKS50b2dnbGUodGhpcy5pc0ludmFsaWQpO1xyXG5cdHRoaXMuZnVsbExhYmVsID0gbmV3IE9PLnVpLkxhYmVsV2lkZ2V0KHtcclxuXHRcdGxhYmVsOnRoaXMubmFtZSArXHJcblx0XHRcdCh0aGlzLnZhbHVlXHJcblx0XHRcdFx0PyBcIiA9IFwiICsgdGhpcy52YWx1ZVxyXG5cdFx0XHRcdDogXCIgXCJcclxuXHRcdFx0KSxcdFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8bGFiZWwgc3R5bGU9J21hcmdpbjogMDsnPlwiKVxyXG5cdH0pO1xyXG5cdHRoaXMuYXV0b2ZpbGxlZEljb24gPSBuZXcgT08udWkuSWNvbldpZGdldCgge1xyXG5cdFx0aWNvbjogXCJyb2JvdFwiLFxyXG5cdFx0dGl0bGU6IFwiQXV0b2ZpbGxlZCBieSBSYXRlclwiLFxyXG5cdFx0ZmxhZ3M6IFwicHJvZ3Jlc3NpdmVcIixcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J21hcmdpbjogMCAtNXB4IDAgNXB4O21pbi13aWR0aDogMTZweDt3aWR0aDogMTZweDsnPlwiKVxyXG5cdH0gKS50b2dnbGUodGhpcy5hdXRvZmlsbGVkKTtcclxuXHR0aGlzLmVkaXRCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGljb246IFwiZWRpdFwiLFxyXG5cdFx0ZnJhbWVkOiBmYWxzZSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J21hcmdpbi1ib3R0b206IDA7Jz5cIilcclxuXHR9KTtcclxuXHR0aGlzLmVkaXRCdXR0b24uJGVsZW1lbnQuZmluZChcImFcIikuY3NzKHtcclxuXHRcdFwiYm9yZGVyLXJhZGl1c1wiOiBcIjAgMTBweCAxMHB4IDBcIixcclxuXHRcdFwibWFyZ2luLWxlZnRcIjogXCI1cHhcIlxyXG5cdH0pO1xyXG5cdHRoaXMuZWRpdEJ1dHRvbi4kZWxlbWVudC5maW5kKFwiYSBzcGFuXCIpLmZpcnN0KCkuY3NzKHtcclxuXHRcdFwibWluLXdpZHRoXCI6IFwidW5zZXRcIixcclxuXHRcdFwid2lkdGhcIjogXCIxNnB4XCJcclxuXHR9KTtcclxuXHJcblx0dGhpcy5yZWFkTGF5b3V0ID0gbmV3IE9PLnVpLkhvcml6b250YWxMYXlvdXQoe1xyXG5cdFx0aXRlbXM6IFtcclxuXHRcdFx0dGhpcy5pbnZhbGlkSWNvbixcclxuXHRcdFx0dGhpcy5mdWxsTGFiZWwsXHJcblx0XHRcdHRoaXMuYXV0b2ZpbGxlZEljb24sXHJcblx0XHRcdHRoaXMuZWRpdEJ1dHRvblxyXG5cdFx0XSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J21hcmdpbjowO3dpZHRoOnVuc2V0Oyc+XCIpXHJcblx0fSk7XHJcblx0aWYgKHRoaXMuY2hlY2tib3gpIHtcclxuXHRcdHRoaXMucmVhZExheW91dC5hZGRJdGVtcyhbdGhpcy5jaGVja2JveF0sIDIpO1xyXG5cdH1cclxuXHJcblx0LyogLS0tIENPTlRBSU5FUiBGT1IgQk9USCBMQVlPVVRTIC0tLSAqL1xyXG5cdHRoaXMuJGVsZW1lbnQgPSAkKFwiPGRpdj5cIikuYWRkQ2xhc3MoXCJyYXRlci1wYXJhbWV0ZXJXaWRnZXRcIilcclxuXHRcdC5jc3Moe1xyXG5cdFx0XHRcIndpZHRoXCI6IFwidW5zZXRcIixcclxuXHRcdFx0XCJkaXNwbGF5XCI6IFwiaW5saW5lLWJsb2NrXCIsXHJcblx0XHRcdFwiYm9yZGVyXCI6IHRoaXMuYXV0b2ZpbGxlZCA/IFwiMXB4IGRhc2hlZCAjMzZjXCIgOiBcIjFweCBzb2xpZCAjZGRkXCIsXHJcblx0XHRcdFwiYm9yZGVyLXJhZGl1c1wiOiBcIjEwcHhcIixcclxuXHRcdFx0XCJwYWRkaW5nLWxlZnRcIjogXCIxMHB4XCIsXHJcblx0XHRcdFwibWFyZ2luXCI6IFwiMCA4cHggOHB4IDBcIixcclxuXHRcdFx0XCJiYWNrZ3JvdW5kXCI6IHRoaXMuaXNJbnZhbGlkID8gXCIjZmRkZFwiIDogXCIjZmZmZVwiXHJcblx0XHR9KVxyXG5cdFx0LmFwcGVuZCh0aGlzLnJlYWRMYXlvdXQuJGVsZW1lbnQsIHRoaXMuZWRpdExheW91dC4kZWxlbWVudCk7XHJcbiAgICBcclxuXHR0aGlzLmVkaXRCdXR0b24uY29ubmVjdCggdGhpcywgeyBcImNsaWNrXCI6IFwib25FZGl0Q2xpY2tcIiB9ICk7XHJcblx0dGhpcy5jb25maXJtQnV0dG9uLmNvbm5lY3QoIHRoaXMsIHsgXCJjbGlja1wiOiBcIm9uQ29uZmlybUNsaWNrXCIgfSApO1xyXG5cdHRoaXMuY2FuY2VsQnV0dG9uLmNvbm5lY3QoIHRoaXMsIHsgXCJjbGlja1wiOiBcIm9uQ2FuY2VsQ2xpY2tcIiB9ICk7XHJcblx0dGhpcy5kZWxldGVCdXR0b24uY29ubmVjdCggdGhpcywgeyBcImNsaWNrXCI6IFwib25EZWxldGVDbGlja1wiIH0gKTtcclxuXHRpZiAodGhpcy5jaGVja2JveCkge1xyXG5cdFx0dGhpcy5jaGVja2JveC5jb25uZWN0KHRoaXMsIHtcImNoYW5nZVwiOiBcIm9uQ2hlY2tib3hDaGFuZ2VcIn0gKTtcclxuXHR9XHJcbn1cclxuT08uaW5oZXJpdENsYXNzKCBQYXJhbWV0ZXJXaWRnZXQsIE9PLnVpLldpZGdldCApO1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vblVwZGF0ZWRTaXplID0gZnVuY3Rpb24oKSB7XHJcblx0Ly8gRW1pdCBhbiBcInVwZGF0ZWRTaXplXCIgZXZlbnQgc28gdGhlIHBhcmVudCB3aW5kb3cgY2FuIHVwZGF0ZSBzaXplLCBpZiBuZWVkZWRcclxuXHR0aGlzLmVtaXQoXCJ1cGRhdGVkU2l6ZVwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlcldpZGdldC5wcm90b3R5cGUub25FZGl0Q2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnJlYWRMYXlvdXQudG9nZ2xlKGZhbHNlKTtcclxuXHR0aGlzLmVkaXRMYXlvdXQudG9nZ2xlKHRydWUpO1xyXG5cdHRoaXMuJGVsZW1lbnQuY3NzKHtcImJhY2tncm91bmRcIjogXCIjZmZmZVwifSk7XHJcblx0dGhpcy5pbnB1dC5mb2N1cygpO1xyXG5cdHRoaXMub25VcGRhdGVkU2l6ZSgpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vbkNvbmZpcm1DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuc2V0VmFsdWUoXHJcblx0XHR0aGlzLmlucHV0LmdldFZhbHVlKClcclxuXHQpO1xyXG5cdHRoaXMucmVhZExheW91dC50b2dnbGUodHJ1ZSk7XHJcblx0dGhpcy5lZGl0TGF5b3V0LnRvZ2dsZShmYWxzZSk7XHJcblx0dGhpcy5vblVwZGF0ZWRTaXplKCk7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJXaWRnZXQucHJvdG90eXBlLm9uQ2FuY2VsQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmlucHV0LnNldFZhbHVlKHRoaXMudmFsdWUpO1xyXG5cdHRoaXMucmVhZExheW91dC50b2dnbGUodHJ1ZSk7XHJcblx0dGhpcy5lZGl0TGF5b3V0LnRvZ2dsZShmYWxzZSk7XHJcblx0dGhpcy5vblVwZGF0ZWRTaXplKCk7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJXaWRnZXQucHJvdG90eXBlLm9uRGVsZXRlQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmRlbGV0ZSgpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vbkNoZWNrYm94Q2hhbmdlID0gZnVuY3Rpb24oaXNTZWxlY3RlZCwgaXNJbmRldGVybWluYXRlKSB7XHJcblx0aWYgKGlzSW5kZXRlcm1pbmF0ZSkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHRpZiAoaXNTZWxlY3RlZCkge1xyXG5cdFx0dGhpcy5zZXRWYWx1ZSh0aGlzLmFsbG93ZWRWYWx1ZXNbMF0pO1xyXG5cdH0gZWxzZSB7XHJcblx0XHR0aGlzLnNldFZhbHVlKHRoaXMuYWxsb3dlZFZhbHVlc1sxXSk7XHJcblx0fVxyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmVtaXQoXCJkZWxldGVcIik7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJXaWRnZXQucHJvdG90eXBlLnNldFZhbHVlID0gZnVuY3Rpb24odmFsKSB7XHJcblx0Ly8gVHVybiBvZmYgYXV0b2ZpbGwgc3R5bGluZ3MvaWNvblxyXG5cdHRoaXMuYXV0b2ZpbGxlZCA9IGZhbHNlO1xyXG5cdHRoaXMuYXV0b2ZpbGxlZEljb24udG9nZ2xlKGZhbHNlKTtcclxuXHR0aGlzLiRlbGVtZW50LmNzcyh7XCJib3JkZXJcIjogXCIxcHggc29saWQgI2RkZFwifSk7XHJcblxyXG5cdC8vIFVwZGF0ZSB0aGUgc3RvcmVkIHZhbHVlXHJcblx0dGhpcy52YWx1ZSA9IHZhbDtcclxuXHJcblx0Ly8gVXBkYXRlIHRoZSBpbnB1dCB2YWx1ZSBmb3IgZWRpdCBtb2RlXHJcblx0dGhpcy5pbnB1dC5zZXRWYWx1ZSh0aGlzLnZhbHVlKTtcclxuXHJcblx0Ly8gVXBkYXRlIHZhbGlkaXR5XHJcblx0dGhpcy5pc0ludmFsaWQgPSB0aGlzLnZhbHVlID09IG51bGw7XHJcblx0dGhpcy5pbnZhbGlkSWNvbi50b2dnbGUodGhpcy5pc0ludmFsaWQpO1xyXG5cdHRoaXMuJGVsZW1lbnQuY3NzKHtcImJhY2tncm91bmRcIjogdGhpcy5pc0ludmFsaWQgPyBcIiNmZGRkXCIgOiBcIiNmZmZlXCJ9KTtcclxuXHJcblx0Ly8gVXBkYXRlZCB0aGUgbGFiZWwgZm9yIHJlYWQgbW9kZVxyXG5cdHRoaXMuZnVsbExhYmVsLnNldExhYmVsKFxyXG5cdFx0dGhpcy5uYW1lICtcclxuXHRcdCh0aGlzLnZhbHVlXHJcblx0XHRcdD8gXCIgPSBcIiArIHRoaXMudmFsdWVcclxuXHRcdFx0OiBcIlwiXHJcblx0XHQpXHJcblx0KTtcclxuXHJcblx0Ly8gVXBkYXRlIHRoZSBjaGVja2JveCAoaWYgdGhlcmUgaXMgb25lKVxyXG5cdGlmICh0aGlzLmNoZWNrYm94KSB7XHJcblx0XHR2YXIgaXNGaXJzdEFsbG93ZWRWYWwgPSAoXHJcblx0XHRcdHRoaXMuYWxsb3dlZFZhbHVlcy5pbmRleE9mKCB2YWwgKSA9PT0gMCB8fFxyXG5cdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMubWFwKG5vcm1hbGlzZVllc05vKS5pbmRleE9mKCBub3JtYWxpc2VZZXNObyh2YWwpICkgPT09IDBcclxuXHRcdCk7XHJcblx0XHR2YXIgaXNTZWNvbmRBbGxvd2VkVmFsID0gKFxyXG5cdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMuaW5kZXhPZiggdmFsIHx8IG51bGwgKSA9PT0gMSB8fFxyXG5cdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMubWFwKG5vcm1hbGlzZVllc05vKS5pbmRleE9mKCB2YWwgPyBub3JtYWxpc2VZZXNObyh2YWwpIDogbnVsbCkgPT09IDFcclxuXHRcdCk7XHJcblx0XHR2YXIgaXNJbmRldGVybWluYXRlID0gIWlzRmlyc3RBbGxvd2VkVmFsICYmICFpc1NlY29uZEFsbG93ZWRWYWw7XHJcblx0XHR0aGlzLmNoZWNrYm94LnNldEluZGV0ZXJtaW5hdGUoaXNJbmRldGVybWluYXRlLCB0cnVlKTtcclxuXHRcdGlmICghaXNJbmRldGVybWluYXRlKSB7XHJcblx0XHRcdHZhciBpc1NlbGVjdGVkID0gaXNGaXJzdEFsbG93ZWRWYWw7XHJcblx0XHRcdHRoaXMuY2hlY2tib3guc2V0U2VsZWN0ZWQoaXNTZWxlY3RlZCwgdHJ1ZSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBFbWl0IGEgY2hhbmdlIGV2ZW50XHJcblx0dGhpcy5lbWl0KFwiY2hhbmdlXCIpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5zZXRBdXRvZmlsbGVkID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5hdXRvZmlsbGVkID0gdHJ1ZTtcclxuXHR0aGlzLmF1dG9maWxsZWRJY29uLnRvZ2dsZSh0cnVlKTtcclxuXHR0aGlzLiRlbGVtZW50LmNzcyh7XCJib3JkZXJcIjogXCIxcHggZGFzaGVkICMzNmNcIn0pO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5tYWtlV2lraXRleHQgPSBmdW5jdGlvbihwaXBlU3R5bGUsIGVxdWFsc1N0eWxlKSB7XHJcblx0aWYgKHRoaXMuaXNJbnZhbGlkKSB7XHJcblx0XHRyZXR1cm4gXCJcIjtcclxuXHR9XHJcblx0cmV0dXJuIHBpcGVTdHlsZSArIHRoaXMubmFtZSArIGVxdWFsc1N0eWxlICsgKHRoaXMudmFsdWV8fFwiXCIpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5mb2N1c0lucHV0ID0gZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHRoaXMuaW5wdXQuZm9jdXMoKTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFBhcmFtZXRlcldpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IGNvbmZpZyBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG5mdW5jdGlvbiBQcmVmc0Zvcm1XaWRnZXQoIGNvbmZpZyApIHtcclxuXHQvLyBDb25maWd1cmF0aW9uIGluaXRpYWxpemF0aW9uXHJcblx0Y29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG5cdC8vIENhbGwgcGFyZW50IGNvbnN0cnVjdG9yXHJcblx0UHJlZnNGb3JtV2lkZ2V0LnN1cGVyLmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG5cclxuXHR0aGlzLiRlbGVtZW50LmFkZENsYXNzKFwicmF0ZXItcHJlZnNGb3JtV2lkZ2V0XCIpO1xyXG5cclxuXHR0aGlzLmxheW91dCA9ICBuZXcgT08udWkuRmllbGRzZXRMYXlvdXQoIHtcclxuXHRcdGxhYmVsOiBcIlByZWZlcmVuY2VzXCIsXHJcblx0XHQkZWxlbWVudDogdGhpcy4kZWxlbWVudFxyXG5cdH0gKTtcclxuXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IHtcclxuXHRcdFwiYXV0b3N0YXJ0XCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5Ub2dnbGVTd2l0Y2hXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQXV0b3N0YXJ0IFJhdGVyXCJcclxuXHRcdH0sXHJcblx0XHRcImF1dG9zdGFydFJlZGlyZWN0c1wiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuVG9nZ2xlU3dpdGNoV2lkZ2V0KCksXHJcblx0XHRcdGxhYmVsOiBcIkF1dG9zdGFydCBvbiByZWRpcmVjdHNcIlxyXG5cdFx0fSxcclxuXHRcdFwiYXV0b3N0YXJ0TmFtZXNwYWNlc1wiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgbXcud2lkZ2V0cy5OYW1lc3BhY2VzTXVsdGlzZWxlY3RXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQXV0b3N0YXJ0IGluIHRoZXNlIG5hbWVzcGFjZXNcIlxyXG5cdFx0fSxcclxuXHRcdFwiYnlwYXNzUmVkaXJlY3RzXCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5Ub2dnbGVTd2l0Y2hXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQnlwYXNzIHJlZGlyZWN0cyB0byBiYW5uZXJzXCJcclxuXHRcdH0sXHJcblx0XHRcImF1dG9maWxsQ2xhc3NGcm9tT3RoZXJzXCI6ICB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuVG9nZ2xlU3dpdGNoV2lkZ2V0KCksXHJcblx0XHRcdGxhYmVsOiBcIkF1dG9maWxsIGNsYXNzIGZyb20gb3RoZXIgYmFubmVyc1wiXHJcblx0XHR9LFxyXG5cdFx0XCJhdXRvZmlsbENsYXNzRnJvbU9yZXNcIjoge1xyXG5cdFx0XHRpbnB1dDogbmV3IE9PLnVpLlRvZ2dsZVN3aXRjaFdpZGdldCgpLFxyXG5cdFx0XHRsYWJlbDogXCJBdXRvZmlsbCBjbGFzcyBiYXNlZCBvbiBPUkVTIHByZWRpY3Rpb25cIlxyXG5cdFx0fSxcclxuXHRcdFwiYXV0b2ZpbGxJbXBvcnRhbmNlXCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5Ub2dnbGVTd2l0Y2hXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQXV0b2ZpbGwgbG93IGltcG9ydGFuY2VcIlxyXG5cdFx0fSxcclxuXHRcdFwiY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0XCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5OdW1iZXJJbnB1dFdpZGdldCggeyBcIm1pblwiOiAxIH0gKSxcclxuXHRcdFx0bGFiZWw6IFwiTWluaW11bSBudW1iZXIgb2YgcGFyYW1ldGVycyB0byBzaG93IHVuY29sbGFwc2VkXCJcclxuXHRcdH0sXHJcblx0XHRcIndhdGNobGlzdFwiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuQnV0dG9uU2VsZWN0V2lkZ2V0KCB7XHJcblx0XHRcdFx0aXRlbXM6IFtcclxuXHRcdFx0XHRcdG5ldyBPTy51aS5CdXR0b25PcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdFx0ZGF0YTogXCJwcmVmZXJlbmNlc1wiLFxyXG5cdFx0XHRcdFx0XHRsYWJlbDogXCJEZWZhdWx0XCIsXHJcblx0XHRcdFx0XHRcdHRpdGxlOiBcIlVzZXMgdGhlIHNhbWUgc2V0dGluZyBhcyBpZiB5b3UgbWFudWFsbHkgZWRpdGVkIHRoZSBwYWdlLCBhcyBwZXIgU3BlY2lhbDpQcmVmZXJlbmNlc1wiXHJcblx0XHRcdFx0XHR9ICksXHJcblx0XHRcdFx0XHRuZXcgT08udWkuQnV0dG9uT3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdGRhdGE6IFwid2F0Y2hcIixcclxuXHRcdFx0XHRcdFx0bGFiZWw6IFwiQWx3YXlzXCIsXHJcblx0XHRcdFx0XHRcdHRpdGxlOiBcIkFsd2F5cyBhZGQgcGFnZXMgUmF0ZXIgZWRpdHMgdG8geW91ciB3YXRjaGxpc3RcIlxyXG5cdFx0XHRcdFx0fSApLFxyXG5cdFx0XHRcdFx0bmV3IE9PLnVpLkJ1dHRvbk9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0XHRkYXRhOiBcIm5vY2hhbmdlXCIsXHJcblx0XHRcdFx0XHRcdGxhYmVsOiBcIk5ldmVyXCIsXHJcblx0XHRcdFx0XHRcdHRpdGxlOiBcIk5ldmVyIGFkZCBwYWdlcyBSYXRlciBlZGl0IHRvIHlvdXIgd2F0Y2hsaXN0XCJcclxuXHRcdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRdXHJcblx0XHRcdH0pLnNlbGVjdEl0ZW1CeURhdGEoXCJwcmVmZXJlbmNlc1wiKSxcclxuXHRcdFx0bGFiZWw6IFwiQWRkIGVkaXRlZCBwYWdlcyB0byB3YXRjaGxpc3RcIlxyXG5cdFx0fSxcclxuXHRcdFwicmVzZXRDYWNoZVwiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0bGFiZWw6IFwiUmVzZXQgY2FjaGVcIixcclxuXHRcdFx0XHR0aXRsZTogXCJSZW1vdmUgY2FjaGVkIGRhdGEsIGluY2x1ZGluZyBsaXN0IG9mIFdpa2lQcm9qZWN0cyBhbmQgdGVtcGxhdGUgcGFyYW1ldGVyc1wiLFxyXG5cdFx0XHRcdGZsYWdzOiBbXCJkZXN0cnVjdGl2ZVwiXVxyXG5cdFx0XHR9IClcclxuXHRcdH1cclxuXHR9O1xyXG5cclxuXHRmb3IgKGxldCBwcmVmTmFtZSBpbiB0aGlzLnByZWZlcmVuY2VzICkge1xyXG5cdFx0dGhpcy5sYXlvdXQuYWRkSXRlbXMoW1xyXG5cdFx0XHRuZXcgT08udWkuRmllbGRMYXlvdXQoIHRoaXMucHJlZmVyZW5jZXNbcHJlZk5hbWVdLmlucHV0LCB7XHJcblx0XHRcdFx0bGFiZWw6IHRoaXMucHJlZmVyZW5jZXNbcHJlZk5hbWVdLmxhYmVsLFxyXG5cdFx0XHRcdGFsaWduOiBcInJpZ2h0XCJcclxuXHRcdFx0fSApXHJcblx0XHRdKTtcclxuXHR9XHJcblxyXG5cdHRoaXMucHJlZmVyZW5jZXMucmVzZXRDYWNoZS5pbnB1dC5jb25uZWN0KHRoaXMsIHtcImNsaWNrXCI6IFwib25SZXNldENhY2hlQ2xpY2tcIn0pO1xyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggUHJlZnNGb3JtV2lkZ2V0LCBPTy51aS5XaWRnZXQgKTtcclxuXHJcblByZWZzRm9ybVdpZGdldC5wcm90b3R5cGUuc2V0UHJlZlZhbHVlcyA9IGZ1bmN0aW9uKHByZWZzKSB7XHJcblx0Zm9yIChsZXQgcHJlZk5hbWUgaW4gcHJlZnMgKSB7XHJcblx0XHRsZXQgdmFsdWUgPSBwcmVmc1twcmVmTmFtZV07XHJcblx0XHRsZXQgaW5wdXQgPSB0aGlzLnByZWZlcmVuY2VzW3ByZWZOYW1lXSAmJiB0aGlzLnByZWZlcmVuY2VzW3ByZWZOYW1lXS5pbnB1dDtcclxuXHRcdHN3aXRjaCAoaW5wdXQgJiYgaW5wdXQuY29uc3RydWN0b3IubmFtZSkge1xyXG5cdFx0Y2FzZSBcIk9vVWlCdXR0b25TZWxlY3RXaWRnZXRcIjpcclxuXHRcdFx0aW5wdXQuc2VsZWN0SXRlbUJ5RGF0YSh2YWx1ZSk7XHJcblx0XHRcdGJyZWFrO1xyXG5cdFx0Y2FzZSBcIk9vVWlOdW1iZXJJbnB1dFdpZGdldFwiOlxyXG5cdFx0Y2FzZSBcIk9vVWlUb2dnbGVTd2l0Y2hXaWRnZXRcIjpcclxuXHRcdFx0aW5wdXQuc2V0VmFsdWUodmFsdWUpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdGNhc2UgXCJNd1dpZGdldHNOYW1lc3BhY2VzTXVsdGlzZWxlY3RXaWRnZXRcIjpcclxuXHRcdFx0aW5wdXQuY2xlYXJJdGVtcygpO1xyXG5cdFx0XHR2YWx1ZS5mb3JFYWNoKG5zID0+XHJcblx0XHRcdFx0aW5wdXQuYWRkVGFnKFxyXG5cdFx0XHRcdFx0bnMudG9TdHJpbmcoKSxcclxuXHRcdFx0XHRcdG5zID09PSAwXHJcblx0XHRcdFx0XHRcdD8gXCIoTWFpbilcIlxyXG5cdFx0XHRcdFx0XHQ6IGNvbmZpZy5tdy53Z0Zvcm1hdHRlZE5hbWVzcGFjZXNbbnNdXHJcblx0XHRcdFx0KVxyXG5cdFx0XHQpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdH1cclxuXHR9XHJcbn07XHJcblxyXG5QcmVmc0Zvcm1XaWRnZXQucHJvdG90eXBlLmdldFByZWZzID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIHByZWZzID0ge307XHJcblx0Zm9yIChsZXQgcHJlZk5hbWUgaW4gdGhpcy5wcmVmZXJlbmNlcyApIHtcclxuXHRcdGxldCBpbnB1dCA9IHRoaXMucHJlZmVyZW5jZXNbcHJlZk5hbWVdLmlucHV0O1xyXG5cdFx0bGV0IHZhbHVlO1xyXG5cdFx0c3dpdGNoIChpbnB1dC5jb25zdHJ1Y3Rvci5uYW1lKSB7XHJcblx0XHRjYXNlIFwiT29VaUJ1dHRvblNlbGVjdFdpZGdldFwiOlxyXG5cdFx0XHR2YWx1ZSA9IGlucHV0LmZpbmRTZWxlY3RlZEl0ZW0oKS5nZXREYXRhKCk7XHJcblx0XHRcdGJyZWFrO1xyXG5cdFx0Y2FzZSBcIk9vVWlUb2dnbGVTd2l0Y2hXaWRnZXRcIjpcclxuXHRcdFx0dmFsdWUgPSBpbnB1dC5nZXRWYWx1ZSgpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdGNhc2UgXCJPb1VpTnVtYmVySW5wdXRXaWRnZXRcIjpcclxuXHRcdFx0dmFsdWUgPSBOdW1iZXIoaW5wdXQuZ2V0VmFsdWUoKSk7IC8vIHdpZGdldCB1c2VzIHN0cmluZ3MsIG5vdCBudW1iZXJzIVxyXG5cdFx0XHRicmVhaztcclxuXHRcdGNhc2UgXCJNd1dpZGdldHNOYW1lc3BhY2VzTXVsdGlzZWxlY3RXaWRnZXRcIjpcclxuXHRcdFx0dmFsdWUgPSBpbnB1dC5nZXRWYWx1ZSgpLm1hcChOdW1iZXIpOyAvLyB3aWRnZXQgdXNlcyBzdHJpbmdzLCBub3QgbnVtYmVycyFcclxuXHRcdFx0YnJlYWs7XHJcblx0XHR9XHJcblx0XHRwcmVmc1twcmVmTmFtZV0gPSB2YWx1ZTtcclxuXHR9XHJcblx0cmV0dXJuIHByZWZzO1xyXG59O1xyXG5cclxuUHJlZnNGb3JtV2lkZ2V0LnByb3RvdHlwZS5vblJlc2V0Q2FjaGVDbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdE9PLnVpLmNvbmZpcm0oXCJBZnRlciByZXNldGluZyBjYWNoZSwgUmF0ZXIgd2lsbCBjbG9zZSBhbmQgcmVzdGFydC4gQW55IGNoYW5nZXMgbWFkZSB3aWxsIGJlIGRpc2NhcmRlZC5cIilcclxuXHRcdC50aGVuKGNvbmZpcm1lZCA9PiB7XHJcblx0XHRcdGlmIChjb25maXJtZWQpIHsgXHJcblx0XHRcdFx0dGhpcy5lbWl0KFwicmVzZXRDYWNoZVwiKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBQcmVmc0Zvcm1XaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsIi8vIDxub3dpa2k+XHJcblxyXG52YXIgU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldCA9IGZ1bmN0aW9uIFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQoIGNvbmZpZyApIHtcclxuXHRPTy51aS5UZXh0SW5wdXRXaWRnZXQuY2FsbCggdGhpcywgY29uZmlnICk7XHJcblx0T08udWkubWl4aW4uTG9va3VwRWxlbWVudC5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLnN1Z2dlc3Rpb25zID0gQXJyYXkuaXNBcnJheShjb25maWcuc3VnZ2VzdGlvbnMpID8gY29uZmlnLnN1Z2dlc3Rpb25zIDogW107XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLXN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXRcIik7XHJcbn07XHJcbk9PLmluaGVyaXRDbGFzcyggU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldCwgT08udWkuVGV4dElucHV0V2lkZ2V0ICk7XHJcbk9PLm1peGluQ2xhc3MoIFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQsIE9PLnVpLm1peGluLkxvb2t1cEVsZW1lbnQgKTtcclxuXHJcbi8vIFNldCBzdWdnZXN0aW9uLiBwYXJhbTogT2JqZWN0W10gd2l0aCBvYmplY3RzIG9mIHRoZSBmb3JtIHsgZGF0YTogLi4uICwgbGFiZWw6IC4uLiB9XHJcblN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQucHJvdG90eXBlLnNldFN1Z2dlc3Rpb25zID0gZnVuY3Rpb24oc3VnZ2VzdGlvbnMpIHtcclxuXHRpZiAoIUFycmF5LmlzQXJyYXkoc3VnZ2VzdGlvbnMpKSB7XHJcblx0XHRpZiAoc3VnZ2VzdGlvbnMgIT0gbnVsbCkge1xyXG5cdFx0XHRjb25zb2xlLndhcm4oXCJbUmF0ZXJdIFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQucHJvdG90eXBlLnNldFN1Z2dlc3Rpb25zIGNhbGxlZCB3aXRoIGEgbm9uLWFycmF5IHZhbHVlOlwiLCBzdWdnZXN0aW9ucyk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdHRoaXMuc3VnZ2VzdGlvbnMgPSBzdWdnZXN0aW9ucztcclxufTtcclxuXHJcbi8vIFJldHVybnMgZGF0YSwgYXMgYSByZXNvbHV0aW9uIHRvIGEgcHJvbWlzZSwgdG8gYmUgcGFzc2VkIHRvICNnZXRMb29rdXBNZW51T3B0aW9uc0Zyb21EYXRhXHJcblN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQucHJvdG90eXBlLmdldExvb2t1cFJlcXVlc3QgPSBmdW5jdGlvbiAoKSB7XHJcblx0dmFyIGRlZmVycmVkID0gJC5EZWZlcnJlZCgpLnJlc29sdmUobmV3IFJlZ0V4cChcIlxcXFxiXCIgKyBtdy51dGlsLmVzY2FwZVJlZ0V4cCh0aGlzLmdldFZhbHVlKCkpLCBcImlcIikpO1xyXG5cdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCB7IGFib3J0OiBmdW5jdGlvbiAoKSB7fSB9ICk7XHJcbn07XHJcblxyXG4vLyA/Pz9cclxuU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldC5wcm90b3R5cGUuZ2V0TG9va3VwQ2FjaGVEYXRhRnJvbVJlc3BvbnNlID0gZnVuY3Rpb24gKCByZXNwb25zZSApIHtcclxuXHRyZXR1cm4gcmVzcG9uc2UgfHwgW107XHJcbn07XHJcblxyXG4vLyBJcyBwYXNzZWQgZGF0YSBmcm9tICNnZXRMb29rdXBSZXF1ZXN0LCByZXR1cm5zIGFuIGFycmF5IG9mIG1lbnUgaXRlbSB3aWRnZXRzIFxyXG5TdWdnZXN0aW9uTG9va3VwVGV4dElucHV0V2lkZ2V0LnByb3RvdHlwZS5nZXRMb29rdXBNZW51T3B0aW9uc0Zyb21EYXRhID0gZnVuY3Rpb24gKCBwYXR0ZXJuICkge1xyXG5cdHZhciBsYWJlbE1hdGNoZXNJbnB1dFZhbCA9IGZ1bmN0aW9uKHN1Z2dlc3Rpb25JdGVtKSB7XHJcblx0XHRyZXR1cm4gcGF0dGVybi50ZXN0KHN1Z2dlc3Rpb25JdGVtLmxhYmVsKSB8fCAoICFzdWdnZXN0aW9uSXRlbS5sYWJlbCAmJiBwYXR0ZXJuLnRlc3Qoc3VnZ2VzdGlvbkl0ZW0uZGF0YSkgKTtcclxuXHR9O1xyXG5cdHZhciBtYWtlTWVudU9wdGlvbldpZGdldCA9IGZ1bmN0aW9uKG9wdGlvbkl0ZW0pIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRkYXRhOiBvcHRpb25JdGVtLmRhdGEsXHJcblx0XHRcdGxhYmVsOiBvcHRpb25JdGVtLmxhYmVsIHx8IG9wdGlvbkl0ZW0uZGF0YVxyXG5cdFx0fSApO1xyXG5cdH07XHJcblx0cmV0dXJuIHRoaXMuc3VnZ2VzdGlvbnMuZmlsdGVyKGxhYmVsTWF0Y2hlc0lucHV0VmFsKS5tYXAobWFrZU1lbnVPcHRpb25XaWRnZXQpO1xyXG59O1xyXG5cclxuLy8gRXh0ZW5kIG9uTG9va3VwTWVudUNob29zZSBtZXRob2QgdG8gZW1pdCBhbiBjaG9vc2UgZXZlbnRcclxuU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldC5wcm90b3R5cGUub25Mb29rdXBNZW51Q2hvb3NlID0gZnVuY3Rpb24gKCBpdGVtICkge1xyXG5cdC8vIEdldCBkYXRhXHJcblx0Y29uc3QgaXRlbURhdGEgPSBpdGVtLmdldERhdGEoKTtcclxuXHQvLyBTaW1wbGlmeSBpdGVtIGRhdGEgaWYgaXQgaXMgYW4gb2JqZWN0IHdpdGggYSBuYW1lIHByb3BlcnR5XHJcblx0aWYgKGl0ZW1EYXRhICYmIGl0ZW1EYXRhLm5hbWUpIHtcclxuXHRcdGl0ZW0uc2V0RGF0YShpdGVtRGF0YS5uYW1lKTtcclxuXHR9XHJcblx0Ly8gRmlyc3QgYmx1ciB0aGUgaW5wdXQsIHRvIHByZXZlbnQgdGhlIG1lbnUgcG9wcGluZyBiYWNrIHVwXHJcblx0dGhpcy4kaW5wdXQuYmx1cigpO1xyXG5cdE9PLnVpLm1peGluLkxvb2t1cEVsZW1lbnQucHJvdG90eXBlLm9uTG9va3VwTWVudUNob29zZS5jYWxsKHRoaXMsIGl0ZW0pO1xyXG5cdHRoaXMuZW1pdChcImNob29zZVwiLCBpdGVtRGF0YSApO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IGFwcENvbmZpZyBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XHJcbmltcG9ydCBTdWdnZXN0aW9uTG9va3VwVGV4dElucHV0V2lkZ2V0IGZyb20gXCIuL1N1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXRcIjtcclxuaW1wb3J0IHtnZXRCYW5uZXJOYW1lc30gZnJvbSBcIi4uLy4uL2dldEJhbm5lcnNcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbmZ1bmN0aW9uIFRvcEJhcldpZGdldCggY29uZmlnICkge1xyXG5cdC8vIENvbmZpZ3VyYXRpb24gaW5pdGlhbGl6YXRpb25cclxuXHRjb25maWcgPSAkLmV4dGVuZChcclxuXHRcdHtcclxuXHRcdFx0ZXhwYW5kZWQ6IGZhbHNlLFxyXG5cdFx0XHRmcmFtZWQ6IGZhbHNlLFxyXG5cdFx0XHRwYWRkZWQ6IGZhbHNlXHJcblx0XHR9LFxyXG5cdFx0Y29uZmlnIHx8IHt9XHJcblx0KTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdFRvcEJhcldpZGdldC5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLiRvdmVybGF5ID0gY29uZmlnLiRvdmVybGF5O1xyXG4gICAgXHJcblx0Ly8gU2VhcmNoIGJveFxyXG5cdHRoaXMuc2VhcmNoQm94ID0gbmV3IFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQoIHtcclxuXHRcdHBsYWNlaG9sZGVyOiBcIkFkZCBhIFdpa2lQcm9qZWN0Li4uXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxkaXYgc3R5bGU9J2Rpc3BsYXk6aW5saW5lLWJsb2NrOyBtYXJnaW46MCAtMXB4OyB3aWR0aDpjYWxjKDEwMCUgLSA1NXB4KTsnPlwiKSxcclxuXHRcdCRvdmVybGF5OiB0aGlzLiRvdmVybGF5LFxyXG5cdH0gKTtcclxuXHRnZXRCYW5uZXJOYW1lcygpXHJcblx0XHQudGhlbihiYW5uZXJzID0+IFtcclxuXHRcdFx0Li4uYmFubmVycy53aXRoUmF0aW5ncy5tYXAoYmFubmVyTmFtZSA9PiAoe1xyXG5cdFx0XHRcdGxhYmVsOiBiYW5uZXJOYW1lLnJlcGxhY2UoXCJXaWtpUHJvamVjdCBcIiwgXCJcIiksXHJcblx0XHRcdFx0ZGF0YToge1xyXG5cdFx0XHRcdFx0bmFtZTogYmFubmVyTmFtZVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSkpLFxyXG5cdFx0XHQuLi5iYW5uZXJzLndpdGhvdXRSYXRpbmdzLm1hcChiYW5uZXJOYW1lID0+ICh7XHJcblx0XHRcdFx0bGFiZWw6IGJhbm5lck5hbWUucmVwbGFjZShcIldpa2lQcm9qZWN0IFwiLCBcIlwiKSxcclxuXHRcdFx0XHRkYXRhOiB7XHJcblx0XHRcdFx0XHRuYW1lOiBiYW5uZXJOYW1lLFxyXG5cdFx0XHRcdFx0d2l0aG91dFJhdGluZ3M6IHRydWVcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pKSxcclxuXHRcdFx0Li4uYmFubmVycy53cmFwcGVycy5tYXAoYmFubmVyTmFtZSA9PiAoe1xyXG5cdFx0XHRcdGxhYmVsOiBiYW5uZXJOYW1lLnJlcGxhY2UoXCJXaWtpUHJvamVjdCBcIiwgXCJcIikgKyBcIiBbdGVtcGxhdGUgd3JhcHBlcl1cIixcclxuXHRcdFx0XHRkYXRhOiB7XHJcblx0XHRcdFx0XHRuYW1lOiBiYW5uZXJOYW1lLFxyXG5cdFx0XHRcdFx0d3JhcHBlcjogdHJ1ZVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSkpLFxyXG5cdFx0XHQuLi5iYW5uZXJzLm5vdFdQQk0ubWFwKGJhbm5lck5hbWUgPT4gKHtcclxuXHRcdFx0XHRsYWJlbDogYmFubmVyTmFtZS5yZXBsYWNlKFwiV2lraVByb2plY3QgXCIsIFwiXCIpLFxyXG5cdFx0XHRcdGRhdGE6IHtcclxuXHRcdFx0XHRcdG5hbWU6IGJhbm5lck5hbWVcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pKSxcclxuXHRcdFx0Li4uYmFubmVycy5pbmFjdGl2ZS5tYXAoYmFubmVyTmFtZSA9PiAoe1xyXG5cdFx0XHRcdGxhYmVsOiBiYW5uZXJOYW1lLnJlcGxhY2UoXCJXaWtpUHJvamVjdCBcIiwgXCJcIikgKyBcIiBbaW5hY3RpdmVdXCIsXHJcblx0XHRcdFx0ZGF0YToge1xyXG5cdFx0XHRcdFx0bmFtZTogYmFubmVyTmFtZSxcclxuXHRcdFx0XHRcdHdpdGhvdXRSYXRpbmdzOiB0cnVlXHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KSksXHJcblx0XHRcdC4uLmJhbm5lcnMud2lyLm1hcChiYW5uZXJOYW1lID0+ICh7XHJcblx0XHRcdFx0bGFiZWw6IGJhbm5lck5hbWUgKyBcIiBbV29tZW4gSW4gUmVkIG1lZXR1cC9pbml0aWF0aXZlXVwiLFxyXG5cdFx0XHRcdGRhdGE6IHtcclxuXHRcdFx0XHRcdG5hbWU6IGJhbm5lck5hbWUsXHJcblx0XHRcdFx0XHR3aXRob3V0UmF0aW5nczogdHJ1ZVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSkpXHJcblx0XHRdKVxyXG5cdFx0LnRoZW4oYmFubmVyT3B0aW9ucyA9PiB0aGlzLnNlYXJjaEJveC5zZXRTdWdnZXN0aW9ucyhiYW5uZXJPcHRpb25zKSk7XHJcbiAgICBcclxuXHQvLyBBZGQgYnV0dG9uXHJcblx0dGhpcy5hZGRCYW5uZXJCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRpY29uOiBcImFkZFwiLFxyXG5cdFx0dGl0bGU6IFwiQWRkXCIsXHJcblx0XHRmbGFnczogXCJwcm9ncmVzc2l2ZVwiLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nZmxvYXQ6cmlnaHQ7bWFyZ2luOiAwO3RyYW5zZm9ybTogdHJhbnNsYXRlWCgtMTJweCk7Jz5cIiksXHJcblx0fSApO1xyXG5cdHZhciAkc2VhcmNoQ29udGFpbmVyID0gJChcIjxkaXYgc3R5bGU9J2Rpc3BsYXk6aW5saW5lLWJsb2NrOyBmbGV4LXNocmluazoxOyBmbGV4LWdyb3c6MTAwOyBtaW4td2lkdGg6MjUwcHg7IHdpZHRoOjUwJTsnPlwiKVxyXG5cdFx0LmFwcGVuZCh0aGlzLnNlYXJjaEJveC4kZWxlbWVudCwgdGhpcy5hZGRCYW5uZXJCdXR0b24uJGVsZW1lbnQpO1xyXG5cclxuXHQvLyBTZXQgYWxsIGNsYXNzZXMvaW1wb3J0YW5jZXNcclxuXHQvLyBpbiB0aGUgc3R5bGUgb2YgYSBwb3B1cCBidXR0b24gd2l0aCBhIG1lbnUgKGlzIGFjdHVhbGx5IGEgZHJvcGRvd24gd2l0aCBhIGhpZGRlbiBsYWJlbCwgYmVjYXVzZSB0aGF0IG1ha2VzIHRoZSBjb2RpbmcgZWFzaWVyLilcclxuXHR0aGlzLnNldEFsbERyb3BEb3duID0gbmV3IE9PLnVpLkRyb3Bkb3duV2lkZ2V0KCB7XHJcblx0XHRpY29uOiBcInRhZ1wiLFxyXG5cdFx0bGFiZWw6IFwiU2V0IGFsbC4uLlwiLFxyXG5cdFx0aW52aXNpYmxlTGFiZWw6IHRydWUsXHJcblx0XHRtZW51OiB7XHJcblx0XHRcdGl0ZW1zOiBbXHJcblx0XHRcdFx0bmV3IE9PLnVpLk1lbnVTZWN0aW9uT3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRsYWJlbDogXCJDbGFzc2VzXCJcclxuXHRcdFx0XHR9ICksXHJcblx0XHRcdFx0bmV3IE9PLnVpLk1lbnVPcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdGRhdGE6IHtjbGFzczogbnVsbH0sXHJcblx0XHRcdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFwiPHNwYW4gc3R5bGU9XFxcImNvbG9yOiM3NzdcXFwiPihubyBjbGFzcyk8L3NwYW4+XCIpXHJcblx0XHRcdFx0fSApLFxyXG5cdFx0XHRcdC4uLmFwcENvbmZpZy5iYW5uZXJEZWZhdWx0cy5jbGFzc2VzLm1hcChjbGFzc25hbWUgPT4gbmV3IE9PLnVpLk1lbnVPcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdGRhdGE6IHtjbGFzczogY2xhc3NuYW1lfSxcclxuXHRcdFx0XHRcdGxhYmVsOiBjbGFzc25hbWVcclxuXHRcdFx0XHR9IClcclxuXHRcdFx0XHQpLFxyXG5cdFx0XHRcdG5ldyBPTy51aS5NZW51U2VjdGlvbk9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0bGFiZWw6IFwiSW1wb3J0YW5jZXNcIlxyXG5cdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0ZGF0YToge2ltcG9ydGFuY2U6IG51bGx9LFxyXG5cdFx0XHRcdFx0bGFiZWw6IG5ldyBPTy51aS5IdG1sU25pcHBldChcIjxzcGFuIHN0eWxlPVxcXCJjb2xvcjojNzc3XFxcIj4obm8gaW1wb3J0YW5jZSk8L3NwYW4+XCIpXHJcblx0XHRcdFx0fSApLFxyXG5cdFx0XHRcdC4uLmFwcENvbmZpZy5iYW5uZXJEZWZhdWx0cy5pbXBvcnRhbmNlcy5tYXAoaW1wb3J0YW5jZSA9PiBuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0ZGF0YToge2ltcG9ydGFuY2U6IGltcG9ydGFuY2V9LFxyXG5cdFx0XHRcdFx0bGFiZWw6IGltcG9ydGFuY2VcclxuXHRcdFx0XHR9IClcclxuXHRcdFx0XHQpXHJcblx0XHRcdF1cclxuXHRcdH0sXHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPVxcXCJ3aWR0aDphdXRvO2Rpc3BsYXk6aW5saW5lLWJsb2NrO2Zsb2F0OmxlZnQ7bWFyZ2luOjBcXFwiIHRpdGxlPSdTZXQgYWxsLi4uJz5cIiksXHJcblx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHR9ICk7XHJcblxyXG5cdC8vIFJlbW92ZSBhbGwgYmFubmVycyBidXR0b25cclxuXHR0aGlzLnJlbW92ZUFsbEJ1dHRvbiA9IG5ldyBPTy51aS5CdXR0b25XaWRnZXQoIHtcclxuXHRcdGljb246IFwidHJhc2hcIixcclxuXHRcdHRpdGxlOiBcIlJlbW92ZSBhbGxcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCJcclxuXHR9ICk7XHJcblxyXG5cdC8vIENsZWFyIGFsbCBwYXJhbWV0ZXJzIGJ1dHRvblxyXG5cdHRoaXMuY2xlYXJBbGxCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRpY29uOiBcImNhbmNlbFwiLFxyXG5cdFx0dGl0bGU6IFwiQ2xlYXIgYWxsXCIsXHJcblx0XHRmbGFnczogXCJkZXN0cnVjdGl2ZVwiXHJcblx0fSApO1xyXG5cclxuXHQvLyBHcm91cCB0aGUgYnV0dG9ucyB0b2dldGhlclxyXG5cdHRoaXMubWVudUJ1dHRvbnMgPSBuZXcgT08udWkuQnV0dG9uR3JvdXBXaWRnZXQoIHtcclxuXHRcdGl0ZW1zOiBbXHJcblx0XHRcdHRoaXMucmVtb3ZlQWxsQnV0dG9uLFxyXG5cdFx0XHR0aGlzLmNsZWFyQWxsQnV0dG9uXHJcblx0XHRdLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nZmxleDoxIDAgYXV0bzsnPlwiKSxcclxuXHR9ICk7XHJcblx0Ly8gSW5jbHVkZSB0aGUgZHJvcGRvd24gaW4gdGhlIGdyb3VwXHJcblx0dGhpcy5tZW51QnV0dG9ucy4kZWxlbWVudC5wcmVwZW5kKHRoaXMuc2V0QWxsRHJvcERvd24uJGVsZW1lbnQpO1xyXG5cclxuXHQvLyBQdXQgZXZlcnl0aGluZyBpbnRvIGEgbGF5b3V0XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLXRvcEJhcldpZGdldFwiKVxyXG5cdFx0LmNzcyh7XHJcblx0XHRcdFwicG9zaXRpb25cIjogXCJmaXhlZFwiLFxyXG5cdFx0XHRcIndpZHRoXCI6IFwiMTAwJVwiLFxyXG5cdFx0XHRcImJhY2tncm91bmRcIjogXCIjY2NjXCIsXHJcblx0XHRcdFwiZGlzcGxheVwiOiBcImZsZXhcIixcclxuXHRcdFx0XCJmbGV4LXdyYXBcIjogXCJ3cmFwXCIsXHJcblx0XHRcdFwianVzdGlmeS1jb250ZW50XCI6IFwic3BhY2UtYXJvdW5kXCIsXHJcblx0XHRcdFwibWFyZ2luXCI6IFwiLTJweCAwIDAgMFwiXHJcblx0XHR9KVxyXG5cdFx0LmFwcGVuZChcclxuXHRcdFx0JHNlYXJjaENvbnRhaW5lcixcclxuXHRcdFx0dGhpcy5tZW51QnV0dG9ucy4kZWxlbWVudFxyXG5cdFx0KTtcclxuXHJcblx0LyogLS0tIEV2ZW50IGhhbmRsaW5nIC0tLSAqL1xyXG4gICAgXHJcblx0dGhpcy5zZWFyY2hCb3guY29ubmVjdCh0aGlzLCB7XHJcblx0XHRcImVudGVyXCI6IFwib25TZWFyY2hTZWxlY3RcIixcclxuXHRcdFwiY2hvb3NlXCI6IFwib25TZWFyY2hTZWxlY3RcIlxyXG5cdH0pO1xyXG5cdHRoaXMuYWRkQmFubmVyQnV0dG9uLmNvbm5lY3QodGhpcywge1wiY2xpY2tcIjogXCJvblNlYXJjaFNlbGVjdFwifSk7XHJcblx0dGhpcy5zZXRBbGxEcm9wRG93bi5nZXRNZW51KCkuY29ubmVjdCh0aGlzLCB7XCJjaG9vc2VcIjogXCJvblJhdGluZ0Nob29zZVwifSk7XHJcblx0dGhpcy5yZW1vdmVBbGxCdXR0b24uY29ubmVjdCh0aGlzLCB7XCJjbGlja1wiOiBcIm9uUmVtb3ZlQWxsQ2xpY2tcIn0pO1xyXG5cdHRoaXMuY2xlYXJBbGxCdXR0b24uY29ubmVjdCh0aGlzLCB7XCJjbGlja1wiOiBcIm9uQ2xlYXJBbGxDbGlja1wifSk7XHJcbn1cclxuT08uaW5oZXJpdENsYXNzKCBUb3BCYXJXaWRnZXQsIE9PLnVpLlBhbmVsTGF5b3V0ICk7XHJcblxyXG5Ub3BCYXJXaWRnZXQucHJvdG90eXBlLm9uU2VhcmNoU2VsZWN0ID0gZnVuY3Rpb24oZGF0YSkge1xyXG5cdHRoaXMuZW1pdChcInNlYXJjaFNlbGVjdFwiLCBkYXRhKTtcclxufTtcclxuXHJcblRvcEJhcldpZGdldC5wcm90b3R5cGUub25SYXRpbmdDaG9vc2UgPSBmdW5jdGlvbihpdGVtKSB7XHJcblx0Y29uc3QgZGF0YSA9IGl0ZW0uZ2V0RGF0YSgpO1xyXG5cdGlmIChkYXRhLmNsYXNzIHx8IGRhdGEuY2xhc3M9PT1udWxsKSB7XHJcblx0XHR0aGlzLmVtaXQoXCJzZXRDbGFzc2VzXCIsIGRhdGEuY2xhc3MpO1xyXG5cdH1cclxuXHRpZiAoZGF0YS5pbXBvcnRhbmNlIHx8IGRhdGEuaW1wb3J0YW5jZT09PW51bGwpIHtcclxuXHRcdHRoaXMuZW1pdChcInNldEltcG9ydGFuY2VzXCIsIGRhdGEuaW1wb3J0YW5jZSk7XHJcblx0fVxyXG59O1xyXG5cclxuVG9wQmFyV2lkZ2V0LnByb3RvdHlwZS5vblJlbW92ZUFsbENsaWNrID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5lbWl0KFwicmVtb3ZlQWxsXCIpO1xyXG59O1xyXG5cclxuVG9wQmFyV2lkZ2V0LnByb3RvdHlwZS5vbkNsZWFyQWxsQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmVtaXQoXCJjbGVhckFsbFwiKTtcclxufTtcclxuXHJcblRvcEJhcldpZGdldC5wcm90b3R5cGUuc2V0RGlzYWJsZWQgPSBmdW5jdGlvbihkaXNhYmxlKSB7XHJcblx0W1xyXG5cdFx0dGhpcy5zZWFyY2hCb3gsXHJcblx0XHR0aGlzLmFkZEJhbm5lckJ1dHRvbixcclxuXHRcdHRoaXMuc2V0QWxsRHJvcERvd24sXHJcblx0XHR0aGlzLnJlbW92ZUFsbEJ1dHRvbixcclxuXHRcdHRoaXMuY2xlYXJBbGxCdXR0b25cclxuXHRdLmZvckVhY2god2lkZ2V0ID0+IHdpZGdldC5zZXREaXNhYmxlZChkaXNhYmxlKSk7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBUb3BCYXJXaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuLi9hcGlcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbi8qIHZhciBpbmNyZW1lbnRQcm9ncmVzc0J5SW50ZXJ2YWwgPSBmdW5jdGlvbigpIHtcclxuXHR2YXIgaW5jcmVtZW50SW50ZXJ2YWxEZWxheSA9IDEwMDtcclxuXHR2YXIgaW5jcmVtZW50SW50ZXJ2YWxBbW91bnQgPSAwLjE7XHJcblx0dmFyIGluY3JlbWVudEludGVydmFsTWF4dmFsID0gOTg7XHJcblx0cmV0dXJuIHdpbmRvdy5zZXRJbnRlcnZhbChcclxuXHRcdGluY3JlbWVudFByb2dyZXNzLFxyXG5cdFx0aW5jcmVtZW50SW50ZXJ2YWxEZWxheSxcclxuXHRcdGluY3JlbWVudEludGVydmFsQW1vdW50LFxyXG5cdFx0aW5jcmVtZW50SW50ZXJ2YWxNYXh2YWxcclxuXHQpO1xyXG59OyAqL1xyXG5cclxudmFyIExvYWREaWFsb2cgPSBmdW5jdGlvbiBMb2FkRGlhbG9nKCBjb25maWcgKSB7XHJcblx0TG9hZERpYWxvZy5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxufTtcclxuT08uaW5oZXJpdENsYXNzKCBMb2FkRGlhbG9nLCBPTy51aS5EaWFsb2cgKTsgXHJcblxyXG5Mb2FkRGlhbG9nLnN0YXRpYy5uYW1lID0gXCJsb2FkRGlhbG9nXCI7XHJcbkxvYWREaWFsb2cuc3RhdGljLnRpdGxlID0gXCJMb2FkaW5nIFJhdGVyLi4uXCI7XHJcblxyXG4vLyBDdXN0b21pemUgdGhlIGluaXRpYWxpemUoKSBmdW5jdGlvbjogVGhpcyBpcyB3aGVyZSB0byBhZGQgY29udGVudCB0byB0aGUgZGlhbG9nIGJvZHkgYW5kIHNldCB1cCBldmVudCBoYW5kbGVycy5cclxuTG9hZERpYWxvZy5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuXHQvLyBDYWxsIHRoZSBwYXJlbnQgbWV0aG9kLlxyXG5cdExvYWREaWFsb2cuc3VwZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCggdGhpcyApO1xyXG5cdC8vIENyZWF0ZSBhIGxheW91dFxyXG5cdHRoaXMuY29udGVudCA9IG5ldyBPTy51aS5QYW5lbExheW91dCggeyBcclxuXHRcdHBhZGRlZDogdHJ1ZSxcclxuXHRcdGV4cGFuZGVkOiBmYWxzZSBcclxuXHR9ICk7XHJcblx0Ly8gQ3JlYXRlIGNvbnRlbnRcclxuXHR0aGlzLnByb2dyZXNzQmFyID0gbmV3IE9PLnVpLlByb2dyZXNzQmFyV2lkZ2V0KCB7XHJcblx0XHRwcm9ncmVzczogMVxyXG5cdH0gKTtcclxuXHR0aGlzLnNldHVwdGFza3MgPSBbXHJcblx0XHRuZXcgT08udWkuTGFiZWxXaWRnZXQoIHtcclxuXHRcdFx0bGFiZWw6IFwiTG9hZGluZyB5b3VyIFJhdGVyIHByZWZlcmVuY2VzLi4uXCIsXHJcblx0XHRcdCRlbGVtZW50OiAkKFwiPHAgc3R5bGU9XFxcImRpc3BsYXk6YmxvY2tcXFwiPlwiKVxyXG5cdFx0fSksXHJcblx0XHRuZXcgT08udWkuTGFiZWxXaWRnZXQoIHtcclxuXHRcdFx0bGFiZWw6IFwiTG9hZGluZyBsaXN0IG9mIHByb2plY3QgYmFubmVycy4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIkxvYWRpbmcgdGFsa3BhZ2Ugd2lraXRleHQuLi5cIixcclxuXHRcdFx0JGVsZW1lbnQ6ICQoXCI8cCBzdHlsZT1cXFwiZGlzcGxheTpibG9ja1xcXCI+XCIpXHJcblx0XHR9KSxcclxuXHRcdG5ldyBPTy51aS5MYWJlbFdpZGdldCgge1xyXG5cdFx0XHRsYWJlbDogXCJQYXJzaW5nIHRhbGtwYWdlIHRlbXBsYXRlcy4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIkdldHRpbmcgdGVtcGxhdGVzJyBwYXJhbWV0ZXIgZGF0YS4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIkNoZWNraW5nIHN1YmplY3QgcGFnZS4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIlJldHJpZXZpbmcgcXVhbGl0eSBwcmVkaWN0aW9uLi4uXCIsXHJcblx0XHRcdCRlbGVtZW50OiAkKFwiPHAgc3R5bGU9XFxcImRpc3BsYXk6YmxvY2tcXFwiPlwiKVxyXG5cdFx0fSkudG9nZ2xlKCksXHJcblx0XTtcclxuXHR0aGlzLmNsb3NlQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCgge1xyXG5cdFx0bGFiZWw6IFwiQ2xvc2VcIlxyXG5cdH0pLnRvZ2dsZSgpO1xyXG5cdHRoaXMuc2V0dXBQcm9taXNlcyA9IFtdO1xyXG5cclxuXHQvLyBBcHBlbmQgY29udGVudCB0byBsYXlvdXRcclxuXHR0aGlzLmNvbnRlbnQuJGVsZW1lbnQuYXBwZW5kKFxyXG5cdFx0dGhpcy5wcm9ncmVzc0Jhci4kZWxlbWVudCxcclxuXHRcdChuZXcgT08udWkuTGFiZWxXaWRnZXQoIHtcclxuXHRcdFx0bGFiZWw6IFwiSW5pdGlhbGlzaW5nOlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxzdHJvbmcgc3R5bGU9XFxcImRpc3BsYXk6YmxvY2tcXFwiPlwiKVxyXG5cdFx0fSkpLiRlbGVtZW50LFxyXG5cdFx0Li4udGhpcy5zZXR1cHRhc2tzLm1hcCh3aWRnZXQgPT4gd2lkZ2V0LiRlbGVtZW50KSxcclxuXHRcdHRoaXMuY2xvc2VCdXR0b24uJGVsZW1lbnRcclxuXHQpO1xyXG5cclxuXHQvLyBBcHBlbmQgbGF5b3V0IHRvIGRpYWxvZ1xyXG5cdHRoaXMuJGJvZHkuYXBwZW5kKCB0aGlzLmNvbnRlbnQuJGVsZW1lbnQgKTtcclxuXHJcblx0Ly8gQ29ubmVjdCBldmVudHMgdG8gaGFuZGxlcnNcclxuXHR0aGlzLmNsb3NlQnV0dG9uLmNvbm5lY3QoIHRoaXMsIHsgXCJjbGlja1wiOiBcIm9uQ2xvc2VCdXR0b25DbGlja1wiIH0gKTtcclxufTtcclxuXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLm9uQ2xvc2VCdXR0b25DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdC8vIENsb3NlIHRoaXMgZGlhbG9nLCB3aXRob3V0IHBhc3NpbmcgYW55IGRhdGFcclxuXHR0aGlzLmNsb3NlKCk7XHJcbn07XHJcblxyXG4vLyBPdmVycmlkZSB0aGUgZ2V0Qm9keUhlaWdodCgpIG1ldGhvZCB0byBzcGVjaWZ5IGEgY3VzdG9tIGhlaWdodCAob3IgZG9uJ3QgdG8gdXNlIHRoZSBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBoZWlnaHQpLlxyXG5Mb2FkRGlhbG9nLnByb3RvdHlwZS5nZXRCb2R5SGVpZ2h0ID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiB0aGlzLmNvbnRlbnQuJGVsZW1lbnQub3V0ZXJIZWlnaHQoIHRydWUgKTtcclxufTtcclxuXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLmluY3JlbWVudFByb2dyZXNzID0gZnVuY3Rpb24oYW1vdW50LCBtYXhpbXVtKSB7XHJcblx0dmFyIHByaW9yUHJvZ3Jlc3MgPSB0aGlzLnByb2dyZXNzQmFyLmdldFByb2dyZXNzKCk7XHJcblx0dmFyIGluY3JlbWVudGVkUHJvZ3Jlc3MgPSBNYXRoLm1pbihtYXhpbXVtIHx8IDEwMCwgcHJpb3JQcm9ncmVzcyArIGFtb3VudCk7XHJcblx0dGhpcy5wcm9ncmVzc0Jhci5zZXRQcm9ncmVzcyhpbmNyZW1lbnRlZFByb2dyZXNzKTtcclxufTtcclxuXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLmFkZFRhc2tQcm9taXNlSGFuZGxlcnMgPSBmdW5jdGlvbih0YXNrUHJvbWlzZXMpIHtcclxuXHR2YXIgb25UYXNrRG9uZSA9IGluZGV4ID0+IHtcclxuXHRcdC8vIEFkZCBcIkRvbmUhXCIgdG8gbGFiZWxcclxuXHRcdHZhciB3aWRnZXQgPSB0aGlzLnNldHVwdGFza3NbaW5kZXhdO1xyXG5cdFx0d2lkZ2V0LnNldExhYmVsKHdpZGdldC5nZXRMYWJlbCgpICsgXCIgRG9uZSFcIik7XHJcblx0XHQvLyBJbmNyZW1lbnQgc3RhdHVzIGJhci4gU2hvdyBhIHNtb290aCB0cmFuc2l0aW9uIGJ5XHJcblx0XHQvLyB1c2luZyBzbWFsbCBzdGVwcyBvdmVyIGEgc2hvcnQgZHVyYXRpb24uXHJcblx0XHR2YXIgdG90YWxJbmNyZW1lbnQgPSAxMDAgLyB0aGlzLnNldHVwdGFza3MubGVuZ3RoOyAvLyBwZXJjZW50XHJcblx0XHR2YXIgdG90YWxUaW1lID0gNDAwOyAvLyBtaWxsaXNlY29uZHNcclxuXHRcdHZhciB0b3RhbFN0ZXBzID0gMTA7XHJcblx0XHR2YXIgaW5jcmVtZW50UGVyU3RlcCA9IHRvdGFsSW5jcmVtZW50IC8gdG90YWxTdGVwcztcclxuXHJcblx0XHRmb3IgKCB2YXIgc3RlcD0wOyBzdGVwIDwgdG90YWxTdGVwczsgc3RlcCsrKSB7XHJcblx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KFxyXG5cdFx0XHRcdHRoaXMuaW5jcmVtZW50UHJvZ3Jlc3MuYmluZCh0aGlzKSxcclxuXHRcdFx0XHR0b3RhbFRpbWUgKiBzdGVwIC8gdG90YWxTdGVwcyxcclxuXHRcdFx0XHRpbmNyZW1lbnRQZXJTdGVwXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblx0fTtcclxuXHR2YXIgb25UYXNrRXJyb3IgPSAoaW5kZXgsIGNvZGUsIGluZm8pID0+IHtcclxuXHRcdHZhciB3aWRnZXQgPSB0aGlzLnNldHVwdGFza3NbaW5kZXhdO1xyXG5cdFx0d2lkZ2V0LnNldExhYmVsKFxyXG5cdFx0XHR3aWRnZXQuZ2V0TGFiZWwoKSArIFwiIEZhaWxlZC4gXCIgKyBtYWtlRXJyb3JNc2coY29kZSwgaW5mbylcclxuXHRcdCk7XHJcblx0XHR0aGlzLmNsb3NlQnV0dG9uLnRvZ2dsZSh0cnVlKTtcclxuXHRcdHRoaXMudXBkYXRlU2l6ZSgpO1xyXG5cdH07XHJcblx0dGFza1Byb21pc2VzLmZvckVhY2goZnVuY3Rpb24ocHJvbWlzZSwgaW5kZXgpIHtcclxuXHRcdHByb21pc2UudGhlbihcclxuXHRcdFx0KCkgPT4gb25UYXNrRG9uZShpbmRleCksXHJcblx0XHRcdChjb2RlLCBpbmZvKSA9PiBvblRhc2tFcnJvcihpbmRleCwgY29kZSwgaW5mbylcclxuXHRcdCk7XHJcblx0fSk7XHJcbn07XHJcblxyXG4vLyBVc2UgZ2V0U2V0dXBQcm9jZXNzKCkgdG8gc2V0IHVwIHRoZSB3aW5kb3cgd2l0aCBkYXRhIHBhc3NlZCB0byBpdCBhdCB0aGUgdGltZSBcclxuLy8gb2Ygb3BlbmluZ1xyXG5Mb2FkRGlhbG9nLnByb3RvdHlwZS5nZXRTZXR1cFByb2Nlc3MgPSBmdW5jdGlvbiAoIGRhdGEgKSB7XHJcblx0ZGF0YSA9IGRhdGEgfHwge307XHJcblx0cmV0dXJuIExvYWREaWFsb2cuc3VwZXIucHJvdG90eXBlLmdldFNldHVwUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdC5uZXh0KCAoKSA9PiB7XHJcblx0XHRcdHZhciBzaG93T3Jlc1Rhc2sgPSAhIWRhdGEub3JlcztcclxuXHRcdFx0dGhpcy5zZXR1cHRhc2tzWzZdLnRvZ2dsZShzaG93T3Jlc1Rhc2spO1xyXG5cdFx0XHR2YXIgdGFza1Byb21pc2VzID0gZGF0YS5vcmVzID8gZGF0YS5wcm9taXNlcyA6IGRhdGEucHJvbWlzZXMuc2xpY2UoMCwgLTEpO1xyXG5cdFx0XHRkYXRhLmlzT3BlbmVkLnRoZW4oKCkgPT4gdGhpcy5hZGRUYXNrUHJvbWlzZUhhbmRsZXJzKHRhc2tQcm9taXNlcykpO1xyXG5cdFx0fSwgdGhpcyApO1xyXG59O1xyXG5cclxuLy8gUHJldmVudCB3aW5kb3cgZnJvbSBjbG9zaW5nIHRvbyBxdWlja2x5LCB1c2luZyBnZXRIb2xkUHJvY2VzcygpXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLmdldEhvbGRQcm9jZXNzID0gZnVuY3Rpb24gKCBkYXRhICkge1xyXG5cdGRhdGEgPSBkYXRhIHx8IHt9O1xyXG5cdGlmIChkYXRhLnN1Y2Nlc3MpIHtcclxuXHRcdC8vIFdhaXQgYSBiaXQgYmVmb3JlIHByb2Nlc3NpbmcgdGhlIGNsb3NlLCB3aGljaCBoYXBwZW5zIGF1dG9tYXRpY2FsbHlcclxuXHRcdHJldHVybiBMb2FkRGlhbG9nLnN1cGVyLnByb3RvdHlwZS5nZXRIb2xkUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdFx0Lm5leHQoODAwKTtcclxuXHR9XHJcblx0Ly8gTm8gbmVlZCB0byB3YWl0IGlmIGNsb3NlZCBtYW51YWxseVxyXG5cdHJldHVybiBMb2FkRGlhbG9nLnN1cGVyLnByb3RvdHlwZS5nZXRIb2xkUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhICk7XHJcbn07XHJcblxyXG4vLyBVc2UgdGhlIGdldFRlYXJkb3duUHJvY2VzcygpIG1ldGhvZCB0byBwZXJmb3JtIGFjdGlvbnMgd2hlbmV2ZXIgdGhlIGRpYWxvZyBpcyBjbG9zZWQuIFxyXG5Mb2FkRGlhbG9nLnByb3RvdHlwZS5nZXRUZWFyZG93blByb2Nlc3MgPSBmdW5jdGlvbiAoIGRhdGEgKSB7XHJcblx0cmV0dXJuIExvYWREaWFsb2cuc3VwZXIucHJvdG90eXBlLmdldFRlYXJkb3duUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdC5maXJzdCggKCkgPT4ge1xyXG5cdFx0Ly8gUGVyZm9ybSBjbGVhbnVwOiByZXNldCBsYWJlbHNcclxuXHRcdFx0dGhpcy5zZXR1cHRhc2tzLmZvckVhY2goIHNldHVwdGFzayA9PiB7XHJcblx0XHRcdFx0dmFyIGN1cnJlbnRMYWJlbCA9IHNldHVwdGFzay5nZXRMYWJlbCgpO1xyXG5cdFx0XHRcdHNldHVwdGFzay5zZXRMYWJlbChcclxuXHRcdFx0XHRcdGN1cnJlbnRMYWJlbC5zbGljZSgwLCBjdXJyZW50TGFiZWwuaW5kZXhPZihcIi4uLlwiKSszKVxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH0gKTtcclxuXHRcdH0sIHRoaXMgKTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IExvYWREaWFsb2c7XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCBCYW5uZXJXaWRnZXQgZnJvbSBcIi4vQ29tcG9uZW50cy9CYW5uZXJXaWRnZXRcIjtcclxuaW1wb3J0IEJhbm5lckxpc3RXaWRnZXQgZnJvbSBcIi4vQ29tcG9uZW50cy9CYW5uZXJMaXN0V2lkZ2V0XCI7XHJcbmltcG9ydCBhcHBDb25maWcgZnJvbSBcIi4uL2NvbmZpZ1wiO1xyXG5pbXBvcnQgQVBJLCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuLi9hcGlcIjtcclxuaW1wb3J0IFByZWZzRm9ybVdpZGdldCBmcm9tIFwiLi9Db21wb25lbnRzL1ByZWZzRm9ybVdpZGdldFwiO1xyXG5pbXBvcnQgeyBzZXRQcmVmcyBhcyBBcGlTZXRQcmVmcyB9IGZyb20gXCIuLi9wcmVmc1wiO1xyXG5pbXBvcnQgeyBwYXJzZVRlbXBsYXRlcyB9IGZyb20gXCIuLi9UZW1wbGF0ZVwiO1xyXG5pbXBvcnQgVG9wQmFyV2lkZ2V0IGZyb20gXCIuL0NvbXBvbmVudHMvVG9wQmFyV2lkZ2V0XCI7XHJcbmltcG9ydCB7IGZpbHRlckFuZE1hcCwgdW5pcXVlQXJyYXkgfSBmcm9tIFwiLi4vdXRpbFwiO1xyXG5pbXBvcnQgKiBhcyBjYWNoZSBmcm9tIFwiLi4vY2FjaGVcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbmZ1bmN0aW9uIE1haW5XaW5kb3coIGNvbmZpZyApIHtcclxuXHRNYWluV2luZG93LnN1cGVyLmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggTWFpbldpbmRvdywgT08udWkuUHJvY2Vzc0RpYWxvZyApO1xyXG5cclxuTWFpbldpbmRvdy5zdGF0aWMubmFtZSA9IFwibWFpblwiO1xyXG5NYWluV2luZG93LnN0YXRpYy50aXRsZSA9ICQoXCI8c3Bhbj5cIikuY3NzKHtcImZvbnQtd2VpZ2h0XCI6XCJub3JtYWxcIn0pLmFwcGVuZChcclxuXHQkKFwiPGE+XCIpLmNzcyh7XCJmb250LXdlaWdodFwiOiBcImJvbGRcIn0pLmF0dHIoe1wiaHJlZlwiOiBtdy51dGlsLmdldFVybChcIldQOlJBVEVSXCIpLCBcInRhcmdldFwiOiBcIl9ibGFua1wifSkudGV4dChcIlJhdGVyXCIpLFxyXG5cdFwiIChcIixcclxuXHQkKFwiPGE+XCIpLmF0dHIoe1wiaHJlZlwiOiBtdy51dGlsLmdldFVybChcIldUOlJBVEVSXCIpLCBcInRhcmdldFwiOiBcIl9ibGFua1wifSkudGV4dChcInRhbGtcIiksXHJcblx0XCIpIFwiLFxyXG5cdCQoXCI8c3Bhbj5cIikuY3NzKHtcImZvbnQtc2l6ZVwiOlwiOTAlXCJ9KS50ZXh0KFwidlwiK2FwcENvbmZpZy5zY3JpcHQudmVyc2lvbilcclxuKTtcclxuTWFpbldpbmRvdy5zdGF0aWMuc2l6ZSA9IFwibGFyZ2VcIjtcclxuTWFpbldpbmRvdy5zdGF0aWMuYWN0aW9ucyA9IFtcclxuXHQvLyBQcmltYXJ5ICh0b3AgcmlnaHQpOlxyXG5cdHtcclxuXHRcdGxhYmVsOiBcIlhcIiwgLy8gbm90IHVzaW5nIGFuIGljb24gc2luY2UgY29sb3IgYmVjb21lcyBpbnZlcnRlZCwgaS5lLiB3aGl0ZSBvbiBsaWdodC1ncmV5XHJcblx0XHR0aXRsZTogXCJDbG9zZSAoYW5kIGRpc2NhcmQgYW55IGNoYW5nZXMpXCIsXHJcblx0XHRmbGFnczogXCJwcmltYXJ5XCIsXHJcblx0XHRtb2RlczogW1wiZWRpdFwiLCBcImRpZmZcIiwgXCJwcmV2aWV3XCJdIC8vIGF2YWlsYWJsZSB3aGVuIGN1cnJlbnQgbW9kZSBpc24ndCBcInByZWZzXCJcclxuXHR9LFxyXG5cdC8vIFNhZmUgKHRvcCBsZWZ0KVxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJzaG93UHJlZnNcIixcclxuXHRcdGZsYWdzOiBcInNhZmVcIixcclxuXHRcdGljb246IFwic2V0dGluZ3NcIixcclxuXHRcdHRpdGxlOiBcIlByZWZlcmVuY2VzXCIsXHJcblx0XHRtb2RlczogW1wiZWRpdFwiLCBcImRpZmZcIiwgXCJwcmV2aWV3XCJdIC8vIGF2YWlsYWJsZSB3aGVuIGN1cnJlbnQgbW9kZSBpc24ndCBcInByZWZzXCJcclxuXHR9LFxyXG5cdC8vIE90aGVycyAoYm90dG9tKVxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJzYXZlXCIsXHJcblx0XHRhY2Nlc3NLZXk6IFwic1wiLFxyXG5cdFx0bGFiZWw6IG5ldyBPTy51aS5IdG1sU25pcHBldChcIjxzcGFuIHN0eWxlPSdwYWRkaW5nOjAgMWVtOyc+U2F2ZTwvc3Bhbj5cIiksXHJcblx0XHRmbGFnczogW1wicHJpbWFyeVwiLCBcInByb2dyZXNzaXZlXCJdLFxyXG5cdFx0bW9kZXM6IFtcImVkaXRcIiwgXCJkaWZmXCIsIFwicHJldmlld1wiXSAvLyBhdmFpbGFibGUgd2hlbiBjdXJyZW50IG1vZGUgaXNuJ3QgXCJwcmVmc1wiXHJcblx0fSxcclxuXHR7XHJcblx0XHRhY3Rpb246IFwicHJldmlld1wiLFxyXG5cdFx0YWNjZXNzS2V5OiBcInBcIixcclxuXHRcdGxhYmVsOiBcIlNob3cgcHJldmlld1wiLFxyXG5cdFx0bW9kZXM6IFtcImVkaXRcIiwgXCJkaWZmXCJdIC8vIGF2YWlsYWJsZSB3aGVuIGN1cnJlbnQgbW9kZSBpc24ndCBcInByZXZpZXdcIiBvciBcInByZWZzXCJcclxuXHR9LFxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJjaGFuZ2VzXCIsXHJcblx0XHRhY2Nlc3NLZXk6IFwidlwiLFxyXG5cdFx0bGFiZWw6IFwiU2hvdyBjaGFuZ2VzXCIsXHJcblx0XHRtb2RlczogW1wiZWRpdFwiLCBcInByZXZpZXdcIl0gLy8gYXZhaWxhYmxlIHdoZW4gY3VycmVudCBtb2RlIGlzbid0IFwiZGlmZlwiIG9yIFwicHJlZnNcIlxyXG5cdH0sXHJcblx0e1xyXG5cdFx0YWN0aW9uOiBcImJhY2tcIixcclxuXHRcdGxhYmVsOiBcIkJhY2tcIixcclxuXHRcdG1vZGVzOiBbXCJkaWZmXCIsIFwicHJldmlld1wiXSAvLyBhdmFpbGFibGUgd2hlbiBjdXJyZW50IG1vZGUgaXMgXCJkaWZmXCIgb3IgXCJwcmVmc1wiXHJcblx0fSxcclxuXHRcclxuXHQvLyBcInByZWZzXCIgbW9kZSBvbmx5XHJcblx0e1xyXG5cdFx0YWN0aW9uOiBcInNhdmVQcmVmc1wiLFxyXG5cdFx0bGFiZWw6IFwiVXBkYXRlXCIsXHJcblx0XHRmbGFnczogW1wicHJpbWFyeVwiLCBcInByb2dyZXNzaXZlXCJdLFxyXG5cdFx0bW9kZXM6IFwicHJlZnNcIiBcclxuXHR9LFxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJjbG9zZVByZWZzXCIsXHJcblx0XHRsYWJlbDogXCJDYW5jZWxcIixcclxuXHRcdGZsYWdzOiBcInNhZmVcIixcclxuXHRcdG1vZGVzOiBcInByZWZzXCJcclxuXHR9XHJcbl07XHJcblxyXG4vLyBDdXN0b21pemUgdGhlIGluaXRpYWxpemUoKSBmdW5jdGlvbjogVGhpcyBpcyB3aGVyZSB0byBhZGQgY29udGVudCB0byB0aGUgZGlhbG9nIGJvZHkgYW5kIHNldCB1cCBldmVudCBoYW5kbGVycy5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuXHQvLyBDYWxsIHRoZSBwYXJlbnQgbWV0aG9kLlxyXG5cdE1haW5XaW5kb3cuc3VwZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCggdGhpcyApO1xyXG5cclxuXHQvKiAtLS0gUFJFRlMgLS0tICovXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IGFwcENvbmZpZy5kZWZhdWx0UHJlZnM7XHJcblx0XHJcblx0LyogLS0tIFRPUCBCQVIgLS0tICovXHJcblx0dGhpcy50b3BCYXIgPSBuZXcgVG9wQmFyV2lkZ2V0KHtcclxuXHRcdCRvdmVybGF5OiB0aGlzLiRvdmVybGF5XHJcblx0fSApO1xyXG5cdHRoaXMuJGhlYWQuY3NzKHtcImhlaWdodFwiOlwiNzNweFwifSkuYXBwZW5kKHRoaXMudG9wQmFyLiRlbGVtZW50KTtcclxuXHJcblx0LyogLS0tIEZPT1RFUiAtLS0gKi9cclxuXHR0aGlzLm9yZXNMYWJlbCA9IG5ldyBPTy51aS5MYWJlbFdpZGdldCh7XHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPSdmbG9hdDpyaWdodDsgcGFkZGluZzogMTBweDsgbWF4LXdpZHRoOiA1MCU7IHRleHQtYWxpZ246IGNlbnRlcjsnPlwiKSxcclxuXHRcdGxhYmVsOiAkKFwiPHNwYW4+XCIpLmFwcGVuZChcclxuXHRcdFx0JChcIjxhPlwiKVxyXG5cdFx0XHRcdC5hdHRyKHtcImhyZWZcIjptdy51dGlsLmdldFVybChcIm13Ok9SRVNcIiksIFwidGFyZ2V0XCI6XCJfYmxhbmtcIn0pXHJcblx0XHRcdFx0LmFwcGVuZChcclxuXHRcdFx0XHRcdCQoXCI8aW1nPlwiKVxyXG5cdFx0XHRcdFx0XHQuY3NzKHtcInZlcnRpY2FsLWFsaWduXCI6IFwidGV4dC1ib3R0b207XCJ9KVxyXG5cdFx0XHRcdFx0XHQuYXR0cih7XHJcblx0XHRcdFx0XHRcdFx0XCJzcmNcIjogXCIvL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzUvNTEvT2JqZWN0aXZlX1JldmlzaW9uX0V2YWx1YXRpb25fU2VydmljZV9sb2dvLnN2Zy80MHB4LU9iamVjdGl2ZV9SZXZpc2lvbl9FdmFsdWF0aW9uX1NlcnZpY2VfbG9nby5zdmcucG5nXCIsXHJcblx0XHRcdFx0XHRcdFx0XCJ0aXRsZVwiOiBcIk1hY2hpbmUgcHJlZGljdGVkIHF1YWxpdHkgZnJvbSBPUkVTXCIsXHJcblx0XHRcdFx0XHRcdFx0XCJhbHRcIjogXCJPUkVTIGxvZ29cIixcclxuXHRcdFx0XHRcdFx0XHRcIndpZHRoXCI6IFwiMjBweFwiLFxyXG5cdFx0XHRcdFx0XHRcdFwiaGVpZ2h0XCI6IFwiMjBweFwiXHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KSxcclxuXHRcdFx0XCIgXCIsXHJcblx0XHRcdCQoXCI8c3BhbiBjbGFzcz0nb3Jlc1ByZWRpY3Rpb24nPlwiKVxyXG5cdFx0KVxyXG5cdH0pLnRvZ2dsZShmYWxzZSk7XHJcblx0dGhpcy5wYWdldHlwZUxhYmVsID0gbmV3IE9PLnVpLkxhYmVsV2lkZ2V0KHtcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J2Zsb2F0OnJpZ2h0OyBwYWRkaW5nOiAxMHB4OyBtYXgtd2lkdGg6IDMzLjMzJTsgdGV4dC1hbGlnbjogY2VudGVyOyc+XCIpXHJcblx0fSkudG9nZ2xlKGZhbHNlKTtcclxuXHR0aGlzLiRmb290LnByZXBlbmQodGhpcy5vcmVzTGFiZWwuJGVsZW1lbnQsIHRoaXMucGFnZXR5cGVMYWJlbC4kZWxlbWVudCk7XHJcblxyXG5cdC8qIC0tLSBDT05URU5UIEFSRUEgLS0tICovXHJcblxyXG5cdC8vIEJhbm5lcnMgYWRkZWQgZHluYW1pY2FsbHkgdXBvbiBvcGVuaW5nLCBzbyBqdXN0IG5lZWQgYSBsYXlvdXQgd2l0aCBhbiBlbXB0eSBsaXN0XHJcblx0dGhpcy5iYW5uZXJMaXN0ID0gbmV3IEJhbm5lckxpc3RXaWRnZXQoe1xyXG5cdFx0cHJlZmVyZW5jZXM6IHRoaXMucHJlZmVyZW5jZXNcclxuXHR9KTtcclxuXHR0aGlzLmVkaXRMYXlvdXQgPSBuZXcgT08udWkuUGFuZWxMYXlvdXQoIHtcclxuXHRcdHBhZGRlZDogZmFsc2UsXHJcblx0XHRleHBhbmRlZDogZmFsc2UsXHJcblx0XHQkY29udGVudDogdGhpcy5iYW5uZXJMaXN0LiRlbGVtZW50XHJcblx0fSApO1xyXG5cclxuXHQvLyBQcmVmZXJlbmNlcywgZmlsbGVkIGluIHdpdGggY3VycmVudCBwcmVmcyB1cG9uIGxvYWRpbmcuXHJcblx0Ly8gVE9ETzogTWFrZSB0aGlzIGludG8gYSBjb21wb25lbnQsIGFkZCBmaWVsZHMgYW5kIGlucHV0c1xyXG5cdHRoaXMucHJlZnNGb3JtID0gbmV3IFByZWZzRm9ybVdpZGdldCgpO1xyXG5cdHRoaXMucHJlZnNMYXlvdXQgPSBuZXcgT08udWkuUGFuZWxMYXlvdXQoIHtcclxuXHRcdHBhZGRlZDogdHJ1ZSxcclxuXHRcdGV4cGFuZGVkOiBmYWxzZSxcclxuXHRcdCRjb250ZW50OiB0aGlzLnByZWZzRm9ybS4kZWxlbWVudFxyXG5cdH0gKTtcclxuXHJcblx0Ly8gUHJldmlldywgU2hvdyBjaGFuZ2VzXHJcblx0dGhpcy5wYXJzZWRDb250ZW50Q29udGFpbmVyID0gbmV3IE9PLnVpLkZpZWxkc2V0TGF5b3V0KCB7XHJcblx0XHRsYWJlbDogXCJQcmV2aWV3XCJcclxuXHR9ICk7XHJcblx0dGhpcy5wYXJzZWRDb250ZW50V2lkZ2V0ID0gbmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7bGFiZWw6IFwiXCIsXHQkZWxlbWVudDokKFwiPGRpdj5cIilcdH0pO1xyXG5cdHRoaXMucGFyc2VkQ29udGVudENvbnRhaW5lci5hZGRJdGVtcyhbXHJcblx0XHRuZXcgT08udWkuRmllbGRMYXlvdXQoXHJcblx0XHRcdHRoaXMucGFyc2VkQ29udGVudFdpZGdldCxcdFx0XHRcclxuXHRcdFx0eyBhbGlnbjogXCJ0b3BcIiB9XHJcblx0XHQpXHJcblx0XSk7XHJcblx0dGhpcy5wYXJzZWRDb250ZW50TGF5b3V0ID0gbmV3IE9PLnVpLlBhbmVsTGF5b3V0KCB7XHJcblx0XHRwYWRkZWQ6IHRydWUsXHJcblx0XHRleHBhbmRlZDogZmFsc2UsXHJcblx0XHQkY29udGVudDogdGhpcy5wYXJzZWRDb250ZW50Q29udGFpbmVyLiRlbGVtZW50XHJcblx0fSApO1xyXG5cclxuXHR0aGlzLmNvbnRlbnRBcmVhID0gbmV3IE9PLnVpLlN0YWNrTGF5b3V0KCB7XHJcblx0XHRpdGVtczogW1xyXG5cdFx0XHR0aGlzLmVkaXRMYXlvdXQsXHJcblx0XHRcdHRoaXMucHJlZnNMYXlvdXQsXHJcblx0XHRcdHRoaXMucGFyc2VkQ29udGVudExheW91dFxyXG5cdFx0XSxcclxuXHRcdHBhZGRlZDogZmFsc2UsXHJcblx0XHRleHBhbmRlZDogZmFsc2VcclxuXHR9ICk7XHJcblxyXG5cdHRoaXMuJGJvZHkuY3NzKHtcInRvcFwiOlwiNzNweFwifSkuYXBwZW5kKHRoaXMuY29udGVudEFyZWEuJGVsZW1lbnQpO1xyXG5cclxuXHQvKiAtLS0gRVZFTlQgSEFORExJTkcgLS0tICovXHJcblxyXG5cdHRoaXMudG9wQmFyLmNvbm5lY3QodGhpcywge1xyXG5cdFx0XCJzZWFyY2hTZWxlY3RcIjogXCJvblNlYXJjaFNlbGVjdFwiLFxyXG5cdFx0XCJzZXRDbGFzc2VzXCI6IFwib25TZXRDbGFzc2VzXCIsXHJcblx0XHRcInNldEltcG9ydGFuY2VzXCI6IFwib25TZXRJbXBvcnRhbmNlc1wiLFxyXG5cdFx0XCJyZW1vdmVBbGxcIjogXCJvblJlbW92ZUFsbFwiLFxyXG5cdFx0XCJjbGVhckFsbFwiOiBcIm9uQ2xlYXJBbGxcIlxyXG5cdH0pO1xyXG5cdHRoaXMuYmFubmVyTGlzdC5jb25uZWN0KHRoaXMsIHtcInVwZGF0ZWRTaXplXCI6IFwib25CYW5uZXJMaXN0VXBkYXRlU2l6ZVwifSk7XHJcblxyXG5cdC8vIEhhbmRsZSBjZXJ0YWluIGtleWJvYXJkIGV2ZW50cy4gUmVxdWlyZXMgc29tZXRoaW5nIGluIHRoZSBSYXRlciB3aW5kb3cgdG8gYmUgZm9jdXNlZCxcclxuXHQvLyBzbyBhZGQgYSB0YWJpbmRleCB0byB0aGUgYm9keSBhbmQgaXQncyBwYXJlbnQgY29udGFpbmVyLlxyXG5cdHRoaXMuJGJvZHkuYXR0cihcInRhYmluZGV4XCIsIFwiOTk5XCIpXHJcblx0XHQucGFyZW50KCkuYXR0cihcInRhYmluZGV4XCIsIFwiOTk5XCIpLmtleWRvd24oZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cdFx0XHRsZXQgc2Nyb2xsQW1vdW50O1xyXG5cdFx0XHRzd2l0Y2goZXZlbnQud2hpY2gpIHtcclxuXHRcdFx0Y2FzZSAzMzogLy8gcGFnZSB1cFxyXG5cdFx0XHRcdHNjcm9sbEFtb3VudCA9IHRoaXMuJGJvZHkuc2Nyb2xsVG9wKCkgLSB0aGlzLiRib2R5LmhlaWdodCgpKjAuOTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0Y2FzZSAzNDogLy8gcGFnZSBkb3duXHJcblx0XHRcdFx0c2Nyb2xsQW1vdW50ID0gdGhpcy4kYm9keS5zY3JvbGxUb3AoKSArIHRoaXMuJGJvZHkuaGVpZ2h0KCkqMC45O1xyXG5cdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRkZWZhdWx0OlxyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLiRib2R5LnNjcm9sbFRvcChzY3JvbGxBbW91bnQpO1xyXG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0fS5iaW5kKHRoaXMpKTtcclxuXHJcblx0dGhpcy5wcmVmc0Zvcm0uY29ubmVjdCh0aGlzLCB7XCJyZXNldENhY2hlXCI6IFwib25SZXNldENhY2hlXCJ9KTtcclxuXHRcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uQmFubmVyTGlzdFVwZGF0ZVNpemUgPSBmdW5jdGlvbigpIHtcclxuXHQvLyBHZXQgdGhlIGN1cnJlbnQgc2Nyb2xsIGFtb3VudFxyXG5cdGNvbnN0IHNjcm9sbEFtb3VudCA9IHRoaXMuJGJvZHkuc2Nyb2xsVG9wKCk7XHJcblx0Ly8gVXBkYXRlIHNpemUgKHdoaWNoIHJlc2V0cyB0aGUgc2Nyb2xsIHRvIDApXHJcblx0dGhpcy51cGRhdGVTaXplKCk7XHJcblx0Ly8gU2Nyb2xsIHRvIHdoZXJlIGl0IHdhcyBiZWZvcmVcclxuXHR0aGlzLiRib2R5LnNjcm9sbFRvcChzY3JvbGxBbW91bnQpO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUubWFrZURyYWdnYWJsZSA9IGZ1bmN0aW9uKCkge1xyXG5cdGxldCAkZnJhbWVFbCA9IHRoaXMuJGVsZW1lbnQuZmluZChcIi5vby11aS13aW5kb3ctZnJhbWVcIik7XHJcblx0bGV0ICRoYW5kbGVFbCA9IHRoaXMuJGVsZW1lbnQuZmluZChcIi5vby11aS1wcm9jZXNzRGlhbG9nLWxvY2F0aW9uXCIpLmNzcyh7XCJjdXJzb3JcIjpcIm1vdmVcIn0pO1xyXG5cdC8vIFBvc2l0aW9uIGZvciBjc3MgdHJhbnNsYXRlIHRyYW5zZm9ybWF0aW9ucywgcmVsYXRpdmUgdG8gaW5pdGlhbCBwb3NpdGlvblxyXG5cdC8vICh3aGljaCBpcyBjZW50ZXJlZCBvbiB2aWV3cG9ydCB3aGVuIHNjcm9sbGVkIHRvIHRvcClcclxuXHRsZXQgcG9zaXRpb24gPSB7IHg6IDAsIHk6IDAgfTtcclxuXHRjb25zdCBjb25zdHJhaW4gPSBmdW5jdGlvbih2YWwsIG1pblZhbCwgbWF4VmFsKSB7XHJcblx0XHRpZiAodmFsIDwgbWluVmFsKSByZXR1cm4gbWluVmFsO1xyXG5cdFx0aWYgKHZhbCA+IG1heFZhbCkgcmV0dXJuIG1heFZhbDtcclxuXHRcdHJldHVybiB2YWw7XHJcblx0fTtcclxuXHRjb25zdCBjb25zdHJhaW5YID0gKHZhbCkgPT4ge1xyXG5cdFx0Ly8gRG9uJ3QgdG9vIGZhciBob3Jpem9udGFsbHkgKGxlYXZlIGF0IGxlYXN0IDEwMHB4IHZpc2libGUpXHJcblx0XHRsZXQgbGltaXQgPSB3aW5kb3cuaW5uZXJXaWR0aC8yICsgJGZyYW1lRWwub3V0ZXJXaWR0aCgpLzIgLSAxMDA7XHJcblx0XHRyZXR1cm4gY29uc3RyYWluKHZhbCwgLTEqbGltaXQsIGxpbWl0KTtcclxuXHR9O1xyXG5cdGNvbnN0IGNvbnN0cmFpblkgPSAodmFsKSA9PiB7XHJcblx0XHQvLyBDYW4ndCB0YWtlIHRpdGxlIGJhciBvZmYgdGhlIHZpZXdwb3J0LCBzaW5jZSBpdCdzIHRoZSBkcmFnIGhhbmRsZVxyXG5cdFx0bGV0IG1pbkxpbWl0ID0gLTEqKHdpbmRvdy5pbm5lckhlaWdodCAtICRmcmFtZUVsLm91dGVySGVpZ2h0KCkpLzI7XHJcblx0XHQvLyBEb24ndCBnbyB0b28gZmFyIGRvd24gdGhlIHBhZ2U6ICh3aG9sZSBwYWdlIGhlaWdodCkgLSAoaW5pdGlhbCBwb3NpdGlvbilcclxuXHRcdGxldCBtYXhMaW1pdCA9IChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnR8fGRvY3VtZW50KS5zY3JvbGxIZWlnaHQgLSB3aW5kb3cuaW5uZXJIZWlnaHQvMjtcclxuXHRcdHJldHVybiBjb25zdHJhaW4odmFsLCBtaW5MaW1pdCwgbWF4TGltaXQpO1xyXG5cdH07XHJcblxyXG5cdGxldCBwb2ludGVyZG93biA9IGZhbHNlO1xyXG5cdGxldCBkcmFnRnJvbSA9IHt9O1xyXG5cclxuXHRsZXQgb25EcmFnU3RhcnQgPSBldmVudCA9PiB7XHJcblx0XHRwb2ludGVyZG93biA9IHRydWU7XHJcblx0XHRkcmFnRnJvbS54ID0gZXZlbnQuY2xpZW50WDtcclxuXHRcdGRyYWdGcm9tLnkgPSBldmVudC5jbGllbnRZO1xyXG5cdH07XHJcblx0bGV0IG9uRHJhZ01vdmUgPSBldmVudCA9PiB7XHJcblx0XHRpZiAoIXBvaW50ZXJkb3duIHx8IGRyYWdGcm9tLnggPT0gbnVsbCB8fCBkcmFnRnJvbS55ID09PSBudWxsKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGR4ID0gZXZlbnQuY2xpZW50WCAtIGRyYWdGcm9tLng7XHJcblx0XHRjb25zdCBkeSA9IGV2ZW50LmNsaWVudFkgLSBkcmFnRnJvbS55O1xyXG5cdFx0ZHJhZ0Zyb20ueCA9IGV2ZW50LmNsaWVudFg7XHJcblx0XHRkcmFnRnJvbS55ID0gZXZlbnQuY2xpZW50WTtcclxuXHRcdHBvc2l0aW9uLnggPSBjb25zdHJhaW5YKHBvc2l0aW9uLnggKyBkeCk7XHJcblx0XHRwb3NpdGlvbi55ID0gY29uc3RyYWluWShwb3NpdGlvbi55ICsgZHkpO1xyXG5cdFx0JGZyYW1lRWwuY3NzKFwidHJhbnNmb3JtXCIsIGB0cmFuc2xhdGUoJHtwb3NpdGlvbi54fXB4LCAke3Bvc2l0aW9uLnl9cHgpYCk7XHJcblx0fTtcclxuXHRsZXQgb25EcmFnRW5kID0gKCkgPT4ge1xyXG5cdFx0cG9pbnRlcmRvd24gPSBmYWxzZTtcclxuXHRcdGRlbGV0ZSBkcmFnRnJvbS54O1xyXG5cdFx0ZGVsZXRlIGRyYWdGcm9tLnk7XHJcblx0XHQvLyBNYWtlIHN1cmUgZmluYWwgcG9zaXRpb25zIGFyZSB3aG9sZSBudW1iZXJzXHJcblx0XHRwb3NpdGlvbi54ID0gTWF0aC5yb3VuZChwb3NpdGlvbi54KTtcclxuXHRcdHBvc2l0aW9uLnkgPSBNYXRoLnJvdW5kKHBvc2l0aW9uLnkpO1xyXG5cdFx0JGZyYW1lRWwuY3NzKFwidHJhbnNmb3JtXCIsIGB0cmFuc2xhdGUoJHtwb3NpdGlvbi54fXB4LCAke3Bvc2l0aW9uLnl9cHgpYCk7XHJcblx0fTtcclxuXHJcblx0Ly8gVXNlIHBvaW50ZXIgZXZlbnRzIGlmIGF2YWlsYWJsZTsgb3RoZXJ3aXNlIHVzZSBtb3VzZSBldmVudHNcclxuXHRjb25zdCBwb2ludGVyID0gKFwiUG9pbnRlckV2ZW50XCIgaW4gd2luZG93KSA/IFwicG9pbnRlclwiIDogXCJtb3VzZVwiO1xyXG5cdCRoYW5kbGVFbC5vbihwb2ludGVyK1wiZW50ZXIucmF0ZXJNYWluV2luXCIsICgpID0+ICRmcmFtZUVsLmNzcyhcIndpbGwtY2hhbmdlXCIsIFwidHJhbnNmb3JtXCIpICk7IC8vIFRlbGwgYnJvd3NlciB0byBvcHRpbWlzZSB0cmFuc2Zvcm1cclxuXHQkaGFuZGxlRWwub24ocG9pbnRlcitcImxlYXZlLnJhdGVyTWFpbldpblwiLCAoKSA9PiB7IGlmICghcG9pbnRlcmRvd24pICRmcmFtZUVsLmNzcyhcIndpbGwtY2hhbmdlXCIsIFwiXCIpOyB9ICk7IC8vIFJlbW92ZSBvcHRpbWlzYXRpb24gaWYgbm90IGRyYWdnaW5nXHJcblx0JGhhbmRsZUVsLm9uKHBvaW50ZXIrXCJkb3duLnJhdGVyTWFpbldpblwiLCBvbkRyYWdTdGFydCk7XHJcblx0JChcImJvZHlcIikub24ocG9pbnRlcitcIm1vdmUucmF0ZXJNYWluV2luXCIsIG9uRHJhZ01vdmUpO1xyXG5cdCQoXCJib2R5XCIpLm9uKHBvaW50ZXIrXCJ1cC5yYXRlck1haW5XaW5cIiwgb25EcmFnRW5kKTtcclxufTtcclxuXHJcbi8vIE92ZXJyaWRlIHRoZSBnZXRCb2R5SGVpZ2h0KCkgbWV0aG9kIHRvIHNwZWNpZnkgYSBjdXN0b20gaGVpZ2h0XHJcbk1haW5XaW5kb3cucHJvdG90eXBlLmdldEJvZHlIZWlnaHQgPSBmdW5jdGlvbiAoKSB7XHJcblx0dmFyIGN1cnJlbnRsYXlvdXQgPSB0aGlzLmNvbnRlbnRBcmVhLmdldEN1cnJlbnRJdGVtKCk7XHJcblx0dmFyIGxheW91dEhlaWdodCA9IGN1cnJlbnRsYXlvdXQgJiYgY3VycmVudGxheW91dC4kZWxlbWVudC5vdXRlckhlaWdodCh0cnVlKTtcclxuXHR2YXIgY29udGVudEhlaWdodCA9IGN1cnJlbnRsYXlvdXQgJiYgY3VycmVudGxheW91dC4kZWxlbWVudC5jaGlsZHJlbihcIjpmaXJzdC1jaGlsZFwiKS5vdXRlckhlaWdodCh0cnVlKTtcclxuXHRyZXR1cm4gTWF0aC5tYXgoMjAwLCBsYXlvdXRIZWlnaHQsIGNvbnRlbnRIZWlnaHQpO1xyXG59O1xyXG5cclxuLy8gVXNlIGdldFNldHVwUHJvY2VzcygpIHRvIHNldCB1cCB0aGUgd2luZG93IHdpdGggZGF0YSBwYXNzZWQgdG8gaXQgYXQgdGhlIHRpbWUgXHJcbi8vIG9mIG9wZW5pbmdcclxuTWFpbldpbmRvdy5wcm90b3R5cGUuZ2V0U2V0dXBQcm9jZXNzID0gZnVuY3Rpb24gKCBkYXRhICkge1xyXG5cdGRhdGEgPSBkYXRhIHx8IHt9O1xyXG5cdHJldHVybiBNYWluV2luZG93LnN1cGVyLnByb3RvdHlwZS5nZXRTZXR1cFByb2Nlc3MuY2FsbCggdGhpcywgZGF0YSApXHJcblx0XHQubmV4dCggKCkgPT4ge1xyXG5cdFx0XHR0aGlzLm1ha2VEcmFnZ2FibGUoKTtcclxuXHRcdFx0Ly8gU2V0IHVwIHByZWZlcmVuY2VzXHJcblx0XHRcdHRoaXMuc2V0UHJlZmVyZW5jZXMoZGF0YS5wcmVmZXJlbmNlcyk7XHJcblx0XHRcdHRoaXMucHJlZnNGb3JtLnNldFByZWZWYWx1ZXMoZGF0YS5wcmVmZXJlbmNlcyk7XHJcblx0XHRcdC8vIFNldCBzdWJqZWN0IHBhZ2UgaW5mb1xyXG5cdFx0XHR0aGlzLnN1YmplY3RQYWdlID0gZGF0YS5zdWJqZWN0UGFnZTtcclxuXHRcdFx0dGhpcy5wYWdlSW5mbyA9IHtcclxuXHRcdFx0XHRyZWRpcmVjdDogZGF0YS5yZWRpcmVjdFRhcmdldCxcclxuXHRcdFx0XHRpc0Rpc2FtYmlnOiBkYXRhLmRpc2FtYmlnLFxyXG5cdFx0XHRcdGhhc1N0dWJ0YWc6IGRhdGEuc3R1YnRhZyxcclxuXHRcdFx0XHRpc0FydGljbGU6IGRhdGEuaXNBcnRpY2xlXHJcblx0XHRcdH07XHJcblx0XHRcdC8vIFNldCB1cCBlZGl0IG1vZGUgYmFubmVyc1xyXG5cdFx0XHR0aGlzLmFjdGlvbnMuc2V0TW9kZShcImVkaXRcIik7XHJcblx0XHRcdHRoaXMuYmFubmVyTGlzdC5vcmVzQ2xhc3MgPSAoZGF0YS5pc0FydGljbGUgJiYgZGF0YS5pc0xpc3QpXHJcblx0XHRcdFx0PyBcIkxpc3RcIlxyXG5cdFx0XHRcdDogZGF0YS5vcmVzICYmIGRhdGEub3Jlcy5wcmVkaWN0aW9uO1xyXG5cdFx0XHR0aGlzLmJhbm5lckxpc3QucGFnZUluZm8gPSB0aGlzLnBhZ2VJbmZvO1xyXG5cdFx0XHR0aGlzLmJhbm5lckxpc3QuYWRkSXRlbXMoXHJcblx0XHRcdFx0ZGF0YS5iYW5uZXJzLm1hcCggYmFubmVyVGVtcGxhdGUgPT4gbmV3IEJhbm5lcldpZGdldChcclxuXHRcdFx0XHRcdGJhbm5lclRlbXBsYXRlLFxyXG5cdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRwcmVmZXJlbmNlczogdGhpcy5wcmVmZXJlbmNlcyxcclxuXHRcdFx0XHRcdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXksXHJcblx0XHRcdFx0XHRcdGlzQXJ0aWNsZTogdGhpcy5wYWdlSW5mby5pc0FydGljbGVcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHQpIClcclxuXHRcdFx0KTtcclxuXHRcdFx0bGV0IHNoZWxsVGVtcGxhdGVCYW5uZXIgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMuZmluZChiYW5uZXIgPT4gYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSk7XHJcblx0XHRcdGlmIChzaGVsbFRlbXBsYXRlQmFubmVyICYmIHNoZWxsVGVtcGxhdGVCYW5uZXIuc2hlbGxQYXJhbTFWYWx1ZSkge1xyXG5cdFx0XHRcdHNoZWxsVGVtcGxhdGVCYW5uZXIubm9uU3RhbmRhcmRUZW1wbGF0ZXMgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMucmVkdWNlKFxyXG5cdFx0XHRcdFx0KGJhbm5lcnNMaXN0LCBjdXJCYW5uZXIpID0+IGJhbm5lcnNMaXN0LnJlcGxhY2UoY3VyQmFubmVyLndpa2l0ZXh0LCBcIlwiKSxcclxuXHRcdFx0XHRcdHNoZWxsVGVtcGxhdGVCYW5uZXIuc2hlbGxQYXJhbTFWYWx1ZVxyXG5cdFx0XHRcdCkudHJpbSgpLnJlcGxhY2UoL1xcbisvZywgXCJcXG5cIik7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5iYW5uZXJMaXN0LmFkZFNoZWxsVGVtcGxhdGVJZk5lZWVkZWQoKVxyXG5cdFx0XHRcdC5zeW5jU2hlbGxUZW1wbGF0ZVdpdGhCaW9ncmFwaHlCYW5uZXIoKTtcclxuXHRcdFx0Ly8gU2hvdyBwYWdlIHR5cGUsIG9yIE9SRVMgcHJlZGljdGlvbiwgaWYgYXZhaWxhYmxlXHJcblx0XHRcdGlmICh0aGlzLnBhZ2VJbmZvLnJlZGlyZWN0KSB7XHJcblx0XHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnNldExhYmVsKFwiUmVkaXJlY3QgcGFnZVwiKS50b2dnbGUodHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSBpZiAodGhpcy5wYWdlSW5mby5pc0Rpc2FtYmlnKSB7XHJcblx0XHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnNldExhYmVsKFwiRGlzYW1iaWd1YXRpb24gcGFnZVwiKS50b2dnbGUodHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSBpZiAodGhpcy5wYWdlSW5mby5pc0FydGljbGUgJiYgZGF0YS5pc0dBKSB7XHJcblx0XHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnNldExhYmVsKFwiR29vZCBhcnRpY2xlXCIpLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fSBlbHNlIGlmICh0aGlzLnBhZ2VJbmZvLmlzQXJ0aWNsZSAmJiBkYXRhLmlzRkEpIHtcclxuXHRcdFx0XHR0aGlzLnBhZ2V0eXBlTGFiZWwuc2V0TGFiZWwoXCJGZWF0dXJlZCBhcnRpY2xlXCIpLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fSBlbHNlIGlmICh0aGlzLnBhZ2VJbmZvLmlzQXJ0aWNsZSAmJiBkYXRhLmlzRkwpIHtcclxuXHRcdFx0XHR0aGlzLnBhZ2V0eXBlTGFiZWwuc2V0TGFiZWwoXCJGZWF0dXJlZCBsaXN0XCIpLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fSBlbHNlIGlmICh0aGlzLnBhZ2VJbmZvLmlzQXJ0aWNsZSAmJiBkYXRhLmlzTGlzdCkge1xyXG5cdFx0XHRcdHRoaXMucGFnZXR5cGVMYWJlbC5zZXRMYWJlbChcIkxpc3QgYXJ0aWNsZVwiKS50b2dnbGUodHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZGF0YS5vcmVzKSB7XHJcblx0XHRcdFx0dGhpcy5vcmVzQ2xhc3MgPSBkYXRhLm9yZXMucHJlZGljdGlvbjtcclxuXHRcdFx0XHR0aGlzLm9yZXNMYWJlbC50b2dnbGUodHJ1ZSkuJGVsZW1lbnQuZmluZChcIi5vcmVzUHJlZGljdGlvblwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcIlByZWRpY3Rpb246IFwiLFxyXG5cdFx0XHRcdFx0JChcIjxzdHJvbmc+XCIpLnRleHQoZGF0YS5vcmVzLnByZWRpY3Rpb24pLFxyXG5cdFx0XHRcdFx0XCImbmJzcDsoXCIgKyBkYXRhLm9yZXMucHJvYmFiaWxpdHkgKyBcIilcIlxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH0gZWxzZSBpZiAodGhpcy5wYWdlSW5mby5pc0FydGljbGUpIHtcclxuXHRcdFx0XHR0aGlzLnBhZ2V0eXBlTGFiZWwuc2V0TGFiZWwoXCJBcnRpY2xlIHBhZ2VcIikudG9nZ2xlKHRydWUpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMucGFnZXR5cGVMYWJlbC5zZXRMYWJlbCggdGhpcy5zdWJqZWN0UGFnZS5nZXROYW1lc3BhY2VQcmVmaXgoKS5zbGljZSgwLC0xKSArIFwiIHBhZ2VcIiApLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fVxyXG5cdFx0XHQvLyBTZXQgcHJvcHMgZm9yIHVzZSBpbiBtYWtpbmcgd2lraXRleHQgYW5kIGVkaXQgc3VtbWFyaWVzXHJcblx0XHRcdHRoaXMudGFsa1dpa2l0ZXh0ID0gZGF0YS50YWxrV2lraXRleHQ7XHJcblx0XHRcdHRoaXMuZXhpc3RpbmdCYW5uZXJOYW1lcyA9IGRhdGEuYmFubmVycy5tYXAoIGJhbm5lclRlbXBsYXRlID0+IGJhbm5lclRlbXBsYXRlLm5hbWUgKTtcclxuXHRcdFx0dGhpcy50YWxrcGFnZSA9IGRhdGEudGFsa3BhZ2U7XHJcblx0XHRcdC8vIEZvcmNlIGEgc2l6ZSB1cGRhdGUgdG8gZW5zdXJlIGV2ZXl0aGluZyBmaXRzIG9rYXlcclxuXHRcdFx0dGhpcy51cGRhdGVTaXplKCk7XHJcblx0XHR9LCB0aGlzICk7XHJcbn07XHJcblxyXG4vLyBTZXQgdXAgdGhlIHdpbmRvdyBpdCBpcyByZWFkeTogYXR0YWNoZWQgdG8gdGhlIERPTSwgYW5kIG9wZW5pbmcgYW5pbWF0aW9uIGNvbXBsZXRlZFxyXG5NYWluV2luZG93LnByb3RvdHlwZS5nZXRSZWFkeVByb2Nlc3MgPSBmdW5jdGlvbiAoIGRhdGEgKSB7XHJcblx0ZGF0YSA9IGRhdGEgfHwge307XHJcblx0cmV0dXJuIE1haW5XaW5kb3cuc3VwZXIucHJvdG90eXBlLmdldFJlYWR5UHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdC5uZXh0KCAoKSA9PiB0aGlzLnRvcEJhci5zZWFyY2hCb3guZm9jdXMoKSApO1xyXG59O1xyXG5cclxuLy8gVXNlIHRoZSBnZXRBY3Rpb25Qcm9jZXNzKCkgbWV0aG9kIHRvIGRvIHRoaW5ncyB3aGVuIGFjdGlvbnMgYXJlIGNsaWNrZWRcclxuTWFpbldpbmRvdy5wcm90b3R5cGUuZ2V0QWN0aW9uUHJvY2VzcyA9IGZ1bmN0aW9uICggYWN0aW9uICkge1xyXG5cdGlmICggYWN0aW9uID09PSBcInNob3dQcmVmc1wiICkge1xyXG5cdFx0dGhpcy5hY3Rpb25zLnNldE1vZGUoXCJwcmVmc1wiKTtcclxuXHRcdHRoaXMuY29udGVudEFyZWEuc2V0SXRlbSggdGhpcy5wcmVmc0xheW91dCApO1xyXG5cdFx0dGhpcy50b3BCYXIuc2V0RGlzYWJsZWQodHJ1ZSk7XHJcblx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcInNhdmVQcmVmc1wiICkge1xyXG5cdFx0dmFyIHVwZGF0ZWRQcmVmcyA9IHRoaXMucHJlZnNGb3JtLmdldFByZWZzKCk7XHJcblx0XHRyZXR1cm4gbmV3IE9PLnVpLlByb2Nlc3MoKS5uZXh0KFxyXG5cdFx0XHRBcGlTZXRQcmVmcyh1cGRhdGVkUHJlZnMpLnRoZW4oXHJcblx0XHRcdFx0Ly8gU3VjY2Vzc1xyXG5cdFx0XHRcdCgpID0+IHtcclxuXHRcdFx0XHRcdHRoaXMuc2V0UHJlZmVyZW5jZXModXBkYXRlZFByZWZzKTtcclxuXHRcdFx0XHRcdHRoaXMuYWN0aW9ucy5zZXRNb2RlKFwiZWRpdFwiKTtcclxuXHRcdFx0XHRcdHRoaXMuY29udGVudEFyZWEuc2V0SXRlbSggdGhpcy5lZGl0TGF5b3V0ICk7XHJcblx0XHRcdFx0XHR0aGlzLnRvcEJhci5zZXREaXNhYmxlZChmYWxzZSk7XHJcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdC8vIEZhaWx1cmVcclxuXHRcdFx0XHQoY29kZSwgZXJyKSA9PiAkLkRlZmVycmVkKCkucmVqZWN0KFxyXG5cdFx0XHRcdFx0bmV3IE9PLnVpLkVycm9yKFxyXG5cdFx0XHRcdFx0XHQkKFwiPGRpdj5cIikuYXBwZW5kKFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nIHN0eWxlPSdkaXNwbGF5OmJsb2NrOyc+XCIpLnRleHQoXCJDb3VsZCBub3Qgc2F2ZSBwcmVmZXJlbmNlcy5cIiksXHJcblx0XHRcdFx0XHRcdFx0JChcIjxzcGFuIHN0eWxlPSdjb2xvcjojNzc3Jz5cIikudGV4dCggbWFrZUVycm9yTXNnKGNvZGUsIGVycikgKVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KVxyXG5cdFx0XHQpXHJcblx0XHQpO1xyXG5cclxuXHR9IGVsc2UgaWYgKCBhY3Rpb24gPT09IFwiY2xlYXJDYWNoZVwiICkge1xyXG5cdFx0cmV0dXJuIG5ldyBPTy51aS5Qcm9jZXNzKCkubmV4dCgoKSA9PiB7XHJcblx0XHRcdGNhY2hlLmNsZWFyQWxsSXRlbXMoKTtcclxuXHRcdFx0dGhpcy5jbG9zZSh7cmVzdGFydDogdHJ1ZX0pO1xyXG5cdFx0fSk7XHJcblxyXG5cclxuXHR9IGVsc2UgaWYgKCBhY3Rpb24gPT09IFwiY2xvc2VQcmVmc1wiICkge1xyXG5cdFx0dGhpcy5hY3Rpb25zLnNldE1vZGUoXCJlZGl0XCIpO1xyXG5cdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLmVkaXRMYXlvdXQgKTtcclxuXHRcdHRoaXMudG9wQmFyLnNldERpc2FibGVkKGZhbHNlKTtcclxuXHRcdHRoaXMucHJlZnNGb3JtLnNldFByZWZWYWx1ZXModGhpcy5wcmVmZXJlbmNlcyk7XHJcblx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcInNhdmVcIiApIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdEFQSS5lZGl0V2l0aFJldHJ5KFxyXG5cdFx0XHRcdHRoaXMudGFsa3BhZ2UuZ2V0UHJlZml4ZWRUZXh0KCksXHJcblx0XHRcdFx0e3J2c2VjdGlvbjogMH0sXHJcblx0XHRcdFx0cmV2aXNpb24gPT4gKHtcclxuXHRcdFx0XHRcdHNlY3Rpb246IDAsXHJcblx0XHRcdFx0XHR0ZXh0OiB0aGlzLnRyYW5zZm9ybVRhbGtXaWtpdGV4dChyZXZpc2lvbi5jb250ZW50KSxcclxuXHRcdFx0XHRcdHN1bW1hcnk6IHRoaXMubWFrZUVkaXRTdW1tYXJ5KCksXHJcblx0XHRcdFx0XHR3YXRjaGxpc3Q6IHRoaXMucHJlZmVyZW5jZXMud2F0Y2hsaXN0XHJcblx0XHRcdFx0fSlcclxuXHRcdFx0KS5jYXRjaCgoY29kZSwgZXJyKSA9PiAkLkRlZmVycmVkKCkucmVqZWN0KFxyXG5cdFx0XHRcdG5ldyBPTy51aS5FcnJvcihcclxuXHRcdFx0XHRcdCQoXCI8ZGl2PlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nIHN0eWxlPSdkaXNwbGF5OmJsb2NrOyc+XCIpLnRleHQoXCJDb3VsZCBub3Qgc2F2ZSB5b3VyIGNoYW5nZXMuXCIpLFxyXG5cdFx0XHRcdFx0XHQkKFwiPHNwYW4gc3R5bGU9J2NvbG9yOiM3NzcnPlwiKS50ZXh0KCBtYWtlRXJyb3JNc2coY29kZSwgZXJyKSApXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KVxyXG5cdFx0XHQpIClcclxuXHRcdCkubmV4dCggKCkgPT4gdGhpcy5jbG9zZSh7XHJcblx0XHRcdHN1Y2Nlc3M6IHRydWUsXHJcblx0XHRcdHVwZ3JhZGVkU3R1YjogdGhpcy5wYWdlSW5mby5oYXNTdHVidGFnICYmIHRoaXMuaXNSYXRlZEFuZE5vdFN0dWIoKVxyXG5cdFx0fSkgKTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcInByZXZpZXdcIiApIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdEFQSS5wb3N0KHtcclxuXHRcdFx0XHRhY3Rpb246IFwicGFyc2VcIixcclxuXHRcdFx0XHRjb250ZW50bW9kZWw6IFwid2lraXRleHRcIixcclxuXHRcdFx0XHR0ZXh0OiB0aGlzLnRyYW5zZm9ybVRhbGtXaWtpdGV4dCh0aGlzLnRhbGtXaWtpdGV4dCkgKyBcIlxcbjxocj5cXG5cIiArIFwiJycnRWRpdCBzdW1tYXJ5OicnJyBcIiArIHRoaXMubWFrZUVkaXRTdW1tYXJ5KCksXHJcblx0XHRcdFx0dGl0bGU6IHRoaXMudGFsa3BhZ2UuZ2V0UHJlZml4ZWRUZXh0KCksXHJcblx0XHRcdFx0cHN0OiAxXHJcblx0XHRcdH0pLnRoZW4oIHJlc3VsdCA9PiB7XHJcblx0XHRcdFx0aWYgKCAhcmVzdWx0IHx8ICFyZXN1bHQucGFyc2UgfHwgIXJlc3VsdC5wYXJzZS50ZXh0IHx8ICFyZXN1bHQucGFyc2UudGV4dFtcIipcIl0gKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdChcIkVtcHR5IHJlc3VsdFwiKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dmFyIHByZXZpZXdIdG1sU25pcHBldCA9IG5ldyBPTy51aS5IdG1sU25pcHBldChyZXN1bHQucGFyc2UudGV4dFtcIipcIl0pO1xyXG5cclxuXHRcdFx0XHR0aGlzLnBhcnNlZENvbnRlbnRXaWRnZXQuc2V0TGFiZWwocHJldmlld0h0bWxTbmlwcGV0KTtcclxuXHRcdFx0XHR0aGlzLnBhcnNlZENvbnRlbnRDb250YWluZXIuc2V0TGFiZWwoXCJQcmV2aWV3OlwiKTtcclxuXHRcdFx0XHR0aGlzLmFjdGlvbnMuc2V0TW9kZShcInByZXZpZXdcIik7XHJcblx0XHRcdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLnBhcnNlZENvbnRlbnRMYXlvdXQgKTtcclxuXHRcdFx0XHR0aGlzLnRvcEJhci5zZXREaXNhYmxlZCh0cnVlKTtcclxuXHRcdFx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHRcdFx0fSlcclxuXHRcdFx0XHQuY2F0Y2goIChjb2RlLCBlcnIpID0+ICQuRGVmZXJyZWQoKS5yZWplY3QoXHJcblx0XHRcdFx0XHRuZXcgT08udWkuRXJyb3IoXHJcblx0XHRcdFx0XHRcdCQoXCI8ZGl2PlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdFx0JChcIjxzdHJvbmcgc3R5bGU9J2Rpc3BsYXk6YmxvY2s7Jz5cIikudGV4dChcIkNvdWxkIG5vdCBzaG93IGNoYW5nZXMuXCIpLFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3BhbiBzdHlsZT0nY29sb3I6Izc3Nyc+XCIpLnRleHQoIG1ha2VFcnJvck1zZyhjb2RlLCBlcnIpIClcclxuXHRcdFx0XHRcdFx0KVxyXG5cdFx0XHRcdFx0KVxyXG5cdFx0XHRcdCkgKVxyXG5cdFx0KTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcImNoYW5nZXNcIiApIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdEFQSS5wb3N0KHtcclxuXHRcdFx0XHRhY3Rpb246IFwiY29tcGFyZVwiLFxyXG5cdFx0XHRcdGZvcm1hdDogXCJqc29uXCIsXHJcblx0XHRcdFx0ZnJvbXRleHQ6IHRoaXMudGFsa1dpa2l0ZXh0LFxyXG5cdFx0XHRcdGZyb21jb250ZW50bW9kZWw6IFwid2lraXRleHRcIixcclxuXHRcdFx0XHR0b3RleHQ6IHRoaXMudHJhbnNmb3JtVGFsa1dpa2l0ZXh0KHRoaXMudGFsa1dpa2l0ZXh0KSxcclxuXHRcdFx0XHR0b2NvbnRlbnRtb2RlbDogXCJ3aWtpdGV4dFwiLFxyXG5cdFx0XHRcdHByb3A6IFwiZGlmZlwiXHJcblx0XHRcdH0pXHJcblx0XHRcdFx0LnRoZW4oIHJlc3VsdCA9PiB7XHJcblx0XHRcdFx0XHRpZiAoICFyZXN1bHQgfHwgIXJlc3VsdC5jb21wYXJlIHx8ICFyZXN1bHQuY29tcGFyZVtcIipcIl0gKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KFwiRW1wdHkgcmVzdWx0XCIpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0dmFyICRkaWZmID0gJChcIjx0YWJsZT5cIikuYWRkQ2xhc3MoXCJkaWZmXCIpLmNzcyhcIndpZHRoXCIsIFwiMTAwJVwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdCQoXCI8dHI+XCIpLmFwcGVuZChcclxuXHRcdFx0XHRcdFx0XHQkKFwiPHRoPlwiKS5hdHRyKHtcImNvbHNwYW5cIjpcIjJcIiwgXCJzY29wZVwiOlwiY29sXCJ9KS5jc3MoXCJ3aWR0aFwiLCBcIjUwJVwiKS50ZXh0KFwiTGF0ZXN0IHJldmlzaW9uXCIpLFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8dGg+XCIpLmF0dHIoe1wiY29sc3BhblwiOlwiMlwiLCBcInNjb3BlXCI6XCJjb2xcIn0pLmNzcyhcIndpZHRoXCIsIFwiNTAlXCIpLnRleHQoXCJOZXcgdGV4dFwiKVxyXG5cdFx0XHRcdFx0XHQpLFxyXG5cdFx0XHRcdFx0XHRyZXN1bHQuY29tcGFyZVtcIipcIl0sXHJcblx0XHRcdFx0XHRcdCQoXCI8dGZvb3Q+XCIpLmFwcGVuZChcclxuXHRcdFx0XHRcdFx0XHQkKFwiPHRyPlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdFx0XHQkKFwiPHRkIGNvbHNwYW49JzQnPlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nPlwiKS50ZXh0KFwiRWRpdCBzdW1tYXJ5OiBcIiksXHJcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMubWFrZUVkaXRTdW1tYXJ5KClcclxuXHRcdFx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRcdFx0dGhpcy5wYXJzZWRDb250ZW50V2lkZ2V0LnNldExhYmVsKCRkaWZmKTtcclxuXHRcdFx0XHRcdHRoaXMucGFyc2VkQ29udGVudENvbnRhaW5lci5zZXRMYWJlbChcIkNoYW5nZXM6XCIpO1xyXG5cdFx0XHRcdFx0dGhpcy5hY3Rpb25zLnNldE1vZGUoXCJkaWZmXCIpO1xyXG5cdFx0XHRcdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLnBhcnNlZENvbnRlbnRMYXlvdXQgKTtcclxuXHRcdFx0XHRcdHRoaXMudG9wQmFyLnNldERpc2FibGVkKHRydWUpO1xyXG5cdFx0XHRcdFx0dGhpcy51cGRhdGVTaXplKCk7XHJcblx0XHRcdFx0fSApXHJcblx0XHRcdFx0LmNhdGNoKCAoY29kZSwgZXJyKSA9PiAkLkRlZmVycmVkKCkucmVqZWN0KFxyXG5cdFx0XHRcdFx0bmV3IE9PLnVpLkVycm9yKFxyXG5cdFx0XHRcdFx0XHQkKFwiPGRpdj5cIikuYXBwZW5kKFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nIHN0eWxlPSdkaXNwbGF5OmJsb2NrOyc+XCIpLnRleHQoXCJDb3VsZCBub3Qgc2hvdyBjaGFuZ2VzLlwiKSxcclxuXHRcdFx0XHRcdFx0XHQkKFwiPHNwYW4gc3R5bGU9J2NvbG9yOiM3NzcnPlwiKS50ZXh0KCBtYWtlRXJyb3JNc2coY29kZSwgZXJyKSApXHJcblx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdClcclxuXHRcdFx0XHQpIClcclxuXHRcdCk7XHJcblxyXG5cdH0gZWxzZSBpZiAoIGFjdGlvbiA9PT0gXCJiYWNrXCIgKSB7XHJcblx0XHR0aGlzLmFjdGlvbnMuc2V0TW9kZShcImVkaXRcIik7XHJcblx0XHR0aGlzLmNvbnRlbnRBcmVhLnNldEl0ZW0oIHRoaXMuZWRpdExheW91dCApO1xyXG5cdFx0dGhpcy50b3BCYXIuc2V0RGlzYWJsZWQoZmFsc2UpO1xyXG5cdFx0dGhpcy51cGRhdGVTaXplKCk7XHJcblxyXG5cdH0gZWxzZSBpZiAoIWFjdGlvbiAmJiB0aGlzLmJhbm5lckxpc3QuY2hhbmdlZCkge1xyXG5cdFx0Ly8gQ29uZmlybSBjbG9zaW5nIG9mIGRpYWxvZyBpZiB0aGVyZSBoYXZlIGJlZW4gY2hhbmdlcyBcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdE9PLnVpLmNvbmZpcm0oXCJDaGFuZ2VzIG1hZGUgd2lsbCBiZSBkaXNjYXJkZWQuXCIsIHt0aXRsZTpcIkNsb3NlIFJhdGVyP1wifSlcclxuXHRcdFx0XHQudGhlbihjb25maXJtZWQgPT4gY29uZmlybWVkID8gdGhpcy5jbG9zZSgpIDogbnVsbClcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gTWFpbldpbmRvdy5zdXBlci5wcm90b3R5cGUuZ2V0QWN0aW9uUHJvY2Vzcy5jYWxsKCB0aGlzLCBhY3Rpb24gKTtcclxufTtcclxuXHJcbi8vIFVzZSB0aGUgZ2V0VGVhcmRvd25Qcm9jZXNzKCkgbWV0aG9kIHRvIHBlcmZvcm0gYWN0aW9ucyB3aGVuZXZlciB0aGUgZGlhbG9nIGlzIGNsb3NlZC5cclxuLy8gYGRhdGFgIGlzIHRoZSBkYXRhIHBhc3NlZCBpbnRvIHRoZSB3aW5kb3cncyAuY2xvc2UoKSBtZXRob2QuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLmdldFRlYXJkb3duUHJvY2VzcyA9IGZ1bmN0aW9uICggZGF0YSApIHtcclxuXHRyZXR1cm4gTWFpbldpbmRvdy5zdXBlci5wcm90b3R5cGUuZ2V0VGVhcmRvd25Qcm9jZXNzLmNhbGwoIHRoaXMsIGRhdGEgKVxyXG5cdFx0LmZpcnN0KCAoKSA9PiB7XHJcblx0XHRcdHRoaXMuYmFubmVyTGlzdC5jbGVhckl0ZW1zKCk7XHJcblx0XHRcdHRoaXMudG9wQmFyLnNlYXJjaEJveC5zZXRWYWx1ZShcIlwiKTtcclxuXHRcdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLmVkaXRMYXlvdXQgKTtcclxuXHRcdFx0dGhpcy50b3BCYXIuc2V0RGlzYWJsZWQoZmFsc2UpO1xyXG5cdFx0XHR0aGlzLm9yZXNMYWJlbC50b2dnbGUoZmFsc2UpLiRlbGVtZW50LmZpbmQoXCIub3Jlc1ByZWRpY3Rpb25cIikuZW1wdHkoKTtcclxuXHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnRvZ2dsZShmYWxzZSkuc2V0TGFiZWwoXCJcIik7XHJcblxyXG5cdFx0XHR0aGlzLiRlbGVtZW50LmZpbmQoXCIub28tdWktd2luZG93LWZyYW1lXCIpLmNzcyhcInRyYW5zZm9ybVwiLFwiXCIpO1xyXG5cdFx0XHR0aGlzLiRlbGVtZW50LmZpbmQoXCIub28tdWktcHJvY2Vzc0RpYWxvZy1sb2NhdGlvblwiKS5vZmYoXCIucmF0ZXJNYWluV2luXCIpO1xyXG5cdFx0XHQkKFwiYm9keVwiKS5vZmYoXCIucmF0ZXJNYWluV2luXCIpO1xyXG5cdFx0fSApO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUuc2V0UHJlZmVyZW5jZXMgPSBmdW5jdGlvbihwcmVmcykge1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSAkLmV4dGVuZCh7fSwgYXBwQ29uZmlnLmRlZmF1bHRQcmVmcywgcHJlZnMpO1xyXG5cdC8vIEFwcGxpZXMgcHJlZmVyZW5jZXMgdG8gZXhpc3RpbmcgaXRlbXMgaW4gdGhlIHdpbmRvdzpcclxuXHR0aGlzLmJhbm5lckxpc3Quc2V0UHJlZmVyZW5jZXModGhpcy5wcmVmZXJlbmNlcyk7XHJcbn07XHJcblxyXG5NYWluV2luZG93LnByb3RvdHlwZS5vblJlc2V0Q2FjaGUgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmV4ZWN1dGVBY3Rpb24oXCJjbGVhckNhY2hlXCIpO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUub25TZWFyY2hTZWxlY3QgPSBmdW5jdGlvbihkYXRhKSB7XHJcblx0dGhpcy50b3BCYXIuc2VhcmNoQm94LnB1c2hQZW5kaW5nKCk7XHJcblx0dmFyIG5hbWUgPSB0aGlzLnRvcEJhci5zZWFyY2hCb3guZ2V0VmFsdWUoKS50cmltKCk7XHJcblx0aWYgKCFuYW1lKSB7XHJcblx0XHR0aGlzLnRvcEJhci5zZWFyY2hCb3gucG9wUGVuZGluZygpLmZvY3VzKCk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdHZhciBleGlzdGluZ0Jhbm5lciA9IHRoaXMuYmFubmVyTGlzdC5pdGVtcy5maW5kKGJhbm5lciA9PiB7XHJcblx0XHRyZXR1cm4gYmFubmVyLm1haW5UZXh0ID09PSBuYW1lIHx8XHRiYW5uZXIucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9PT0gbmFtZTtcclxuXHR9KTtcclxuXHJcblx0Ly8gQWJvcnQgYW5kIHNob3cgYWxlcnQgaWYgYmFubmVyIGFscmVhZHkgZXhpc3RzXHJcblx0aWYgKGV4aXN0aW5nQmFubmVyKSB7XHJcblx0XHR0aGlzLnRvcEJhci5zZWFyY2hCb3gucG9wUGVuZGluZygpO1xyXG5cdFx0cmV0dXJuIE9PLnVpLmFsZXJ0KFwiVGhlcmUgaXMgYWxyZWFkeSBhIHt7XCIgKyBuYW1lICsgXCJ9fSBiYW5uZXJcIikudGhlbih0aGlzLnNlYXJjaEJveC5mb2N1cygpKTtcclxuXHR9XHJcblxyXG5cdC8vIENvbmZpcm1hdGlvbiByZXF1aXJlZCBmb3IgYmFubmVycyBtaXNzaW5nIFdpa2lQcm9qZWN0IGZyb20gbmFtZSwgYW5kIGZvciB1bmNyZWF0ZWQgZGlzYW1iaWd1YXRpb24gdGFsayBwYWdlc1xyXG5cdHZhciBjb25maXJtVGV4dDtcclxuXHRpZiAoIS9eW1d3XSg/OlB8aWtpW1BwXXJvamVjdCkvLnRlc3QobmFtZSkpIHtcclxuXHRcdGNvbmZpcm1UZXh0ID0gbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFxyXG5cdFx0XHRcInt7XCIgKyBtdy5odG1sLmVzY2FwZShuYW1lKSArIFwifX0gaXMgbm90IGEgcmVjb2duaXNlZCBXaWtpUHJvamVjdCBiYW5uZXIuPGJyLz5EbyB5b3Ugd2FudCB0byBjb250aW51ZT9cIlxyXG5cdFx0KTtcclxuXHR9IGVsc2UgaWYgKG5hbWUgPT09IFwiV2lraVByb2plY3QgRGlzYW1iaWd1YXRpb25cIiAmJiAkKFwiI2NhLXRhbGsubmV3XCIpLmxlbmd0aCAhPT0gMCAmJiB0aGlzLmJhbm5lckxpc3QuaXRlbXMubGVuZ3RoID09PSAwKSB7XHJcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1lc2NhcGVcclxuXHRcdGNvbmZpcm1UZXh0ID0gXCJOZXcgdGFsayBwYWdlcyBzaG91bGRuJ3QgYmUgY3JlYXRlZCBpZiB0aGV5IHdpbGwgb25seSBjb250YWluIHRoZSBcXHtcXHtXaWtpUHJvamVjdCBEaXNhbWJpZ3VhdGlvblxcfVxcfSBiYW5uZXIuIENvbnRpbnVlP1wiO1xyXG5cdH1cclxuXHQkLndoZW4oIGNvbmZpcm1UZXh0ID8gT08udWkuY29uZmlybShjb25maXJtVGV4dCkgOiB0cnVlKVxyXG5cdFx0LnRoZW4oIGNvbmZpcm1lZCA9PiB7XHJcblx0XHRcdGlmICghY29uZmlybWVkKSByZXR1cm47XHJcblx0XHRcdC8vIENyZWF0ZSBUZW1wbGF0ZSBvYmplY3RcclxuXHRcdFx0cmV0dXJuIEJhbm5lcldpZGdldC5uZXdGcm9tVGVtcGxhdGVOYW1lKG5hbWUsIGRhdGEsIHtcclxuXHRcdFx0XHRwcmVmZXJlbmNlczogdGhpcy5wcmVmZXJlbmNlcyxcclxuXHRcdFx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdFx0XHRpc0FydGljbGU6IHRoaXMucGFnZUluZm8uaXNBcnRpY2xlXHJcblx0XHRcdH0pXHJcblx0XHRcdFx0LnRoZW4oYmFubmVyID0+IHtcclxuXHRcdFx0XHRcdHRoaXMuYmFubmVyTGlzdC5hZGRJdGVtcyggW2Jhbm5lcl0gKTtcclxuXHRcdFx0XHRcdGJhbm5lci5zZXRDaGFuZ2VkKCk7XHJcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pXHJcblx0XHQudGhlbiggKCkgPT4gdGhpcy50b3BCYXIuc2VhcmNoQm94LnNldFZhbHVlKFwiXCIpLmZvY3VzKCkucG9wUGVuZGluZygpICk7XHJcbn07XHJcblxyXG5NYWluV2luZG93LnByb3RvdHlwZS5vblNldENsYXNzZXMgPSBmdW5jdGlvbihjbGFzc1ZhbCkge1xyXG5cdGNvbnN0IHNoZWxsVGVtcGxhdGUgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMuZmluZChiYW5uZXIgPT4gYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSk7XHJcblx0aWYgKHNoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHNoZWxsVGVtcGxhdGUuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YShjbGFzc1ZhbCk7XHJcblx0XHRzaGVsbFRlbXBsYXRlLmNsYXNzRHJvcGRvd24uc2V0QXV0b2ZpbGxlZChmYWxzZSk7XHJcblx0fVxyXG5cdHRoaXMuYmFubmVyTGlzdC5pdGVtcy5mb3JFYWNoKGJhbm5lciA9PiB7XHJcblx0XHRpZiAoYmFubmVyLmhhc0NsYXNzUmF0aW5ncyAmJiFiYW5uZXIuaXNTaGVsbFRlbXBsYXRlKSB7XHJcblx0XHRcdGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5zZWxlY3RJdGVtQnlEYXRhKHNoZWxsVGVtcGxhdGUgPyBudWxsIDogY2xhc3NWYWwpO1xyXG5cdFx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5zZXRBdXRvZmlsbGVkKGZhbHNlKTtcclxuXHRcdH1cclxuXHR9KTtcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uU2V0SW1wb3J0YW5jZXMgPSBmdW5jdGlvbihpbXBvcnRhbmNlVmFsKSB7XHJcblx0dGhpcy5iYW5uZXJMaXN0Lml0ZW1zLmZvckVhY2goYmFubmVyID0+IHtcclxuXHRcdGlmIChiYW5uZXIuaGFzSW1wb3J0YW5jZVJhdGluZ3MpIHtcclxuXHRcdFx0YmFubmVyLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YShpbXBvcnRhbmNlVmFsKTtcclxuXHRcdFx0YmFubmVyLmltcG9ydGFuY2VEcm9wZG93bi5zZXRBdXRvZmlsbGVkKGZhbHNlKTtcclxuXHRcdH1cclxuXHR9KTtcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uUmVtb3ZlQWxsID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5iYW5uZXJMaXN0LmNsZWFySXRlbXMoKTtcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uQ2xlYXJBbGwgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmJhbm5lckxpc3QuaXRlbXMuZm9yRWFjaCggYmFubmVyID0+IGJhbm5lci5vbkNsZWFyQnV0dG9uQ2xpY2soKSApO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUudHJhbnNmb3JtVGFsa1dpa2l0ZXh0ID0gZnVuY3Rpb24odGFsa1dpa2l0ZXh0KSB7XHJcblx0dmFyIGJhbm5lcnNXaWtpdGV4dCA9IHRoaXMuYmFubmVyTGlzdC5tYWtlV2lraXRleHQoKTtcclxuXHRpZiAoIXRhbGtXaWtpdGV4dCkge1xyXG5cdFx0cmV0dXJuIGJhbm5lcnNXaWtpdGV4dC50cmltKCk7XHJcblx0fVxyXG5cdC8vIFJlcGFyc2UgdGVtcGxhdGVzLCBpbiBjYXNlIHRhbGtwYWdlIHdpa2l0ZXh0IGhhcyBjaGFuZ2VkXHJcblx0dmFyIHRhbGtUZW1wbGF0ZXMgPSBwYXJzZVRlbXBsYXRlcyh0YWxrV2lraXRleHQsIHRydWUpO1xyXG5cdC8vIHJlcGxhY2UgZXhpc3RpbmcgYmFubmVycyB3aWtpdGV4dCB3aXRoIGEgY29udHJvbCBjaGFyYWN0ZXJcclxuXHR0YWxrVGVtcGxhdGVzLmZvckVhY2godGVtcGxhdGUgPT4ge1xyXG5cdFx0aWYgKHRoaXMuZXhpc3RpbmdCYW5uZXJOYW1lcy5pbmNsdWRlcyh0ZW1wbGF0ZS5uYW1lKSkge1xyXG5cdFx0XHR0YWxrV2lraXRleHQgPSB0YWxrV2lraXRleHQucmVwbGFjZSh0ZW1wbGF0ZS53aWtpdGV4dCwgXCJcXHgwMVwiKTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHQvLyByZXBsYWNlIGluc2VydGlvbiBwb2ludCAoZmlyc3QgY29udHJvbCBjaGFyYWN0ZXIpIHdpdGggYSBkaWZmZXJlbnQgY29udHJvbCBjaGFyYWN0ZXJcclxuXHR0YWxrV2lraXRleHQgPSB0YWxrV2lraXRleHQucmVwbGFjZShcIlxceDAxXCIsIFwiXFx4MDJcIik7XHJcblx0Ly8gcmVtb3ZlIG90aGVyIGNvbnRyb2wgY2hhcmFjdGVyc1xyXG5cdC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4ICovXHJcblx0dGFsa1dpa2l0ZXh0ID0gdGFsa1dpa2l0ZXh0LnJlcGxhY2UoLyg/Olxcc3xcXG4pKlxceDAxKD86XFxzfFxcbikqL2csXCJcIik7XHJcblx0Ly8gc3BsaXQgaW50byB3aWtpdGV4dCBiZWZvcmUvYWZ0ZXIgdGhlIHJlbWFpbmluZyBjb250cm9sIGNoYXJhY3RlciAoYW5kIHRyaW0gZWFjaCBzZWN0aW9uKVxyXG5cdHZhciB0YWxrV2lraXRleHRTZWN0aW9ucyA9IHRhbGtXaWtpdGV4dC5zcGxpdChcIlxceDAyXCIpLm1hcCh0ID0+IHQudHJpbSgpKTtcclxuXHRpZiAodGFsa1dpa2l0ZXh0U2VjdGlvbnMubGVuZ3RoID09PSAyKSB7XHJcblx0XHQvLyBGb3VuZCB0aGUgaW5zZXJ0aW9uIHBvaW50IGZvciB0aGUgYmFubmVyc1xyXG5cdFx0cmV0dXJuICh0YWxrV2lraXRleHRTZWN0aW9uc1swXSArIFwiXFxuXCIgKyBiYW5uZXJzV2lraXRleHQudHJpbSgpICsgXCJcXG5cIiArIHRhbGtXaWtpdGV4dFNlY3Rpb25zWzFdKS50cmltKCk7XHJcblx0fVxyXG5cdC8vIENoZWNrIGlmIHRoZXJlJ3MgYW55dGhpbmcgYmVzaWRlIHRlbXBsYXRlc1xyXG5cdHZhciB0ZW1wU3RyID0gdGFsa1dpa2l0ZXh0O1xyXG5cdHRhbGtUZW1wbGF0ZXMuZm9yRWFjaCh0ZW1wbGF0ZSA9PiB7XHJcblx0XHR0ZW1wU3RyID0gdGVtcFN0ci5yZXBsYWNlKHRlbXBsYXRlLndpa2l0ZXh0LCBcIlwiKTtcclxuXHR9KTtcclxuXHRpZiAoL14jUkVESVJFQ1QvaS50ZXN0KHRhbGtXaWtpdGV4dCkgfHwgIXRlbXBTdHIudHJpbSgpKSB7XHJcblx0XHQvLyBJcyBhIHJlZGlyZWN0LCBvciBldmVyeXRoaW5nIGlzIGEgdGVtcGxhdGU6IGluc2VydCBhdCB0aGUgZW5kXHJcblx0XHRyZXR1cm4gdGFsa1dpa2l0ZXh0LnRyaW0oKSArIFwiXFxuXCIgKyBiYW5uZXJzV2lraXRleHQudHJpbSgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHQvLyBUaGVyZSBpcyBub24tdGVtcGxhdGUgY29udGVudCwgc28gaW5zZXJ0IGF0IHRoZSBzdGFydFxyXG5cdFx0cmV0dXJuIGJhbm5lcnNXaWtpdGV4dC50cmltKCkgKyBcIlxcblwiICsgdGFsa1dpa2l0ZXh0LnRyaW0oKTtcclxuXHR9XHJcbn07XHJcblxyXG5NYWluV2luZG93LnByb3RvdHlwZS5pc1JhdGVkQW5kTm90U3R1YiA9IGZ1bmN0aW9uKCkge1xyXG5cdGNvbnN0IG5vblN0dWJSYXRpbmdncyA9IHRoaXMuYmFubmVyTGlzdC5pdGVtcy5maWx0ZXIoYmFubmVyID0+XHJcblx0XHRiYW5uZXIuaGFzQ2xhc3NSYXRpbmdzICYmXHJcblx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRWYWx1ZSgpICYmXHJcblx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRWYWx1ZSgpICE9PSBcIlN0dWJcIlxyXG5cdCk7XHJcblx0cmV0dXJuIG5vblN0dWJSYXRpbmdncy5sZW5ndGggPiAwO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUubWFrZUVkaXRTdW1tYXJ5ID0gZnVuY3Rpb24oKSB7XHJcblx0Y29uc3QgcmVtb3ZlZEJhbm5lcnMgPSBbXTtcclxuXHRjb25zdCBlZGl0ZWRCYW5uZXJzID0gW107XHJcblx0Y29uc3QgbmV3QmFubmVycyA9IFtdO1xyXG5cdGNvbnN0IHNob3J0TmFtZSA9IG5hbWUgPT4gbmFtZS5yZXBsYWNlKFwiV2lraVByb2plY3QgXCIsXCJcIikucmVwbGFjZShcIlN1YnN0OlwiLFwiXCIpO1xyXG5cclxuXHQvLyBPdmVyYWxsIGNsYXNzL2ltcG9ydGFuY2UsIGlmIGFsbCB0aGUgc2FtZVxyXG5cdGNvbnN0IGFsbENsYXNzZXMgPSB1bmlxdWVBcnJheShcclxuXHRcdGZpbHRlckFuZE1hcCh0aGlzLmJhbm5lckxpc3QuaXRlbXMsXHJcblx0XHRcdGJhbm5lciA9PiBiYW5uZXIuaGFzQ2xhc3NSYXRpbmdzIHx8IGJhbm5lci5pc1NoZWxsVGVtcGxhdGUsXHJcblx0XHRcdGJhbm5lciA9PiBiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRWYWx1ZSgpXHJcblx0XHQpXHJcblx0KTtcclxuXHRsZXQgb3ZlcmFsbENsYXNzID0gYWxsQ2xhc3Nlcy5sZW5ndGggPT09IDEgJiYgYWxsQ2xhc3Nlc1swXTtcclxuXHRjb25zdCBhbGxJbXBvcnRhbmNlcyA9IHVuaXF1ZUFycmF5KFxyXG5cdFx0ZmlsdGVyQW5kTWFwKHRoaXMuYmFubmVyTGlzdC5pdGVtcyxcclxuXHRcdFx0YmFubmVyID0+IGJhbm5lci5oYXNJbXBvcnRhbmNlUmF0aW5ncyxcclxuXHRcdFx0YmFubmVyID0+IGJhbm5lci5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0VmFsdWUoKVxyXG5cdFx0KVxyXG5cdCk7XHJcblx0bGV0IG92ZXJhbGxJbXBvcnRhbmNlID0gYWxsSW1wb3J0YW5jZXMubGVuZ3RoID09PSAxICYmIGFsbEltcG9ydGFuY2VzWzBdO1xyXG5cdC8vIERvbid0IHVzZSB0aGVtIHVubGVzcyBzb21lIGhhdmUgY2hhbmdlZFxyXG5cdGxldCBzb21lQ2xhc3Nlc0NoYW5nZWQgPSBmYWxzZTtcclxuXHRsZXQgc29tZUltcG9ydGFuY2VzQ2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuXHQvLyByZW1vdmVkIGJhbm5lcnM6XHJcblx0dGhpcy5leGlzdGluZ0Jhbm5lck5hbWVzLmZvckVhY2gobmFtZSA9PiB7XHJcblx0XHRjb25zdCBiYW5uZXIgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMuZmluZCggYmFubmVyID0+IGJhbm5lci5uYW1lID09PSBuYW1lIHx8IGJhbm5lci5ieXBhc3NlZE5hbWUgPT09IG5hbWUgKTtcclxuXHRcdGlmICghYmFubmVyKSB7XHJcblx0XHRcdHJlbW92ZWRCYW5uZXJzLnB1c2goXCLiiJJcIiArIHNob3J0TmFtZShuYW1lKSk7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0Ly8gZWRpdGVkICYgbmV3IGJhbm5lcnNcclxuXHR0aGlzLmJhbm5lckxpc3QuaXRlbXMuZm9yRWFjaCggYmFubmVyID0+IHtcclxuXHRcdGNvbnN0IGlzTmV3ID0gIWJhbm5lci53aWtpdGV4dDsgLy8gbm90IGFkZGVkIGZyb20gd2lraXRleHQgb24gcGFnZVxyXG5cdFx0aWYgKCFpc05ldyAmJiAhYmFubmVyLmNoYW5nZWQpIHtcclxuXHRcdFx0Ly8gTm90IGNoYW5nZWRcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0bGV0IG5ld0NsYXNzID0gYmFubmVyLmhhc0NsYXNzUmF0aW5ncyAmJiAgKGlzTmV3IHx8IGJhbm5lci5jbGFzc0NoYW5nZWQpICYmIGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldFZhbHVlKCk7XHJcblx0XHRpZiAobmV3Q2xhc3MpIHsgc29tZUNsYXNzZXNDaGFuZ2VkID0gdHJ1ZTsgfVxyXG5cdFx0aWYgKG92ZXJhbGxDbGFzcykgeyBuZXdDbGFzcyA9IG51bGw7IH1cclxuXHJcblx0XHRsZXQgbmV3SW1wb3J0YW5jZSA9IGJhbm5lci5oYXNJbXBvcnRhbmNlUmF0aW5ncyAmJiAoaXNOZXcgfHwgYmFubmVyLmltcG9ydGFuY2VDaGFuZ2VkKSAmJiBiYW5uZXIuaW1wb3J0YW5jZURyb3Bkb3duLmdldFZhbHVlKCk7XHJcblx0XHRpZiAobmV3SW1wb3J0YW5jZSkgeyBzb21lSW1wb3J0YW5jZXNDaGFuZ2VkID0gdHJ1ZTsgfVxyXG5cdFx0aWYgKG92ZXJhbGxJbXBvcnRhbmNlKSB7IG5ld0ltcG9ydGFuY2UgPSBudWxsOyB9XHJcblxyXG5cdFx0bGV0IHJhdGluZyA9IChuZXdDbGFzcyAmJiBuZXdJbXBvcnRhbmNlKVxyXG5cdFx0XHQ/IG5ld0NsYXNzICsgXCIvXCIgKyBuZXdJbXBvcnRhbmNlXHJcblx0XHRcdDogbmV3Q2xhc3MgfHwgbmV3SW1wb3J0YW5jZSB8fCBcIlwiO1xyXG5cdFx0aWYgKHJhdGluZykgeyByYXRpbmcgPSBcIiAoXCIgKyByYXRpbmcgKyBcIilcIjsgfVxyXG5cdFx0XHJcblx0XHRpZiAoaXNOZXcpIHtcclxuXHRcdFx0bmV3QmFubmVycy5wdXNoKFwiK1wiICsgc2hvcnROYW1lKGJhbm5lci5uYW1lKSArIHJhdGluZyk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRlZGl0ZWRCYW5uZXJzLnB1c2goc2hvcnROYW1lKGJhbm5lci5uYW1lKSArIHJhdGluZyk7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0Ly8gb3ZlcmFsbCByYXRpbmdcclxuXHRsZXQgb3ZlcmFsbFJhdGluZyA9IChzb21lQ2xhc3Nlc0NoYW5nZWQgJiYgb3ZlcmFsbENsYXNzICYmIHNvbWVJbXBvcnRhbmNlc0NoYW5nZWQgJiYgb3ZlcmFsbEltcG9ydGFuY2UpXHJcblx0XHQ/IG92ZXJhbGxDbGFzcyArIFwiL1wiICsgb3ZlcmFsbEltcG9ydGFuY2VcclxuXHRcdDogKHNvbWVDbGFzc2VzQ2hhbmdlZCAmJiBvdmVyYWxsQ2xhc3MpIHx8IChzb21lSW1wb3J0YW5jZXNDaGFuZ2VkICYmIG92ZXJhbGxJbXBvcnRhbmNlKSB8fCBcIlwiO1xyXG5cdGlmIChvdmVyYWxsUmF0aW5nKSB7IG92ZXJhbGxSYXRpbmcgPSBcIiAoXCIgKyBvdmVyYWxsUmF0aW5nICsgXCIpXCI7IH1cclxuXHJcblx0cmV0dXJuIGBBc3Nlc3NtZW50JHtvdmVyYWxsUmF0aW5nfTogJHtbLi4uZWRpdGVkQmFubmVycywgLi4ubmV3QmFubmVycywgLi4ucmVtb3ZlZEJhbm5lcnNdLmpvaW4oXCIsIFwiKX0ke2FwcENvbmZpZy5zY3JpcHQuYWR2ZXJ0fWA7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBNYWluV2luZG93O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxudmFyIEFQSSA9IG5ldyBtdy5BcGkoIHtcclxuXHRhamF4OiB7XHJcblx0XHRoZWFkZXJzOiB7IFxyXG5cdFx0XHRcIkFwaS1Vc2VyLUFnZW50XCI6IFwiUmF0ZXIvXCIgKyBjb25maWcuc2NyaXB0LnZlcnNpb24gKyBcclxuXHRcdFx0XHRcIiAoIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VzZXI6RXZhZDM3L1JhdGVyIClcIlxyXG5cdFx0fVxyXG5cdH1cclxufSApO1xyXG5cclxuLyogLS0tLS0tLS0tLSBBUEkgZm9yIE9SRVMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5BUEkuZ2V0T1JFUyA9IGZ1bmN0aW9uKHJldmlzaW9uSUQpIHtcclxuXHRyZXR1cm4gJC5nZXQoXCJodHRwczovL29yZXMud2lraW1lZGlhLm9yZy92My9zY29yZXMvZW53aWtpP21vZGVscz1hcnRpY2xlcXVhbGl0eSZyZXZpZHM9XCIrcmV2aXNpb25JRCk7XHJcbn07XHJcblxyXG4vKiAtLS0tLS0tLS0tIFJhdyB3aWtpdGV4dCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcbkFQSS5nZXRSYXcgPSBmdW5jdGlvbihwYWdlKSB7XHJcblx0cmV0dXJuICQuZ2V0KFwiaHR0cHM6XCIgKyBjb25maWcubXcud2dTZXJ2ZXIgKyBtdy51dGlsLmdldFVybChwYWdlLCB7YWN0aW9uOlwicmF3XCJ9KSlcclxuXHRcdC50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcclxuXHRcdFx0aWYgKCAhZGF0YSApIHtcclxuXHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdChcIm9rLWJ1dC1lbXB0eVwiKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gZGF0YTtcclxuXHRcdH0pO1xyXG59O1xyXG5cclxuLyogLS0tLS0tLS0tLSBFZGl0IHdpdGggcmV0cnkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG4vKipcclxuICogQHBhcmFtIHtTdHJpbmd9IHRpdGxlXHJcbiAqIEBwYXJhbSB7T2JqZWN0P30gcGFyYW1zIGFkZGl0aW9uYWwgcGFyYW1zIGZvciB0aGUgZ2V0IHJlcXVlc3RcclxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0LCBzdHJpbmc+fSBwYWdlLCBzdGFydHRpbWUgdGltZXN0YW1wXHJcbiAqL1xyXG52YXIgZ2V0UGFnZSA9IGZ1bmN0aW9uKHRpdGxlLCBwYXJhbXMpIHtcclxuXHRyZXR1cm4gQVBJLmdldChcclxuXHRcdCQuZXh0ZW5kKFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0XCJhY3Rpb25cIjogXCJxdWVyeVwiLFxyXG5cdFx0XHRcdFwiZm9ybWF0XCI6IFwianNvblwiLFxyXG5cdFx0XHRcdFwiY3VydGltZXN0YW1wXCI6IDEsXHJcblx0XHRcdFx0XCJ0aXRsZXNcIjogdGl0bGUsXHJcblx0XHRcdFx0XCJwcm9wXCI6IFwicmV2aXNpb25zfGluZm9cIixcclxuXHRcdFx0XHRcInJ2cHJvcFwiOiBcImNvbnRlbnR8dGltZXN0YW1wXCIsXHJcblx0XHRcdFx0XCJydnNsb3RzXCI6IFwibWFpblwiXHRcdFx0XHRcdFxyXG5cdFx0XHR9LFxyXG5cdFx0XHRwYXJhbXNcclxuXHRcdClcclxuXHQpLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG5cdFx0dmFyIHBhZ2UgPSBPYmplY3QudmFsdWVzKHJlc3BvbnNlLnF1ZXJ5LnBhZ2VzKVswXTtcclxuXHRcdHZhciBzdGFydHRpbWUgPSByZXNwb25zZS5jdXJ0aW1lc3RhbXA7XHJcblx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlc29sdmUocGFnZSwgc3RhcnR0aW1lKTtcclxuXHR9KTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSBkZXRhaWxzIG9iamVjdCBmcm9tIEFQSVxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RhcnR0aW1lIHRpbWVzdGFtcFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gY2FsbGJhY2sgdGhhdCBwcmVwYXJlcyB0aGUgZWRpdDpcclxuICogIHtPYmplY3R9IHNpbXBsaWZpZWRQYWdlID0+IHtPYmplY3R8UHJvbWlzZTxPYmplY3Q+fSBlZGl0IHBhcmFtc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBwYXJhbXMgZm9yIGVkaXQgcXVlcnlcclxuICovXHJcbnZhciBwcm9jZXNzUGFnZSA9IGZ1bmN0aW9uKHBhZ2UsIHN0YXJ0dGltZSwgdHJhbnNmb3JtKSB7XHJcblx0dmFyIGJhc2V0aW1lc3RhbXAgPSBwYWdlLnJldmlzaW9ucyAmJiBwYWdlLnJldmlzaW9uc1swXS50aW1lc3RhbXA7XHJcblx0dmFyIHNpbXBsaWZpZWRQYWdlID0ge1xyXG5cdFx0cGFnZWlkOiBwYWdlLnBhZ2VpZCxcclxuXHRcdG1pc3Npbmc6IHBhZ2UubWlzc2luZyA9PT0gXCJcIixcclxuXHRcdHJlZGlyZWN0OiBwYWdlLnJlZGlyZWN0ID09PSBcIlwiLFxyXG5cdFx0Y2F0ZWdvcmllczogcGFnZS5jYXRlZ29yaWVzLFxyXG5cdFx0bnM6IHBhZ2UubnMsXHJcblx0XHR0aXRsZTogcGFnZS50aXRsZSxcclxuXHRcdGNvbnRlbnQ6IHBhZ2UucmV2aXNpb25zICYmIHBhZ2UucmV2aXNpb25zWzBdLnNsb3RzLm1haW5bXCIqXCJdXHJcblx0fTtcclxuXHRyZXR1cm4gJC53aGVuKCB0cmFuc2Zvcm0oc2ltcGxpZmllZFBhZ2UpIClcclxuXHRcdC50aGVuKCBlZGl0UGFyYW1zID0+XHJcblx0XHRcdCQuZXh0ZW5kKCB7XHJcblx0XHRcdFx0YWN0aW9uOiBcImVkaXRcIixcclxuXHRcdFx0XHR0aXRsZTogcGFnZS50aXRsZSxcclxuXHRcdFx0XHQvLyBQcm90ZWN0IGFnYWluc3QgZXJyb3JzIGFuZCBjb25mbGljdHNcclxuXHRcdFx0XHRhc3NlcnQ6IFwidXNlclwiLFxyXG5cdFx0XHRcdGJhc2V0aW1lc3RhbXA6IGJhc2V0aW1lc3RhbXAsXHJcblx0XHRcdFx0c3RhcnR0aW1lc3RhbXA6IHN0YXJ0dGltZVxyXG5cdFx0XHR9LCBlZGl0UGFyYW1zIClcclxuXHRcdCk7XHJcbn07XHJcblxyXG4vKiogZWRpdFdpdGhSZXRyeVxyXG4gKiBcclxuICogRWRpdHMgYSBwYWdlLCByZXNvbHZpbmcgZWRpdCBjb25mbGljdHMsIGFuZCByZXRyeWluZyBlZGl0cyB0aGF0IGZhaWwuIFRoZVxyXG4gKiB0cmFuZm9ybSBmdW5jdGlvbiBtYXkgcmV0dXJuIGEgcmVqZWN0ZWQgcHJvbWlzZSBpZiB0aGUgcGFnZSBzaG91bGQgbm90IGJlXHJcbiAqIGVkaXRlZDsgdGhlIEByZXR1cm5zIHtQcm9taXNlfSB3aWxsIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgc2FtZSByZWplY3Rpb25cclxuICogdmFsdWVzLlxyXG4gKiBcclxuICogTm90ZTogVW5saWtlIFttdy5BcGkjRWRpdF0sIGEgbWlzc2luZyBwYWdlIHdpbGwgYmUgY3JlYXRlZCwgdW5sZXNzIHRoZVxyXG4gKiB0cmFuc2Zvcm0gY2FsbGJhY2sgaW5jbHVkZXMgdGhlIFwibm9jcmVhdGVcIiBwYXJhbS5cclxuICogXHJcbiAqIFttdy5BcGkjRWRpdF06IDxodHRwczovL2RvYy53aWtpbWVkaWEub3JnL21lZGlhd2lraS1jb3JlL21hc3Rlci9qcy8jIS9hcGkvbXcuQXBpLnBsdWdpbi5lZGl0PlxyXG4gKiBcclxuICogQHBhcmFtIHtTdHJpbmd9IHRpdGxlIHBhZ2UgdG8gYmUgZWRpdGVkXHJcbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx9IGdldFBhcmFtcyBhZGRpdGlvbmFsIHBhcmFtcyBmb3IgdGhlIGdldCByZXF1ZXN0XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBjYWxsYmFjayB0aGF0IHByZXBhcmVzIHRoZSBlZGl0OlxyXG4gKiAge09iamVjdH0gc2ltcGxpZmllZFBhZ2UgPT4ge09iamVjdHxQcm9taXNlPE9iamVjdD59IHBhcmFtcyBmb3IgQVBJIGVkaXRpbmdcclxuICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0Pn0gcHJvbWlzZSwgcmVzb2x2ZWQgb24gc3VjY2VzcywgcmVqZWN0ZWQgaWZcclxuICogIHBhZ2Ugd2FzIG5vdCBlZGl0ZWRcclxuICovXHJcbkFQSS5lZGl0V2l0aFJldHJ5ID0gZnVuY3Rpb24odGl0bGUsIGdldFBhcmFtcywgdHJhbnNmb3JtKSB7XHJcblx0cmV0dXJuIGdldFBhZ2UodGl0bGUsIGdldFBhcmFtcylcclxuXHRcdC50aGVuKFxyXG5cdFx0Ly8gU3VjY2VzOiBwcm9jZXNzIHRoZSBwYWdlXHJcblx0XHRcdChwYWdlLCBzdGFydHRpbWUpID0+IHByb2Nlc3NQYWdlKHBhZ2UsIHN0YXJ0dGltZSwgdHJhbnNmb3JtKSxcclxuXHRcdFx0Ly8gRmFpbHVyZTogdHJ5IGFnYWluXHJcblx0XHRcdCgpID0+IGdldFBhZ2UodGl0bGUsIGdldFBhcmFtcykudGhlbihwcm9jZXNzUGFnZSwgdHJhbnNmb3JtKVxyXG5cdFx0KVxyXG5cdFx0LnRoZW4oZWRpdFBhcmFtcyA9PlxyXG5cdFx0XHRBUEkucG9zdFdpdGhUb2tlbihcImNzcmZcIiwgZWRpdFBhcmFtcylcclxuXHRcdFx0XHQuY2F0Y2goIGVycm9yQ29kZSA9PiB7XHJcblx0XHRcdFx0XHRpZiAoIGVycm9yQ29kZSA9PT0gXCJlZGl0Y29uZmxpY3RcIiApIHtcclxuXHRcdFx0XHRcdFx0Ly8gVHJ5IGFnYWluLCBzdGFydGluZyBvdmVyXHJcblx0XHRcdFx0XHRcdHJldHVybiBBUEkuZWRpdFdpdGhSZXRyeSh0aXRsZSwgZ2V0UGFyYW1zLCB0cmFuc2Zvcm0pO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0Ly8gVHJ5IGFnYWluXHJcblx0XHRcdFx0XHRyZXR1cm4gQVBJLnBvc3RXaXRoVG9rZW4oXCJjc3JmXCIsIGVkaXRQYXJhbXMpO1xyXG5cdFx0XHRcdH0pXHJcblx0XHQpO1xyXG59O1xyXG5cclxudmFyIG1ha2VFcnJvck1zZyA9IGZ1bmN0aW9uKGZpcnN0LCBzZWNvbmQpIHtcclxuXHR2YXIgY29kZSwgeGhyLCBtZXNzYWdlO1xyXG5cdGlmICggdHlwZW9mIGZpcnN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBzZWNvbmQgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHQvLyBFcnJvcnMgZnJvbSAkLmdldCBiZWluZyByZWplY3RlZCAoT1JFUyAmIFJhdyB3aWtpdGV4dClcclxuXHRcdHZhciBlcnJvck9iaiA9IGZpcnN0LnJlc3BvbnNlSlNPTiAmJiBmaXJzdC5yZXNwb25zZUpTT04uZXJyb3I7XHJcblx0XHRpZiAoIGVycm9yT2JqICkge1xyXG5cdFx0XHQvLyBHb3QgYW4gYXBpLXNwZWNpZmljIGVycm9yIGNvZGUvbWVzc2FnZVxyXG5cdFx0XHRjb2RlID0gZXJyb3JPYmouY29kZTtcclxuXHRcdFx0bWVzc2FnZSA9IGVycm9yT2JqLm1lc3NhZ2U7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR4aHIgPSBmaXJzdDtcclxuXHRcdH1cclxuXHR9IGVsc2UgaWYgKCB0eXBlb2YgZmlyc3QgPT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIHNlY29uZCA9PT0gXCJvYmplY3RcIiApIHtcclxuXHRcdC8vIEVycm9ycyBmcm9tIG13LkFwaSBvYmplY3RcclxuXHRcdHZhciBtd0Vycm9yT2JqID0gc2Vjb25kLmVycm9yO1xyXG5cdFx0aWYgKG13RXJyb3JPYmopIHtcclxuXHRcdFx0Ly8gR290IGFuIGFwaS1zcGVjaWZpYyBlcnJvciBjb2RlL21lc3NhZ2VcclxuXHRcdFx0Y29kZSA9IGVycm9yT2JqLmNvZGU7XHJcblx0XHRcdG1lc3NhZ2UgPSBlcnJvck9iai5pbmZvO1xyXG5cdFx0fSBlbHNlIGlmIChmaXJzdCA9PT0gXCJvay1idXQtZW1wdHlcIikge1xyXG5cdFx0XHRjb2RlID0gbnVsbDtcclxuXHRcdFx0bWVzc2FnZSA9IFwiR290IGFuIGVtcHR5IHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlclwiO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0eGhyID0gc2Vjb25kICYmIHNlY29uZC54aHI7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoY29kZSAmJiBtZXNzYWdlKSB7XHJcblx0XHRyZXR1cm4gYEFQSSBlcnJvciAke2NvZGV9OiAke21lc3NhZ2V9YDtcclxuXHR9IGVsc2UgaWYgKG1lc3NhZ2UpIHtcclxuXHRcdHJldHVybiBgQVBJIGVycm9yOiAke21lc3NhZ2V9YDtcclxuXHR9IGVsc2UgaWYgKHhocikge1xyXG5cdFx0cmV0dXJuIGBIVFRQIGVycm9yICR7eGhyLnN0YXR1c31gO1xyXG5cdH0gZWxzZSBpZiAoXHJcblx0XHR0eXBlb2YgZmlyc3QgPT09IFwic3RyaW5nXCIgJiYgZmlyc3QgIT09IFwiZXJyb3JcIiAmJlxyXG5cdFx0dHlwZW9mIHNlY29uZCA9PT0gXCJzdHJpbmdcIiAmJiBzZWNvbmQgIT09IFwiZXJyb3JcIlxyXG5cdCkge1xyXG5cdFx0cmV0dXJuIGBFcnJvciAke2ZpcnN0fTogJHtzZWNvbmR9YDtcclxuXHR9IGVsc2UgaWYgKHR5cGVvZiBmaXJzdCA9PT0gXCJzdHJpbmdcIiAmJiBmaXJzdCAhPT0gXCJlcnJvclwiKSB7XHJcblx0XHRyZXR1cm4gYEVycm9yOiAke2ZpcnN0fWA7XHJcblx0fSBlbHNlIHtcclxuXHRcdHJldHVybiBcIlVua25vd24gQVBJIGVycm9yXCI7XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQVBJO1xyXG5leHBvcnQgeyBtYWtlRXJyb3JNc2cgfTtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IGNvbmZpZyBmcm9tIFwiLi9jb25maWdcIjtcclxuaW1wb3J0IHsgZ2V0UHJlZnMgfSBmcm9tIFwiLi9wcmVmc1wiO1xyXG5pbXBvcnQgQVBJLCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgc2V0dXBSYXRlciBmcm9tIFwiLi9zZXR1cFwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxudmFyIGF1dG9TdGFydCA9IGZ1bmN0aW9uIGF1dG9TdGFydCgpIHtcclxuXHJcblx0cmV0dXJuIGdldFByZWZzKCkudGhlbihwcmVmcyA9PiB7XHJcblx0XHQvLyBDaGVjayBpZiBwcmVmIGlzIHR1cm5lZCBvZmZcclxuXHRcdGlmICghcHJlZnMuYXV0b3N0YXJ0KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdC8vIENoZWNrIGlmIHByZWYgaXMgdHVybmVkIG9mZiBmb3IgcmVkaXJlY3RzLCBhbmQgY3VycmVudCBwYWdlIGlzIGEgcmVkaXJlY3RcclxuXHRcdGlmICghcHJlZnMuYXV0b3N0YXJ0UmVkaXJlY3RzICYmIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guaW5jbHVkZXMoXCJyZWRpcmVjdD1ub1wiKSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHQvLyBDaGVjayBpZiB2aWV3aW5nIGRpZmYvaGlzdG9yeS9vbGQgdmVyc2lvblxyXG5cdFx0aWYgKC8oYWN0aW9ufGRpZmZ8b2xkaWQpLy50ZXN0KHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IHN1YmplY3RUaXRsZSA9IG13LlRpdGxlLm5ld0Zyb21UZXh0KGNvbmZpZy5tdy53Z1BhZ2VOYW1lKS5nZXRTdWJqZWN0UGFnZSgpO1xyXG5cdFx0Ly8gQ2hlY2sgaWYgc3ViamVjdCBwYWdlIGlzIHRoZSBtYWluIHBhZ2VcclxuXHRcdGlmIChzdWJqZWN0VGl0bGUuZ2V0UHJlZml4ZWRUZXh0KCkgPT09IFwiTWFpbiBQYWdlXCIpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0Ly8gQ2hlY2sgc3ViamVjdCBwYWdlIG5hbWVzcGFjZVxyXG5cdFx0aWYgKFxyXG5cdFx0XHRwcmVmcy5hdXRvc3RhcnROYW1lc3BhY2VzICYmXHJcblx0XHRcdHByZWZzLmF1dG9zdGFydE5hbWVzcGFjZXMubGVuZ3RoICYmXHJcblx0XHRcdCFwcmVmcy5hdXRvc3RhcnROYW1lc3BhY2VzLmluY2x1ZGVzKGNvbmZpZy5tdy53Z05hbWVzcGFjZU51bWJlcilcclxuXHRcdCkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHJcblx0XHQvLyBJZiB0YWxrIHBhZ2UgZG9lcyBub3QgZXhpc3QsIGNhbiBqdXN0IGF1dG9zdGFydFxyXG5cdFx0aWYgKCAkKFwiI2NhLXRhbGsubmV3XCIpLmxlbmd0aCApIHtcclxuXHRcdFx0cmV0dXJuIHNldHVwUmF0ZXIoKTtcclxuXHRcdH1cdFxyXG5cclxuXHRcdC8qIENoZWNrIHRlbXBsYXRlcyBwcmVzZW50IG9uIHRhbGsgcGFnZS4gRmV0Y2hlcyBpbmRpcmVjdGx5IHRyYW5zY2x1ZGVkIHRlbXBsYXRlcywgc28gd2lsbCBmaW5kXHJcblx0XHRcdFRlbXBsYXRlOldQQmFubmVyTWV0YSAoYW5kIGl0cyBzdWJ0ZW1wbGF0ZXMpLiBCdXQgc29tZSBiYW5uZXJzIHN1Y2ggYXMgTUlMSElTVCBkb24ndCB1c2UgdGhhdFxyXG5cdFx0XHRtZXRhIHRlbXBsYXRlLCBzbyB3ZSBhbHNvIGhhdmUgdG8gY2hlY2sgZm9yIHRlbXBsYXRlIHRpdGxlcyBjb250YWluZyAnV2lraVByb2plY3QnXHJcblx0XHQqL1xyXG5cdFx0Y29uc3QgdGFsa1RpdGxlID0gbXcuVGl0bGUubmV3RnJvbVRleHQoY29uZmlnLm13LndnUGFnZU5hbWUpLmdldFRhbGtQYWdlKCk7XHJcblx0XHRyZXR1cm4gQVBJLmdldCh7XHJcblx0XHRcdGFjdGlvbjogXCJxdWVyeVwiLFxyXG5cdFx0XHRmb3JtYXQ6IFwianNvblwiLFxyXG5cdFx0XHRwcm9wOiBcInRlbXBsYXRlc1wiLFxyXG5cdFx0XHR0aXRsZXM6IHRhbGtUaXRsZS5nZXRQcmVmaXhlZFRleHQoKSxcclxuXHRcdFx0dGxuYW1lc3BhY2U6IFwiMTBcIixcclxuXHRcdFx0dGxsaW1pdDogXCI1MDBcIixcclxuXHRcdFx0aW5kZXhwYWdlaWRzOiAxXHJcblx0XHR9KVxyXG5cdFx0XHQudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcclxuXHRcdFx0XHR2YXIgaWQgPSByZXN1bHQucXVlcnkucGFnZWlkcztcclxuXHRcdFx0XHR2YXIgdGVtcGxhdGVzID0gcmVzdWx0LnF1ZXJ5LnBhZ2VzW2lkXS50ZW1wbGF0ZXM7XHJcblx0XHRcdFxyXG5cdFx0XHRcdGlmICggIXRlbXBsYXRlcyApIHtcclxuXHRcdFx0XHRcdHJldHVybiBzZXR1cFJhdGVyKCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcclxuXHRcdFx0XHR2YXIgaGFzV2lraXByb2plY3QgPSB0ZW1wbGF0ZXMuc29tZSh0ZW1wbGF0ZSA9PiAvKFdpa2lQcm9qZWN0fFdQQmFubmVyKS8udGVzdCh0ZW1wbGF0ZS50aXRsZSkpO1xyXG5cdFx0XHRcclxuXHRcdFx0XHRpZiAoICFoYXNXaWtpcHJvamVjdCApIHtcclxuXHRcdFx0XHRcdHJldHVybiBzZXR1cFJhdGVyKCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcclxuXHRcdFx0fSxcclxuXHRcdFx0ZnVuY3Rpb24oY29kZSwganF4aHIpIHtcclxuXHRcdFx0Ly8gU2lsZW50bHkgaWdub3JlIGZhaWx1cmVzIChqdXN0IGxvZyB0byBjb25zb2xlKVxyXG5cdFx0XHRcdGNvbnNvbGUud2FybihcclxuXHRcdFx0XHRcdFwiW1JhdGVyXSBFcnJvciB3aGlsZSBjaGVja2luZyB3aGV0aGVyIHRvIGF1dG9zdGFydC5cIiArXHJcblx0XHRcdFx0KCBjb2RlID09IG51bGwgKSA/IFwiXCIgOiBcIiBcIiArIG1ha2VFcnJvck1zZyhjb2RlLCBqcXhocilcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KCk7XHJcblx0XHRcdH0pO1xyXG5cdH0pO1xyXG5cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGF1dG9TdGFydDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IHtpc0FmdGVyRGF0ZX0gZnJvbSBcIi4vdXRpbFwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxuLyoqIHdyaXRlXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcclxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHZhbFxyXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhbGVEYXlzIE51bWJlciBvZiBkYXlzIGFmdGVyIHdoaWNoIHRoZSBkYXRhIGJlY29tZXMgc3RhbGUgKHVzYWJsZSwgYnV0IHNob3VsZFxyXG4gKiAgYmUgdXBkYXRlZCBmb3IgbmV4dCB0aW1lKS5cclxuICogQHBhcmFtIHtOdW1iZXJ9IGV4cGlyeURheXMgTnVtYmVyIG9mIGRheXMgYWZ0ZXIgd2hpY2ggdGhlIGNhY2hlZCBkYXRhIG1heSBiZSBkZWxldGVkLlxyXG4gKi9cclxuY29uc3Qgd3JpdGUgPSBmdW5jdGlvbihrZXksIHZhbCwgc3RhbGVEYXlzLCBleHBpcnlEYXlzKSB7XHJcblx0dHJ5IHtcclxuXHRcdGNvbnN0IGRlZmF1bHRTdGFsZURheXMgPSAxO1xyXG5cdFx0Y29uc3QgZGVmYXVsdEV4cGlyeURheXMgPSAzMDtcclxuXHRcdGNvbnN0IG1pbGxpc2Vjb25kc1BlckRheSA9IDI0KjYwKjYwKjEwMDA7XHJcblxyXG5cdFx0Y29uc3Qgc3RhbGVEdXJhdGlvbiA9IChzdGFsZURheXMgfHwgZGVmYXVsdFN0YWxlRGF5cykqbWlsbGlzZWNvbmRzUGVyRGF5O1xyXG5cdFx0Y29uc3QgZXhwaXJ5RHVyYXRpb24gPSAoZXhwaXJ5RGF5cyB8fCBkZWZhdWx0RXhwaXJ5RGF5cykqbWlsbGlzZWNvbmRzUGVyRGF5O1xyXG5cclxuXHRcdGNvbnN0IHN0cmluZ1ZhbCA9IEpTT04uc3RyaW5naWZ5KHtcclxuXHRcdFx0dmFsdWU6IHZhbCxcclxuXHRcdFx0c3RhbGVEYXRlOiBuZXcgRGF0ZShEYXRlLm5vdygpICsgc3RhbGVEdXJhdGlvbikudG9JU09TdHJpbmcoKSxcclxuXHRcdFx0ZXhwaXJ5RGF0ZTogbmV3IERhdGUoRGF0ZS5ub3coKSArIGV4cGlyeUR1cmF0aW9uKS50b0lTT1N0cmluZygpXHJcblx0XHR9KTtcclxuXHRcdGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwiUmF0ZXItXCIra2V5LCBzdHJpbmdWYWwpO1xyXG5cdH0gIGNhdGNoKGUpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHlcclxufTtcclxuLyoqIHJlYWRcclxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxyXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fFN0cmluZ3xOdWxsfSBDYWNoZWQgYXJyYXkgb3Igb2JqZWN0LCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IHlldCBjYWNoZWQsXHJcbiAqICAgICAgICAgIG9yIG51bGwgaWYgdGhlcmUgd2FzIGVycm9yLlxyXG4gKi9cclxuY29uc3QgcmVhZCA9IGZ1bmN0aW9uKGtleSkge1xyXG5cdGxldCB2YWw7XHJcblx0dHJ5IHtcclxuXHRcdGNvbnN0IHN0cmluZ1ZhbCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiUmF0ZXItXCIra2V5KTtcclxuXHRcdGlmICggc3RyaW5nVmFsICE9PSBcIlwiICkge1xyXG5cdFx0XHR2YWwgPSBKU09OLnBhcnNlKHN0cmluZ1ZhbCk7XHJcblx0XHR9XHJcblx0fSAgY2F0Y2goZSkge1xyXG5cdFx0Y29uc29sZS5sb2coXCJbUmF0ZXJdIGVycm9yIHJlYWRpbmcgXCIgKyBrZXkgKyBcIiBmcm9tIGxvY2FsU3RvcmFnZSBjYWNoZTpcIik7XHJcblx0XHRjb25zb2xlLmxvZyhcclxuXHRcdFx0XCJcXHRcIiArIGUubmFtZSArIFwiIG1lc3NhZ2U6IFwiICsgZS5tZXNzYWdlICtcclxuXHRcdFx0KCBlLmF0ID8gXCIgYXQ6IFwiICsgZS5hdCA6IFwiXCIpICtcclxuXHRcdFx0KCBlLnRleHQgPyBcIiB0ZXh0OiBcIiArIGUudGV4dCA6IFwiXCIpXHJcblx0XHQpO1xyXG5cdH1cclxuXHRyZXR1cm4gdmFsIHx8IG51bGw7XHJcbn07XHJcblxyXG5jb25zdCBpc1JhdGVyS2V5ID0ga2V5ID0+IGtleSAmJiBrZXkuaW5kZXhPZihcIlJhdGVyLVwiKSA9PT0gMDtcclxuXHJcbmNvbnN0IGNsZWFySXRlbUlmSW52YWxpZCA9IGZ1bmN0aW9uKGtleSkge1xyXG5cdGlmICggIWlzUmF0ZXJLZXkoa2V5KSApIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Y29uc3QgaXRlbSA9IHJlYWQoa2V5LnJlcGxhY2UoXCJSYXRlci1cIixcIlwiKSk7XHJcblx0Y29uc3QgaXNJbnZhbGlkID0gIWl0ZW0gfHwgIWl0ZW0uZXhwaXJ5RGF0ZSB8fCBpc0FmdGVyRGF0ZShpdGVtLmV4cGlyeURhdGUpO1xyXG5cdGlmICggaXNJbnZhbGlkICkge1xyXG5cdFx0bG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oa2V5KTtcclxuXHR9XHJcbn07XHJcblxyXG5jb25zdCBjbGVhckludmFsaWRJdGVtcyA9IGZ1bmN0aW9uKCkge1xyXG5cdC8vIExvb3AgYmFja3dhcmRzIGFzIGxvY2FsU3RvcmFnZSBsZW5ndGggd2lsbCBkZWNyZWFzZSBhcyBpdGVtcyBhcmUgcmVtb3ZlZFxyXG5cdGZvciAobGV0IGkgPSBsb2NhbFN0b3JhZ2UubGVuZ3RoOyBpID49IDA7IGktLSkge1xyXG5cdFx0c2V0VGltZW91dChjbGVhckl0ZW1JZkludmFsaWQsIDEwMCwgbG9jYWxTdG9yYWdlLmtleShpKSk7XHJcblx0fVxyXG59O1xyXG5cclxuY29uc3QgY2xlYXJBbGxJdGVtcyA9IGZ1bmN0aW9uKCkge1xyXG5cdC8vIExvb3AgYmFja3dhcmRzIGFzIGxvY2FsU3RvcmFnZSBsZW5ndGggd2lsbCBkZWNyZWFzZSBhcyBpdGVtcyBhcmUgcmVtb3ZlZFxyXG5cdGZvciAobGV0IGkgPSBsb2NhbFN0b3JhZ2UubGVuZ3RoOyBpID49IDA7IGktLSkge1xyXG5cdFx0bGV0IGtleSA9IGxvY2FsU3RvcmFnZS5rZXkoaSk7XHJcblx0XHRpZiAoaXNSYXRlcktleShrZXkpKSB7XHJcblx0XHRcdGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7XHJcblx0XHR9XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IHsgd3JpdGUsIHJlYWQsIGNsZWFySXRlbUlmSW52YWxpZCwgY2xlYXJJbnZhbGlkSXRlbXMsIGNsZWFyQWxsSXRlbXMgfTtcclxuLy8gPC9ub3dpa2k+IiwiLy8gPG5vd2lraT5cclxuY29uc3QgcGFja2FnZWpzb24gPSByZXF1aXJlKFwiLi4vcGFja2FnZS5qc29uXCIpO1xyXG52YXIgdmVyc2lvbiA9IHBhY2thZ2Vqc29uLnZlcnNpb247XHJcblxyXG4vLyBBIGdsb2JhbCBvYmplY3QgdGhhdCBzdG9yZXMgYWxsIHRoZSBwYWdlIGFuZCB1c2VyIGNvbmZpZ3VyYXRpb24gYW5kIHNldHRpbmdzXHJcbnZhciBjb25maWcgPSB7XHJcblx0Ly8gU2NyaXB0IGluZm9cclxuXHRzY3JpcHQ6IHtcclxuXHRcdC8vIEFkdmVydCB0byBhcHBlbmQgdG8gZWRpdCBzdW1tYXJpZXNcclxuXHRcdGFkdmVydDogIGAgKFtbV1A6UkFURVIjJHt2ZXJzaW9ufXxSYXRlcl1dKWAsXHJcblx0XHR2ZXJzaW9uOiB2ZXJzaW9uXHJcblx0fSxcclxuXHQvLyBEZWZhdWx0IHByZWZlcmVuY2VzLCBpZiB1c2VyIHN1YnBhZ2UgcmF0ZXJQcmVmcy5qc29uIGRvZXMgbm90IGV4aXN0XHJcblx0ZGVmYXVsdFByZWZzOiB7XHJcblx0XHRcImF1dG9zdGFydFwiOiBmYWxzZSxcclxuXHRcdFwiYXV0b3N0YXJ0UmVkaXJlY3RzXCI6IGZhbHNlLFxyXG5cdFx0XCJhdXRvc3RhcnROYW1lc3BhY2VzXCI6IFswXSxcclxuXHRcdFwibWluRm9yU2hlbGxcIjogMSxcclxuXHRcdFwiYnlwYXNzUmVkaXJlY3RzXCI6IHRydWUsXHJcblx0XHRcImF1dG9maWxsQ2xhc3NGcm9tT3RoZXJzXCI6IHRydWUsXHJcblx0XHRcImF1dG9maWxsQ2xhc3NGcm9tT3Jlc1wiOiB0cnVlLFxyXG5cdFx0XCJhdXRvZmlsbEltcG9ydGFuY2VcIjogdHJ1ZSxcclxuXHRcdFwiY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0XCI6IDYsXHJcblx0XHRcIndhdGNobGlzdFwiOiBcInByZWZlcmVuY2VzXCJcclxuXHR9LFxyXG5cdC8vIE1lZGlhV2lraSBjb25maWd1cmF0aW9uIHZhbHVlc1xyXG5cdG13OiBtdy5jb25maWcuZ2V0KCBbXHJcblx0XHRcInNraW5cIixcclxuXHRcdFwid2dQYWdlTmFtZVwiLFxyXG5cdFx0XCJ3Z05hbWVzcGFjZU51bWJlclwiLFxyXG5cdFx0XCJ3Z1VzZXJOYW1lXCIsXHJcblx0XHRcIndnRm9ybWF0dGVkTmFtZXNwYWNlc1wiLFxyXG5cdFx0XCJ3Z01vbnRoTmFtZXNcIixcclxuXHRcdFwid2dSZXZpc2lvbklkXCIsXHJcblx0XHRcIndnU2NyaXB0UGF0aFwiLFxyXG5cdFx0XCJ3Z1NlcnZlclwiLFxyXG5cdFx0XCJ3Z0NhdGVnb3JpZXNcIixcclxuXHRcdFwid2dJc01haW5QYWdlXCJcclxuXHRdICksXHJcblx0YmFubmVyRGVmYXVsdHM6IHtcclxuXHRcdGNsYXNzZXM6IFtcclxuXHRcdFx0XCJGQVwiLFxyXG5cdFx0XHRcIkZMXCIsXHJcblx0XHRcdFwiQVwiLFxyXG5cdFx0XHRcIkdBXCIsXHJcblx0XHRcdFwiQlwiLFxyXG5cdFx0XHRcIkNcIixcclxuXHRcdFx0XCJTdGFydFwiLFxyXG5cdFx0XHRcIlN0dWJcIixcclxuXHRcdFx0XCJMaXN0XCJcclxuXHRcdF0sXHJcblx0XHRpbXBvcnRhbmNlczogW1xyXG5cdFx0XHRcIlRvcFwiLFxyXG5cdFx0XHRcIkhpZ2hcIixcclxuXHRcdFx0XCJNaWRcIixcclxuXHRcdFx0XCJMb3dcIlxyXG5cdFx0XSxcclxuXHRcdGV4dGVuZGVkQ2xhc3NlczogW1xyXG5cdFx0XHRcIkNhdGVnb3J5XCIsXHJcblx0XHRcdFwiRHJhZnRcIixcclxuXHRcdFx0XCJGaWxlXCIsXHJcblx0XHRcdFwiRk1cIixcclxuXHRcdFx0XCJQb3J0YWxcIixcclxuXHRcdFx0XCJQcm9qZWN0XCIsXHJcblx0XHRcdFwiVGVtcGxhdGVcIixcclxuXHRcdFx0XCJCcGx1c1wiLFxyXG5cdFx0XHRcIkZ1dHVyZVwiLFxyXG5cdFx0XHRcIkN1cnJlbnRcIixcclxuXHRcdFx0XCJEaXNhbWJpZ1wiLFxyXG5cdFx0XHRcIk5BXCIsXHJcblx0XHRcdFwiUmVkaXJlY3RcIixcclxuXHRcdFx0XCJCb29rXCJcclxuXHRcdF0sXHJcblx0XHRleHRlbmRlZEltcG9ydGFuY2VzOiBbXHJcblx0XHRcdFwiVG9wXCIsXHJcblx0XHRcdFwiSGlnaFwiLFxyXG5cdFx0XHRcIk1pZFwiLFxyXG5cdFx0XHRcIkxvd1wiLFxyXG5cdFx0XHRcIkJvdHRvbVwiLFxyXG5cdFx0XHRcIk5BXCJcclxuXHRcdF1cclxuXHR9LFxyXG5cdGN1c3RvbUJhbm5lcnM6IHtcclxuXHRcdFwiV2lraVByb2plY3QgTWlsaXRhcnkgaGlzdG9yeVwiOiB7XHJcblx0XHRcdGNsYXNzZXM6IFtcclxuXHRcdFx0XHRcIkZBXCIsXHJcblx0XHRcdFx0XCJGTFwiLFxyXG5cdFx0XHRcdFwiQVwiLFxyXG5cdFx0XHRcdFwiR0FcIixcclxuXHRcdFx0XHRcIkJcIixcclxuXHRcdFx0XHRcIkNcIixcclxuXHRcdFx0XHRcIlN0YXJ0XCIsXHJcblx0XHRcdFx0XCJTdHViXCIsXHJcblx0XHRcdFx0XCJMaXN0XCIsXHJcblx0XHRcdFx0XCJBTFwiLFxyXG5cdFx0XHRcdFwiQkxcIixcclxuXHRcdFx0XHRcIkNMXCIsXHJcblx0XHRcdFx0XCJDYXRlZ29yeVwiLFxyXG5cdFx0XHRcdFwiRHJhZnRcIixcclxuXHRcdFx0XHRcIkZpbGVcIixcclxuXHRcdFx0XHRcIlBvcnRhbFwiLFxyXG5cdFx0XHRcdFwiUHJvamVjdFwiLFxyXG5cdFx0XHRcdFwiVGVtcGxhdGVcIixcclxuXHRcdFx0XHRcIkRpc2FtYmlnXCIsXHJcblx0XHRcdFx0XCJSZWRpcmVjdFwiLFxyXG5cdFx0XHRcdFwiQm9va1wiXHRcdFx0XHJcblx0XHRcdF0sXHJcblx0XHRcdGltcG9ydGFuY2VzOiBbXVxyXG5cdFx0fSxcclxuXHRcdFwiV2lraVByb2plY3QgUG9ydGFsc1wiOiB7XHJcblx0XHRcdGNsYXNzZXM6IFtcclxuXHRcdFx0XHRcIkZQb1wiLFxyXG5cdFx0XHRcdFwiQ29tcGxldGVcIixcclxuXHRcdFx0XHRcIlN1YnN0YW50aWFsXCIsXHJcblx0XHRcdFx0XCJCYXNpY1wiLFxyXG5cdFx0XHRcdFwiSW5jb21wbGV0ZVwiLFxyXG5cdFx0XHRcdFwiTWV0YVwiLFxyXG5cdFx0XHRcdFwiTGlzdFwiLFxyXG5cdFx0XHRcdFwiQ2F0ZWdvcnlcIixcclxuXHRcdFx0XHRcIkRyYWZ0XCIsXHJcblx0XHRcdFx0XCJGaWxlXCIsXHJcblx0XHRcdFx0XCJQcm9qZWN0XCIsXHJcblx0XHRcdFx0XCJUZW1wbGF0ZVwiLFxyXG5cdFx0XHRcdFwiRGlzYW1iaWdcIixcclxuXHRcdFx0XHRcIk5BXCIsXHJcblx0XHRcdFx0XCJSZWRpcmVjdFwiXHJcblx0XHRcdF0sXHJcblx0XHRcdGltcG9ydGFuY2VzOiBbXHJcblx0XHRcdFx0XCJUb3BcIixcclxuXHRcdFx0XHRcIkhpZ2hcIixcclxuXHRcdFx0XHRcIk1pZFwiLFxyXG5cdFx0XHRcdFwiTG93XCIsXHJcblx0XHRcdFx0XCJCb3R0b21cIixcclxuXHRcdFx0XHRcIk5BXCJcclxuXHRcdFx0XVxyXG5cdFx0fSxcclxuXHRcdFwiV2lraVByb2plY3QgVmlkZW8gZ2FtZXNcIjoge1xyXG5cdFx0XHRjbGFzc2VzOiBbXHJcblx0XHRcdFx0XCJGQVwiLFwiRkxcIixcIkZNXCIsXCJHQVwiLFwiQlwiLFwiQ1wiLFwiU3RhcnRcIixcIlN0dWJcIixcIkxpc3RcIixcIkNhdGVnb3J5XCIsXCJEcmFmdFwiLFwiRmlsZVwiLFwiUG9ydGFsXCIsXCJQcm9qZWN0XCIsXCJUZW1wbGF0ZVwiLFwiRGlzYW1iaWdcIixcIlJlZGlyZWN0XCJcclxuXHRcdFx0XSxcclxuXHRcdFx0aW1wb3J0YW5jZXM6IFtcclxuXHRcdFx0XHRcIlRvcFwiLFwiSGlnaFwiLFwiTWlkXCIsXCJMb3dcIixcIk5BXCJcclxuXHRcdFx0XVxyXG5cdFx0fVxyXG5cdH0sXHJcblx0c2hlbGxUZW1wbGF0ZXM6IFtcclxuXHRcdFwiV2lraVByb2plY3QgYmFubmVyIHNoZWxsXCIsXHJcblx0XHRcIldpa2lQcm9qZWN0QmFubmVyc1wiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBCYW5uZXJzXCIsXHJcblx0XHRcIldQQlwiLFxyXG5cdFx0XCJXUEJTXCIsXHJcblx0XHRcIldpa2lwcm9qZWN0YmFubmVyc2hlbGxcIixcclxuXHRcdFwiV2lraVByb2plY3QgQmFubmVyIFNoZWxsXCIsXHJcblx0XHRcIldwYlwiLFxyXG5cdFx0XCJXUEJhbm5lclNoZWxsXCIsXHJcblx0XHRcIldwYnNcIixcclxuXHRcdFwiV2lraXByb2plY3RiYW5uZXJzXCIsXHJcblx0XHRcIldQIEJhbm5lciBTaGVsbFwiLFxyXG5cdFx0XCJXUCBiYW5uZXIgc2hlbGxcIixcclxuXHRcdFwiQmFubmVyc2hlbGxcIixcclxuXHRcdFwiV2lraXByb2plY3QgYmFubmVyIHNoZWxsXCIsXHJcblx0XHRcIldpa2lQcm9qZWN0IEJhbm5lcnMgU2hlbGxcIixcclxuXHRcdFwiV2lraVByb2plY3RCYW5uZXIgU2hlbGxcIixcclxuXHRcdFwiV2lraVByb2plY3RCYW5uZXJTaGVsbFwiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBCYW5uZXJTaGVsbFwiLFxyXG5cdFx0XCJXaWtpcHJvamVjdEJhbm5lclNoZWxsXCIsXHJcblx0XHRcIldpa2lQcm9qZWN0IGJhbm5lciBzaGVsbC9yZWRpcmVjdFwiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBTaGVsbFwiLFxyXG5cdFx0XCJCYW5uZXIgc2hlbGxcIixcclxuXHRcdFwiU2NvcGUgc2hlbGxcIixcclxuXHRcdFwiUHJvamVjdCBzaGVsbFwiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBiYW5uZXJcIlxyXG5cdF0sXHJcblx0ZGVmYXVsdFBhcmFtZXRlckRhdGE6IHtcclxuXHRcdFwiYXV0b1wiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJBdXRvLXJhdGVkXCJcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJkZXNjcmlwdGlvblwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIkF1dG9tYXRpY2FsbHkgcmF0ZWQgYnkgYSBib3QuIEFsbG93ZWQgdmFsdWVzOiBbJ3llcyddLlwiXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiYXV0b3ZhbHVlXCI6IFwieWVzXCJcclxuXHRcdH0sXHJcblx0XHRcImxpc3Rhc1wiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJMaXN0IGFzXCJcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJkZXNjcmlwdGlvblwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIlNvcnRrZXkgZm9yIHRhbGsgcGFnZVwiXHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblx0XHRcInNtYWxsXCI6IHtcclxuXHRcdFx0XCJsYWJlbFwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIlNtYWxsP1wiLFxyXG5cdFx0XHR9LFxyXG5cdFx0XHRcImRlc2NyaXB0aW9uXCI6IHtcclxuXHRcdFx0XHRcImVuXCI6IFwiRGlzcGxheSBhIHNtYWxsIHZlcnNpb24uIEFsbG93ZWQgdmFsdWVzOiBbJ3llcyddLlwiXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiYXV0b3ZhbHVlXCI6IFwieWVzXCJcclxuXHRcdH0sXHJcblx0XHRcImF0dGVudGlvblwiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJBdHRlbnRpb24gcmVxdWlyZWQ/XCIsXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiZGVzY3JpcHRpb25cIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJJbW1lZGlhdGUgYXR0ZW50aW9uIHJlcXVpcmVkLiBBbGxvd2VkIHZhbHVlczogWyd5ZXMnXS5cIlxyXG5cdFx0XHR9LFxyXG5cdFx0XHRcImF1dG92YWx1ZVwiOiBcInllc1wiXHJcblx0XHR9LFxyXG5cdFx0XCJuZWVkcy1pbWFnZVwiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJOZWVkcyBpbWFnZT9cIixcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJkZXNjcmlwdGlvblwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIlJlcXVlc3QgdGhhdCBhbiBpbWFnZSBvciBwaG90b2dyYXBoIG9mIHRoZSBzdWJqZWN0IGJlIGFkZGVkIHRvIHRoZSBhcnRpY2xlLiBBbGxvd2VkIHZhbHVlczogWyd5ZXMnXS5cIlxyXG5cdFx0XHR9LFxyXG5cdFx0XHRcImFsaWFzZXNcIjogW1xyXG5cdFx0XHRcdFwibmVlZHMtcGhvdG9cIlxyXG5cdFx0XHRdLFxyXG5cdFx0XHRcImF1dG92YWx1ZVwiOiBcInllc1wiLFxyXG5cdFx0XHRcInN1Z2dlc3RlZFwiOiB0cnVlXHJcblx0XHR9LFxyXG5cdFx0XCJuZWVkcy1pbmZvYm94XCI6IHtcclxuXHRcdFx0XCJsYWJlbFwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIk5lZWRzIGluZm9ib3g/XCIsXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiZGVzY3JpcHRpb25cIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJSZXF1ZXN0IHRoYXQgYW4gaW5mb2JveCBiZSBhZGRlZCB0byB0aGUgYXJ0aWNsZS4gQWxsb3dlZCB2YWx1ZXM6IFsneWVzJ10uXCJcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJhbGlhc2VzXCI6IFtcclxuXHRcdFx0XHRcIm5lZWRzLXBob3RvXCJcclxuXHRcdFx0XSxcclxuXHRcdFx0XCJhdXRvdmFsdWVcIjogXCJ5ZXNcIixcclxuXHRcdFx0XCJzdWdnZXN0ZWRcIjogdHJ1ZVxyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNvbmZpZztcclxuLy8gPC9ub3dpa2k+IiwiLy8gPG5vd2lraT5cclxuXHJcbi8vIEF0dHJpYnV0aW9uOiBEaWZmIHN0eWxlcyBiYXNlZCBvbiA8aHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvV2lraXBlZGlhOkF1dG9XaWtpQnJvd3Nlci9zdHlsZS5jc3M+XHJcbmNvbnN0IHN0eWxlcyA9IGB0YWJsZS5kaWZmLCB0ZC5kaWZmLW90aXRsZSwgdGQuZGlmZi1udGl0bGUgeyB0YWJsZS1sYXlvdXQ6IGF1dG8gIWltcG9ydGFudDs7IH1cclxudGQuZGlmZi1vdGl0bGUsIHRkLmRpZmYtbnRpdGxlIHsgdGV4dC1hbGlnbjogY2VudGVyOyB9XHJcbnRkLmRpZmYtbWFya2VyIHsgdGV4dC1hbGlnbjogcmlnaHQ7IGZvbnQtd2VpZ2h0OiBib2xkOyBmb250LXNpemU6IDEuMjVlbTsgfVxyXG50ZC5kaWZmLWxpbmVubyB7IGZvbnQtd2VpZ2h0OiBib2xkOyB9XHJcbnRkLmRpZmYtYWRkZWRsaW5lLCB0ZC5kaWZmLWRlbGV0ZWRsaW5lLCB0ZC5kaWZmLWNvbnRleHQgeyBmb250LXNpemU6IDg4JTsgdmVydGljYWwtYWxpZ246IHRvcDsgd2hpdGUtc3BhY2U6IC1tb3otcHJlLXdyYXA7IHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsgfVxyXG50ZC5kaWZmLWFkZGVkbGluZSwgdGQuZGlmZi1kZWxldGVkbGluZSB7IGJvcmRlci1zdHlsZTogc29saWQ7IGJvcmRlci13aWR0aDogMXB4IDFweCAxcHggNHB4OyBib3JkZXItcmFkaXVzOiAwLjMzZW07IH1cclxudGQuZGlmZi1hZGRlZGxpbmUgeyBib3JkZXItY29sb3I6ICNhM2QzZmY7IH1cclxudGQuZGlmZi1kZWxldGVkbGluZSB7IGJvcmRlci1jb2xvcjogI2ZmZTQ5YzsgfVxyXG50ZC5kaWZmLWNvbnRleHQgeyBiYWNrZ3JvdW5kOiAjZjNmM2YzOyBjb2xvcjogIzMzMzMzMzsgYm9yZGVyLXN0eWxlOiBzb2xpZDsgYm9yZGVyLXdpZHRoOiAxcHggMXB4IDFweCA0cHg7IGJvcmRlci1jb2xvcjogI2U2ZTZlNjsgYm9yZGVyLXJhZGl1czogMC4zM2VtOyB9XHJcbi5kaWZmY2hhbmdlIHsgZm9udC13ZWlnaHQ6IGJvbGQ7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfVxyXG50YWJsZS5kaWZmIHtcclxuICAgIGJvcmRlcjogbm9uZTtcclxuICAgIHdpZHRoOiA5OCU7IGJvcmRlci1zcGFjaW5nOiA0cHg7XHJcbiAgICB0YWJsZS1sYXlvdXQ6IGZpeGVkOyAvKiBFbnN1cmVzIHRoYXQgY29sdW1zIGFyZSBvZiBlcXVhbCB3aWR0aCAqL1xyXG59XHJcbnRkLmRpZmYtYWRkZWRsaW5lIC5kaWZmY2hhbmdlLCB0ZC5kaWZmLWRlbGV0ZWRsaW5lIC5kaWZmY2hhbmdlIHsgYm9yZGVyLXJhZGl1czogMC4zM2VtOyBwYWRkaW5nOiAwLjI1ZW0gMDsgfVxyXG50ZC5kaWZmLWFkZGVkbGluZSAuZGlmZmNoYW5nZSB7XHRiYWNrZ3JvdW5kOiAjZDhlY2ZmOyB9XHJcbnRkLmRpZmYtZGVsZXRlZGxpbmUgLmRpZmZjaGFuZ2UgeyBiYWNrZ3JvdW5kOiAjZmVlZWM4OyB9XHJcbnRhYmxlLmRpZmYgdGQge1x0cGFkZGluZzogMC4zM2VtIDAuNjZlbTsgfVxyXG50YWJsZS5kaWZmIGNvbC5kaWZmLW1hcmtlciB7IHdpZHRoOiAyJTsgfVxyXG50YWJsZS5kaWZmIGNvbC5kaWZmLWNvbnRlbnQgeyB3aWR0aDogNDglOyB9XHJcbnRhYmxlLmRpZmYgdGQgZGl2IHtcclxuICAgIC8qIEZvcmNlLXdyYXAgdmVyeSBsb25nIGxpbmVzIHN1Y2ggYXMgVVJMcyBvciBwYWdlLXdpZGVuaW5nIGNoYXIgc3RyaW5ncy4gKi9cclxuICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDtcclxuICAgIC8qIEFzIGZhbGxiYWNrIChGRjwzLjUsIE9wZXJhIDwxMC41KSwgc2Nyb2xsYmFycyB3aWxsIGJlIGFkZGVkIGZvciB2ZXJ5IHdpZGUgY2VsbHNcclxuICAgICAgICBpbnN0ZWFkIG9mIHRleHQgb3ZlcmZsb3dpbmcgb3Igd2lkZW5pbmcgKi9cclxuICAgIG92ZXJmbG93OiBhdXRvO1xyXG59YCArXHJcblxyXG4vLyBPdmVycmlkZSBPT1VJIHdpbmRvdyBtYW5hZ2VyIHByZXZlbnRpbmcgYmFja2dyb3VuZCBzY3JvbGxpbmcvaW50ZXJhY3Rpb24uXHJcbi8vIFNjb3BlZCB0byBSYXRlcidzIG93biB3aW5kb3cgbWFuYWdlciAoLnJhdGVyLXdpbmRvd01hbmFnZXIpLCBzbyB0aGF0IG90aGVyXHJcbi8vIE9PVUkgZGlhbG9ncyAoZS5nLiBPTy51aS5jb25maXJtIGluICNtdy10ZWxlcG9ydC10YXJnZXQpIGtlZXAgdGhlaXIgZGVmYXVsdFxyXG4vLyBmaXhlZCBwb3NpdGlvbmluZyBhbmQgcmVtYWluIHZpc2libGUuXHJcbmBodG1sIGJvZHkucmF0ZXItbWFpbldpbmRvdy1vcGVuIHtcclxuXHRwb3NpdGlvbjogdW5zZXQ7XHJcblx0b3ZlcmZsb3c6IHVuc2V0O1xyXG59XHJcbmh0bWwgYm9keS5yYXRlci1tYWluV2luZG93LW9wZW4gLnJhdGVyLXdpbmRvd01hbmFnZXIgPiAub28tdWktZGlhbG9nLm9vLXVpLXdpbmRvdy1hY3RpdmUge1xyXG4gICAgcG9zaXRpb246IHN0YXRpYztcclxuICAgIHBhZGRpbmc6IDA7XHJcbn1gICtcclxuLy8gSW5jcmVhc2Ugei1pbmRleCwgdG8gYmUgYWJvdmUgc2tpbiBtZW51cyBldGM7IHNtb290aCB0cmFuc2l0aW9uIGZvciBkcmFnZ2luZyAodHJhbnNmb3JtOnRyYW5zbGF0ZSlcclxuLy8gNDAwIGtlZXBzIFJhdGVyIGFib3ZlIFRpbWVsZXNzIHNpZGViYXIgZHJvcGRvd25zICguc2lkZWJhci1pbm5lciwgMzUwKSAvIG1lbnVzLWNvdmVyICgzMDApIC9cclxuLy8gZml4ZWQgaGVhZGVyICgyMDApLCBidXQgYmVsb3cgI213LXRlbGVwb3J0LXRhcmdldCAoNDUwKSBzbyBPTy51aS5jb25maXJtIGRpYWxvZ3Mgc3RheSBvbiB0b3AuXHJcbmBodG1sIGJvZHkucmF0ZXItbWFpbldpbmRvdy1vcGVuIC5yYXRlci13aW5kb3dNYW5hZ2VyID4gLm9vLXVpLWRpYWxvZy5vby11aS13aW5kb3ctYWN0aXZlID4gZGl2IHtcclxuICAgIHotaW5kZXg6IDQwMDtcclxuICAgIHRyYW5zaXRpb246IGFsbCAwLjI1cyBlYXNlLW91dCAwcywgdHJhbnNmb3JtIDBzICFpbXBvcnRhbnRcclxufVxyXG5gO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgc3R5bGVzO1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgQVBJLCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgeyBpc0FmdGVyRGF0ZSB9IGZyb20gXCIuL3V0aWxcIjtcclxuaW1wb3J0ICogYXMgY2FjaGUgZnJvbSBcIi4vY2FjaGVcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbnZhciBjYWNoZUJhbm5lcnMgPSBmdW5jdGlvbihiYW5uZXJzKSB7XHJcblx0Y2FjaGUud3JpdGUoXCJiYW5uZXJzXCIsIGJhbm5lcnMsIDIsIDYwKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIGJhbm5lcnMvb3B0aW9ucyBmcm9tIHRoZSBBcGlcclxuICogXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlfSBSZXNvbHZlZCB3aXRoOiBiYW5uZXJzIG9iamVjdCwgYmFubmVyT3B0aW9ucyBhcnJheVxyXG4gKi9cclxudmFyIGdldExpc3RPZkJhbm5lcnNGcm9tQXBpID0gZnVuY3Rpb24oKSB7XHJcblxyXG5cdHZhciBmaW5pc2hlZFByb21pc2UgPSAkLkRlZmVycmVkKCk7XHJcblxyXG5cdHZhciBxdWVyeVNrZWxldG9uID0ge1xyXG5cdFx0YWN0aW9uOiBcInF1ZXJ5XCIsXHJcblx0XHRmb3JtYXQ6IFwianNvblwiLFxyXG5cdFx0bGlzdDogXCJjYXRlZ29yeW1lbWJlcnNcIixcclxuXHRcdGNtcHJvcDogXCJ0aXRsZVwiLFxyXG5cdFx0Y21uYW1lc3BhY2U6IFwiMTBcIixcclxuXHRcdGNtbGltaXQ6IFwiNTAwXCJcclxuXHR9O1xyXG5cclxuXHR2YXIgY2F0ZWdvcmllcyA9IFtcclxuXHRcdHtcclxuXHRcdFx0dGl0bGU6IFwiQ2F0ZWdvcnk6V2lraVByb2plY3QgYmFubmVycyB3aXRoIHF1YWxpdHkgYXNzZXNzbWVudFwiLFxyXG5cdFx0XHRhYmJyZXZpYXRpb246IFwid2l0aFJhdGluZ3NcIixcclxuXHRcdFx0YmFubmVyczogW10sXHJcblx0XHRcdHByb2Nlc3NlZDogJC5EZWZlcnJlZCgpXHJcblx0XHR9LFxyXG5cdFx0e1xyXG5cdFx0XHR0aXRsZTogXCJDYXRlZ29yeTpXaWtpUHJvamVjdCBiYW5uZXJzIHdpdGhvdXQgcXVhbGl0eSBhc3Nlc3NtZW50XCIsXHJcblx0XHRcdGFiYnJldmlhdGlvbjogXCJ3aXRob3V0UmF0aW5nc1wiLFxyXG5cdFx0XHRiYW5uZXJzOiBbXSxcclxuXHRcdFx0cHJvY2Vzc2VkOiAkLkRlZmVycmVkKClcclxuXHRcdH0sXHJcblx0XHR7XHJcblx0XHRcdHRpdGxlOiBcIkNhdGVnb3J5Oldpa2lQcm9qZWN0IGJhbm5lciB3cmFwcGVyIHRlbXBsYXRlc1wiLFxyXG5cdFx0XHRhYmJyZXZpYXRpb246IFwid3JhcHBlcnNcIixcclxuXHRcdFx0YmFubmVyczogW10sXHJcblx0XHRcdHByb2Nlc3NlZDogJC5EZWZlcnJlZCgpXHJcblx0XHR9LFxyXG5cdFx0e1xyXG5cdFx0XHR0aXRsZTogXCJDYXRlZ29yeTpXaWtpUHJvamVjdCBiYW5uZXIgdGVtcGxhdGVzIG5vdCBiYXNlZCBvbiBXUEJhbm5lck1ldGFcIixcclxuXHRcdFx0YWJicmV2aWF0aW9uOiBcIm5vdFdQQk1cIixcclxuXHRcdFx0YmFubmVyczogW10sXHJcblx0XHRcdHByb2Nlc3NlZDogJC5EZWZlcnJlZCgpXHJcblx0XHR9LFxyXG5cdFx0e1xyXG5cdFx0XHR0aXRsZTogXCJDYXRlZ29yeTpJbmFjdGl2ZSBXaWtpUHJvamVjdCBiYW5uZXJzXCIsXHJcblx0XHRcdGFiYnJldmlhdGlvbjogXCJpbmFjdGl2ZVwiLFxyXG5cdFx0XHRiYW5uZXJzOiBbXSxcclxuXHRcdFx0cHJvY2Vzc2VkOiAkLkRlZmVycmVkKClcclxuXHRcdH0sXHJcblx0XHR7XHJcblx0XHRcdHRpdGxlOiBcIkNhdGVnb3J5OldyYXBwZXIgdGVtcGxhdGVzIGZvciBXaWtpUHJvamVjdCBXb21lbiBpbiBSZWRcIixcclxuXHRcdFx0YWJicmV2aWF0aW9uOiBcIndpclwiLFxyXG5cdFx0XHRiYW5uZXJzOiBbXSxcclxuXHRcdFx0cHJvY2Vzc2VkOiAkLkRlZmVycmVkKClcclxuXHRcdH1cclxuXHRdO1xyXG5cclxuXHR2YXIgcHJvY2Vzc1F1ZXJ5ID0gZnVuY3Rpb24ocmVzdWx0LCBjYXRJbmRleCkge1xyXG5cdFx0aWYgKCAhcmVzdWx0LnF1ZXJ5IHx8ICFyZXN1bHQucXVlcnkuY2F0ZWdvcnltZW1iZXJzICkge1xyXG5cdFx0XHQvLyBObyByZXN1bHRzXHJcblx0XHRcdC8vIFRPRE86IGVycm9yIG9yIHdhcm5pbmcgKioqKioqKipcclxuXHRcdFx0ZmluaXNoZWRQcm9taXNlLnJlamVjdCgpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdC8vIEdhdGhlciB0aXRsZXMgaW50byBhcnJheSAtIGV4Y2x1ZGluZyBcIlRlbXBsYXRlOlwiIHByZWZpeFxyXG5cdFx0dmFyIHJlc3VsdFRpdGxlcyA9IHJlc3VsdC5xdWVyeS5jYXRlZ29yeW1lbWJlcnMubWFwKGZ1bmN0aW9uKGluZm8pIHtcclxuXHRcdFx0cmV0dXJuIGluZm8udGl0bGUuc2xpY2UoOSk7XHJcblx0XHR9KTtcclxuXHRcdEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNhdGVnb3JpZXNbY2F0SW5kZXhdLmJhbm5lcnMsIHJlc3VsdFRpdGxlcyk7XHJcblx0XHRcclxuXHRcdC8vIENvbnRpbnVlIHF1ZXJ5IGlmIG5lZWRlZFxyXG5cdFx0aWYgKCByZXN1bHQuY29udGludWUgKSB7XHJcblx0XHRcdGRvQXBpUXVlcnkoJC5leHRlbmQoY2F0ZWdvcmllc1tjYXRJbmRleF0ucXVlcnksIHJlc3VsdC5jb250aW51ZSksIGNhdEluZGV4KTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHRjYXRlZ29yaWVzW2NhdEluZGV4XS5wcm9jZXNzZWQucmVzb2x2ZSgpO1xyXG5cdH07XHJcblxyXG5cdHZhciBkb0FwaVF1ZXJ5ID0gZnVuY3Rpb24ocSwgY2F0SW5kZXgpIHtcclxuXHRcdEFQSS5nZXQoIHEgKVxyXG5cdFx0XHQuZG9uZSggZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHRcdFx0cHJvY2Vzc1F1ZXJ5KHJlc3VsdCwgY2F0SW5kZXgpO1xyXG5cdFx0XHR9IClcclxuXHRcdFx0LmZhaWwoIGZ1bmN0aW9uKGNvZGUsIGpxeGhyKSB7XHJcblx0XHRcdFx0Y29uc29sZS53YXJuKFwiW1JhdGVyXSBcIiArIG1ha2VFcnJvck1zZyhjb2RlLCBqcXhociwgXCJDb3VsZCBub3QgcmV0cmlldmUgcGFnZXMgZnJvbSBbWzpcIiArIHEuY210aXRsZSArIFwiXV1cIikpO1xyXG5cdFx0XHRcdGZpbmlzaGVkUHJvbWlzZS5yZWplY3QoKTtcclxuXHRcdFx0fSApO1xyXG5cdH07XHJcblx0XHJcblx0Y2F0ZWdvcmllcy5mb3JFYWNoKGZ1bmN0aW9uKGNhdCwgaW5kZXgsIGFycikge1xyXG5cdFx0Y2F0LnF1ZXJ5ID0gJC5leHRlbmQoIHsgXCJjbXRpdGxlXCI6Y2F0LnRpdGxlIH0sIHF1ZXJ5U2tlbGV0b24gKTtcclxuXHRcdCQud2hlbiggYXJyW2luZGV4LTFdICYmIGFycltpbmRleC0xXS5wcm9jZXNzZWQgfHwgdHJ1ZSApLnRoZW4oZnVuY3Rpb24oKXtcclxuXHRcdFx0ZG9BcGlRdWVyeShjYXQucXVlcnksIGluZGV4KTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdFxyXG5cdGNhdGVnb3JpZXNbY2F0ZWdvcmllcy5sZW5ndGgtMV0ucHJvY2Vzc2VkLnRoZW4oZnVuY3Rpb24oKXtcclxuXHRcdGxldCBiYW5uZXJzID0ge307XHJcblx0XHRjYXRlZ29yaWVzLmZvckVhY2goY2F0T2JqZWN0ID0+IHtcclxuXHRcdFx0YmFubmVyc1tjYXRPYmplY3QuYWJicmV2aWF0aW9uXSA9IGNhdE9iamVjdC5iYW5uZXJzO1xyXG5cdFx0fSk7XHJcblx0XHRcclxuXHRcdGZpbmlzaGVkUHJvbWlzZS5yZXNvbHZlKGJhbm5lcnMpO1xyXG5cdH0pO1xyXG5cdFxyXG5cdHJldHVybiBmaW5pc2hlZFByb21pc2U7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyBiYW5uZXJzIGZyb20gY2FjaGUsIGlmIHRoZXJlIGFuZCBub3QgdG9vIG9sZFxyXG4gKiBcclxuICogQHJldHVybnMge1Byb21pc2V9IFJlc29sdmVkIHdpdGggYmFubmVycyBvYmplY3RcclxuICovXHJcbnZhciBnZXRCYW5uZXJzRnJvbUNhY2hlID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIGNhY2hlZEJhbm5lcnMgPSBjYWNoZS5yZWFkKFwiYmFubmVyc1wiKTtcclxuXHRpZiAoXHJcblx0XHQhY2FjaGVkQmFubmVycyB8fFxyXG5cdFx0IWNhY2hlZEJhbm5lcnMudmFsdWUgfHxcclxuXHRcdCFjYWNoZWRCYW5uZXJzLnN0YWxlRGF0ZVxyXG5cdCkge1xyXG5cdFx0cmV0dXJuICQuRGVmZXJyZWQoKS5yZWplY3QoKTtcclxuXHR9XHJcblx0aWYgKCBpc0FmdGVyRGF0ZShjYWNoZWRCYW5uZXJzLnN0YWxlRGF0ZSkgKSB7XHJcblx0XHQvLyBVcGRhdGUgaW4gdGhlIGJhY2tncm91bmQ7IHN0aWxsIHVzZSBvbGQgbGlzdCB1bnRpbCB0aGVuICBcclxuXHRcdGdldExpc3RPZkJhbm5lcnNGcm9tQXBpKCkudGhlbihjYWNoZUJhbm5lcnMpO1xyXG5cdH1cclxuXHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlc29sdmUoY2FjaGVkQmFubmVycy52YWx1ZSk7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyBiYW5uZXIgbmFtZXMsIGdyb3VwZWQgYnkgdHlwZSAod2l0aFJhdGluZ3MsIHdpdGhvdXRSYXRpbmdzLCB3cmFwcGVycywgbm90V1BCTSlcclxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gT2JqZWN0IG9mIHN0cmluZyBhcnJheXMga2V5ZWQgYnkgdHlwZSAod2l0aFJhdGluZ3MsIHdpdGhvdXRSYXRpbmdzLCB3cmFwcGVycywgbm90V1BCTSlcclxuICovXHJcbnZhciBnZXRCYW5uZXJOYW1lcyA9ICgpID0+IGdldEJhbm5lcnNGcm9tQ2FjaGUoKVxyXG5cdC50aGVuKCBiYW5uZXJzID0+IHtcclxuXHRcdC8vIEVuc3VyZSBhbGwga2V5cyBleGlzdFxyXG5cdFx0aWYgKCFiYW5uZXJzLndpdGhSYXRpbmdzIHx8ICFiYW5uZXJzLndpdGhvdXRSYXRpbmdzIHx8ICFiYW5uZXJzLndyYXBwZXJzIHx8ICFiYW5uZXJzLm5vdFdQQk0gfHwgIWJhbm5lcnMuaW5hY3RpdmUgfHwgIWJhbm5lcnMud2lyKSB7XHJcblx0XHRcdGdldExpc3RPZkJhbm5lcnNGcm9tQXBpKCkudGhlbihjYWNoZUJhbm5lcnMpO1xyXG5cdFx0XHRyZXR1cm4gJC5leHRlbmQoXHJcblx0XHRcdFx0eyB3aXRoUmF0aW5nczogW10sIHdpdGhvdXRSYXRpbmdzOiBbXSwgd3JhcHBlcnM6IFtdLCBub3RXUEJNOiBbXSwgaW5hY3RpdmU6IFtdLCB3aXI6IFtdIH0sXHJcblx0XHRcdFx0YmFubmVyc1xyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gU3VjY2VzczogcGFzcyB0aHJvdWdoXHJcblx0XHRyZXR1cm4gYmFubmVycztcclxuXHR9IClcclxuXHQuY2F0Y2goICgpID0+IHtcclxuXHRcdC8vIEZhaWx1cmU6IGdldCBmcm9tIEFwaSwgdGhlbiBjYWNoZSB0aGVtXHJcblx0XHRsZXQgYmFubmVyc1Byb21pc2UgPSBnZXRMaXN0T2ZCYW5uZXJzRnJvbUFwaSgpO1xyXG5cdFx0YmFubmVyc1Byb21pc2UudGhlbihjYWNoZUJhbm5lcnMpO1xyXG5cdFx0cmV0dXJuIGJhbm5lcnNQcm9taXNlO1xyXG5cdH0gKTtcclxuXHJcbmV4cG9ydCB7IGdldEJhbm5lck5hbWVzIH07XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCBBUEkgZnJvbSBcIi4vYXBpXCI7XHJcbmltcG9ydCB7IGlzQWZ0ZXJEYXRlIH0gZnJvbSBcIi4vdXRpbFwiO1xyXG5pbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG5pbXBvcnQgKiBhcyBjYWNoZSBmcm9tIFwiLi9jYWNoZVwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxuY29uc3QgcHJlZnNQYWdlID0gYFVzZXI6JHttdy5jb25maWcuZ2V0KFwid2dVc2VyTmFtZVwiKX0vcmF0ZXJQcmVmcy5qc29uYDtcclxuXHJcbmNvbnN0IHdyaXRlUHJlZnNUb0NhY2hlID0gcHJlZnMgPT4gY2FjaGUud3JpdGUoXHJcblx0XCJwcmVmc1wiLFxyXG5cdHByZWZzLFxyXG5cdCgxLzI0LzYwKSoxLCAvLyAxIG1pblxyXG5cdCgxLzI0LzYwKSoxICAvLyAxIG1pblxyXG4pO1xyXG5cclxuY29uc3QgZ2V0UHJlZnNGcm9tQXBpID0gZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIEFQSS5nZXQoe1xyXG5cdFx0XCJhY3Rpb25cIjogXCJxdWVyeVwiLFxyXG5cdFx0XCJmb3JtYXRcIjogXCJqc29uXCIsXHJcblx0XHRcInByb3BcIjogXCJyZXZpc2lvbnNcIixcclxuXHRcdFwidGl0bGVzXCI6IHByZWZzUGFnZSxcclxuXHRcdFwicnZwcm9wXCI6IFwiY29udGVudFwiLFxyXG5cdFx0XCJydnNsb3RzXCI6IFwibWFpblwiXHJcblx0fSkudGhlbihyZXNwb25zZSA9PiB7XHJcblx0XHRjb25zdCBwYWdlID0gcmVzcG9uc2UucXVlcnkucGFnZXNbT2JqZWN0LmtleXMocmVzcG9uc2UucXVlcnkucGFnZXMpWzBdXTtcclxuXHRcdGlmICghcGFnZS5wYWdlaWQgfHwgcGFnZS5taXNzaW5nPT09XCJcIikge1xyXG5cdFx0XHRyZXR1cm4gY29uZmlnLmRlZmF1bHRQcmVmcztcclxuXHRcdH1cclxuXHRcdGxldCBwcmVmcztcclxuXHRcdHRyeSB7XHJcblx0XHRcdHByZWZzID0gSlNPTi5wYXJzZSggcGFnZS5yZXZpc2lvbnNbMF0uc2xvdHMubWFpbltcIipcIl0gKTtcclxuXHRcdH0gY2F0Y2goZSkge1xyXG5cdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdChcIkpTT04tcGFyc2luZy1lcnJvclwiLCBlKTtcclxuXHRcdH1cclxuXHRcdHdyaXRlUHJlZnNUb0NhY2hlKHByZWZzKTtcclxuXHRcdHJldHVybiBwcmVmcztcclxuXHR9KTtcclxufTtcclxuXHJcbmNvbnN0IGdldFByZWZzRnJvbUNhY2hlID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIGNhY2hlZFByZWZzID0gY2FjaGUucmVhZChcInByZWZzXCIpO1xyXG5cdGlmIChcclxuXHRcdCFjYWNoZWRQcmVmcyB8fFxyXG5cdFx0IWNhY2hlZFByZWZzLnZhbHVlIHx8XHJcblx0XHQhY2FjaGVkUHJlZnMuc3RhbGVEYXRlIHx8XHJcblx0XHRpc0FmdGVyRGF0ZShjYWNoZWRQcmVmcy5zdGFsZURhdGUpXHJcblx0KSB7XHJcblx0XHQvLyBObyBjYWNoZWQgdmFsdWUsIG9yIGlzIHRvbyBvbGRcclxuXHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KCk7XHJcblx0fVxyXG5cdHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZShjYWNoZWRQcmVmcy52YWx1ZSk7XHJcbn07XHJcblxyXG5jb25zdCBnZXRQcmVmcyA9ICgpID0+IGdldFByZWZzRnJvbUNhY2hlKCkudGhlbihcclxuXHQvLyBTdWNjZXNzOiBwYXNzIHRocm91Z2ggKGZpcnN0IHBhcmFtIG9ubHkpXHJcblx0cHJlZnMgPT4gJC5EZWZlcnJlZCgpLnJlc29sdmUocHJlZnMpLFxyXG5cdC8vIEZhaWx1cmU6IGdldCBmcm9tIEFwaVxyXG5cdCgpID0+IGdldFByZWZzRnJvbUFwaSgpXHJcbik7XHJcblxyXG4vKipcclxuICogXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSB1cGRhdGVkUHJlZnMgb2JqZWN0IHdpdGgga2V5OnZhbHVlIHBhaXJzIGZvciBwcmVmZXJlbmNlcyBqc29uLlxyXG4gKi9cclxuY29uc3Qgc2V0UHJlZnMgPSBmdW5jdGlvbih1cGRhdGVkUHJlZnMpIHtcclxuXHRyZXR1cm4gQVBJLmVkaXRXaXRoUmV0cnkocHJlZnNQYWdlLFx0bnVsbCxcclxuXHRcdCgpID0+ICh7XHJcblx0XHRcdFwidGV4dFwiOiBKU09OLnN0cmluZ2lmeSh1cGRhdGVkUHJlZnMpLFxyXG5cdFx0XHRcInN1bW1hcnlcIjogXCJTYXZpbmcgUmF0ZXIgcHJlZmVyZW5jZXMgXCIgKyBjb25maWcuc2NyaXB0LmFkdmVydFxyXG5cdFx0fSlcclxuXHQpXHJcblx0XHQudGhlbiggKCkgPT4gd3JpdGVQcmVmc1RvQ2FjaGUodXBkYXRlZFByZWZzKSApO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgKHtnZXQ6IGdldFByZWZzLCBzZXQ6IHNldFByZWZzfSk7XHJcbmV4cG9ydCB7IGdldFByZWZzLCBzZXRQcmVmcyB9O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG5pbXBvcnQgQVBJIGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgeyBwYXJzZVRlbXBsYXRlcywgZ2V0V2l0aFJlZGlyZWN0VG8gfSBmcm9tIFwiLi9UZW1wbGF0ZVwiO1xyXG5pbXBvcnQge2dldEJhbm5lck5hbWVzfSBmcm9tIFwiLi9nZXRCYW5uZXJzXCI7XHJcbmltcG9ydCAqIGFzIGNhY2hlIGZyb20gXCIuL2NhY2hlXCI7XHJcbmltcG9ydCB3aW5kb3dNYW5hZ2VyIGZyb20gXCIuL3dpbmRvd01hbmFnZXJcIjtcclxuaW1wb3J0IHsgZ2V0UHJlZnMgfSBmcm9tIFwiLi9wcmVmc1wiO1xyXG5pbXBvcnQgeyBmaWx0ZXJBbmRNYXAgfSBmcm9tIFwiLi91dGlsXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG52YXIgc2V0dXBSYXRlciA9IGZ1bmN0aW9uKGNsaWNrRXZlbnQpIHtcclxuXHRpZiAoIGNsaWNrRXZlbnQgKSB7XHJcblx0XHRjbGlja0V2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0fVxyXG5cclxuXHR2YXIgc2V0dXBDb21wbGV0ZWRQcm9taXNlID0gJC5EZWZlcnJlZCgpO1xyXG4gICAgXHJcblx0dmFyIGN1cnJlbnRQYWdlID0gbXcuVGl0bGUubmV3RnJvbVRleHQoY29uZmlnLm13LndnUGFnZU5hbWUpO1xyXG5cdHZhciB0YWxrUGFnZSA9IGN1cnJlbnRQYWdlICYmIGN1cnJlbnRQYWdlLmdldFRhbGtQYWdlKCk7XHJcblx0dmFyIHN1YmplY3RQYWdlID0gY3VycmVudFBhZ2UgJiYgY3VycmVudFBhZ2UuZ2V0U3ViamVjdFBhZ2UoKTtcclxuXHR2YXIgc3ViamVjdElzQXJ0aWNsZSA9IGNvbmZpZy5tdy53Z05hbWVzcGFjZU51bWJlciA8PSAxO1xyXG4gXHJcblx0Ly8gR2V0IHByZWZlcmVuY2VzICh0YXNrIDApXHJcblx0dmFyIHByZWZzUHJvbWlzZSA9IGdldFByZWZzKCk7XHJcblxyXG5cdC8vIEdldCBsaXN0cyBvZiBhbGwgYmFubmVycyAodGFzayAxKVxyXG5cdHZhciBiYW5uZXJzUHJvbWlzZSA9IGdldEJhbm5lck5hbWVzKCk7XHJcblxyXG5cdC8vIExvYWQgdGFsayBwYWdlICh0YXNrIDIpXHJcblx0dmFyIGxvYWRUYWxrUHJvbWlzZSA9IEFQSS5nZXQoIHtcclxuXHRcdGFjdGlvbjogXCJxdWVyeVwiLFxyXG5cdFx0cHJvcDogXCJyZXZpc2lvbnNcIixcclxuXHRcdHJ2cHJvcDogXCJjb250ZW50XCIsXHJcblx0XHRydnNlY3Rpb246IFwiMFwiLFxyXG5cdFx0dGl0bGVzOiB0YWxrUGFnZS5nZXRQcmVmaXhlZFRleHQoKSxcclxuXHRcdGluZGV4cGFnZWlkczogMVxyXG5cdH0gKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcclxuXHRcdHZhciBpZCA9IHJlc3VsdC5xdWVyeS5wYWdlaWRzO1x0XHRcclxuXHRcdHZhciB3aWtpdGV4dCA9ICggaWQgPCAwICkgPyBcIlwiIDogcmVzdWx0LnF1ZXJ5LnBhZ2VzW2lkXS5yZXZpc2lvbnNbMF1bXCIqXCJdO1xyXG5cdFx0cmV0dXJuIHdpa2l0ZXh0O1xyXG5cdH0pO1xyXG5cclxuXHQvLyBQYXJzZSB0YWxrIHBhZ2UgZm9yIGJhbm5lcnMgKHRhc2sgMylcclxuXHR2YXIgcGFyc2VUYWxrUHJvbWlzZSA9IGxvYWRUYWxrUHJvbWlzZS50aGVuKHdpa2l0ZXh0ID0+IHBhcnNlVGVtcGxhdGVzKHdpa2l0ZXh0LCB0cnVlKSkgLy8gR2V0IGFsbCB0ZW1wbGF0ZXNcclxuXHRcdC50aGVuKHRlbXBsYXRlcyA9PiB0ZW1wbGF0ZXMuZmlsdGVyKHRlbXBsYXRlID0+IHRlbXBsYXRlLmdldFRpdGxlKCkgIT09IG51bGwpKSAvLyBGaWx0ZXIgb3V0IGludmFsaWQgdGVtcGxhdGVzIChlLmcuIHBhcnNlciBmdW5jdGlvbnMpXHJcblx0XHQudGhlbih0ZW1wbGF0ZXMgPT4gZ2V0V2l0aFJlZGlyZWN0VG8odGVtcGxhdGVzKSkgLy8gQ2hlY2sgZm9yIHJlZGlyZWN0c1xyXG5cdFx0LnRoZW4odGVtcGxhdGVzID0+IHtcclxuXHRcdFx0cmV0dXJuIGJhbm5lcnNQcm9taXNlLnRoZW4oKGFsbEJhbm5lcnMpID0+IHsgLy8gR2V0IGxpc3Qgb2YgYWxsIGJhbm5lciB0ZW1wbGF0ZXNcclxuXHRcdFx0XHRyZXR1cm4gZmlsdGVyQW5kTWFwKFxyXG5cdFx0XHRcdFx0dGVtcGxhdGVzLCBcdFx0XHRcclxuXHRcdFx0XHRcdC8vIEZpbHRlciBvdXQgbm9uLWJhbm5lcnNcclxuXHRcdFx0XHRcdHRlbXBsYXRlID0+IHsgXHJcblx0XHRcdFx0XHRcdGlmICh0ZW1wbGF0ZS5pc1NoZWxsVGVtcGxhdGUoKSkgeyByZXR1cm4gdHJ1ZTsgfVxyXG5cdFx0XHRcdFx0XHR2YXIgbWFpblRleHQgPSB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldFxyXG5cdFx0XHRcdFx0XHRcdD8gdGVtcGxhdGUucmVkaXJlY3RUYXJnZXQuZ2V0TWFpblRleHQoKVxyXG5cdFx0XHRcdFx0XHRcdDogdGVtcGxhdGUuZ2V0VGl0bGUoKS5nZXRNYWluVGV4dCgpO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gYWxsQmFubmVycy53aXRoUmF0aW5ncy5pbmNsdWRlcyhtYWluVGV4dCkgfHwgXHJcblx0XHRcdFx0XHRcdGFsbEJhbm5lcnMud2l0aG91dFJhdGluZ3MuaW5jbHVkZXMobWFpblRleHQpIHx8XHJcblx0XHRcdFx0XHRcdGFsbEJhbm5lcnMud3JhcHBlcnMuaW5jbHVkZXMobWFpblRleHQpIHx8XHJcblx0XHRcdFx0XHRcdGFsbEJhbm5lcnMubm90V1BCTS5pbmNsdWRlcyhtYWluVGV4dCkgfHxcclxuXHRcdFx0XHRcdFx0YWxsQmFubmVycy5pbmFjdGl2ZS5pbmNsdWRlcyhtYWluVGV4dCkgfHxcclxuXHRcdFx0XHRcdFx0YWxsQmFubmVycy53aXIuaW5jbHVkZXMobWFpblRleHQpO1xyXG5cdFx0XHRcdFx0fSxcclxuXHRcdFx0XHRcdC8vIFNldCBhZGRpdGlvbmFsIHByb3BlcnRpZXMgaWYgbmVlZGVkXHJcblx0XHRcdFx0XHR0ZW1wbGF0ZSA9PiB7XHJcblx0XHRcdFx0XHRcdHZhciBtYWluVGV4dCA9IHRlbXBsYXRlLnJlZGlyZWN0VGFyZ2V0XHJcblx0XHRcdFx0XHRcdFx0PyB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldC5nZXRNYWluVGV4dCgpXHJcblx0XHRcdFx0XHRcdFx0OiB0ZW1wbGF0ZS5nZXRUaXRsZSgpLmdldE1haW5UZXh0KCk7XHJcblx0XHRcdFx0XHRcdGlmIChhbGxCYW5uZXJzLndyYXBwZXJzLmluY2x1ZGVzKG1haW5UZXh0KSkge1xyXG5cdFx0XHRcdFx0XHRcdHRlbXBsYXRlLnJlZGlyZWN0VGFyZ2V0ID0gbXcuVGl0bGUubmV3RnJvbVRleHQoXCJUZW1wbGF0ZTpTdWJzdDpcIiArIG1haW5UZXh0KTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHRcdFx0YWxsQmFubmVycy53aXRob3V0UmF0aW5ncy5pbmNsdWRlcyhtYWluVGV4dCkgfHxcclxuXHRcdFx0XHRcdFx0XHRhbGxCYW5uZXJzLndpci5pbmNsdWRlcyhtYWluVGV4dClcclxuXHRcdFx0XHRcdFx0KSB7XHJcblx0XHRcdFx0XHRcdFx0dGVtcGxhdGUud2l0aG91dFJhdGluZ3MgPSB0cnVlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGlmICggYWxsQmFubmVycy5pbmFjdGl2ZS5pbmNsdWRlcyhtYWluVGV4dCkgKSB7XHJcblx0XHRcdFx0XHRcdFx0dGVtcGxhdGUuaW5hY3RpdmVQcm9qZWN0ID0gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRyZXR1cm4gdGVtcGxhdGU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHRcclxuXHQvLyBSZXRyaWV2ZSBhbmQgc3RvcmUgY2xhc3NlcywgaW1wb3J0YW5jZXMsIGFuZCBUZW1wbGF0ZURhdGEgKHRhc2sgNClcclxuXHR2YXIgdGVtcGxhdGVEZXRhaWxzUHJvbWlzZSA9IHBhcnNlVGFsa1Byb21pc2UudGhlbihmdW5jdGlvbih0ZW1wbGF0ZXMpIHtcclxuXHRcdC8vIFdhaXQgZm9yIGFsbCBwcm9taXNlcyB0byByZXNvbHZlXHJcblx0XHRyZXR1cm4gJC53aGVuLmFwcGx5KG51bGwsIFtcclxuXHRcdFx0Li4udGVtcGxhdGVzLm1hcCh0ZW1wbGF0ZSA9PiB0ZW1wbGF0ZS5pc1NoZWxsVGVtcGxhdGUoKSA/IG51bGwgOiB0ZW1wbGF0ZS5zZXRDbGFzc2VzQW5kSW1wb3J0YW5jZXMoKSksXHJcblx0XHRcdC4uLnRlbXBsYXRlcy5tYXAodGVtcGxhdGUgPT4gdGVtcGxhdGUuc2V0UGFyYW1EYXRhQW5kU3VnZ2VzdGlvbnMoKSlcclxuXHRcdF0pLnRoZW4oKCkgPT4ge1xyXG5cdFx0XHQvLyBBZGQgbWlzc2luZyByZXF1aXJlZC9zdWdnZXN0ZWQgdmFsdWVzXHJcblx0XHRcdHRlbXBsYXRlcy5mb3JFYWNoKHRlbXBsYXRlID0+IHRlbXBsYXRlLmFkZE1pc3NpbmdQYXJhbXMoKSk7XHJcblx0XHRcdC8vIFJldHVybiB0aGUgbm93LW1vZGlmaWVkIHRlbXBsYXRlc1xyXG5cdFx0XHRyZXR1cm4gdGVtcGxhdGVzO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblxyXG5cdC8vIENoZWNrIHN1YmplY3QgcGFnZSBmZWF0dXJlcyAodGFzayA1KSAtIGJ1dCBkb24ndCBlcnJvciBvdXQgaWYgcmVxdWVzdCBmYWlsc1xyXG5cdHZhciBzdWJqZWN0UGFnZUNoZWNrUHJvbWlzZSA9IEFQSS5nZXQoe1xyXG5cdFx0YWN0aW9uOiBcInF1ZXJ5XCIsXHJcblx0XHRmb3JtYXQ6IFwianNvblwiLFxyXG5cdFx0Zm9ybWF0dmVyc2lvbjogXCIyXCIsXHJcblx0XHRwcm9wOiBcImNhdGVnb3JpZXNcIixcclxuXHRcdHRpdGxlczogc3ViamVjdFBhZ2UuZ2V0UHJlZml4ZWRUZXh0KCksXHJcblx0XHRyZWRpcmVjdHM6IDEsXHJcblx0XHRjbGNhdGVnb3JpZXM6IFtcclxuXHRcdFx0XCJDYXRlZ29yeTpBbGwgZGlzYW1iaWd1YXRpb24gcGFnZXNcIixcclxuXHRcdFx0XCJDYXRlZ29yeTpBbGwgc3R1YiBhcnRpY2xlc1wiLFxyXG5cdFx0XHRcIkNhdGVnb3J5Okdvb2QgYXJ0aWNsZXNcIixcclxuXHRcdFx0XCJDYXRlZ29yeTpGZWF0dXJlZCBhcnRpY2xlc1wiLFxyXG5cdFx0XHRcIkNhdGVnb3J5OkZlYXR1cmVkIGxpc3RzXCJcclxuXHRcdF1cclxuXHR9KS50aGVuKHJlc3BvbnNlID0+IHtcclxuXHRcdGlmICggIXJlc3BvbnNlIHx8ICFyZXNwb25zZS5xdWVyeSB8fCAhcmVzcG9uc2UucXVlcnkucGFnZXMgKSB7XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgcmVkaXJlY3RUYXJnZXQgPSByZXNwb25zZS5xdWVyeS5yZWRpcmVjdHMgJiYgcmVzcG9uc2UucXVlcnkucmVkaXJlY3RzWzBdLnRvIHx8IGZhbHNlO1xyXG5cdFx0aWYgKCByZWRpcmVjdFRhcmdldCB8fCAhc3ViamVjdElzQXJ0aWNsZSApIHtcclxuXHRcdFx0cmV0dXJuIHsgcmVkaXJlY3RUYXJnZXQgfTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IHBhZ2UgPSByZXNwb25zZS5xdWVyeS5wYWdlc1swXTtcclxuXHRcdGNvbnN0IGhhc0NhdGVnb3J5ID0gY2F0ZWdvcnkgPT4gcGFnZS5jYXRlZ29yaWVzICYmIHBhZ2UuY2F0ZWdvcmllcy5maW5kKGNhdCA9PiBjYXQudGl0bGUgPT09IFwiQ2F0ZWdvcnk6XCIrY2F0ZWdvcnkpO1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0cmVkaXJlY3RUYXJnZXQsXHJcblx0XHRcdGRpc2FtYmlnOiBoYXNDYXRlZ29yeShcIkFsbCBkaXNhbWJpZ3VhdGlvbiBwYWdlc1wiKSxcclxuXHRcdFx0c3R1YnRhZzogaGFzQ2F0ZWdvcnkoXCJBbGwgc3R1YiBhcnRpY2xlc1wiKSxcclxuXHRcdFx0aXNHQTogaGFzQ2F0ZWdvcnkoXCJHb29kIGFydGljbGVzXCIpLFxyXG5cdFx0XHRpc0ZBOiBoYXNDYXRlZ29yeShcIkZlYXR1cmVkIGFydGljbGVzXCIpLFxyXG5cdFx0XHRpc0ZMOiBoYXNDYXRlZ29yeShcIkZlYXR1cmVkIGxpc3RzXCIpLFxyXG5cdFx0XHRpc0xpc3Q6ICFoYXNDYXRlZ29yeShcIkZlYXR1cmVkIGxpc3RzXCIpICYmIC9eTGlzdHM/IG9mLy50ZXN0KHN1YmplY3RQYWdlLmdldFByZWZpeGVkVGV4dCgpKVxyXG5cdFx0fTtcclxuXHR9KS5jYXRjaCgoKSA9PiBudWxsKTsgLy8gRmFpbHVyZSBpZ25vcmVkXHJcblxyXG5cdC8vIFJldHJpZXZlIHJhdGluZyBmcm9tIE9SRVMgKHRhc2sgNiwgb25seSBuZWVkZWQgZm9yIGFydGljbGVzKSAtIGJ1dCBkb24ndCBlcnJvciBvdXQgaWYgcmVxdWVzdCBmYWlsc1xyXG5cdHZhciBzaG91bGRHZXRPcmVzID0gKCBzdWJqZWN0SXNBcnRpY2xlICk7IC8vIFRPRE86IERvbid0IG5lZWQgdG8gZ2V0IE9SRVMgZm9yIHJlZGlyZWN0cyBvciBkaXNhbWJpZ3NcclxuXHRpZiAoIHNob3VsZEdldE9yZXMgKSB7XHJcblx0XHR2YXIgbGF0ZXN0UmV2SWRQcm9taXNlID0gIWN1cnJlbnRQYWdlLmlzVGFsa1BhZ2UoKVxyXG5cdFx0XHQ/ICQuRGVmZXJyZWQoKS5yZXNvbHZlKGNvbmZpZy5tdy53Z1JldmlzaW9uSWQpXHJcblx0XHRcdDogQVBJLmdldCgge1xyXG5cdFx0XHRcdGFjdGlvbjogXCJxdWVyeVwiLFxyXG5cdFx0XHRcdGZvcm1hdDogXCJqc29uXCIsXHJcblx0XHRcdFx0cHJvcDogXCJyZXZpc2lvbnNcIixcclxuXHRcdFx0XHR0aXRsZXM6IHN1YmplY3RQYWdlLmdldFByZWZpeGVkVGV4dCgpLFxyXG5cdFx0XHRcdHJ2cHJvcDogXCJpZHNcIixcclxuXHRcdFx0XHRpbmRleHBhZ2VpZHM6IDFcclxuXHRcdFx0fSApLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHRcdFx0aWYgKHJlc3VsdC5xdWVyeS5yZWRpcmVjdHMpIHtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dmFyIGlkID0gcmVzdWx0LnF1ZXJ5LnBhZ2VpZHM7XHJcblx0XHRcdFx0dmFyIHBhZ2UgPSByZXN1bHQucXVlcnkucGFnZXNbaWRdO1xyXG5cdFx0XHRcdGlmIChwYWdlLm1pc3NpbmcgPT09IFwiXCIpIHtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCBpZCA8IDAgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdCgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gcGFnZS5yZXZpc2lvbnNbMF0ucmV2aWQ7XHJcblx0XHRcdH0pO1xyXG5cdFx0dmFyIG9yZXNQcm9taXNlID0gbGF0ZXN0UmV2SWRQcm9taXNlLnRoZW4oZnVuY3Rpb24obGF0ZXN0UmV2SWQpIHtcclxuXHRcdFx0aWYgKCFsYXRlc3RSZXZJZCkge1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gQVBJLmdldE9SRVMobGF0ZXN0UmV2SWQpXHJcblx0XHRcdFx0LnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHRcdFx0XHR2YXIgZGF0YSA9IHJlc3VsdC5lbndpa2kuc2NvcmVzW2xhdGVzdFJldklkXS5hcnRpY2xlcXVhbGl0eTtcclxuXHRcdFx0XHRcdGlmICggZGF0YS5lcnJvciApIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuICQuRGVmZXJyZWQoKS5yZWplY3QoZGF0YS5lcnJvci50eXBlLCBkYXRhLmVycm9yLm1lc3NhZ2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0Y29uc3QgcHJlZGljdGlvbiA9IGRhdGEuc2NvcmUucHJlZGljdGlvbjtcclxuXHRcdFx0XHRcdGNvbnN0IHByb2JhYmlsaXRpZXMgPSBkYXRhLnNjb3JlLnByb2JhYmlsaXR5O1xyXG5cdFx0XHRcdFx0aWYgKHByZWRpY3Rpb24gPT09IFwiRkFcIiB8fCBwcmVkaWN0aW9uID09PSBcIkdBXCIpIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0XHRwcmVkaWN0aW9uOiBcIkIgb3IgaGlnaGVyXCIsXHJcblx0XHRcdFx0XHRcdFx0cHJvYmFiaWxpdHk6ICgocHJvYmFiaWxpdGllcy5GQSArIHByb2JhYmlsaXRpZXMuR0EgKyBwcm9iYWJpbGl0aWVzLkIpKjEwMCkudG9GaXhlZCgxKStcIiVcIlxyXG5cdFx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0cHJlZGljdGlvbixcclxuXHRcdFx0XHRcdFx0cHJvYmFiaWxpdHk6IChwcm9iYWJpbGl0aWVzWyBwcmVkaWN0aW9uIF0qMTAwKS50b0ZpeGVkKDEpK1wiJVwiXHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH0pLmNhdGNoKCgpID0+IG51bGwpOyAvLyBGYWlsdXJlIGlnbm9yZWQ7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdC8vIE9wZW4gdGhlIGxvYWQgZGlhbG9nXHJcblx0dmFyIGlzT3BlbmVkUHJvbWlzZSA9ICQuRGVmZXJyZWQoKTtcclxuXHR2YXIgbG9hZERpYWxvZ1dpbiA9IHdpbmRvd01hbmFnZXIub3BlbldpbmRvdyhcImxvYWREaWFsb2dcIiwge1xyXG5cdFx0cHJvbWlzZXM6IFtcclxuXHRcdFx0YmFubmVyc1Byb21pc2UsXHJcblx0XHRcdGxvYWRUYWxrUHJvbWlzZSxcclxuXHRcdFx0cGFyc2VUYWxrUHJvbWlzZSxcclxuXHRcdFx0dGVtcGxhdGVEZXRhaWxzUHJvbWlzZSxcclxuXHRcdFx0c3ViamVjdFBhZ2VDaGVja1Byb21pc2UsXHJcblx0XHRcdHNob3VsZEdldE9yZXMgJiYgb3Jlc1Byb21pc2VcclxuXHRcdF0sXHJcblx0XHRvcmVzOiBzaG91bGRHZXRPcmVzLFxyXG5cdFx0aXNPcGVuZWQ6IGlzT3BlbmVkUHJvbWlzZVxyXG5cdH0pO1xyXG5cclxuXHRsb2FkRGlhbG9nV2luLm9wZW5lZC50aGVuKGlzT3BlbmVkUHJvbWlzZS5yZXNvbHZlKTtcclxuXHJcblxyXG5cdCQud2hlbihcclxuXHRcdHByZWZzUHJvbWlzZSxcclxuXHRcdGxvYWRUYWxrUHJvbWlzZSxcclxuXHRcdHRlbXBsYXRlRGV0YWlsc1Byb21pc2UsXHJcblx0XHRzdWJqZWN0UGFnZUNoZWNrUHJvbWlzZSxcclxuXHRcdHNob3VsZEdldE9yZXMgJiYgb3Jlc1Byb21pc2VcclxuXHQpLnRoZW4oXHJcblx0XHQvLyBBbGwgc3VjY2VkZWRcclxuXHRcdGZ1bmN0aW9uKHByZWZlcmVuY2VzLCB0YWxrV2lraXRleHQsIGJhbm5lcnMsIHN1YmplY3RQYWdlQ2hlY2ssIG9yZXNQcmVkaWNpdGlvbiApIHtcclxuXHRcdFx0dmFyIHJlc3VsdCA9IHtcclxuXHRcdFx0XHRzdWNjZXNzOiB0cnVlLFxyXG5cdFx0XHRcdHRhbGtwYWdlOiB0YWxrUGFnZSxcclxuXHRcdFx0XHRzdWJqZWN0UGFnZTogc3ViamVjdFBhZ2UsXHJcblx0XHRcdFx0dGFsa1dpa2l0ZXh0OiB0YWxrV2lraXRleHQsXHJcblx0XHRcdFx0YmFubmVyczogYmFubmVycyxcclxuXHRcdFx0XHRwcmVmZXJlbmNlczogcHJlZmVyZW5jZXMsXHJcblx0XHRcdFx0aXNBcnRpY2xlOiBzdWJqZWN0SXNBcnRpY2xlXHJcblx0XHRcdH07XHJcblx0XHRcdGlmIChzdWJqZWN0UGFnZUNoZWNrKSB7XHJcblx0XHRcdFx0cmVzdWx0ID0geyAuLi5yZXN1bHQsIC4uLnN1YmplY3RQYWdlQ2hlY2sgfTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAob3Jlc1ByZWRpY2l0aW9uICYmIHN1YmplY3RQYWdlQ2hlY2sgJiYgIXN1YmplY3RQYWdlQ2hlY2suaXNHQSAmJiAhc3ViamVjdFBhZ2VDaGVjay5pc0ZBICYmICFzdWJqZWN0UGFnZUNoZWNrLmlzRkwpIHtcclxuXHRcdFx0XHRyZXN1bHQub3JlcyA9IG9yZXNQcmVkaWNpdGlvbjtcclxuXHRcdFx0fVxyXG5cdFx0XHR3aW5kb3dNYW5hZ2VyLmNsb3NlV2luZG93KFwibG9hZERpYWxvZ1wiLCByZXN1bHQpO1xyXG5cdFx0XHRcclxuXHRcdH1cclxuXHQpOyAvLyBBbnkgZmFpbHVyZXMgYXJlIGhhbmRsZWQgYnkgdGhlIGxvYWREaWFsb2cgd2luZG93IGl0c2VsZlxyXG5cclxuXHQvLyBPbiB3aW5kb3cgY2xvc2VkLCBjaGVjayBkYXRhLCBhbmQgcmVzb2x2ZS9yZWplY3Qgc2V0dXBDb21wbGV0ZWRQcm9taXNlXHJcblx0bG9hZERpYWxvZ1dpbi5jbG9zZWQudGhlbihmdW5jdGlvbihkYXRhKSB7XHJcblx0XHRpZiAoZGF0YSAmJiBkYXRhLnN1Y2Nlc3MpIHtcclxuXHRcdFx0Ly8gR290IGV2ZXJ5dGhpbmcgbmVlZGVkOiBSZXNvbHZlIHByb21pc2Ugd2l0aCB0aGlzIGRhdGFcclxuXHRcdFx0c2V0dXBDb21wbGV0ZWRQcm9taXNlLnJlc29sdmUoZGF0YSk7XHJcblx0XHR9IGVsc2UgaWYgKGRhdGEgJiYgZGF0YS5lcnJvcikge1xyXG5cdFx0XHQvLyBUaGVyZSB3YXMgYW4gZXJyb3I6IFJlamVjdCBwcm9taXNlIHdpdGggZXJyb3IgY29kZS9pbmZvXHJcblx0XHRcdHNldHVwQ29tcGxldGVkUHJvbWlzZS5yZWplY3QoZGF0YS5lcnJvci5jb2RlLCBkYXRhLmVycm9yLmluZm8pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Ly8gV2luZG93IGNsb3NlZCBiZWZvcmUgY29tcGxldGlvbjogcmVzb2x2ZSBwcm9taXNlIHdpdGhvdXQgYW55IGRhdGFcclxuXHRcdFx0c2V0dXBDb21wbGV0ZWRQcm9taXNlLnJlc29sdmUobnVsbCk7XHJcblx0XHR9XHJcblx0XHRjYWNoZS5jbGVhckludmFsaWRJdGVtcygpO1xyXG5cdH0pO1xyXG5cdHJldHVybiBzZXR1cENvbXBsZXRlZFByb21pc2U7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBzZXR1cFJhdGVyO1xyXG4vLyA8L25vd2lraT4iLCIvLyA8bm93aWtpPlxyXG5cclxuLy8gVmFyaW91cyB1dGlsaXR5IGZ1bmN0aW9ucyBhbmQgb2JqZWN0cyB0aGF0IG1pZ2h0IGJlIHVzZWQgaW4gbXVsdGlwbGUgcGxhY2VzXHJcblxyXG52YXIgaXNBZnRlckRhdGUgPSBmdW5jdGlvbihkYXRlU3RyaW5nKSB7XHJcblx0cmV0dXJuIG5ldyBEYXRlKGRhdGVTdHJpbmcpIDwgbmV3IERhdGUoKTtcclxufTtcclxuXHJcbnZhciB5ZXNXb3JkcyA9IFtcclxuXHRcImFkZFwiLFxyXG5cdFwiYWRkZWRcIixcclxuXHRcImFmZmlybVwiLFxyXG5cdFwiYWZmaXJtZWRcIixcclxuXHRcImluY2x1ZGVcIixcclxuXHRcImluY2x1ZGVkXCIsXHJcblx0XCJvblwiLFxyXG5cdFwidHJ1ZVwiLFxyXG5cdFwieWVzXCIsXHJcblx0XCJ5XCIsXHJcblx0XCIxXCJcclxuXTtcclxudmFyIG5vV29yZHMgPSBbXHJcblx0XCJkZWNsaW5lXCIsXHJcblx0XCJkZWNsaW5lZFwiLFxyXG5cdFwiZXhjbHVkZVwiLFxyXG5cdFwiZXhjbHVkZWRcIixcclxuXHRcImZhbHNlXCIsXHJcblx0XCJub25lXCIsXHJcblx0XCJub3RcIixcclxuXHRcIm5vXCIsXHJcblx0XCJuXCIsXHJcblx0XCJvZmZcIixcclxuXHRcIm9taXRcIixcclxuXHRcIm9taXR0ZWRcIixcclxuXHRcInJlbW92ZVwiLFxyXG5cdFwicmVtb3ZlZFwiLFxyXG5cdFwiMFwiXHJcbl07XHJcbnZhciBub3JtYWxpc2VZZXNObyA9IGZ1bmN0aW9uKHZhbCkge1xyXG5cdGlmICh2YWwgPT0gbnVsbCkge1xyXG5cdFx0cmV0dXJuIHZhbDtcclxuXHR9XHJcblx0dmFyIHRyaW1tZWRMY1ZhbCA9IHZhbC50cmltKCkudG9Mb3dlckNhc2UoKTtcclxuXHRpZiAoeWVzV29yZHMuaW5jbHVkZXModHJpbW1lZExjVmFsKSkge1xyXG5cdFx0cmV0dXJuIFwieWVzXCI7XHJcblx0fSBlbHNlIGlmIChub1dvcmRzLmluY2x1ZGVzKHRyaW1tZWRMY1ZhbCkpIHtcclxuXHRcdHJldHVybiBcIm5vXCI7XHJcblx0fSBlbHNlIHtcclxuXHRcdHJldHVybiB0cmltbWVkTGNWYWw7XHJcblx0fVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFxyXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZmlsdGVyUHJlZGljYXRlIChjdXJyZW50VmFsLCBjdXJyZW50SW5kZXgsIGFycmF5KSA9PiB7Ym9vbGVhbn1cclxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWFwVHJhbnNmb3JtIChjdXJyZW50VmFsLCBjdXJyZW50SW5kZXgsIGFycmF5KSA9PiB7YW55fVxyXG4gKiBAcmV0dXJucyB7QXJyYXl9XHJcbiAqL1xyXG52YXIgZmlsdGVyQW5kTWFwID0gZnVuY3Rpb24oYXJyYXksIGZpbHRlclByZWRpY2F0ZSwgbWFwVHJhbnNmb3JtKSB7XHJcblx0cmV0dXJuIGFycmF5LnJlZHVjZShcclxuXHRcdChhY2N1bXVsYXRlZCwgY3VycmVudFZhbCwgY3VycmVudEluZGV4KSA9PiB7XHJcblx0XHRcdGlmIChmaWx0ZXJQcmVkaWNhdGUoY3VycmVudFZhbCwgY3VycmVudEluZGV4LCBhcnJheSkpIHtcclxuXHRcdFx0XHRyZXR1cm4gWy4uLmFjY3VtdWxhdGVkLCBtYXBUcmFuc2Zvcm0oY3VycmVudFZhbCwgY3VycmVudEluZGV4LCBhcnJheSldO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBhY2N1bXVsYXRlZDtcclxuXHRcdH0sXHJcblx0XHRbXVxyXG5cdCk7XHJcbn07XHJcblxyXG4vKipcclxuICogXHJcbiAqIEBwYXJhbSB7c3RyaW5nW118bnVtYmVyW119IGFycmF5IFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGl0ZW0gd2l0aCB0aGUgaGlnaGVzdCBmcmVxdWVuY3lcclxuICogZS5nLiBgbW9zdEZyZXF1ZW50KFtcImFwcGxlXCIsIFwiYXBwbGVcIiwgXCJvcmFuZ2VcIl0pYCByZXR1cm5zIGBcImFwcGxlXCJgXHJcbiAqL1xyXG5mdW5jdGlvbiBtb3N0RnJlcXVlbnQoYXJyYXkpIHtcclxuXHRpZiAoIWFycmF5IHx8ICFBcnJheS5pc0FycmF5KGFycmF5KSB8fCBhcnJheS5sZW5ndGggPT09IDApXHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR2YXIgbWFwID0ge307XHJcblx0dmFyIG1vc3RGcmVxID0gbnVsbDtcclxuXHRhcnJheS5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRtYXBbaXRlbV0gPSAobWFwW2l0ZW1dIHx8IDApICsgMTtcclxuXHRcdGlmIChtb3N0RnJlcSA9PT0gbnVsbCB8fCBtYXBbaXRlbV0gPiBtYXBbbW9zdEZyZXFdKSB7XHJcblx0XHRcdG1vc3RGcmVxID0gaXRlbTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRyZXR1cm4gbW9zdEZyZXE7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBcclxuICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0gYXJyYXkgXHJcbiAqIEByZXR1cm5zIHtzdHJpbmdbXXxudW1iZXJbXX0gYXJyYXkgd2l0aCBvbmx5IHVuaXF1ZSB2YWx1ZXNcclxuICogZS5nLiBgdW5pcXVlQXJyYXkoW1wiYXBwbGVcIiwgXCJhcHBsZVwiLCBcIm9yYW5nZVwiXSlgIHJldHVybnMgYFtcImFwcGxlXCIsIFwib3JhbmdlXCJdYFxyXG4gKi9cclxuZnVuY3Rpb24gdW5pcXVlQXJyYXkoYXJyYXkpIHtcclxuXHRpZiAoIWFycmF5IHx8ICFBcnJheS5pc0FycmF5KGFycmF5KSB8fCBhcnJheS5sZW5ndGggPT09IDApXHJcblx0XHRyZXR1cm4gW107XHJcblx0dmFyIHNlZW4gPSB7fTtcclxuXHR2YXIgdW5pcXVlID0gW107XHJcblx0YXJyYXkuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG5cdFx0aWYgKCFzZWVuW2l0ZW1dKSB7XHJcblx0XHRcdHVuaXF1ZS5wdXNoKGl0ZW0pO1xyXG5cdFx0XHRzZWVuW2l0ZW1dID0gdHJ1ZTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRyZXR1cm4gdW5pcXVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjbGFzc01hc2soY2xhc3NWYWwpIHtcclxuXHRpZiAoIWNsYXNzVmFsKSB7XHJcblx0XHRyZXR1cm4gY2xhc3NWYWw7XHJcblx0fVxyXG5cdHN3aXRjaCAoY2xhc3NWYWwudG9Mb3dlckNhc2UoKSkge1xyXG5cdGNhc2UgXCJmYVwiOlxyXG5cdGNhc2UgXCJmbFwiOlxyXG5cdGNhc2UgXCJhXCI6XHJcblx0Y2FzZSBcImdhXCI6XHJcblx0Y2FzZSBcImJcIjpcclxuXHRjYXNlIFwiY1wiOlxyXG5cdGNhc2UgXCJuYVwiOlxyXG5cdGNhc2UgXCJmbVwiOlxyXG5cdGNhc2UgXCJhbFwiOlxyXG5cdGNhc2UgXCJibFwiOlxyXG5cdGNhc2UgXCJjbFwiOlxyXG5cdFx0cmV0dXJuIGNsYXNzVmFsLnRvVXBwZXJDYXNlKCk7XHJcblx0Y2FzZSBcInN0YXJ0XCI6XHJcblx0Y2FzZSBcInN0dWJcIjpcclxuXHRjYXNlIFwibGlzdFwiOlxyXG5cdGNhc2UgXCJwb3J0YWxcIjpcclxuXHRjYXNlIFwicHJvamVjdFwiOlxyXG5cdGNhc2UgXCJkcmFmdFwiOlxyXG5cdGNhc2UgXCJib29rXCI6XHJcblx0Y2FzZSBcImZ1dHVyZVwiOlxyXG5cdGNhc2UgXCJjdXJyZW50XCI6XHJcblx0Y2FzZSBcImNvbXBsZXRlXCI6XHJcblx0Y2FzZSBcInN1YnN0YW50aWFsXCI6XHJcblx0Y2FzZSBcImJhc2ljXCI6XHJcblx0Y2FzZSBcImluY29tcGxldGVcIjpcclxuXHRjYXNlIFwibWV0YVwiOlxyXG5cdFx0cmV0dXJuIGNsYXNzVmFsLnNsaWNlKDAsMSkudG9VcHBlckNhc2UoKSArIGNsYXNzVmFsLnNsaWNlKDEpLnRvTG93ZXJDYXNlKCk7XHJcblx0Y2FzZSBcImltYWdlXCI6XHJcblx0Y2FzZSBcImltZ1wiOlxyXG5cdGNhc2UgXCJmaWxlXCI6XHJcblx0XHRyZXR1cm4gXCJGaWxlXCI7XHJcblx0Y2FzZSBcImNhdGVnb3J5XCI6XHJcblx0Y2FzZSBcImNhdFwiOlxyXG5cdGNhc2UgXCJjYXRlZ1wiOlxyXG5cdFx0cmV0dXJuIFwiQ2F0ZWdvcnlcIjtcclxuXHRjYXNlIFwiZGlzYW1iaWd1YXRpb25cIjpcclxuXHRjYXNlIFwiZGlzYW1iaWdcIjpcclxuXHRjYXNlIFwiZGlzYW1iXCI6XHJcblx0Y2FzZSBcImRhYlwiOlxyXG5cdFx0cmV0dXJuIFwiRGlzYW1iaWdcIjtcclxuXHRjYXNlIFwicmVkaXJlY3RcIjpcclxuXHRjYXNlIFwicmVkaXJcIjpcclxuXHRjYXNlIFwicmVkXCI6XHJcblx0XHRyZXR1cm4gXCJSZWRpcmVjdFwiO1xyXG5cdGNhc2UgXCJ0ZW1wbGF0ZVwiOlxyXG5cdGNhc2UgXCJ0ZW1wXCI6XHJcblx0Y2FzZSBcInRwbFwiOlxyXG5cdFx0cmV0dXJuIFwiVGVtcGxhdGVcIjtcclxuXHRjYXNlIFwiYnBsdXNcIjpcclxuXHRjYXNlIFwiYitcIjpcclxuXHRcdHJldHVybiBcIkJwbHVzXCI7XHJcblx0Y2FzZSBcImZwb1wiOlxyXG5cdFx0cmV0dXJuIFwiRlBvXCI7XHJcblx0ZGVmYXVsdDpcclxuXHRcdHJldHVybiBjbGFzc1ZhbDtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGltcG9ydGFuY2VNYXNrKGltcG9ydGFuY2UpIHtcclxuXHRpZiAoIWltcG9ydGFuY2UpIHtcclxuXHRcdHJldHVybiBpbXBvcnRhbmNlO1xyXG5cdH1cclxuXHRpZiAoaW1wb3J0YW5jZS50b0xvd2VyQ2FzZSgpID09PSBcIm5hXCIpIHtcclxuXHRcdHJldHVybiBcIk5BXCI7XHJcblx0fVxyXG5cdHJldHVybiBpbXBvcnRhbmNlLnNsaWNlKDAsMSkudG9VcHBlckNhc2UoKSArIGltcG9ydGFuY2Uuc2xpY2UoMSkudG9Mb3dlckNhc2UoKTtcclxufVxyXG5cclxuZXhwb3J0IHtcclxuXHRpc0FmdGVyRGF0ZSxcclxuXHRmaWx0ZXJBbmRNYXAsXHJcblx0bm9ybWFsaXNlWWVzTm8sXHJcblx0bW9zdEZyZXF1ZW50LFxyXG5cdHVuaXF1ZUFycmF5LFxyXG5cdGNsYXNzTWFzayxcclxuXHRpbXBvcnRhbmNlTWFza1xyXG59O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgTG9hZERpYWxvZyBmcm9tIFwiLi9XaW5kb3dzL0xvYWREaWFsb2dcIjtcclxuaW1wb3J0IE1haW5XaW5kb3cgZnJvbSBcIi4vV2luZG93cy9NYWluV2luZG93XCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG52YXIgZmFjdG9yeSA9IG5ldyBPTy5GYWN0b3J5KCk7XHJcblxyXG4vLyBSZWdpc3RlciB3aW5kb3cgY29uc3RydWN0b3JzIHdpdGggdGhlIGZhY3RvcnkuXHJcbmZhY3RvcnkucmVnaXN0ZXIoTG9hZERpYWxvZyk7XHJcbmZhY3RvcnkucmVnaXN0ZXIoTWFpbldpbmRvdyk7XHJcblxyXG52YXIgbWFuYWdlciA9IG5ldyBPTy51aS5XaW5kb3dNYW5hZ2VyKCB7XHJcblx0XCJmYWN0b3J5XCI6IGZhY3RvcnlcclxufSApO1xyXG4vLyBNYXJrZXIgY2xhc3MsIHNvIENTUyBydWxlcyBjYW4gdGFyZ2V0IFJhdGVyJ3Mgb3duIHdpbmRvd3Mgd2l0aG91dCBhZmZlY3RpbmdcclxuLy8gb3RoZXIgT09VSSBkaWFsb2dzIChlLmcuIE9PLnVpLmNvbmZpcm0sIHdoaWNoIHJlbmRlcnMgaW4gI213LXRlbGVwb3J0LXRhcmdldClcclxubWFuYWdlci4kZWxlbWVudC5hZGRDbGFzcyggXCJyYXRlci13aW5kb3dNYW5hZ2VyXCIgKTtcclxuJCggZG9jdW1lbnQuYm9keSApLmFwcGVuZCggbWFuYWdlci4kZWxlbWVudCApO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgbWFuYWdlcjtcclxuLy8gPC9ub3dpa2k+Il19 7my2pxbudb57swjb65hb26vbtj4xrok Talk:Mainspace 1 174793 754652 754377 2026-08-02T10:03:31Z Novem Linguae 49714 Assessment (Low): banner shell, +China ([[WP:RATER#2.7.2|Rater]]) 754652 wikitext text/x-wiki {{Old AfD multi |date=14 May 2026 |result='''soft merge selectively''' |page=Mainspace (30th nomination)}} {{WikiProject banner shell |class=Start |1= {{WikiProject Africa |importance=Low}} {{WikiProject Belgium |importance=Low}} {{WikiProject China |importance=Low}} }} == Question == Hello? [[User:Novem Linguae|<span style="color:darkorange;">'''Novem Linguae'''</span>]] [[User talk:Novem Linguae|<span style="color:darkorange;">(Talk)</span>]] 11:22, 17 May 2026 (UTC) a32alus5kao6l4zkpgig71j0ca8mx77 User talk:Enbi 3 175451 754569 754530 2026-08-01T20:00:39Z Enbi 72574 Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-vandalism1|uw-vandalism1]]}} (Fortress-Beta) 754569 wikitext text/x-wiki == July 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 13:46, 31 July 2026 (UTC) {{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 21:28, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:34, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:36, 31 July 2026 (UTC) {{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:37, 31 July 2026 (UTC) <div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:58, 31 July 2026 (UTC) {{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:59, 31 July 2026 (UTC) == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:00, 1 August 2026 (UTC) k90vpdlrgdzw6pkx05e6sie4yx0mqc1 754573 754569 2026-08-01T20:02:54Z Enbi 72574 Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-vandalism2|uw-vandalism2]]}} (Fortress-Beta) 754573 wikitext text/x-wiki == July 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 13:46, 31 July 2026 (UTC) {{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 21:28, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:34, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:36, 31 July 2026 (UTC) {{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:37, 31 July 2026 (UTC) <div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:58, 31 July 2026 (UTC) {{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:59, 31 July 2026 (UTC) == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:00, 1 August 2026 (UTC) [[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:02, 1 August 2026 (UTC) 8klgj4hkql3fui2h4zf5zl969b7n9bq 754576 754573 2026-08-01T20:04:56Z Enbi 72574 Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-vandalism3|uw-vandalism3]]}} (Fortress-Beta) 754576 wikitext text/x-wiki == July 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 13:46, 31 July 2026 (UTC) {{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 21:28, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:34, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:36, 31 July 2026 (UTC) {{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:37, 31 July 2026 (UTC) <div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:58, 31 July 2026 (UTC) {{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:59, 31 July 2026 (UTC) == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:00, 1 August 2026 (UTC) [[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:02, 1 August 2026 (UTC) [[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:04, 1 August 2026 (UTC) jtf8lgbcikjkd6p0gcpjccgf1ikz45z 754579 754576 2026-08-01T20:06:33Z Enbi 72574 Warning user: {{[[Template:uw-vandalism4|uw-vandalism4]]}} (test summary) 754579 wikitext text/x-wiki == July 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 13:46, 31 July 2026 (UTC) {{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 21:28, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:34, 31 July 2026 (UTC) {{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:36, 31 July 2026 (UTC) {{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:37, 31 July 2026 (UTC) <div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:41, 31 July 2026 (UTC) {{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:58, 31 July 2026 (UTC) {{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 22:59, 31 July 2026 (UTC) == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:00, 1 August 2026 (UTC) [[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:02, 1 August 2026 (UTC) [[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:04, 1 August 2026 (UTC) [[File:Stop hand nuvola.svg|30px]] This is the '''last warning''' you will receive for your disruptive edits{{#if:Hi|, such as the one you made to [[:Hi]]}}. If you [[Wikipedia:Vandalism|vandalize]] Wikipedia again, you '''will''' be [[Wikipedia:Blocking policy|blocked]] from editing. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism4 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:06, 1 August 2026 (UTC) 0rjabl4mi9fdnr1d92zob0vsarj18qo 754583 754579 2026-08-01T20:08:40Z Enbi 72574 Blanked the page 754583 wikitext text/x-wiki phoiac9h4m842xq45sp7s6u21eteeq1 754586 754583 2026-08-01T20:08:59Z Enbi 72574 Test Summary 754586 wikitext text/x-wiki == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:08, 1 August 2026 (UTC) 8zrsblfrerwje0iiexmuceo7vs0tyv5 754589 754586 2026-08-01T20:09:14Z Enbi 72574 Test Summary 754589 wikitext text/x-wiki == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:08, 1 August 2026 (UTC) {{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:09, 1 August 2026 (UTC) 1rpc4oo7bfquuloxfkk7r8inddn0wrc 754596 754589 2026-08-01T20:14:08Z Enbi 72574 Test Summary 754596 wikitext text/x-wiki == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:08, 1 August 2026 (UTC) {{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:09, 1 August 2026 (UTC) [[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:14, 1 August 2026 (UTC) d7durb1vnz5f6el9wxe6cmijut4vz56 754600 754596 2026-08-01T20:17:56Z Enbi 72574 Warning [[Special:Contributions/uw-vandalism3|uw-vandalism3]]: {{[[Template:$2|$2]]}} 754600 wikitext text/x-wiki == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:08, 1 August 2026 (UTC) {{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:09, 1 August 2026 (UTC) [[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:14, 1 August 2026 (UTC) [[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:17, 1 August 2026 (UTC) tn29kk5ehyolyurmyhhubava8pdm84f 754603 754600 2026-08-01T20:23:23Z Enbi 72574 Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-test4|uw-test4]]}} 754603 wikitext text/x-wiki == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:08, 1 August 2026 (UTC) {{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:09, 1 August 2026 (UTC) [[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:14, 1 August 2026 (UTC) [[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:17, 1 August 2026 (UTC) {{subst:uw-test4|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:23, 1 August 2026 (UTC) csxl84nrisxdmr4y9192xjmtl8n8l86 754606 754603 2026-08-01T20:23:51Z Enbi 72574 Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:engvar|engvar]]}} 754606 wikitext text/x-wiki == August 2026 == [[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]]&nbsp;to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:08, 1 August 2026 (UTC) {{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:09, 1 August 2026 (UTC) [[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:14, 1 August 2026 (UTC) [[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:17, 1 August 2026 (UTC) {{subst:uw-test4|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:23, 1 August 2026 (UTC) {{subst:uw-engvar|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] &#91;<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>&#93; • &#91;[[User talk:enbi|talk]]&#93;</b> 20:23, 1 August 2026 (UTC) h9eizboa3e4joacab6vk1ua1bvva9my MediaWiki:Gadget-hanja-reading.js 8 177043 754643 753727 2026-08-02T08:22:17Z Namoroka 19627 754643 javascript text/javascript // 한자 독음 표시해주는 소도구 // 설명은 [[사용자:Aspere/한자 독음 소도구]] 참조 // 하위 문서: [[사용자:Aspere/hanja-base.js]], [[사용자:Aspere/hanja-variants.js]], [[사용자:Aspere/hanja-variants-cjkvi.js]], [[사용자:Aspere/hanja-overrides.js]] $(function () { const skin = mw.config.get('skin'); const portlet = 'p-associated-pages' // 버튼 위치 const buttontooltip = '한자를 한글 음가로 표시합니다.' if (![0, 2, 4, 250].includes(mw.config.get('wgNamespaceNumber'))) return; // 적용할 이름공간 번호 var dict = {}; var subWordDict = {}; // 복합어 사전 객체 var subWordKeys = []; // 매칭 정렬용 키 배열 var dictReady = null; var toggled = false; // 기본적으로 한 번 캐시를 받아 1주일 간 사용 var DICT_CACHE_KEY = 'alphatest_v11'; // 이 값을 바꾸면 캐시가 강제로 갱신됨 (1주일 안 기다린다는 얘기) var DICT_CACHE_MAX_AGE = 1000 * 30; // 캐시의 자동 갱신 주기 (1주일) // 한자(정자/이체자/호환용 한자, 기본 다국어 평면 밖의 확장 영역, 반복 부호) var HAN_RE = /[\p{Script=Han}々〻]/u; var HAN_RUN_RE = /[\p{Script=Han}々〻]+/gu; // ---- 두음법칙 ---- // 사전에 담긴 독음은 "비어두형(사전 표제음)"이 기본이므로(예: 樂→락, 女→녀), // "한자 덩어리의 첫 글자인 경우" 두음법칙 규칙을 적용하여 변경 // (적용한 규칙: 한글 맞춤법 제10~12항: ㄴ/ㄹ+이야여예요유 → ㅇ, ㄹ+그 외 모음 → ㄴ) var YI_MEDIALS = new Set([2, 3, 6, 7, 12, 17, 20]); // ㅑㅒㅕㅖㅛㅠㅣ // 아라비아 숫자, 한글 수사, 한자 수사를 아우르는 숫자 패턴 (공백 허용) // 한자 수사 문자 목록은 HANJA_NUMERAL_CHARS 하나로 관리하고 아래 정규식에도 재사용 var HANJA_NUMERAL_CHARS = '一二三四五六七八九十百千萬万億兆〇零'; var NUMBER_SUFX_RE = new RegExp( '(?:[0-9\uFF10-\uFF19' + HANJA_NUMERAL_CHARS + ']' + '|일|이|삼|사|오|육|칠|팔|구|십|백|천|만|억|조' + '|한|두|세|네|다섯|여섯|일곱|여덟|아홉|열|스무|몇|매|수)\\s*$' ); var PAREN_HANGUL_RE = /([가-힣]+)\s*\(\s*$/; // ---- 아라비아 숫자 변환 관련 상수 ---- var ARABIC_NUM_MAP = { '〇': '0', '一': '1', '二': '2', '三': '3', '四': '4', '五': '5', '六': '6', '七': '7', '八': '8', '九': '9' }; function applyDueum(syllable) { if (!syllable) return syllable; var first = syllable.charAt(0); var code = first.charCodeAt(0) - 0xAC00; if (code < 0 || code > 11171) return syllable; // 한글 음절이 아니면 그대로 var initial = Math.floor(code / (21 * 28)); var medial = Math.floor((code % (21 * 28)) / 28); var final = code % 28; var newInitial = initial; if (initial === 2 /* ㄴ */ && YI_MEDIALS.has(medial)) { newInitial = 11; // ㅇ } else if (initial === 5 /* ㄹ */) { newInitial = YI_MEDIALS.has(medial) ? 11 /* ㅇ */ : 2 /* ㄴ */; } else { return syllable; } var newFirst = String.fromCharCode(0xAC00 + (newInitial * 21 + medial) * 28 + final); return newFirst + syllable.slice(1); } // 앞 글자가 모음(받침 없음)이거나 'ㄴ' 받침인지 확인하는 함수 function isVowelOrNieunEnding(syllable) { if (!syllable) return false; var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00; if (code < 0 || code > 11171) return false; var final = code % 28; return final === 0 || final === 4; // 0: 받침 없음(모음), 4: ㄴ 받침 } // 앞 글자가 'ㄹ' 받침인지 확인하는 함수 (의존 명사 '리' 예외 처리용) function isRieulEnding(syllable) { if (!syllable) return false; var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00; if (code < 0 || code > 11171) return false; var final = code % 28; return final === 8; // 8: ㄹ 받침 } // 글자의 초성이 'ㄷ' 또는 'ㅈ'인지 확인하는 함수 ('不' 예외 처리용) function isDigeutOrJieutStarting(syllable) { if (!syllable) return false; var first = syllable.charAt(0); var code = first.charCodeAt(0) - 0xAC00; if (code < 0 || code > 11171) return false; var initial = Math.floor(code / (21 * 28)); return initial === 3 /* ㄷ */ || initial === 12 /* ㅈ */; } function fetchJson(pageName) { var url = mw.util.wikiScript() + '?title=MediaWiki:Gadget-' + encodeURIComponent(pageName) + '&action=raw&ctype=application/json'; return fetch(url).then(function (res) { if (!res.ok) throw new Error(pageName + ' 응답 오류: ' + res.status); return res.json(); }); } function loadDict() { if (dictReady) return dictReady; dictReady = new Promise(function (resolve) { try { var cached = JSON.parse(localStorage.getItem(DICT_CACHE_KEY) || 'null'); if (cached && (Date.now() - cached.time) < DICT_CACHE_MAX_AGE) { dict = cached.dict; subWordDict = cached.subWordDict || {}; subWordKeys = Object.keys(subWordDict).sort(function (a, b) { return b.length - a.length; }); resolve(); return; } } catch (e) { /* 캐시 손상 시 무시 */ } var files = [ 'hanja-base2.json', 'hanja-variants.json', 'hanja-variants-cjkvi.json', 'hanja-history.json', 'hanja-overrides.json', 'hanja-word.json' ]; Promise.all(files.map(fetchJson)) .then(function (results) { // 0~3번 결과는 단일 글자 사전에 병합 dict = Object.assign({}, results[0], results[1], results[2], results[3]); // 4번 결과는 복합어 사전에 할당 후 길이순 정렬 subWordDict = results[4] || {}; subWordKeys = Object.keys(subWordDict).sort(function (a, b) { return b.length - a.length; }); try { localStorage.setItem(DICT_CACHE_KEY, JSON.stringify({ time: Date.now(), dict: dict, subWordDict: subWordDict })); } catch (e) { /* 캐시 실패 무시 */ } resolve(); }) .catch(function (e) { console.error('[한자독음] 사전 로딩 실패:', e); dictReady = null; // 다음 클릭 때 재시도되도록 초기화 resolve(); }); }); return dictReady; } function applyManualOverrides(root) { root.querySelectorAll('.hanja-manual-reading:not(.hanja-converted)').forEach(function (el) { var reading = el.dataset.reading; if (!reading) return; el.dataset.original = el.textContent; el.textContent = reading; el.classList.add('hanja-converted'); el.title = el.dataset.original; }); } // 한자가 아닌 부분은 그대로 두고, 한자 블록(연속된 한자 구간)만 개별 <span>으로 감싼다. // 이렇게 하면 블록 단위로 두음법칙 적용 + 원문 title 표시 + 스타일 지정이 가능하다. function buildConvertedFragment(text, precedingText) { var frag = document.createDocumentFragment(); var lastIndex = 0; var m; HAN_RUN_RE.lastIndex = 0; while ((m = HAN_RUN_RE.exec(text))) { if (m.index > lastIndex) { frag.appendChild(document.createTextNode(text.slice(lastIndex, m.index))); } var run = m[0]; var context = precedingText + text.slice(0, m.index); var convertedChars = []; var chars = Array.from(run); // 코드포인트 단위(확장 한자 서로게이트 쌍 포함) 분리 // 반복 부호(々, 〻)를 바로 앞의 한자로 치환 for (var j = 0; j < chars.length; j++) { if (chars[j] === '々' || chars[j] === '〻') { if (j > 0) { chars[j] = chars[j - 1]; } } } // 한자 수사로만 이루어진 덩어리(예: 六千六百六十六)는 각 자릿수를 독립된 단어처럼 취급해 // 위치와 무관하게 두음법칙을 적용한다. var isPureNumeralRun = chars.length > 1 && chars.every(function (c) { return HANJA_NUMERAL_CHARS.indexOf(c) !== -1; }); for (var i = 0; i < chars.length; ) { // 1) 아라비아 숫자 연속 표기(〇 포함 또는 2자리 이상)의 치환 처리 (예: 二〇二六 -> 2026) var arabicLen = 0; while (i + arabicLen < chars.length && Object.prototype.hasOwnProperty.call(ARABIC_NUM_MAP, chars[i + arabicLen])) { arabicLen++; } var arabicSubRun = chars.slice(i, i + arabicLen); // 길이가 2이상이거나 〇가 포함되어 있으면 아라비아 숫자로 간주 var isArabicCandidate = arabicLen >= 2; if (isArabicCandidate) { var arabicStr = arabicSubRun.map(function(c) { return ARABIC_NUM_MAP[c]; }).join(''); convertedChars.push(arabicStr); i += arabicLen; continue; // 변환 완료 후 다음 글자로 건너뜀 } var ch = chars[i]; if (isPureNumeralRun) { convertedChars.push(applyDueum(dict[ch] || ch)); i++; continue; } var fullBefore = context + convertedChars.join(''); var isAfterNum = NUMBER_SUFX_RE.test(fullBefore); var parenMatch = fullBefore.match(PAREN_HANGUL_RE); var parenHangul = parenMatch ? parenMatch[1] : null; var matchedWord = null; var matchedReading = null; var matchedWordLen = 0; // 2) 전역 복합어 사전을 참조하여 매칭 확인 (Surrogate Pair 오류 방지를 위해 배열 슬라이싱 사용) for (var k = 0; k < subWordKeys.length; k++) { var key = subWordKeys[k]; var keyChars = Array.from(key); if (chars.slice(i, i + keyChars.length).join('') === key) { matchedWord = key; matchedWordLen = keyChars.length; matchedReading = subWordDict[key]; break; } } if (matchedWord) { // 수량사 뒤 "年度" 예외 조정 (연도 -> 년도) if (isAfterNum && matchedWord === "年度") { matchedReading = "년도"; } convertedChars.push(matchedReading); i += matchedWordLen; // 올바른 글자수만큼 인덱스 전진 } else { // 3) 개별 글자 처리 및 문맥 검사 var reading = dict[ch] || ch; // '不' 예외 처리: 뒤에 오는 글자의 초성이 'ㄷ', 'ㅈ'이거나 '實'인 경우 '부'로 발음 if (ch === '不') { var nextCharObj = (i + 1 < chars.length) ? chars[i + 1] : text.charAt(m.index + run.length); var nextCharReading = dict[nextCharObj] || nextCharObj; if (nextCharObj === '實' || isDigeutOrJieutStarting(nextCharReading)) { reading = '부'; } } // '金' 예외 처리: 한자 덩어리 내에서 첫 글자면(앞에 한자가 없으면) '김', 아니면 '금' if (ch === '金' || ch === '金') { reading = (i === 0) ? '김' : '금'; } var finalReading = reading; // 이전 글자(방금 변환된 한글이거나 한자 블록 앞의 일반 텍스트)를 추적 // 띄어쓰기가 있어도 직전 한글을 올바르게 찾도록 정규식 활용 var prevMatch = context.match(/([가-힣])\s*$/); var prevHangul = convertedChars.length > 0 ? convertedChars[convertedChars.length - 1] : (prevMatch ? prevMatch[1] : context.slice(-1)); if (isAfterNum) { if (ch === '兩') finalReading = '냥'; else if (ch === '年') finalReading = '년'; else finalReading = reading; // 일반적인 경우 두음법칙 무력화 (예: 3里 -> 3리) } else if (parenHangul) { // 괄호 바로 앞 한글 가이드와 부합하면 원음 반영 (예: 냥(兩) -> 냥, 냥쭝(兩쭝) -> 냥쭝) if (ch === '兩' && parenHangul.startsWith('냥')) finalReading = '냥'; else if (ch === '兩' && parenHangul.startsWith('양')) finalReading = '양'; else if (ch === '年' && parenHangul.startsWith('년')) finalReading = '년'; else if (ch === '年' && parenHangul.startsWith('연')) finalReading = '연'; else finalReading = (i === 0) ? applyDueum(reading) : reading; } else { // 모음이나 ㄴ 받침 뒤에 이어지는 '렬, 률'은 '열, 율'로 발음 if ((reading === '렬' || reading === '률') && isVowelOrNieunEnding(prevHangul)) { finalReading = (reading === '렬') ? '열' : '율'; } else if (ch === '理' && i === 0 && chars.length === 1 && isRieulEnding(prevHangul)) { // '-을/ㄹ' 어미 뒤에 단독으로 쓰인 '理'는 의존 명사이므로 두음법칙 예외 finalReading = '리'; } else { // 일반적인 한자 덩어리의 첫머리에만 두음법칙 적용 finalReading = (i === 0) ? applyDueum(reading) : reading; } } convertedChars.push(finalReading); i++; } } var span = document.createElement('span'); span.textContent = convertedChars.join(''); span.dataset.original = run; span.title = run; // 마우스 오버 시 원문 한자 확인 span.classList.add('hanja-converted'); frag.appendChild(span); lastIndex = m.index + run.length; } if (lastIndex < text.length) { frag.appendChild(document.createTextNode(text.slice(lastIndex))); } return frag; } // root를 화면(DOM)에서 잠시 떼어낸 뒤 fn(root)를 실행하고 다시 붙인다. function withDetached(root, fn) { var parent = root.parentNode; var nextSibling = root.nextSibling; var wasDetached = !parent; if (!wasDetached) parent.removeChild(root); try { fn(root); } finally { if (!wasDetached) { if (nextSibling) parent.insertBefore(root, nextSibling); else parent.appendChild(root); } } } function convertNode(root) { withDetached(root, function (root) { applyManualOverrides(root); // 1) 틀로 지정된 부분 먼저 처리 // 2) 문서를 순서대로 한 번만 훑으며, 직전 글자를 흘려보낸다 (O(n)) var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null); var lastText = ""; var toProcess = []; var node; while ((node = walker.nextNode())) { var text = node.nodeValue; if (!text) continue; var insideConverted = node.parentNode && node.parentNode.closest && node.parentNode.closest('.hanja-converted'); if (!insideConverted && HAN_RE.test(text)) { toProcess.push({ node: node, precedingText: lastText }); } if (!insideConverted && text.length) { lastText = (lastText + text).slice(-50); // 최근 50글자까지만 버퍼에 보존 } } toProcess.forEach(function (item) { var frag = buildConvertedFragment(item.node.nodeValue, item.precedingText); item.node.parentNode.replaceChild(frag, item.node); }); }); } function restore(root) { withDetached(root, function (root) { root.querySelectorAll('.hanja-converted').forEach(function (span) { if (span.classList.contains('hanja-manual-reading')) { span.textContent = span.dataset.original; span.classList.remove('hanja-converted'); span.removeAttribute('title'); } else { span.replaceWith(document.createTextNode(span.dataset.original)); } }); }); } mw.loader.using('mediawiki.util').then(function () { // 변환된 한자에 옅은 점선 밑줄을 넣어, 원문과 구분되게 하되 가독성은 해치지 않도록 함. mw.util.addCSS( '.hanja-converted {' + ' border-bottom: 1px dotted rgba(128,128,128,0.6);' + ' cursor: help;' + ' text-decoration: none;' + '}' ); mw.util.addPortletLink(portlet, '#', '한자 독음', 'ca-hanja2hangul', buttontooltip); $('#ca-hanja2hangul').on('click', function (e) { e.preventDefault(); loadDict().then(function () { var content = document.querySelector('#mw-content-text .mw-parser-output'); if (!content) return; toggled = !toggled; toggled ? convertNode(content) : restore(content); }); }); }); }); 63ztlek7xjz5su5fndhjys1mkzy089k 754644 754643 2026-08-02T08:28:35Z Namoroka 19627 754644 javascript text/javascript // 한자 독음 표시해주는 소도구 // 설명은 [[사용자:Aspere/한자 독음 소도구]] 참조 // 하위 문서: [[사용자:Aspere/hanja-base.js]], [[사용자:Aspere/hanja-variants.js]], [[사용자:Aspere/hanja-variants-cjkvi.js]], [[사용자:Aspere/hanja-overrides.js]] $(function () { const skin = mw.config.get('skin'); const portlet = 'p-associated-pages' // 버튼 위치 const buttontooltip = '한자를 한글 음가로 표시합니다.' if (![0, 2, 4, 250].includes(mw.config.get('wgNamespaceNumber'))) return; // 적용할 이름공간 번호 var dict = {}; var subWordDict = {}; // 복합어 사전 객체 var subWordKeys = []; // 매칭 정렬용 키 배열 var dictReady = null; var toggled = false; // 기본적으로 한 번 캐시를 받아 1주일 간 사용 var DICT_CACHE_KEY = 'alphatest_v11'; // 이 값을 바꾸면 캐시가 강제로 갱신됨 (1주일 안 기다린다는 얘기) var DICT_CACHE_MAX_AGE = 1000 * 30; // 캐시의 자동 갱신 주기 (1주일) // 한자(정자/이체자/호환용 한자, 기본 다국어 평면 밖의 확장 영역, 반복 부호) var HAN_RE = /[\p{Script=Han}々〻]/u; var HAN_RUN_RE = /[\p{Script=Han}々〻]+/gu; // ---- 두음법칙 ---- // 사전에 담긴 독음은 "비어두형(사전 표제음)"이 기본이므로(예: 樂→락, 女→녀), // "한자 덩어리의 첫 글자인 경우" 두음법칙 규칙을 적용하여 변경 // (적용한 규칙: 한글 맞춤법 제10~12항: ㄴ/ㄹ+이야여예요유 → ㅇ, ㄹ+그 외 모음 → ㄴ) var YI_MEDIALS = new Set([2, 3, 6, 7, 12, 17, 20]); // ㅑㅒㅕㅖㅛㅠㅣ // 아라비아 숫자, 한글 수사, 한자 수사를 아우르는 숫자 패턴 (공백 허용) // 한자 수사 문자 목록은 HANJA_NUMERAL_CHARS 하나로 관리하고 아래 정규식에도 재사용 var HANJA_NUMERAL_CHARS = '一二三四五六七八九十百千萬万億兆〇零'; var NUMBER_SUFX_RE = new RegExp( '(?:[0-9\uFF10-\uFF19' + HANJA_NUMERAL_CHARS + ']' + '|일|이|삼|사|오|육|칠|팔|구|십|백|천|만|억|조' + '|한|두|세|네|다섯|여섯|일곱|여덟|아홉|열|스무|몇|매|수)\\s*$' ); var PAREN_HANGUL_RE = /([가-힣]+)\s*\(\s*$/; // ---- 아라비아 숫자 변환 관련 상수 ---- var ARABIC_NUM_MAP = { '〇': '0', '一': '1', '二': '2', '三': '3', '四': '4', '五': '5', '六': '6', '七': '7', '八': '8', '九': '9' }; function applyDueum(syllable) { if (!syllable) return syllable; var first = syllable.charAt(0); var code = first.charCodeAt(0) - 0xAC00; if (code < 0 || code > 11171) return syllable; // 한글 음절이 아니면 그대로 var initial = Math.floor(code / (21 * 28)); var medial = Math.floor((code % (21 * 28)) / 28); var final = code % 28; var newInitial = initial; if (initial === 2 /* ㄴ */ && YI_MEDIALS.has(medial)) { newInitial = 11; // ㅇ } else if (initial === 5 /* ㄹ */) { newInitial = YI_MEDIALS.has(medial) ? 11 /* ㅇ */ : 2 /* ㄴ */; } else { return syllable; } var newFirst = String.fromCharCode(0xAC00 + (newInitial * 21 + medial) * 28 + final); return newFirst + syllable.slice(1); } // 앞 글자가 모음(받침 없음)이거나 'ㄴ' 받침인지 확인하는 함수 function isVowelOrNieunEnding(syllable) { if (!syllable) return false; var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00; if (code < 0 || code > 11171) return false; var final = code % 28; return final === 0 || final === 4; // 0: 받침 없음(모음), 4: ㄴ 받침 } // 앞 글자가 'ㄹ' 받침인지 확인하는 함수 (의존 명사 '리' 예외 처리용) function isRieulEnding(syllable) { if (!syllable) return false; var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00; if (code < 0 || code > 11171) return false; var final = code % 28; return final === 8; // 8: ㄹ 받침 } // 글자의 초성이 'ㄷ' 또는 'ㅈ'인지 확인하는 함수 ('不' 예외 처리용) function isDigeutOrJieutStarting(syllable) { if (!syllable) return false; var first = syllable.charAt(0); var code = first.charCodeAt(0) - 0xAC00; if (code < 0 || code > 11171) return false; var initial = Math.floor(code / (21 * 28)); return initial === 3 /* ㄷ */ || initial === 12 /* ㅈ */; } function fetchJson(pageName) { var url = mw.util.wikiScript() + '?title=MediaWiki:Gadget-' + encodeURIComponent(pageName) + '&action=raw&ctype=application/json'; return fetch(url).then(function (res) { if (!res.ok) throw new Error(pageName + ' 응답 오류: ' + res.status); return res.json(); }); } function loadDict() { if (dictReady) return dictReady; dictReady = new Promise(function (resolve) { try { var cached = JSON.parse(localStorage.getItem(DICT_CACHE_KEY) || 'null'); if (cached && (Date.now() - cached.time) < DICT_CACHE_MAX_AGE) { dict = cached.dict; subWordDict = cached.subWordDict || {}; subWordKeys = Object.keys(subWordDict).sort(function (a, b) { return b.length - a.length; }); resolve(); return; } } catch (e) { /* 캐시 손상 시 무시 */ } var files = [ 'hanja-base2.json', 'hanja-variants.json', 'hanja-variants-cjkvi.json', 'hanja-history.json', 'hanja-overrides.json', 'hanja-word.json' ]; Promise.all(files.map(fetchJson)) .then(function (results) { // 0~4번 결과는 단일 글자 사전에 병합 dict = Object.assign({}, results[0], results[1], results[2], results[3], results[4]); // 5번 결과는 복합어 사전에 할당 후 길이순 정렬 subWordDict = results[5] || {}; subWordKeys = Object.keys(subWordDict).sort(function (a, b) { return b.length - a.length; }); try { localStorage.setItem(DICT_CACHE_KEY, JSON.stringify({ time: Date.now(), dict: dict, subWordDict: subWordDict })); } catch (e) { /* 캐시 실패 무시 */ } resolve(); }) .catch(function (e) { console.error('[한자독음] 사전 로딩 실패:', e); dictReady = null; // 다음 클릭 때 재시도되도록 초기화 resolve(); }); }); return dictReady; } function applyManualOverrides(root) { root.querySelectorAll('.hanja-manual-reading:not(.hanja-converted)').forEach(function (el) { var reading = el.dataset.reading; if (!reading) return; el.dataset.original = el.textContent; el.textContent = reading; el.classList.add('hanja-converted'); el.title = el.dataset.original; }); } // 한자가 아닌 부분은 그대로 두고, 한자 블록(연속된 한자 구간)만 개별 <span>으로 감싼다. // 이렇게 하면 블록 단위로 두음법칙 적용 + 원문 title 표시 + 스타일 지정이 가능하다. function buildConvertedFragment(text, precedingText) { var frag = document.createDocumentFragment(); var lastIndex = 0; var m; HAN_RUN_RE.lastIndex = 0; while ((m = HAN_RUN_RE.exec(text))) { if (m.index > lastIndex) { frag.appendChild(document.createTextNode(text.slice(lastIndex, m.index))); } var run = m[0]; var context = precedingText + text.slice(0, m.index); var convertedChars = []; var chars = Array.from(run); // 코드포인트 단위(확장 한자 서로게이트 쌍 포함) 분리 // 반복 부호(々, 〻)를 바로 앞의 한자로 치환 for (var j = 0; j < chars.length; j++) { if (chars[j] === '々' || chars[j] === '〻') { if (j > 0) { chars[j] = chars[j - 1]; } } } // 한자 수사로만 이루어진 덩어리(예: 六千六百六十六)는 각 자릿수를 독립된 단어처럼 취급해 // 위치와 무관하게 두음법칙을 적용한다. var isPureNumeralRun = chars.length > 1 && chars.every(function (c) { return HANJA_NUMERAL_CHARS.indexOf(c) !== -1; }); for (var i = 0; i < chars.length; ) { // 1) 아라비아 숫자 연속 표기(〇 포함 또는 2자리 이상)의 치환 처리 (예: 二〇二六 -> 2026) var arabicLen = 0; while (i + arabicLen < chars.length && Object.prototype.hasOwnProperty.call(ARABIC_NUM_MAP, chars[i + arabicLen])) { arabicLen++; } var arabicSubRun = chars.slice(i, i + arabicLen); // 길이가 2이상이거나 〇가 포함되어 있으면 아라비아 숫자로 간주 var isArabicCandidate = arabicLen >= 2; if (isArabicCandidate) { var arabicStr = arabicSubRun.map(function(c) { return ARABIC_NUM_MAP[c]; }).join(''); convertedChars.push(arabicStr); i += arabicLen; continue; // 변환 완료 후 다음 글자로 건너뜀 } var ch = chars[i]; if (isPureNumeralRun) { convertedChars.push(applyDueum(dict[ch] || ch)); i++; continue; } var fullBefore = context + convertedChars.join(''); var isAfterNum = NUMBER_SUFX_RE.test(fullBefore); var parenMatch = fullBefore.match(PAREN_HANGUL_RE); var parenHangul = parenMatch ? parenMatch[1] : null; var matchedWord = null; var matchedReading = null; var matchedWordLen = 0; // 2) 전역 복합어 사전을 참조하여 매칭 확인 (Surrogate Pair 오류 방지를 위해 배열 슬라이싱 사용) for (var k = 0; k < subWordKeys.length; k++) { var key = subWordKeys[k]; var keyChars = Array.from(key); if (chars.slice(i, i + keyChars.length).join('') === key) { matchedWord = key; matchedWordLen = keyChars.length; matchedReading = subWordDict[key]; break; } } if (matchedWord) { // 수량사 뒤 "年度" 예외 조정 (연도 -> 년도) if (isAfterNum && matchedWord === "年度") { matchedReading = "년도"; } convertedChars.push(matchedReading); i += matchedWordLen; // 올바른 글자수만큼 인덱스 전진 } else { // 3) 개별 글자 처리 및 문맥 검사 var reading = dict[ch] || ch; // '不' 예외 처리: 뒤에 오는 글자의 초성이 'ㄷ', 'ㅈ'이거나 '實'인 경우 '부'로 발음 if (ch === '不') { var nextCharObj = (i + 1 < chars.length) ? chars[i + 1] : text.charAt(m.index + run.length); var nextCharReading = dict[nextCharObj] || nextCharObj; if (nextCharObj === '實' || isDigeutOrJieutStarting(nextCharReading)) { reading = '부'; } } // '金' 예외 처리: 한자 덩어리 내에서 첫 글자면(앞에 한자가 없으면) '김', 아니면 '금' if (ch === '金' || ch === '金') { reading = (i === 0) ? '김' : '금'; } var finalReading = reading; // 이전 글자(방금 변환된 한글이거나 한자 블록 앞의 일반 텍스트)를 추적 // 띄어쓰기가 있어도 직전 한글을 올바르게 찾도록 정규식 활용 var prevMatch = context.match(/([가-힣])\s*$/); var prevHangul = convertedChars.length > 0 ? convertedChars[convertedChars.length - 1] : (prevMatch ? prevMatch[1] : context.slice(-1)); if (isAfterNum) { if (ch === '兩') finalReading = '냥'; else if (ch === '年') finalReading = '년'; else finalReading = reading; // 일반적인 경우 두음법칙 무력화 (예: 3里 -> 3리) } else if (parenHangul) { // 괄호 바로 앞 한글 가이드와 부합하면 원음 반영 (예: 냥(兩) -> 냥, 냥쭝(兩쭝) -> 냥쭝) if (ch === '兩' && parenHangul.startsWith('냥')) finalReading = '냥'; else if (ch === '兩' && parenHangul.startsWith('양')) finalReading = '양'; else if (ch === '年' && parenHangul.startsWith('년')) finalReading = '년'; else if (ch === '年' && parenHangul.startsWith('연')) finalReading = '연'; else finalReading = (i === 0) ? applyDueum(reading) : reading; } else { // 모음이나 ㄴ 받침 뒤에 이어지는 '렬, 률'은 '열, 율'로 발음 if ((reading === '렬' || reading === '률') && isVowelOrNieunEnding(prevHangul)) { finalReading = (reading === '렬') ? '열' : '율'; } else if (ch === '理' && i === 0 && chars.length === 1 && isRieulEnding(prevHangul)) { // '-을/ㄹ' 어미 뒤에 단독으로 쓰인 '理'는 의존 명사이므로 두음법칙 예외 finalReading = '리'; } else { // 일반적인 한자 덩어리의 첫머리에만 두음법칙 적용 finalReading = (i === 0) ? applyDueum(reading) : reading; } } convertedChars.push(finalReading); i++; } } var span = document.createElement('span'); span.textContent = convertedChars.join(''); span.dataset.original = run; span.title = run; // 마우스 오버 시 원문 한자 확인 span.classList.add('hanja-converted'); frag.appendChild(span); lastIndex = m.index + run.length; } if (lastIndex < text.length) { frag.appendChild(document.createTextNode(text.slice(lastIndex))); } return frag; } // root를 화면(DOM)에서 잠시 떼어낸 뒤 fn(root)를 실행하고 다시 붙인다. function withDetached(root, fn) { var parent = root.parentNode; var nextSibling = root.nextSibling; var wasDetached = !parent; if (!wasDetached) parent.removeChild(root); try { fn(root); } finally { if (!wasDetached) { if (nextSibling) parent.insertBefore(root, nextSibling); else parent.appendChild(root); } } } function convertNode(root) { withDetached(root, function (root) { applyManualOverrides(root); // 1) 틀로 지정된 부분 먼저 처리 // 2) 문서를 순서대로 한 번만 훑으며, 직전 글자를 흘려보낸다 (O(n)) var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null); var lastText = ""; var toProcess = []; var node; while ((node = walker.nextNode())) { var text = node.nodeValue; if (!text) continue; var insideConverted = node.parentNode && node.parentNode.closest && node.parentNode.closest('.hanja-converted'); if (!insideConverted && HAN_RE.test(text)) { toProcess.push({ node: node, precedingText: lastText }); } if (!insideConverted && text.length) { lastText = (lastText + text).slice(-50); // 최근 50글자까지만 버퍼에 보존 } } toProcess.forEach(function (item) { var frag = buildConvertedFragment(item.node.nodeValue, item.precedingText); item.node.parentNode.replaceChild(frag, item.node); }); }); } function restore(root) { withDetached(root, function (root) { root.querySelectorAll('.hanja-converted').forEach(function (span) { if (span.classList.contains('hanja-manual-reading')) { span.textContent = span.dataset.original; span.classList.remove('hanja-converted'); span.removeAttribute('title'); } else { span.replaceWith(document.createTextNode(span.dataset.original)); } }); }); } mw.loader.using('mediawiki.util').then(function () { // 변환된 한자에 옅은 점선 밑줄을 넣어, 원문과 구분되게 하되 가독성은 해치지 않도록 함. mw.util.addCSS( '.hanja-converted {' + ' border-bottom: 1px dotted rgba(128,128,128,0.6);' + ' cursor: help;' + ' text-decoration: none;' + '}' ); mw.util.addPortletLink(portlet, '#', '한자 독음', 'ca-hanja2hangul', buttontooltip); $('#ca-hanja2hangul').on('click', function (e) { e.preventDefault(); loadDict().then(function () { var content = document.querySelector('#mw-content-text .mw-parser-output'); if (!content) return; toggled = !toggled; toggled ? convertNode(content) : restore(content); }); }); }); }); 9ncdkej370qwbhvhwg5n2lm4bf975sq 754649 754644 2026-08-02T08:45:56Z Namoroka 19627 754649 javascript text/javascript // 한자 독음 표시해주는 소도구 // 설명은 [[사용자:Aspere/한자 독음 소도구]] 참조 // 하위 문서: [[사용자:Aspere/hanja-base.js]], [[사용자:Aspere/hanja-variants.js]], [[사용자:Aspere/hanja-variants-cjkvi.js]], [[사용자:Aspere/hanja-overrides.js]] $(function () { const skin = mw.config.get('skin'); const portlet = 'p-associated-pages' // 버튼 위치 const buttontooltip = '한자를 한글 음가로 표시합니다.' if (![0, 2, 4, 250].includes(mw.config.get('wgNamespaceNumber'))) return; // 적용할 이름공간 번호 var dict = {}; var subWordDict = {}; // 복합어 사전 객체 var subWordKeys = []; // 매칭 정렬용 키 배열 var dictReady = null; var toggled = false; // 기본적으로 한 번 캐시를 받아 1주일 간 사용 var DICT_CACHE_KEY = 'alphatest_v11'; // 이 값을 바꾸면 캐시가 강제로 갱신됨 (1주일 안 기다린다는 얘기) var DICT_CACHE_MAX_AGE = 1000 * 30; // 캐시의 자동 갱신 주기 (1주일) // 한자(정자/이체자/호환용 한자, 기본 다국어 평면 밖의 확장 영역, 반복 부호) var HAN_RE = /[\p{Script=Han}々〻]/u; var HAN_RUN_RE = /[\p{Script=Han}々〻]+/gu; // ---- 두음법칙 ---- // 사전에 담긴 독음은 "비어두형(사전 표제음)"이 기본이므로(예: 樂→락, 女→녀), // "한자 덩어리의 첫 글자인 경우" 두음법칙 규칙을 적용하여 변경 // (적용한 규칙: 한글 맞춤법 제10~12항: ㄴ/ㄹ+이야여예요유 → ㅇ, ㄹ+그 외 모음 → ㄴ) var YI_MEDIALS = new Set([2, 3, 6, 7, 12, 17, 20]); // ㅑㅒㅕㅖㅛㅠㅣ // 아라비아 숫자, 한글 수사, 한자 수사를 아우르는 숫자 패턴 (공백 허용) // 한자 수사 문자 목록은 HANJA_NUMERAL_CHARS 하나로 관리하고 아래 정규식에도 재사용 var HANJA_NUMERAL_CHARS = '一二三四五六七八九十百千萬万億兆〇零'; var NUMBER_SUFX_RE = new RegExp( '(?:[0-9\uFF10-\uFF19' + HANJA_NUMERAL_CHARS + ']' + '|일|이|삼|사|오|육|칠|팔|구|십|백|천|만|억|조' + '|한|두|세|네|다섯|여섯|일곱|여덟|아홉|열|스무|몇|매|수)\\s*$' ); var PAREN_HANGUL_RE = /([가-힣]+)\s*\(\s*$/; // ---- 아라비아 숫자 변환 관련 상수 ---- var ARABIC_NUM_MAP = { '〇': '0', '一': '1', '二': '2', '三': '3', '四': '4', '五': '5', '六': '6', '七': '7', '八': '8', '九': '9' }; function applyDueum(syllable) { if (!syllable) return syllable; var first = syllable.charAt(0); var code = first.charCodeAt(0) - 0xAC00; if (code < 0 || code > 11171) return syllable; // 한글 음절이 아니면 그대로 var initial = Math.floor(code / (21 * 28)); var medial = Math.floor((code % (21 * 28)) / 28); var final = code % 28; var newInitial = initial; if (initial === 2 /* ㄴ */ && YI_MEDIALS.has(medial)) { newInitial = 11; // ㅇ } else if (initial === 5 /* ㄹ */) { newInitial = YI_MEDIALS.has(medial) ? 11 /* ㅇ */ : 2 /* ㄴ */; } else { return syllable; } var newFirst = String.fromCharCode(0xAC00 + (newInitial * 21 + medial) * 28 + final); return newFirst + syllable.slice(1); } // 앞 글자가 모음(받침 없음)이거나 'ㄴ' 받침인지 확인하는 함수 function isVowelOrNieunEnding(syllable) { if (!syllable) return false; var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00; if (code < 0 || code > 11171) return false; var final = code % 28; return final === 0 || final === 4; // 0: 받침 없음(모음), 4: ㄴ 받침 } // 앞 글자가 'ㄹ' 받침인지 확인하는 함수 (의존 명사 '리' 예외 처리용) function isRieulEnding(syllable) { if (!syllable) return false; var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00; if (code < 0 || code > 11171) return false; var final = code % 28; return final === 8; // 8: ㄹ 받침 } // 글자의 초성이 'ㄷ' 또는 'ㅈ'인지 확인하는 함수 ('不' 예외 처리용) function isDigeutOrJieutStarting(syllable) { if (!syllable) return false; var first = syllable.charAt(0); var code = first.charCodeAt(0) - 0xAC00; if (code < 0 || code > 11171) return false; var initial = Math.floor(code / (21 * 28)); return initial === 3 /* ㄷ */ || initial === 12 /* ㅈ */; } function fetchJson(pageName) { var url = mw.util.wikiScript() + '?title=MediaWiki:Gadget-' + encodeURIComponent(pageName) + '&action=raw&ctype=application/json'; return fetch(url).then(function (res) { if (!res.ok) throw new Error(pageName + ' 응답 오류: ' + res.status); return res.json(); }); } function loadDict() { if (dictReady) return dictReady; dictReady = new Promise(function (resolve) { try { var cached = JSON.parse(localStorage.getItem(DICT_CACHE_KEY) || 'null'); if (cached && (Date.now() - cached.time) < DICT_CACHE_MAX_AGE) { dict = cached.dict; subWordDict = cached.subWordDict || {}; subWordKeys = Object.keys(subWordDict).sort(function (a, b) { return b.length - a.length; }); resolve(); return; } } catch (e) { /* 캐시 손상 시 무시 */ } var files = [ 'hanja-base2.json', 'hanja-variants.json', 'hanja-variants-cjkvi.json', 'hanja-history.json', 'hanja-overrides.json', 'hanja-word.json' ]; Promise.all(files.map(fetchJson)) .then(function (results) { // 0~4번 결과는 단일 글자 사전에 병합 dict = Object.assign({}, results[0], results[1], results[2], results[3], results[4]); // 5번 결과는 복합어 사전에 할당 후 길이순 정렬 subWordDict = results[5] || {}; subWordKeys = Object.keys(subWordDict).sort(function (a, b) { return b.length - a.length; }); try { localStorage.setItem(DICT_CACHE_KEY, JSON.stringify({ time: Date.now(), dict: dict, subWordDict: subWordDict })); } catch (e) { /* 캐시 실패 무시 */ } resolve(); }) .catch(function (e) { console.error('[한자독음] 사전 로딩 실패:', e); dictReady = null; // 다음 클릭 때 재시도되도록 초기화 resolve(); }); }); return dictReady; } function applyManualOverrides(root) { root.querySelectorAll('.hanja-manual-reading:not(.hanja-converted)').forEach(function (el) { var reading = el.dataset.reading; if (!reading) return; el.dataset.original = el.textContent; el.textContent = reading; el.classList.add('hanja-converted'); el.title = el.dataset.original; }); } // 한자가 아닌 부분은 그대로 두고, 한자 블록(연속된 한자 구간)만 개별 <span>으로 감싼다. // 이렇게 하면 블록 단위로 두음법칙 적용 + 원문 title 표시 + 스타일 지정이 가능하다. function buildConvertedFragment(text, precedingText) { var frag = document.createDocumentFragment(); var lastIndex = 0; var m; HAN_RUN_RE.lastIndex = 0; while ((m = HAN_RUN_RE.exec(text))) { if (m.index > lastIndex) { frag.appendChild(document.createTextNode(text.slice(lastIndex, m.index))); } var run = m[0]; var context = precedingText + text.slice(0, m.index); var convertedChars = []; var chars = Array.from(run); // 코드포인트 단위(확장 한자 서로게이트 쌍 포함) 분리 // 반복 부호(々, 〻)를 바로 앞의 한자로 치환 for (var j = 0; j < chars.length; j++) { if (chars[j] === '々' || chars[j] === '〻') { if (j > 0) { chars[j] = chars[j - 1]; } } } // 한자 수사로만 이루어진 덩어리(예: 六千六百六十六)는 각 자릿수를 독립된 단어처럼 취급해 // 위치와 무관하게 두음법칙을 적용한다. var isPureNumeralRun = chars.length > 1 && chars.every(function (c) { return HANJA_NUMERAL_CHARS.indexOf(c) !== -1; }); for (var i = 0; i < chars.length; ) { // 1) 아라비아 숫자 연속 표기(전화번호/일련번호 등 "코드형" 숫자열)의 치환 처리 // (예: 二〇二六 -> 2026, 〇二-一二三-四五六七 -> 02-123-4567) // 단, 一一/一々처럼 그냥 같은 수사가 반복된 경우(예: 일일이)는 국어 발음으로 읽어야 하므로 // "〇(영) 포함" 또는 "앞/뒤가 하이픈으로 이어진 자릿수 그룹"일 때만 코드로 간주한다. var arabicLen = 0; while (i + arabicLen < chars.length && Object.prototype.hasOwnProperty.call(ARABIC_NUM_MAP, chars[i + arabicLen])) { arabicLen++; } var arabicSubRun = chars.slice(i, i + arabicLen); var beforeCandidate = context + convertedChars.join(''); var afterRun = chars.slice(i + arabicLen).join('') + text.slice(m.index + run.length); var containsZero = arabicSubRun.indexOf('〇') !== -1; var adjacentDash = /[-–—]\s*$/.test(beforeCandidate) || /^\s*[-–—]/.test(afterRun); var isArabicCandidate = arabicLen >= 2 && (containsZero || adjacentDash); if (isArabicCandidate) { var arabicStr = arabicSubRun.map(function(c) { return ARABIC_NUM_MAP[c]; }).join(''); convertedChars.push(arabicStr); i += arabicLen; continue; // 변환 완료 후 다음 글자로 건너뜀 } var ch = chars[i]; if (isPureNumeralRun) { convertedChars.push(applyDueum(dict[ch] || ch)); i++; continue; } var fullBefore = context + convertedChars.join(''); var isAfterNum = NUMBER_SUFX_RE.test(fullBefore); var parenMatch = fullBefore.match(PAREN_HANGUL_RE); var parenHangul = parenMatch ? parenMatch[1] : null; var matchedWord = null; var matchedReading = null; var matchedWordLen = 0; // 2) 전역 복합어 사전을 참조하여 매칭 확인 (Surrogate Pair 오류 방지를 위해 배열 슬라이싱 사용) for (var k = 0; k < subWordKeys.length; k++) { var key = subWordKeys[k]; var keyChars = Array.from(key); if (chars.slice(i, i + keyChars.length).join('') === key) { matchedWord = key; matchedWordLen = keyChars.length; matchedReading = subWordDict[key]; break; } } if (matchedWord) { // 수량사 뒤 "年度" 예외 조정 (연도 -> 년도) if (isAfterNum && matchedWord === "年度") { matchedReading = "년도"; } convertedChars.push(matchedReading); i += matchedWordLen; // 올바른 글자수만큼 인덱스 전진 } else { // 3) 개별 글자 처리 및 문맥 검사 var reading = dict[ch] || ch; // '不' 예외 처리: 뒤에 오는 글자의 초성이 'ㄷ', 'ㅈ'이거나 '實'인 경우 '부'로 발음 if (ch === '不') { var nextCharObj = (i + 1 < chars.length) ? chars[i + 1] : text.charAt(m.index + run.length); var nextCharReading = dict[nextCharObj] || nextCharObj; if (nextCharObj === '實' || isDigeutOrJieutStarting(nextCharReading)) { reading = '부'; } } // '金' 예외 처리: 한자 덩어리 내에서 첫 글자면(앞에 한자가 없으면) '김', 아니면 '금' if (ch === '金' || ch === '金') { reading = (i === 0) ? '김' : '금'; } var finalReading = reading; // 이전 글자(방금 변환된 한글이거나 한자 블록 앞의 일반 텍스트)를 추적 // 띄어쓰기가 있어도 직전 한글을 올바르게 찾도록 정규식 활용 var prevMatch = context.match(/([가-힣])\s*$/); var prevHangul = convertedChars.length > 0 ? convertedChars[convertedChars.length - 1] : (prevMatch ? prevMatch[1] : context.slice(-1)); if (isAfterNum) { if (ch === '兩') finalReading = '냥'; else if (ch === '年') finalReading = '년'; else finalReading = reading; // 일반적인 경우 두음법칙 무력화 (예: 3里 -> 3리) } else if (parenHangul) { // 괄호 바로 앞 한글 가이드와 부합하면 원음 반영 (예: 냥(兩) -> 냥, 냥쭝(兩쭝) -> 냥쭝) if (ch === '兩' && parenHangul.startsWith('냥')) finalReading = '냥'; else if (ch === '兩' && parenHangul.startsWith('양')) finalReading = '양'; else if (ch === '年' && parenHangul.startsWith('년')) finalReading = '년'; else if (ch === '年' && parenHangul.startsWith('연')) finalReading = '연'; else finalReading = (i === 0) ? applyDueum(reading) : reading; } else { // 모음이나 ㄴ 받침 뒤에 이어지는 '렬, 률'은 '열, 율'로 발음 if ((reading === '렬' || reading === '률') && isVowelOrNieunEnding(prevHangul)) { finalReading = (reading === '렬') ? '열' : '율'; } else if (ch === '理' && i === 0 && chars.length === 1 && isRieulEnding(prevHangul)) { // '-을/ㄹ' 어미 뒤에 단독으로 쓰인 '理'는 의존 명사이므로 두음법칙 예외 finalReading = '리'; } else { // 일반적인 한자 덩어리의 첫머리에만 두음법칙 적용 finalReading = (i === 0) ? applyDueum(reading) : reading; } } convertedChars.push(finalReading); i++; } } var span = document.createElement('span'); span.textContent = convertedChars.join(''); span.dataset.original = run; span.title = run; // 마우스 오버 시 원문 한자 확인 span.classList.add('hanja-converted'); frag.appendChild(span); lastIndex = m.index + run.length; } if (lastIndex < text.length) { frag.appendChild(document.createTextNode(text.slice(lastIndex))); } return frag; } // root를 화면(DOM)에서 잠시 떼어낸 뒤 fn(root)를 실행하고 다시 붙인다. function withDetached(root, fn) { var parent = root.parentNode; var nextSibling = root.nextSibling; var wasDetached = !parent; if (!wasDetached) parent.removeChild(root); try { fn(root); } finally { if (!wasDetached) { if (nextSibling) parent.insertBefore(root, nextSibling); else parent.appendChild(root); } } } function convertNode(root) { withDetached(root, function (root) { applyManualOverrides(root); // 1) 틀로 지정된 부분 먼저 처리 // 2) 문서를 순서대로 한 번만 훑으며, 직전 글자를 흘려보낸다 (O(n)) var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null); var lastText = ""; var toProcess = []; var node; while ((node = walker.nextNode())) { var text = node.nodeValue; if (!text) continue; var insideConverted = node.parentNode && node.parentNode.closest && node.parentNode.closest('.hanja-converted'); if (!insideConverted && HAN_RE.test(text)) { toProcess.push({ node: node, precedingText: lastText }); } if (!insideConverted && text.length) { lastText = (lastText + text).slice(-50); // 최근 50글자까지만 버퍼에 보존 } } toProcess.forEach(function (item) { var frag = buildConvertedFragment(item.node.nodeValue, item.precedingText); item.node.parentNode.replaceChild(frag, item.node); }); }); } function restore(root) { withDetached(root, function (root) { root.querySelectorAll('.hanja-converted').forEach(function (span) { if (span.classList.contains('hanja-manual-reading')) { span.textContent = span.dataset.original; span.classList.remove('hanja-converted'); span.removeAttribute('title'); } else { span.replaceWith(document.createTextNode(span.dataset.original)); } }); }); } mw.loader.using('mediawiki.util').then(function () { // 변환된 한자에 옅은 점선 밑줄을 넣어, 원문과 구분되게 하되 가독성은 해치지 않도록 함. mw.util.addCSS( '.hanja-converted {' + ' border-bottom: 1px dotted rgba(128,128,128,0.6);' + ' cursor: help;' + ' text-decoration: none;' + '}' ); mw.util.addPortletLink(portlet, '#', '한자 독음', 'ca-hanja2hangul', buttontooltip); $('#ca-hanja2hangul').on('click', function (e) { e.preventDefault(); loadDict().then(function () { var content = document.querySelector('#mw-content-text .mw-parser-output'); if (!content) return; toggled = !toggled; toggled ? convertNode(content) : restore(content); }); }); }); }); dz4wu3n3dhhrr55lsh40n2ojjq6d2vt User:Namoroka/sandbox/1 2 177074 754645 754561 2026-08-02T08:31:33Z Namoroka 19627 754645 wikitext text/x-wiki * [[MediaWiki:Gadget-hanja-reading.js]] ** [[MediaWiki:Gadget-hanja-base2.json]] ** [[MediaWiki:Gadget-hanja-variants.json]] ** [[MediaWiki:Gadget-hanja-variants-cjkvi.json]] ** [[MediaWiki:Gadget-hanja-history.json]] ** [[MediaWiki:Gadget-hanja-overrides.json]] ** [[MediaWiki:Gadget-hanja-word.json]] *량(輛), 리(理, 里, 厘, 釐) *량(輛), 列車 한 輛 **차량(車輛) **차량세(車輛稅) **차량용품(車輛用品) *不+ㄷ/ㅈ = 부, 나머지는 전부 불 **불가(不可), 불량(不良), 불합리(不合理) **부당(不當), 절대부등식(絶對不等式), 부적절(不適切) **예외: 부실(不實), 3불정책(三不政策), 독불장군(獨不將軍) (어미 ‘-을’ 뒤에 ‘있다’, ‘없다’ 따위와 함께 쓰여) 1. ‘까닭’, ‘이치’의 뜻을 나타내는 말. *그럴 理가 없다. *그럴理가 없다. *그럴理가없다. *雲養 大監이나 나나 이미 허리 부러진 虎狼인데, 저들이 危險을 무릅쓰면서까지 도와줄 理 있겠소? *外部에서 侵入한 痕跡이 없고 門은 잠겨져 있었으므로 나갔을 理 萬無다. *閔箕의 性格으로 그 祕密을 그의 妻에게 告白하지 않았을 理 또한 없을 터였다. *자네가 모르는 일을 낸들 알 理 있나? *그러나 조만춘이가 逃亡兵인 그를 찾아 이런 後方에까지 내려올 理가 萬無하다. *벌써 데려왔을 理는 없고 마침 제풀에 왔나 하고 가만히 앉았으려니 門이 활짝 열리며 경애가 딱 섰다. *신여성(新女性) *新女性(신여성) *新女性 *女性 *女 *省略 * 金: 김/금 ** 김해 김씨(金海金氏, 金海 金氏), 金海, 金氏 **개금(改金), 과금(課金), 과징금(課懲金), 금강(金剛), 금속(金屬), 비금속(非金屬), 금요일(金曜日), 비자금(秘資金), 장학금(奬學金), 황금(黃金), 금전(金錢), 입금(入金) **김구(金九), 김대중(金大中), 김부겸(金富謙), 김종필(金鍾泌), 김무성(金武星), 김상곤(金相坤) **가서만금(家書萬金), 견금여석(見金如石), 금과옥조(金科玉條), 금란지교(金蘭之交), 금석뇌약(金石牢約), 금자탑(金字塔), 금지옥엽(金枝玉葉), 단금지계교(斷金之契交),일확천금(一攫千金) **금강산(金剛山), 금련산(金連山), 금오산(金烏山), 금정산(金井山), 몽금포(夢金浦), 새만금(새萬金) * 반복부호 **正々堂々(정정당당) **明々白々(명명백백) **各々(각각), 云々(운운), 繼々承々(계계승승), 一々히(일일이), 一一히 **續々(속속) **着々(착착) **歷々히(역력히) **默々히(묵묵히) **細々한(세세한) **赫々한(혁혁한) **紛々할(분분할) **紛〻할 **분々할 * 一二三四五六七八九十百千萬万億兆〇零 ** 二〇二六年, 一九九九年, 二〇〇〇년대 ** 六二〇〇円, 五〇〇원, 五〇〇원 ** 〇二-一二三-四五六七 ** 第一〇〇호, 三〇二호 ** 二.〇 == 테스트 4 == *樂('''악''', 낙, 락, '''요''') → '''樂曲(악곡)''', 樂園(낙원), 娛樂(오락), '''樂山(요산)''' *見(견, '''현''') → 見聞(견문), '''謁見(알현)''' ;제10항 첫음 '녀, 뇨, 뉴, 니' → '여, 요, 유, 이' *여자(女子), 연세(年歲), 요소(尿素), 유대(紐帶), 이토(泥土), 익명(匿名), 여성(女性), 여아(女兒), 여선생(女先生), 여학생(女學生) *예외 1: 냥(兩), 냥쭝('''兩쭝'''), 년(年) / '''十''' 年, 金 '''한 兩''', 銀 두 '''兩쭝''' / 年 降水量(연 강수량, 명사), '''十 年'''(십 년, 의존 명사), 生産 年度(생산 연도, 명사), '''2018 年度'''(2018 년도, 의존 명사), 2018年度(2018년도, 의존 명사) *예외 2: 신여성('''新女性'''), 공염불('''空念佛'''), 남존여비('''男尊女卑''') *예외 3: 한국여자대학('''韓國女子大學'''), 대한요소비료회사(大韓尿素肥料會社) ;제11항 첫음 '랴, 려, 례, 료, 류, 리' → '야, 여, 예, 요, 유, 이' *양심(良心), 역사(歷史), 예의(禮義), 용궁(龍宮), 유행(流行), 이발(理髮) *예외 1: 리(里): '''몇 理'''냐?, 리(理): '''그럴 理'''가 없다. / '''客車''' '''五十 輛'''(객차 오십 량), '''2分''' 5厘 7厘(2푼 5리 7리) *예외 2: 나열('''羅列'''), 치열('''齒列'''), 비열('''卑劣'''), 규율('''規律'''), 비율('''比率'''), 실패율('''失敗率'''), 분열('''分裂'''), 선열('''先烈'''), 진열('''陳列'''), 선율('''旋律'''), 전율('''戰慄'''), 백분율('''百分率''') *예외 3: 신립(申砬), 최린(崔麟), 채륜(蔡倫), 하륜('''河崙''') *예외 4: 국제연합('''國際聯合''') → 국련(國聯), 한국시각장애인연합회('''韓國視覺障礙人聯合會''') → 한시련(韓視聯) *예외 4: 역이용('''逆利用'''), 연이율('''年利率'''), 열역학('''熱力學'''), 해외여행('''海外旅行''') *예외 5: 서울여관(서울旅館), 신흥이발관('''新興理髮館'''), 육천육백육십육('''六千六百六十六''') ;제12항 첫음 '라, 래, 로, 뢰, 루, 르' → '나, 내, 노, 뇌, 누, 느' *낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓) *예외 1: 낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓) *예외 2: 내내월('''來來月'''), 상노인('''上老人'''), 중노동('''重勞動'''), 비논리적('''非論理的''') ;제13항 한 단어 안에서 같은 음절이나 비슷한 음절이 겹쳐 나는 부분 *연연불망('''戀戀不忘'''), 유유상종('''類類相從'''), 누누이('''屢屢이''') *예외: 열렬히('''熱熱히'''), 늠름히('''凜凜히'''), 연년세세(年年歲歲), 낙락장송(落落長松), 냉랭하다(冷冷하다), 역력히(歷歷히), 염념불망(念念不忘) * https://db.history.go.kr/unicode/ * https://kostma.aks.ac.kr/segment/segmentList.aspx * https://www.heritage.go.kr/heri/mem/selectHanjUmka.do * https://www.hanja.ne.kr/jupsu/jupsu07_01.asp * https://oriental-dic.dankook.ac.kr/index * http://www.e-hanja.kr/ * https://hc.jsecs.org/irg/ws2021/app/ * https://db.cyberseodang.or.kr/twochar/index.html# == + == 갈곶리(乫串里) 법곳동(法串洞) 대곶면(大串面) 월곶면(月串面) 보구곶(甫口串) 월곶동(月串洞) 장곳리(獐串里) 홍곳리(洪串里) 삼곶리(三串里) 갈곶동(葛串洞) 지곶동(紙串洞) 갑곶리(甲串里) 월곳리(月串里) 석곶리(石串里) 호미곶(虎尾串) 흥환리(興串里) 사곶리(仕串里) 간절곶(艮絶串) 대산곶(大山串) 모월곶(毛月串) 호미곶(虎尾串) 장기곶(艮絶串) 비파곶(比巴串) 송도곶(松島串) 장산곶(長山串) 등산곶(登山串) 전곶(箭串) 공단곶(功端串) 동외곶(冬外串) 장기곶(長鬐串) 장산곶(長山串) 갑곶(甲串) 본곶(本곶) 모래곶(모래串) 활음조 현상 거란(契丹) 동란국(東丹國) 모란(牧丹) <pre> "開寧民亂": "개령민란", "敦寧": "돈령", "靡寧": "미령", "玉度靡寧": "옥도미령", "會寧": "회령", "武寧": "무령", "孝寧": "효령", "遼寧": "요령", "居寧": "거령", "巨寧": "거령", "濟寧里": "제령리", "宜寧": "의령", "開寧面": "개령면", "河寧里": "하령리", "載寧": "재령", "會寧里": "회령리", "保寧": "보령", "富寧": "부령", "泰寧": "태령", "古寧": "고령", "鐵犂": "철려", "鋤犁": "서려", "踏犂": "답려", "單牛犂": "단우려", "兩牛犂": "양우려", "蟉松": "규송", "瘻癘": "누라", "縶縲": "칩류", "縲紲": "유설", "鶆鳩": "내구", "水剌": "수라", "纍纍": "누누", 惹鬧 야료 起鬧 기뇨 熱鬧 열뇨 鬧擾 요요 息鬧 식뇨 息鬧 식뇨 濟州民鬧 제주민요 作鬧 작뇨 乖鬧 괴뇨 紛鬧 분뇨 喧鬧 훤뇨 煩鬧 번뇨 惹起鬧端-- 야기요단 </pre> == Copyright == The Unicode database is released by Unicode Inc. under the following terms: <blockquote> Copyright © 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. </blockquote> hon2pntwgki8tbbme8vpc87zvj910yg 754646 754645 2026-08-02T08:33:06Z Namoroka 19627 754646 wikitext text/x-wiki * [[MediaWiki:Gadget-hanja-reading.js]] ** [[MediaWiki:Gadget-hanja-base2.json]] ** [[MediaWiki:Gadget-hanja-variants.json]] ** [[MediaWiki:Gadget-hanja-variants-cjkvi.json]] ** [[MediaWiki:Gadget-hanja-history.json]] ** [[MediaWiki:Gadget-hanja-overrides.json]] ** [[MediaWiki:Gadget-hanja-word.json]] *량(輛), 리(理, 里, 厘, 釐) *량(輛), 列車 한 輛 **차량(車輛) **차량세(車輛稅) **차량용품(車輛用品) *不+ㄷ/ㅈ = 부, 나머지는 전부 불 **불가(不可), 불량(不良), 불합리(不合理) **부당(不當), 절대부등식(絶對不等式), 부적절(不適切) **예외: 부실(不實), 3불정책(三不政策), 독불장군(獨不將軍) (어미 ‘-을’ 뒤에 ‘있다’, ‘없다’ 따위와 함께 쓰여) 1. ‘까닭’, ‘이치’의 뜻을 나타내는 말. *그럴 理가 없다. *그럴理가 없다. *그럴理가없다. *雲養 大監이나 나나 이미 허리 부러진 虎狼인데, 저들이 危險을 무릅쓰면서까지 도와줄 理 있겠소? *外部에서 侵入한 痕跡이 없고 門은 잠겨져 있었으므로 나갔을 理 萬無다. *閔箕의 性格으로 그 祕密을 그의 妻에게 告白하지 않았을 理 또한 없을 터였다. *자네가 모르는 일을 낸들 알 理 있나? *그러나 조만춘이가 逃亡兵인 그를 찾아 이런 後方에까지 내려올 理가 萬無하다. *벌써 데려왔을 理는 없고 마침 제풀에 왔나 하고 가만히 앉았으려니 門이 활짝 열리며 경애가 딱 섰다. *신여성(新女性) *新女性(신여성) *新女性 *女性 *女 *省略 * 金: 김/금 ** 김해 김씨(金海金氏, 金海 金氏), 金海, 金氏 **개금(改金), 과금(課金), 과징금(課懲金), 금강(金剛), 금속(金屬), 비금속(非金屬), 금요일(金曜日), 비자금(秘資金), 장학금(奬學金), 황금(黃金), 금전(金錢), 입금(入金) **김구(金九), 김대중(金大中), 김부겸(金富謙), 김종필(金鍾泌), 김무성(金武星), 김상곤(金相坤) **가서만금(家書萬金), 견금여석(見金如石), 금과옥조(金科玉條), 금란지교(金蘭之交), 금석뇌약(金石牢約), 금자탑(金字塔), 금지옥엽(金枝玉葉), 단금지계교(斷金之契交),일확천금(一攫千金) **금강산(金剛山), 금련산(金連山), 금오산(金烏山), 금정산(金井山), 몽금포(夢金浦), 새만금(새萬金) * 반복부호 **正々堂々(정정당당) **明々白々(명명백백) **各々(각각), 云々(운운), 繼々承々(계계승승), 一々이(일일이), 一一이 **續々(속속) **着々(착착) **歷々히(역력히) **默々히(묵묵히) **細々한(세세한) **赫々한(혁혁한) **紛々할(분분할) **紛〻할 **분々할 * 一二三四五六七八九十百千萬万億兆〇零 ** 二〇二六年, 一九九九年, 二〇〇〇년대 ** 六二〇〇円, 五〇〇원, 五〇〇원 ** 〇二-一二三-四五六七 ** 第一〇〇호, 三〇二호 ** 二.〇 == 테스트 4 == *樂('''악''', 낙, 락, '''요''') → '''樂曲(악곡)''', 樂園(낙원), 娛樂(오락), '''樂山(요산)''' *見(견, '''현''') → 見聞(견문), '''謁見(알현)''' ;제10항 첫음 '녀, 뇨, 뉴, 니' → '여, 요, 유, 이' *여자(女子), 연세(年歲), 요소(尿素), 유대(紐帶), 이토(泥土), 익명(匿名), 여성(女性), 여아(女兒), 여선생(女先生), 여학생(女學生) *예외 1: 냥(兩), 냥쭝('''兩쭝'''), 년(年) / '''十''' 年, 金 '''한 兩''', 銀 두 '''兩쭝''' / 年 降水量(연 강수량, 명사), '''十 年'''(십 년, 의존 명사), 生産 年度(생산 연도, 명사), '''2018 年度'''(2018 년도, 의존 명사), 2018年度(2018년도, 의존 명사) *예외 2: 신여성('''新女性'''), 공염불('''空念佛'''), 남존여비('''男尊女卑''') *예외 3: 한국여자대학('''韓國女子大學'''), 대한요소비료회사(大韓尿素肥料會社) ;제11항 첫음 '랴, 려, 례, 료, 류, 리' → '야, 여, 예, 요, 유, 이' *양심(良心), 역사(歷史), 예의(禮義), 용궁(龍宮), 유행(流行), 이발(理髮) *예외 1: 리(里): '''몇 理'''냐?, 리(理): '''그럴 理'''가 없다. / '''客車''' '''五十 輛'''(객차 오십 량), '''2分''' 5厘 7厘(2푼 5리 7리) *예외 2: 나열('''羅列'''), 치열('''齒列'''), 비열('''卑劣'''), 규율('''規律'''), 비율('''比率'''), 실패율('''失敗率'''), 분열('''分裂'''), 선열('''先烈'''), 진열('''陳列'''), 선율('''旋律'''), 전율('''戰慄'''), 백분율('''百分率''') *예외 3: 신립(申砬), 최린(崔麟), 채륜(蔡倫), 하륜('''河崙''') *예외 4: 국제연합('''國際聯合''') → 국련(國聯), 한국시각장애인연합회('''韓國視覺障礙人聯合會''') → 한시련(韓視聯) *예외 4: 역이용('''逆利用'''), 연이율('''年利率'''), 열역학('''熱力學'''), 해외여행('''海外旅行''') *예외 5: 서울여관(서울旅館), 신흥이발관('''新興理髮館'''), 육천육백육십육('''六千六百六十六''') ;제12항 첫음 '라, 래, 로, 뢰, 루, 르' → '나, 내, 노, 뇌, 누, 느' *낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓) *예외 1: 낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓) *예외 2: 내내월('''來來月'''), 상노인('''上老人'''), 중노동('''重勞動'''), 비논리적('''非論理的''') ;제13항 한 단어 안에서 같은 음절이나 비슷한 음절이 겹쳐 나는 부분 *연연불망('''戀戀不忘'''), 유유상종('''類類相從'''), 누누이('''屢屢이''') *예외: 열렬히('''熱熱히'''), 늠름히('''凜凜히'''), 연년세세(年年歲歲), 낙락장송(落落長松), 냉랭하다(冷冷하다), 역력히(歷歷히), 염념불망(念念不忘) * https://db.history.go.kr/unicode/ * https://kostma.aks.ac.kr/segment/segmentList.aspx * https://www.heritage.go.kr/heri/mem/selectHanjUmka.do * https://www.hanja.ne.kr/jupsu/jupsu07_01.asp * https://oriental-dic.dankook.ac.kr/index * http://www.e-hanja.kr/ * https://hc.jsecs.org/irg/ws2021/app/ * https://db.cyberseodang.or.kr/twochar/index.html# == + == 갈곶리(乫串里) 법곳동(法串洞) 대곶면(大串面) 월곶면(月串面) 보구곶(甫口串) 월곶동(月串洞) 장곳리(獐串里) 홍곳리(洪串里) 삼곶리(三串里) 갈곶동(葛串洞) 지곶동(紙串洞) 갑곶리(甲串里) 월곳리(月串里) 석곶리(石串里) 호미곶(虎尾串) 흥환리(興串里) 사곶리(仕串里) 간절곶(艮絶串) 대산곶(大山串) 모월곶(毛月串) 호미곶(虎尾串) 장기곶(艮絶串) 비파곶(比巴串) 송도곶(松島串) 장산곶(長山串) 등산곶(登山串) 전곶(箭串) 공단곶(功端串) 동외곶(冬外串) 장기곶(長鬐串) 장산곶(長山串) 갑곶(甲串) 본곶(本곶) 모래곶(모래串) 활음조 현상 거란(契丹) 동란국(東丹國) 모란(牧丹) <pre> "開寧民亂": "개령민란", "敦寧": "돈령", "靡寧": "미령", "玉度靡寧": "옥도미령", "會寧": "회령", "武寧": "무령", "孝寧": "효령", "遼寧": "요령", "居寧": "거령", "巨寧": "거령", "濟寧里": "제령리", "宜寧": "의령", "開寧面": "개령면", "河寧里": "하령리", "載寧": "재령", "會寧里": "회령리", "保寧": "보령", "富寧": "부령", "泰寧": "태령", "古寧": "고령", "鐵犂": "철려", "鋤犁": "서려", "踏犂": "답려", "單牛犂": "단우려", "兩牛犂": "양우려", "蟉松": "규송", "瘻癘": "누라", "縶縲": "칩류", "縲紲": "유설", "鶆鳩": "내구", "水剌": "수라", "纍纍": "누누", 惹鬧 야료 起鬧 기뇨 熱鬧 열뇨 鬧擾 요요 息鬧 식뇨 息鬧 식뇨 濟州民鬧 제주민요 作鬧 작뇨 乖鬧 괴뇨 紛鬧 분뇨 喧鬧 훤뇨 煩鬧 번뇨 惹起鬧端-- 야기요단 </pre> == Copyright == The Unicode database is released by Unicode Inc. under the following terms: <blockquote> Copyright © 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. </blockquote> ovhl9ucvei80uauvnfov84j3c628ebt 754650 754646 2026-08-02T08:59:29Z Namoroka 19627 754650 wikitext text/x-wiki * [[MediaWiki:Gadget-hanja-reading.js]] ** [[MediaWiki:Gadget-hanja-base2.json]] ** [[MediaWiki:Gadget-hanja-variants.json]] ** [[MediaWiki:Gadget-hanja-variants-cjkvi.json]] ** [[MediaWiki:Gadget-hanja-history.json]] ** [[MediaWiki:Gadget-hanja-overrides.json]] ** [[MediaWiki:Gadget-hanja-word.json]] *량(輛), 리(理, 里, 厘, 釐) *량(輛), 列車 한 輛 **차량(車輛) **차량세(車輛稅) **차량용품(車輛用品) *不+ㄷ/ㅈ = 부, 나머지는 전부 불 **불가(不可), 불량(不良), 불합리(不合理) **부당(不當), 절대부등식(絶對不等式), 부적절(不適切) **예외: 부실(不實), 3불정책(三不政策), 독불장군(獨不將軍) 불가(不可) 불가결(不可缺) 불가능(不可能) 불가침조약(不可侵條約) 불가피(不可避) 불과(不過) 불구(不拘) 불구속(不拘束) 불규칙(不規則) 불균형(不均衡) 불길(不吉) 불능(不能) 불량(不良) 불량배(不良輩) 불량식품(不良食品) 불로초(不老草) 불리(不利) 불륜(不倫) 불만(不滿) 불만족(不滿足) 불면증(不眠症) 불멸(不滅) 불명예(不名譽) 불모지(不毛地) 불문(不問) 불법(不法) 불법적(不法的) 불법행위(不法行爲) 불변(不變) 불복(不服) 불복종(不服從) 불사(不辭/不死) 불사신(不死身) 불사조(不死鳥) 불상사(不祥事) 불성실(不誠實) 불순(不純/不順) 불시(不時) 불신(不信) 불안(不安) 불여귀(不如歸) 불연(不燃) 불연성(不燃性) 불연속(不連續) 불완전(不完全) 불우(不遇) 불운(不運) 불응(不應) 퇴거불응죄(退去不應罪) 불의(不義) 불이익(不利益) 불이행(不履行) 제차신호조작불이행(諸車信號操作不履行) 지시불이행(指示不履行) 불임(不妊) 불참(不參) 불청객(不請客) 불체포특권(不逮捕特權) 불초(不肖) 불쾌(不快) 불쾌감(不快感) 불투명(不透明) 불편(不便) 불평(不平) 불평등(不平等) 불필요(不必要) 불합격(不合格) 불합리(不合理) 불행(不幸) 불허(不許) 불확실(不確實) 불확실성(不確實性) 불황(不況) 불효(不孝) 불후(不朽) 부당(不當) 부도(不渡) 부도덕(不道德) 부동산(不動産) 부득이(不得已) 부등식(不等式) 절대부등식(絶對不等式) 부실(不實) 부작위(不作爲) 부재(不在) 부적절(不適切) 부정(不定/不正/不淨) 부정행위(不正行爲) 부조리(不條理) 부족(不足) 과부족(過不足) 부주의(不注意) 삼부점(三不粘) 가치부전(假痴不癲) 과유불급(過猶不及) 권불십년(權不十年) 독불장군(獨不將軍) 두문불출(杜門不出) 목불인견(目不忍見)[7] 목불식정(目不識丁) 복지부동(伏地不動) 불가항력(不可抗力) 불교이주(不敎而誅) 불구대천(不俱戴天) 오매불망(寤寐不忘) 천부당만부당(千不當萬不當) 표리부동(表裏不同) 부동방면(不動坊面) 불로동(不老洞) 불로봉무동(不老鳳舞洞) 가부(可否) 가부간(可否間) 가타부타(可타否타) 거부(拒否) 낙부(諾否) 부결(否決) 부인(否認) 부정(否定) 부정적(否定的) 안부(安否) 여부(與否) 비색(否塞) 비운(否運) 왈가왈부(曰可曰否) (어미 ‘-을’ 뒤에 ‘있다’, ‘없다’ 따위와 함께 쓰여) 1. ‘까닭’, ‘이치’의 뜻을 나타내는 말. *그럴 理가 없다. *그럴理가 없다. *그럴理가없다. *雲養 大監이나 나나 이미 허리 부러진 虎狼인데, 저들이 危險을 무릅쓰면서까지 도와줄 理 있겠소? *外部에서 侵入한 痕跡이 없고 門은 잠겨져 있었으므로 나갔을 理 萬無다. *閔箕의 性格으로 그 祕密을 그의 妻에게 告白하지 않았을 理 또한 없을 터였다. *자네가 모르는 일을 낸들 알 理 있나? *그러나 조만춘이가 逃亡兵인 그를 찾아 이런 後方에까지 내려올 理가 萬無하다. *벌써 데려왔을 理는 없고 마침 제풀에 왔나 하고 가만히 앉았으려니 門이 활짝 열리며 경애가 딱 섰다. *신여성(新女性) *新女性(신여성) *新女性 *女性 *女 *省略 * 金: 김/금 ** 김해 김씨(金海金氏, 金海 金氏), 金海, 金氏 **개금(改金), 과금(課金), 과징금(課懲金), 금강(金剛), 금속(金屬), 비금속(非金屬), 금요일(金曜日), 비자금(秘資金), 장학금(奬學金), 황금(黃金), 금전(金錢), 입금(入金) **김구(金九), 김대중(金大中), 김부겸(金富謙), 김종필(金鍾泌), 김무성(金武星), 김상곤(金相坤) **가서만금(家書萬金), 견금여석(見金如石), 금과옥조(金科玉條), 금란지교(金蘭之交), 금석뇌약(金石牢約), 금자탑(金字塔), 금지옥엽(金枝玉葉), 단금지계교(斷金之契交),일확천금(一攫千金) **금강산(金剛山), 금련산(金連山), 금오산(金烏山), 금정산(金井山), 몽금포(夢金浦), 새만금(새萬金) * 반복부호 **正々堂々(정정당당) **明々白々(명명백백) **各々(각각), 云々(운운), 繼々承々(계계승승), 一々이(일일이), 一一이 **續々(속속) **着々(착착) **歷々히(역력히) **默々히(묵묵히) **細々한(세세한) **赫々한(혁혁한) **紛々할(분분할) **紛〻할 **분々할 * 一二三四五六七八九十百千萬万億兆〇零 ** 二〇二六年, 一九九九年, 二〇〇〇년대 ** 六二〇〇円, 五〇〇원, 五〇〇원 ** 〇二-一二三-四五六七 ** 第一〇〇호, 三〇二호 ** 二.〇 == 테스트 4 == *樂('''악''', 낙, 락, '''요''') → '''樂曲(악곡)''', 樂園(낙원), 娛樂(오락), '''樂山(요산)''' *見(견, '''현''') → 見聞(견문), '''謁見(알현)''' ;제10항 첫음 '녀, 뇨, 뉴, 니' → '여, 요, 유, 이' *여자(女子), 연세(年歲), 요소(尿素), 유대(紐帶), 이토(泥土), 익명(匿名), 여성(女性), 여아(女兒), 여선생(女先生), 여학생(女學生) *예외 1: 냥(兩), 냥쭝('''兩쭝'''), 년(年) / '''十''' 年, 金 '''한 兩''', 銀 두 '''兩쭝''' / 年 降水量(연 강수량, 명사), '''十 年'''(십 년, 의존 명사), 生産 年度(생산 연도, 명사), '''2018 年度'''(2018 년도, 의존 명사), 2018年度(2018년도, 의존 명사) *예외 2: 신여성('''新女性'''), 공염불('''空念佛'''), 남존여비('''男尊女卑''') *예외 3: 한국여자대학('''韓國女子大學'''), 대한요소비료회사(大韓尿素肥料會社) ;제11항 첫음 '랴, 려, 례, 료, 류, 리' → '야, 여, 예, 요, 유, 이' *양심(良心), 역사(歷史), 예의(禮義), 용궁(龍宮), 유행(流行), 이발(理髮) *예외 1: 리(里): '''몇 理'''냐?, 리(理): '''그럴 理'''가 없다. / '''客車''' '''五十 輛'''(객차 오십 량), '''2分''' 5厘 7厘(2푼 5리 7리) *예외 2: 나열('''羅列'''), 치열('''齒列'''), 비열('''卑劣'''), 규율('''規律'''), 비율('''比率'''), 실패율('''失敗率'''), 분열('''分裂'''), 선열('''先烈'''), 진열('''陳列'''), 선율('''旋律'''), 전율('''戰慄'''), 백분율('''百分率''') *예외 3: 신립(申砬), 최린(崔麟), 채륜(蔡倫), 하륜('''河崙''') *예외 4: 국제연합('''國際聯合''') → 국련(國聯), 한국시각장애인연합회('''韓國視覺障礙人聯合會''') → 한시련(韓視聯) *예외 4: 역이용('''逆利用'''), 연이율('''年利率'''), 열역학('''熱力學'''), 해외여행('''海外旅行''') *예외 5: 서울여관(서울旅館), 신흥이발관('''新興理髮館'''), 육천육백육십육('''六千六百六十六''') ;제12항 첫음 '라, 래, 로, 뢰, 루, 르' → '나, 내, 노, 뇌, 누, 느' *낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓) *예외 1: 낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓) *예외 2: 내내월('''來來月'''), 상노인('''上老人'''), 중노동('''重勞動'''), 비논리적('''非論理的''') ;제13항 한 단어 안에서 같은 음절이나 비슷한 음절이 겹쳐 나는 부분 *연연불망('''戀戀不忘'''), 유유상종('''類類相從'''), 누누이('''屢屢이''') *예외: 열렬히('''熱熱히'''), 늠름히('''凜凜히'''), 연년세세(年年歲歲), 낙락장송(落落長松), 냉랭하다(冷冷하다), 역력히(歷歷히), 염념불망(念念不忘) * https://db.history.go.kr/unicode/ * https://kostma.aks.ac.kr/segment/segmentList.aspx * https://www.heritage.go.kr/heri/mem/selectHanjUmka.do * https://www.hanja.ne.kr/jupsu/jupsu07_01.asp * https://oriental-dic.dankook.ac.kr/index * http://www.e-hanja.kr/ * https://hc.jsecs.org/irg/ws2021/app/ * https://db.cyberseodang.or.kr/twochar/index.html# == + == 갈곶리(乫串里) 법곳동(法串洞) 대곶면(大串面) 월곶면(月串面) 보구곶(甫口串) 월곶동(月串洞) 장곳리(獐串里) 홍곳리(洪串里) 삼곶리(三串里) 갈곶동(葛串洞) 지곶동(紙串洞) 갑곶리(甲串里) 월곳리(月串里) 석곶리(石串里) 호미곶(虎尾串) 흥환리(興串里) 사곶리(仕串里) 간절곶(艮絶串) 대산곶(大山串) 모월곶(毛月串) 호미곶(虎尾串) 장기곶(艮絶串) 비파곶(比巴串) 송도곶(松島串) 장산곶(長山串) 등산곶(登山串) 전곶(箭串) 공단곶(功端串) 동외곶(冬外串) 장기곶(長鬐串) 장산곶(長山串) 갑곶(甲串) 본곶(本곶) 모래곶(모래串) 활음조 현상 거란(契丹) 동란국(東丹國) 모란(牧丹) <pre> "開寧民亂": "개령민란", "敦寧": "돈령", "靡寧": "미령", "玉度靡寧": "옥도미령", "會寧": "회령", "武寧": "무령", "孝寧": "효령", "遼寧": "요령", "居寧": "거령", "巨寧": "거령", "濟寧里": "제령리", "宜寧": "의령", "開寧面": "개령면", "河寧里": "하령리", "載寧": "재령", "會寧里": "회령리", "保寧": "보령", "富寧": "부령", "泰寧": "태령", "古寧": "고령", "鐵犂": "철려", "鋤犁": "서려", "踏犂": "답려", "單牛犂": "단우려", "兩牛犂": "양우려", "蟉松": "규송", "瘻癘": "누라", "縶縲": "칩류", "縲紲": "유설", "鶆鳩": "내구", "水剌": "수라", "纍纍": "누누", 惹鬧 야료 起鬧 기뇨 熱鬧 열뇨 鬧擾 요요 息鬧 식뇨 息鬧 식뇨 濟州民鬧 제주민요 作鬧 작뇨 乖鬧 괴뇨 紛鬧 분뇨 喧鬧 훤뇨 煩鬧 번뇨 惹起鬧端-- 야기요단 </pre> == Copyright == The Unicode database is released by Unicode Inc. under the following terms: <blockquote> Copyright © 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. </blockquote> cu2h0ocx1g4urv9aquxps5fp59s39lf User:Enbi/Fortress/config.yaml.js 2 177456 754570 754527 2026-08-01T20:02:27Z Enbi 72574 754570 javascript text/javascript testwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}} (test summary)" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true lhtdf0bscjetlp6hz7hr4kcxqfjt0jq 754580 754570 2026-08-01T20:07:10Z Enbi 72574 754580 javascript text/javascript testwiki: warnSummary: "Test Summary" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true 7diare3pixfllp9xyniszkyqfkklz5l 754597 754580 2026-08-01T20:17:44Z Enbi 72574 754597 javascript text/javascript testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true 0pyki2xsedgqf4nujuno2qspirkow0u Stripped & Justified 0 177484 754564 754536 2026-08-01T16:08:44Z Jaheim2021 75033 754564 wikitext text/x-wiki {{Use mdy dates|date=December 2022}} {{Infobox album | name = Stripped & Justified | type = studio | artist = [[Thicke Levine Timberlake]] | cover = | alt = | released = {{Start date|2022|11|11}} | genre = {{hlist|[[Pop-rap]]|[[dance-pop]]|[[nu-disco]]|[[electropop]]|[[synth-pop]]}} | studio = | length = | recorded = 2021–2022 | label = {{hlist|[[I Am Other]]|[[222 Records|222]]|[[Interscope Records|Interscope]]}} | producer = {{hlist|Ammo|[[Anderson .Paak]]|[[Ash Howes]]|[[Calvin Harris]]|[[Charlie Puth]]|Duck Blackwell|[[James Ford (musician)|James Ford]]|[[Justin Timberlake]]|Kiris Houston|Linslee Campbell|[[Ludwig Göransson]]|[[Madonna]]|[[Mattman & Robin]]||Nico Stadi|PhD|[[Biffco|Richard "Biff" Stannard]]|Sky Adams|[[Teemu Brunila]]}} | prev_title = [[JT Session]] | prev_year = 2020 | next_title = | next_year = | misc = {{Singles | name = Stripped & Justified | type = studio | single1 = [[Miss a Thing (song)|Miss a Thing]] | single1date = June 17, 2022 | single2 = [[A Second to Midnight (song)|A Second to Midnight]] | single2date = October 28, 2022 | single3 = Can't Stop Writing Songs About You | single3date = November 14, 2022 | single4 = Cake by the Ocean | single4date = March 10, 2023 | single5 = Supernova | single5date = July 21, 2023 }} }} '''''Stripped & Justified''''' is the tenth studio album by American [[Pop-R&B]] group [[Thicke Levine Timberlake]]. It was released on November 11, 2022, via [[I Am Other|I Am Other Entertainment]], [[222 Records]] and [[Interscope Records]]. It features [[guest appearance]]s from [[Halsey (singer)|Halsey]], [[Charlie Puth]], [[Jonas Brothers]], [[Calvin Harris]], [[Anderson .Paak]], [[Meghan Trainor]], [[The Lonely Island]], [[Christina Aguilera]], [[Pharrell Williams|Pharrell]] and [[Kylie Minogue]]. It peaked at number 13 on the [[Top Dance/Electronic Albums]] chart in the United States. It reached number 44 in Italy and number 89 in France. == Background and release == After the release of the group's previous album, ''[[JT Session]]'' (2020), the band released a number of new singles. In early November 2022, the group announced their new album entitled ''Stripped & Justified'' on Instagram. Like their previous album, ''Stripped & Justified'' contains fifteen songs. ==Track listing== ==Personnel== ==Charts== ===Weekly charts=== ===Year-end charts=== ==Certifications== ==References== {{Reflist}} {{Thicke Levine Timberlake}} {{Authority control}} [[Category:2022 albums]] [[Category:Thicke Levine Timberlake albums]] [[Category:I Am Other Entertainment albums]] [[Category:222 Records albums]] [[Category:Interscope Records albums]] [[Category:Albums produced by Calvin Harris]] [[Category:Albums produced by Justin Timberlake]] 4qnptogojhitwzw1648j24gl33e07sm The Preacher's Man 0 177493 754563 754547 2026-08-01T16:06:06Z Jaheim2021 75033 754563 wikitext text/x-wiki {{Use mdy dates|date=May 2025}} {{Infobox album | name = The Preacher's Man | type = studio | artist = [[Chris Martin]] and [[Bono]] | cover = | alt = | released = 4 November 2003 | recorded = 2002–03 | studio = | genre = {{hlist|[[Synth-rap]]|[[synth-pop]]|[[electropop]]}} | length = | label = [[Island Records|Island]] | producer = {{hlist|[[Rik Simpson]]|[[Chris Martin]]|[[Linda Perry]]|[[George Michael]]|[[Daft Punk]]|[[Bono]]|[[Joakim Åhlund]]|[[Rob Dougan]]|[[Rick Nowels]]|[[The Edge]]}} | prev_title = | prev_year = | next_title = | next_year = | misc = {{Extra chronology | artist = [[Chris Martin]] | type = studio | prev_title = [[Welcome to the Carnival]] | prev_year = 2002 | title = The Preacher's Man | year = 2003 | next_title = [[Welcome to London: Creole 101]] | next_year = 2004 }} {{Singles | name = The Preacher's Man | type = studio | single1 = [[I Wanna Be Bad (song)|I Wanna Be Bad]] | single1date = 30 September 2003 | single2 = Shape | single2date = 17 November 2003 | single3 = Rise & Fall | single3date = 18 March 2004 }} }} '''''The Preacher's Man''''' is a collaborative album by English singer [[Chris Martin]] and Irish singer [[Bono]], released on 4 November 2003. The album, which was co-produced by Chris Martin, [[Rik Simpson]], Bono and long-time collaborator [[The Edge]], combines elements of [[Synth-rap]], [[synth-pop]] and [[electropop]]. It uses a number of samples, including the [[A&M Records|A&M]]-inspired "Shape", which samples "[[Shape of My Heart (Sting song)|Shape of My Heart]]". The album contains guest appearances by [[Steven Tyler]], [[Annie Lennox]], [[Mis-Teeq]] and [[Kid Rock]], as well as a vocals feature by [[George Michael]] on the song "City Ain't Big Enough". == Track listing == ==Charts== == References == {{reflist}} {{Chris Martin}} {{Bono}} {{Authority control}} {{DEFAULTSORT:Preacher's Man, The}} [[Category:2003 collaborative albums]] [[Category:Albums produced by Chris Martin]] [[Category:Albums produced by Rik Simpson]] [[Category:Chris Martin albums]] [[Category:Bono albums]] [[Category:Island Records albums]] [[Category:Albums produced by Bono]] [[Category:Albums produced by the Edge]] rw3m35pemdavxa7k35nbp6zuun7h7ba Basura 0 177498 754565 2026-08-01T16:24:23Z PCendrer 75068 Created page with "Aqui van insultos duros" 754565 wikitext text/x-wiki Aqui van insultos duros an6zcyclciw0a9yqku5vxavbrrmb3ci User:Enbi/fortress.yaml 2 177499 754610 2026-08-01T21:19:50Z Enbi 72574 Created page with "Fortress config file. <syntaxhighlight><!----></syntaxhighlight>" 754610 wikitext text/x-wiki Fortress config file. <syntaxhighlight><!----></syntaxhighlight> jdmizdpbskyszb95qt06nz71qjnnyus 754611 754610 2026-08-01T21:21:41Z Enbi 72574 754611 wikitext text/x-wiki Fortress config file. <!--START-OF-FILE--><syntaxhighlight lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> 1scrzteiif42bhkgge2xdibr5cn8tcy 754612 754611 2026-08-01T21:22:58Z Enbi 72574 754612 wikitext text/x-wiki Fortress config file. <syntaxhighlight lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> fyrhqg1apftitwinl7iv0gwk6aa5fif 754613 754612 2026-08-01T22:03:09Z Enbi 72574 754613 wikitext text/x-wiki Fortress config file. <syntaxhighht lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> gbonxlj75wl6ednjhj9icaqs1f3bm02 754614 754613 2026-08-01T22:09:19Z Enbi 72574 754614 wikitext text/x-wiki Fortress config file. <syntaxhighlight lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> fyrhqg1apftitwinl7iv0gwk6aa5fif 754615 754614 2026-08-01T22:09:41Z Enbi 72574 754615 wikitext text/x-wiki Fortress config file. <syntaxhighliht lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> 4shcurb2pg5vl85koxepl0ci6fupr2n 754616 754615 2026-08-01T22:13:52Z Enbi 72574 754616 wikitext text/x-wiki Fortress config file. <syntaxhighlight lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> fyrhqg1apftitwinl7iv0gwk6aa5fif 754617 754616 2026-08-01T22:16:03Z Enbi 72574 754617 wikitext text/x-wiki Fortress config file. <syntaxhighlight lang="yaml"> invalid yaml!!!!!!!!!!"""""""?:?:?:?:? testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> d7pkijqexg7knjf20f1ivv33na34yqv 754619 754617 2026-08-01T22:20:12Z Enbi 72574 754619 wikitext text/x-wiki Fortress config file. <syntaxhighlight lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: "Warning user: {{[[Template:$1|$1]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> fyrhqg1apftitwinl7iv0gwk6aa5fif 754624 754619 2026-08-01T22:32:39Z Enbi 72574 754624 wikitext text/x-wiki Fortress config file. <syntaxhighlight lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}} rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> 0gzzh80mxtcznlt259kvw34z5o1v85c 754625 754624 2026-08-01T22:33:07Z Enbi 72574 754625 wikitext text/x-wiki Fortress config file. <syntaxhighlight lang="yaml"> testwiki: warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}" rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true enwiki: warnSummary: 'Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}' rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)" keymaps: # Keymaps that revert and optionally warn. Schema: # key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action # summary: summary you want fortress to use when reverting # template: (optional) warning to leave, without the level number or uw- prefix # single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning. # Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved. - key: q summary: non-constructive edits template: vandalism - key: d summary: potentially disruptive edits template: disruptive - key: t summary: test edits by template: test - key: r overrideOuter: true summary: Reverting edits (Fortress-Beta) menuCategories: - name: Vandalism warnings: - name: Vandalism template: vandalism summary: non-constructive edits - name: Subtle vandalism template: subtle summary: non-constructive edits - name: Image vandalism template: image summary: inappropriate image additions details: Inappropriate images added to articles - name: Joke edits template: joke summary: non-constructive edits - name: Conduct/content warnings: - name: Personal attacks template: npa summary: non-constructive edits - name: Unsourced template: unsourced summary: unsourced additions - name: Unexplained removal template: delete summary: unexplained content removal - name: MOS template: mos summary: potentially disruptive details: Manual of style violations - name: Disruption warnings: - name: Disruptive editing template: disruptive summary: potentially disruptive edits - name: Factual errors template: error summary: factual errors - name: Test edits template: test summary: Editing tests - name: NPOV warnings: - name: Non-neutral template: npov summary: non-neutral-edits - name: Promotional template: promo summary: potentially promotional content added - name: Single issue warnings: - name: English variant template: engvar summary: incorrect English variants single: true </syntaxhighlight> jak63mtmyyss2ld97aisyskkof8cu9c User:2NumForIce/styles.css 2 177500 754629 2026-08-02T06:22:47Z 2NumForIce 57336 Created page with "/* */" 754629 sanitized-css text/css /* */ 2mxuczfr0dl0l45a16e2oujmzw7k0iv 754630 754629 2026-08-02T06:23:04Z 2NumForIce 57336 2NumForIce moved page [[Template:TemplateStyles sandbox/2NumForIce/styles.css]] to [[User:2NumForIce/styles.css]] without leaving a redirect 754629 sanitized-css text/css /* */ 2mxuczfr0dl0l45a16e2oujmzw7k0iv 754632 754630 2026-08-02T06:24:12Z 2NumForIce 57336 754632 sanitized-css text/css #bodyContent { background-color: black; color: white; } f98z1dlgjch1pxfc11k3ij0gadypaoh 754634 754632 2026-08-02T06:24:59Z 2NumForIce 57336 754634 sanitized-css text/css .hw { background-color: black; color: white; } ontnsbi86s1hz0folenmskshbmn6y1z 754635 754634 2026-08-02T06:25:34Z 2NumForIce 57336 test the extents of ts 754635 sanitized-css text/css #mw-content-text { background-color: black; color: white; } 01qwutlg21uo8270y841g9o2pmu5pf4 User talk:2NumForIce/Header 3 177501 754631 2026-08-02T06:23:38Z 2NumForIce 57336 Created page with "<templatestyles src="User:2NumForIce/styles.css" /> Hello world" 754631 wikitext text/x-wiki <templatestyles src="User:2NumForIce/styles.css" /> Hello world cvrlwzdwdasazun3j5wm5yi4h4w4tz9 754633 754631 2026-08-02T06:24:54Z 2NumForIce 57336 754633 wikitext text/x-wiki <templatestyles src="User:2NumForIce/styles.css" /> <span class="hw">Hello world</span> 87zhx2y9x4m7usnc2in8dh9hjr9k13g Insultos 0 177502 754636 2026-08-02T06:57:42Z PCendrer 75068 Created page with "Insultos muy graves" 754636 wikitext text/x-wiki Insultos muy graves jiq4wrhbch6osdv5ph3tnzxy77n27ry Badabadum 0 177503 754637 2026-08-02T07:01:11Z PCendrer 75068 Created page with "Cuando era chiquitito" 754637 wikitext text/x-wiki Cuando era chiquitito q4hvzf9oxwjerjfht92o8qc2en4e9lf Busara 0 177504 754638 2026-08-02T07:02:24Z PCendrer 75068 Created page with "dshjhdskdlhs" 754638 wikitext text/x-wiki dshjhdskdlhs ru6qfphse7rbj1ar2feh3f7hh8ddzva Ourata 0 177505 754639 2026-08-02T07:05:14Z PCendrer 75068 Created page with "Somos lo piratas" 754639 wikitext text/x-wiki Somos lo piratas dhle17brtda97ap9fhz8medpga8gzt6 Funciona 0 177506 754640 2026-08-02T07:07:25Z PCendrer 75068 Created page with "haz algo" 754640 wikitext text/x-wiki haz algo 6a0pf0vtrk23arr7dun4o65bdqpt49m Wikipedia:Sandbox/MoveIt e2e 2026-08-02T08-36-11-016Z 4 177507 754647 2026-08-02T08:36:12Z ~2026-42693-51 75122 MoveIt end-to-end test (2026-08-02T08-36-11-016Z), safe to delete 754647 wikitext text/x-wiki == Requested move: MoveIt e2e 2026-08-02T08-36-11-016Z == MoveIt end-to-end test, safe to delete (2026-08-02T08-36-11-016Z) <nowiki>{{subst:RMassist | 1 = Example page | 2 = Example page (renamed) | reason = MoveIt end-to-end test, safe to delete}}</nowiki> == Tail sentinel 2026-08-02T08-36-11-016Z == Sentinel: a section-targeted append must land above this heading. nmo52lvuqkb2jgmc6v0l9yt70n1ae8l 754648 754647 2026-08-02T08:36:19Z ~2026-42693-51 75122 MoveIt end-to-end section append (2026-08-02T08-36-11-016Z), safe to delete 754648 wikitext text/x-wiki == Requested move: MoveIt e2e 2026-08-02T08-36-11-016Z == MoveIt end-to-end test, safe to delete (2026-08-02T08-36-11-016Z) <nowiki>{{subst:RMassist | 1 = Example page | 2 = Example page (renamed) | reason = MoveIt end-to-end test, safe to delete}}</nowiki> MoveIt section-targeted append, safe to delete (2026-08-02T08-36-11-016Z) == Tail sentinel 2026-08-02T08-36-11-016Z == Sentinel: a section-targeted append must land above this heading. 11vix7hpb6293cgaza5gxaro4jotsar