replaced CustomEvent polyfill with a direct implementation so we don't interfere with other libraries