LyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBmb3IgS0RFLgogKgogKiAoQykgMTk5OSBMYXJzIEtub2xsIChrbm9sbEBrZGUub3JnKQogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgc2VlIHRoZSBmaWxlIENPUFlJTkcuTElCLiAgSWYgbm90LCB3cml0ZSB0bwogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsCiAqIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBUaGlzIGZpbGUgaW5jbHVkZXMgZXhjZXJwdHMgZnJvbSB0aGUgRG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pCiAqIExldmVsIDEgU3BlY2lmaWNhdGlvbiAoUmVjb21tZW5kYXRpb24pCiAqIGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1ET00tTGV2ZWwtMS8KICogQ29weXJpZ2h0IKkgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSAsIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZgogKiBUZWNobm9sb2d5ICwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgogKiBBdXRvbWF0aXF1ZSAsIEtlaW8gVW5pdmVyc2l0eSApLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAkSWQkCiAqLwoKI2lmbmRlZiBIVE1MX0JBU0VfSAojZGVmaW5lIEhUTUxfQkFTRV9ICgojaW5jbHVkZSA8ZG9tL2h0bWxfZWxlbWVudC5oPgoKbmFtZXNwYWNlIERPTSB7CgpjbGFzcyBIVE1MQm9keUVsZW1lbnRJbXBsOwpjbGFzcyBET01TdHJpbmc7CgovKioKICogVGhlIEhUTUwgZG9jdW1lbnQgYm9keS4gVGhpcyBlbGVtZW50IGlzIGFsd2F5cyBwcmVzZW50IGluIHRoZSBET00KICogQVBJLCBldmVuIGlmIHRoZSB0YWdzIGFyZSBub3QgcHJlc2VudCBpbiB0aGUgc291cmNlIGRvY3VtZW50LiBTZWUKICogdGhlIDxhCiAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvc3RydWN0L2dsb2JhbC5odG1sI2VkZWYtQk9EWSI+CiAqIEJPRFkgZWxlbWVudCBkZWZpbml0aW9uIDwvYT4gaW4gSFRNTCA0LjAuCiAqCiAqLwpjbGFzcyBIVE1MQm9keUVsZW1lbnQgOiBwdWJsaWMgSFRNTEVsZW1lbnQKewpwdWJsaWM6CiAgICBIVE1MQm9keUVsZW1lbnQoKTsKICAgIEhUTUxCb2R5RWxlbWVudChjb25zdCBIVE1MQm9keUVsZW1lbnQgJm90aGVyKTsKICAgIEhUTUxCb2R5RWxlbWVudChjb25zdCBOb2RlICZvdGhlcikgOiBIVE1MRWxlbWVudCgpCiAgICAgICAgIHsoKnRoaXMpPW90aGVyO30KcHJvdGVjdGVkOgogICAgSFRNTEJvZHlFbGVtZW50KEhUTUxCb2R5RWxlbWVudEltcGwgKmltcGwpOwpwdWJsaWM6CgogICAgSFRNTEJvZHlFbGVtZW50ICYgb3BlcmF0b3IgPSAoY29uc3QgSFRNTEJvZHlFbGVtZW50ICZvdGhlcik7CiAgICBIVE1MQm9keUVsZW1lbnQgJiBvcGVyYXRvciA9IChjb25zdCBOb2RlICZvdGhlcik7CgogICAgfkhUTUxCb2R5RWxlbWVudCgpOwoKICAgIC8qKgogICAgICogQ29sb3Igb2YgYWN0aXZlIGxpbmtzIChhZnRlciBtb3VzZS1idXR0b24gZG93biwgYnV0IGJlZm9yZQogICAgICogbW91c2UtYnV0dG9uIHVwKS4gU2VlIHRoZSA8YQogICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9zdHJ1Y3QvZ2xvYmFsLmh0bWwjYWRlZi1hbGluayI+CiAgICAgKiBhbGluayBhdHRyaWJ1dGUgZGVmaW5pdGlvbiA8L2E+IGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcwogICAgICogZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIERPTVN0cmluZyBhTGluaygpIGNvbnN0OwoKICAgIC8qKgogICAgICogc2VlIEByZWYgYUxpbmsKICAgICAqLwogICAgdm9pZCBzZXRBTGluayggY29uc3QgRE9NU3RyaW5nICYgKTsKCiAgICAvKioKICAgICAqIFVSSSBvZiB0aGUgYmFja2dyb3VuZCB0ZXh0dXJlIHRpbGUgaW1hZ2UuIFNlZSB0aGUgPGEKICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvc3RydWN0L2dsb2JhbC5odG1sI2FkZWYtYmFja2dyb3VuZCI+CiAgICAgKiBiYWNrZ3JvdW5kIGF0dHJpYnV0ZSBkZWZpbml0aW9uIDwvYT4gaW4gSFRNTCA0LjAuIFRoaXMKICAgICAqIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgogICAgICoKICAgICAqLwogICAgRE9NU3RyaW5nIGJhY2tncm91bmQoKSBjb25zdDsKCiAgICAvKioKICAgICAqIHNlZSBAcmVmIGJhY2tncm91bmQKICAgICAqLwogICAgdm9pZCBzZXRCYWNrZ3JvdW5kKCBjb25zdCBET01TdHJpbmcgJiApOwoKICAgIC8qKgogICAgICogRG9jdW1lbnQgYmFja2dyb3VuZCBjb2xvci4gU2VlIHRoZSA8YQogICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9wcmVzZW50L2dyYXBoaWNzLmh0bWwjYWRlZi1iZ2NvbG9yIj4KICAgICAqIGJnY29sb3IgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUKICAgICAqIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCiAgICAgKgogICAgICovCiAgICBET01TdHJpbmcgYmdDb2xvcigpIGNvbnN0OwoKICAgIC8qKgogICAgICogc2VlIEByZWYgYmdDb2xvcgogICAgICovCiAgICB2b2lkIHNldEJnQ29sb3IoIGNvbnN0IERPTVN0cmluZyAmICk7CgogICAgLyoqCiAgICAgKiBDb2xvciBvZiBsaW5rcyB0aGF0IGFyZSBub3QgYWN0aXZlIGFuZCB1bnZpc2l0ZWQuIFNlZSB0aGUgPGEKICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvc3RydWN0L2dsb2JhbC5odG1sI2FkZWYtbGluayI+CiAgICAgKiBsaW5rIGF0dHJpYnV0ZSBkZWZpbml0aW9uIDwvYT4gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzCiAgICAgKiBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgogICAgICoKICAgICAqLwogICAgRE9NU3RyaW5nIGxpbmsoKSBjb25zdDsKCiAgICAvKioKICAgICAqIHNlZSBAcmVmIGxpbmsKICAgICAqLwogICAgdm9pZCBzZXRMaW5rKCBjb25zdCBET01TdHJpbmcgJiApOwoKICAgIC8qKgogICAgICogRG9jdW1lbnQgdGV4dCBjb2xvci4gU2VlIHRoZSA8YQogICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9zdHJ1Y3QvZ2xvYmFsLmh0bWwjYWRlZi10ZXh0Ij4KICAgICAqIHRleHQgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMKICAgICAqIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCiAgICAgKgogICAgICovCiAgICBET01TdHJpbmcgdGV4dCgpIGNvbnN0OwoKICAgIC8qKgogICAgICogc2VlIEByZWYgdGV4dAogICAgICovCiAgICB2b2lkIHNldFRleHQoIGNvbnN0IERPTVN0cmluZyAmICk7CgogICAgLyoqCiAgICAgKiBDb2xvciBvZiBsaW5rcyB0aGF0IGhhdmUgYmVlbiB2aXNpdGVkIGJ5IHRoZSB1c2VyLiBTZWUgdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3N0cnVjdC9nbG9iYWwuaHRtbCNhZGVmLXZsaW5rIj4KICAgICAqIHZsaW5rIGF0dHJpYnV0ZSBkZWZpbml0aW9uIDwvYT4gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzCiAgICAgKiBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgogICAgICoKICAgICAqLwogICAgRE9NU3RyaW5nIHZMaW5rKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBzZWUgQHJlZiB2TGluawogICAgICovCiAgICB2b2lkIHNldFZMaW5rKCBjb25zdCBET01TdHJpbmcgJiApOwp9OwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmNsYXNzIEhUTUxGcmFtZUVsZW1lbnRJbXBsOwpjbGFzcyBET01TdHJpbmc7CgovKioKICogQ3JlYXRlIGEgZnJhbWUuIFNlZSB0aGUgPGEKICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9wcmVzZW50L2ZyYW1lcy5odG1sI2VkZWYtRlJBTUUiPgogKiBGUkFNRSBlbGVtZW50IGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICoKICovCmNsYXNzIEhUTUxGcmFtZUVsZW1lbnQgOiBwdWJsaWMgSFRNTEVsZW1lbnQKewpwdWJsaWM6CiAgICBIVE1MRnJhbWVFbGVtZW50KCk7CiAgICBIVE1MRnJhbWVFbGVtZW50KGNvbnN0IEhUTUxGcmFtZUVsZW1lbnQgJm90aGVyKTsKICAgIEhUTUxGcmFtZUVsZW1lbnQoY29uc3QgTm9kZSAmb3RoZXIpIDogSFRNTEVsZW1lbnQoKQogICAgICAgICB7KCp0aGlzKT1vdGhlcjt9CnByb3RlY3RlZDoKICAgIEhUTUxGcmFtZUVsZW1lbnQoSFRNTEZyYW1lRWxlbWVudEltcGwgKmltcGwpOwpwdWJsaWM6CgogICAgSFRNTEZyYW1lRWxlbWVudCAmIG9wZXJhdG9yID0gKGNvbnN0IEhUTUxGcmFtZUVsZW1lbnQgJm90aGVyKTsKICAgIEhUTUxGcmFtZUVsZW1lbnQgJiBvcGVyYXRvciA9IChjb25zdCBOb2RlICZvdGhlcik7CgogICAgfkhUTUxGcmFtZUVsZW1lbnQoKTsKCiAgICAvKioKICAgICAqIFJlcXVlc3QgZnJhbWUgYm9yZGVycy4gU2VlIHRoZSA8YQogICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9wcmVzZW50L2ZyYW1lcy5odG1sI2FkZWYtZnJhbWVib3JkZXIiPgogICAgICogZnJhbWVib3JkZXIgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIERPTVN0cmluZyBmcmFtZUJvcmRlcigpIGNvbnN0OwoKICAgIC8qKgogICAgICogc2VlIEByZWYgZnJhbWVCb3JkZXIKICAgICAqLwogICAgdm9pZCBzZXRGcmFtZUJvcmRlciggY29uc3QgRE9NU3RyaW5nICYgKTsKCiAgICAvKioKICAgICAqIFVSSSBkZXNpZ25hdGluZyBhIGxvbmcgZGVzY3JpcHRpb24gb2YgdGhpcyBpbWFnZSBvciBmcmFtZS4gU2VlCiAgICAgKiB0aGUgPGEKICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvcHJlc2VudC9mcmFtZXMuaHRtbCNhZGVmLWxvbmdkZXNjLUZSQU1FIj4KICAgICAqIGxvbmdkZXNjIGF0dHJpYnV0ZSBkZWZpbml0aW9uIDwvYT4gaW4gSFRNTCA0LjAuCiAgICAgKgogICAgICovCiAgICBET01TdHJpbmcgbG9uZ0Rlc2MoKSBjb25zdDsKCiAgICAvKioKICAgICAqIHNlZSBAcmVmIGxvbmdEZXNjCiAgICAgKi8KICAgIHZvaWQgc2V0TG9uZ0Rlc2MoIGNvbnN0IERPTVN0cmluZyAmICk7CgogICAgLyoqCiAgICAgKiBGcmFtZSBtYXJnaW4gaGVpZ2h0LCBpbiBwaXhlbHMuIFNlZSB0aGUgPGEKICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvcHJlc2VudC9mcmFtZXMuaHRtbCNhZGVmLW1hcmdpbmhlaWdodCI+CiAgICAgKiBtYXJnaW5oZWlnaHQgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIERPTVN0cmluZyBtYXJnaW5IZWlnaHQoKSBjb25zdDsKCiAgICAvKioKICAgICAqIHNlZSBAcmVmIG1hcmdpbkhlaWdodAogICAgICovCiAgICB2b2lkIHNldE1hcmdpbkhlaWdodCggY29uc3QgRE9NU3RyaW5nICYgKTsKCiAgICAvKioKICAgICAqIEZyYW1lIG1hcmdpbiB3aWR0aCwgaW4gcGl4ZWxzLiBTZWUgdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3ByZXNlbnQvZnJhbWVzLmh0bWwjYWRlZi1tYXJnaW53aWR0aCI+CiAgICAgKiBtYXJnaW53aWR0aCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiA8L2E+IGluIEhUTUwgNC4wLgogICAgICoKICAgICAqLwogICAgRE9NU3RyaW5nIG1hcmdpbldpZHRoKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBzZWUgQHJlZiBtYXJnaW5XaWR0aAogICAgICovCiAgICB2b2lkIHNldE1hcmdpbldpZHRoKCBjb25zdCBET01TdHJpbmcgJiApOwoKICAgIC8qKgogICAgICogVGhlIGZyYW1lIG5hbWUgKG9iamVjdCBvZiB0aGUgPGNvZGU+IHRhcmdldCA8L2NvZGU+IGF0dHJpYnV0ZSkuCiAgICAgKiBTZWUgdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3ByZXNlbnQvZnJhbWVzLmh0bWwjYWRlZi1uYW1lLUZSQU1FIj4KICAgICAqIG5hbWUgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIERPTVN0cmluZyBuYW1lKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBzZWUgQHJlZiBuYW1lCiAgICAgKi8KICAgIHZvaWQgc2V0TmFtZSggY29uc3QgRE9NU3RyaW5nICYgKTsKCiAgICAvKioKICAgICAqIFdoZW4gdHJ1ZSwgZm9yYmlkIHVzZXIgZnJvbSByZXNpemluZyBmcmFtZS4gU2VlIHRoZSA8YQogICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9wcmVzZW50L2ZyYW1lcy5odG1sI2FkZWYtbm9yZXNpemUiPgogICAgICogbm9yZXNpemUgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIGJvb2wgbm9SZXNpemUoKSBjb25zdDsKCiAgICAvKioKICAgICAqIHNlZSBAcmVmIG5vUmVzaXplCiAgICAgKi8KICAgIHZvaWQgc2V0Tm9SZXNpemUoIGJvb2wgKTsKCiAgICAvKioKICAgICAqIFNwZWNpZnkgd2hldGhlciBvciBub3QgdGhlIGZyYW1lIHNob3VsZCBoYXZlIHNjcm9sbGJhcnMuIFNlZQogICAgICogdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3ByZXNlbnQvZnJhbWVzLmh0bWwjYWRlZi1zY3JvbGxpbmciPgogICAgICogc2Nyb2xsaW5nIGF0dHJpYnV0ZSBkZWZpbml0aW9uIDwvYT4gaW4gSFRNTCA0LjAuCiAgICAgKgogICAgICovCiAgICBET01TdHJpbmcgc2Nyb2xsaW5nKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBzZWUgQHJlZiBzY3JvbGxpbmcKICAgICAqLwogICAgdm9pZCBzZXRTY3JvbGxpbmcoIGNvbnN0IERPTVN0cmluZyAmICk7CgogICAgLyoqCiAgICAgKiBBIFVSSSBkZXNpZ25hdGluZyB0aGUgaW5pdGlhbCBmcmFtZSBjb250ZW50cy4gU2VlIHRoZSA8YQogICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9wcmVzZW50L2ZyYW1lcy5odG1sI2FkZWYtc3JjLUZSQU1FIj4KICAgICAqIHNyYyBhdHRyaWJ1dGUgZGVmaW5pdGlvbiA8L2E+IGluIEhUTUwgNC4wLgogICAgICoKICAgICAqLwogICAgRE9NU3RyaW5nIHNyYygpIGNvbnN0OwoKICAgIC8qKgogICAgICogc2VlIEByZWYgc3JjCiAgICAgKi8KICAgIHZvaWQgc2V0U3JjKCBjb25zdCBET01TdHJpbmcgJiApOwp9OwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmNsYXNzIEhUTUxGcmFtZVNldEVsZW1lbnRJbXBsOwpjbGFzcyBET01TdHJpbmc7CgovKioKICogQ3JlYXRlIGEgZ3JpZCBvZiBmcmFtZXMuIFNlZSB0aGUgPGEKICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9wcmVzZW50L2ZyYW1lcy5odG1sI2VkZWYtRlJBTUVTRVQiPgogKiBGUkFNRVNFVCBlbGVtZW50IGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICoKICovCmNsYXNzIEhUTUxGcmFtZVNldEVsZW1lbnQgOiBwdWJsaWMgSFRNTEVsZW1lbnQKewpwdWJsaWM6CiAgICBIVE1MRnJhbWVTZXRFbGVtZW50KCk7CiAgICBIVE1MRnJhbWVTZXRFbGVtZW50KGNvbnN0IEhUTUxGcmFtZVNldEVsZW1lbnQgJm90aGVyKTsKICAgIEhUTUxGcmFtZVNldEVsZW1lbnQoY29uc3QgTm9kZSAmb3RoZXIpIDogSFRNTEVsZW1lbnQoKQogICAgICAgICB7KCp0aGlzKT1vdGhlcjt9CnByb3RlY3RlZDoKICAgIEhUTUxGcmFtZVNldEVsZW1lbnQoSFRNTEZyYW1lU2V0RWxlbWVudEltcGwgKmltcGwpOwpwdWJsaWM6CgogICAgSFRNTEZyYW1lU2V0RWxlbWVudCAmIG9wZXJhdG9yID0gKGNvbnN0IEhUTUxGcmFtZVNldEVsZW1lbnQgJm90aGVyKTsKICAgIEhUTUxGcmFtZVNldEVsZW1lbnQgJiBvcGVyYXRvciA9IChjb25zdCBOb2RlICZvdGhlcik7CgogICAgfkhUTUxGcmFtZVNldEVsZW1lbnQoKTsKCiAgICAvKioKICAgICAqIFRoZSBudW1iZXIgb2YgY29sdW1ucyBvZiBmcmFtZXMgaW4gdGhlIGZyYW1lc2V0LiBTZWUgdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3ByZXNlbnQvZnJhbWVzLmh0bWwjYWRlZi1jb2xzLUZSQU1FU0VUIj4KICAgICAqIGNvbHMgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIERPTVN0cmluZyBjb2xzKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBzZWUgQHJlZiBjb2xzCiAgICAgKi8KICAgIHZvaWQgc2V0Q29scyggY29uc3QgRE9NU3RyaW5nICYgKTsKCiAgICAvKioKICAgICAqIFRoZSBudW1iZXIgb2Ygcm93cyBvZiBmcmFtZXMgaW4gdGhlIGZyYW1lc2V0LiBTZWUgdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3ByZXNlbnQvZnJhbWVzLmh0bWwjYWRlZi1yb3dzLUZSQU1FU0VUIj4KICAgICAqIHJvd3MgYXR0cmlidXRlIGRlZmluaXRpb24gPC9hPiBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIERPTVN0cmluZyByb3dzKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBzZWUgQHJlZiByb3dzCiAgICAgKi8KICAgIHZvaWQgc2V0Um93cyggY29uc3QgRE9NU3RyaW5nICYgKTsKfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbGFzcyBIVE1MSGVhZEVsZW1lbnRJbXBsOwpjbGFzcyBET01TdHJpbmc7CgovKioKICogRG9jdW1lbnQgaGVhZCBpbmZvcm1hdGlvbi4gU2VlIHRoZSA8YQogKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3N0cnVjdC9nbG9iYWwuaHRtbCNlZGVmLUhFQUQiPgogKiBIRUFEIGVsZW1lbnQgZGVmaW5pdGlvbiA8L2E+IGluIEhUTUwgNC4wLgogKgogKi8KY2xhc3MgSFRNTEhlYWRFbGVtZW50IDogcHVibGljIEhUTUxFbGVtZW50CnsKcHVibGljOgogICAgSFRNTEhlYWRFbGVtZW50KCk7CiAgICBIVE1MSGVhZEVsZW1lbnQoY29uc3QgSFRNTEhlYWRFbGVtZW50ICZvdGhlcik7CiAgICBIVE1MSGVhZEVsZW1lbnQoY29uc3QgTm9kZSAmb3RoZXIpIDogSFRNTEVsZW1lbnQoKQogICAgICAgICB7KCp0aGlzKT1vdGhlcjt9CnByb3RlY3RlZDoKICAgIEhUTUxIZWFkRWxlbWVudChIVE1MSGVhZEVsZW1lbnRJbXBsICppbXBsKTsKcHVibGljOgoKICAgIEhUTUxIZWFkRWxlbWVudCAmIG9wZXJhdG9yID0gKGNvbnN0IEhUTUxIZWFkRWxlbWVudCAmb3RoZXIpOwogICAgSFRNTEhlYWRFbGVtZW50ICYgb3BlcmF0b3IgPSAoY29uc3QgTm9kZSAmb3RoZXIpOwoKICAgIH5IVE1MSGVhZEVsZW1lbnQoKTsKCiAgICAvKioKICAgICAqIFVSSSBkZXNpZ25hdGluZyBhIG1ldGFkYXRhIHByb2ZpbGUuIFNlZSB0aGUgPGEKICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvc3RydWN0L2dsb2JhbC5odG1sI2FkZWYtcHJvZmlsZSI+CiAgICAgKiBwcm9maWxlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIDwvYT4gaW4gSFRNTCA0LjAuCiAgICAgKgogICAgICovCiAgICBET01TdHJpbmcgcHJvZmlsZSgpIGNvbnN0OwoKICAgIC8qKgogICAgICogc2VlIEByZWYgcHJvZmlsZQogICAgICovCiAgICB2b2lkIHNldFByb2ZpbGUoIGNvbnN0IERPTVN0cmluZyAmICk7Cn07CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgSFRNTEh0bWxFbGVtZW50SW1wbDsKY2xhc3MgRE9NU3RyaW5nOwoKLyoqCiAqIFJvb3Qgb2YgYW4gSFRNTCBkb2N1bWVudC4gU2VlIHRoZSA8YQogKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3N0cnVjdC9nbG9iYWwuaHRtbCNlZGVmLUhUTUwiPgogKiBIVE1MIGVsZW1lbnQgZGVmaW5pdGlvbiA8L2E+IGluIEhUTUwgNC4wLgogKgogKi8KY2xhc3MgSFRNTEh0bWxFbGVtZW50IDogcHVibGljIEhUTUxFbGVtZW50CnsKcHVibGljOgogICAgSFRNTEh0bWxFbGVtZW50KCk7CiAgICBIVE1MSHRtbEVsZW1lbnQoY29uc3QgSFRNTEh0bWxFbGVtZW50ICZvdGhlcik7CiAgICBIVE1MSHRtbEVsZW1lbnQoY29uc3QgTm9kZSAmb3RoZXIpIDogSFRNTEVsZW1lbnQoKQogICAgICAgICB7KCp0aGlzKT1vdGhlcjt9CnByb3RlY3RlZDoKICAgIEhUTUxIdG1sRWxlbWVudChIVE1MSHRtbEVsZW1lbnRJbXBsICppbXBsKTsKcHVibGljOgoKICAgIEhUTUxIdG1sRWxlbWVudCAmIG9wZXJhdG9yID0gKGNvbnN0IEhUTUxIdG1sRWxlbWVudCAmb3RoZXIpOwogICAgSFRNTEh0bWxFbGVtZW50ICYgb3BlcmF0b3IgPSAoY29uc3QgTm9kZSAmb3RoZXIpOwoKICAgIH5IVE1MSHRtbEVsZW1lbnQoKTsKCiAgICAvKioKICAgICAqIFZlcnNpb24gaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRvY3VtZW50J3MgRFRELiBTZWUgdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3N0cnVjdC9nbG9iYWwuaHRtbCNhZGVmLXZlcnNpb24iPgogICAgICogdmVyc2lvbiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiA8L2E+IGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZQogICAgICogaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KICAgICAqCiAgICAgKi8KICAgIERPTVN0cmluZyB2ZXJzaW9uKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBzZWUgQHJlZiB2ZXJzaW9uCiAgICAgKi8KICAgIHZvaWQgc2V0VmVyc2lvbiggY29uc3QgRE9NU3RyaW5nICYgKTsKfTsKCn07IC8vbmFtZXNwYWNlCgojZW5kaWYK