(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("react"), require("prop-types"), require("axios")); else if(typeof define === 'function' && define.amd) define(["react", "prop-types", "axios"], factory); else { var a = typeof exports === 'object' ? factory(require("react"), require("prop-types"), require("axios")) : factory(root["react"], root["prop-types"], root["axios"]); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } })(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_21__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/dest/"; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 268); /******/ }) /************************************************************************/ /******/ ({ /***/ 0: /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_0__; /***/ }), /***/ 1: /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_1__; /***/ }), /***/ 135: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _lodash = __webpack_require__(18); var _lodash2 = _interopRequireDefault(_lodash); var _react = __webpack_require__(0); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var useView = function useView() { var _useState = (0, _react.useState)(0), _useState2 = _slicedToArray(_useState, 2), screenWidth = _useState2[0], setScreenWidth = _useState2[1]; (0, _react.useEffect)(function () { var viewWidth = document.documentElement.offsetWidth; setScreenWidth(viewWidth); }, []); (0, _react.useEffect)(function () { var screen = function screen() { if (document && document.documentElement) { setScreenWidth(document.documentElement.offsetWidth); } }; window.addEventListener('resize', (0, _lodash2.default)(screen, 200)); return function () { return window.removeEventListener('resize', screen); }; }, []); return [screenWidth]; }; exports.default = useView; /***/ }), /***/ 16: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(39); /***/ }), /***/ 17: /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ // eslint-disable-line strict /** * Traverses properties on objects and arrays. If an intermediate property is * either null or undefined, it is instead returned. The purpose of this method * is to simplify extracting properties from a chain of maybe-typed properties. * * === EXAMPLE === * * Consider the following type: * * const props: { * user: ?{ * name: string, * friends: ?Array<User>, * } * }; * * Getting to the friends of my first friend would resemble: * * props.user && * props.user.friends && * props.user.friends[0] && * props.user.friends[0].friends * * Instead, `idx` allows us to safely write: * * idx(props, _ => _.user.friends[0].friends) * * The second argument must be a function that returns one or more nested member * expressions. Any other expression has undefined behavior. * * === NOTE === * * The code below exists for the purpose of illustrating expected behavior and * is not meant to be executed. The `idx` function is used in conjunction with a * Babel transform that replaces it with better performing code: * * props.user == null ? props.user : * props.user.friends == null ? props.user.friends : * props.user.friends[0] == null ? props.user.friends[0] : * props.user.friends[0].friends * * All this machinery exists due to the fact that an existential operator does * not currently exist in JavaScript. */ function idx(input, accessor) { try { return accessor(input); } catch (error) { if (error instanceof TypeError) { if (nullPattern.test(error)) { return null; } else if (undefinedPattern.test(error)) { return undefined; } } throw error; } } /** * Some actual error messages for null: * * TypeError: Cannot read property 'bar' of null * TypeError: Cannot convert null value to object * TypeError: foo is null * TypeError: null has no properties * TypeError: null is not an object (evaluating 'foo.bar') * TypeError: null is not an object (evaluating '(" undefined ", null).bar') */ var nullPattern = /^null | null$|^[^(]* null /i; var undefinedPattern = /^undefined | undefined$|^[^(]* undefined /i; idx.default = idx; module.exports = idx; /***/ }), /***/ 18: /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {/** * lodash (Custom Build) <https://lodash.com/> * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors <https://jquery.org/> * Released under MIT license <https://lodash.com/license> * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** Used as references for various `Number` constants. */ var NAN = 0 / 0; /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString = objectProto.toString; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min; /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = function() { return root.Date.now(); }; /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time; // Start the timer for the trailing edge. timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result = wait - timeSinceLastCall; return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } // Restart the timer. timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { // Handle invocations in a tight loop. timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } /** * Creates a throttled function that only invokes `func` at most once per * every `wait` milliseconds. The throttled function comes with a `cancel` * method to cancel delayed `func` invocations and a `flush` method to * immediately invoke them. Provide `options` to indicate whether `func` * should be invoked on the leading and/or trailing edge of the `wait` * timeout. The `func` is invoked with the last arguments provided to the * throttled function. Subsequent calls to the throttled function return the * result of the last `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the throttled function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.throttle` and `_.debounce`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to throttle. * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=true] * Specify invoking on the leading edge of the timeout. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new throttled function. * @example * * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); * jQuery(element).on('click', throttled); * * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel); */ function throttle(func, wait, options) { var leading = true, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } if (isObject(options)) { leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing }); } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && objectToString.call(value) == symbolTag); } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } module.exports = throttle; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) /***/ }), /***/ 19: /***/ (function(module, exports) { // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; /***/ }), /***/ 190: /***/ (function(module, exports) { module.exports = "https://sfiles.cnyes.cool/fe-common/8d7ec61e/46e26e94bec30c49f0d733067ce7f884.svg"; /***/ }), /***/ 191: /***/ (function(module, exports) { module.exports = [{"name":"home","title":"首頁","url":"https://www.{{host}}","isNew":false,"blank":false,"enable":true,"subItems":[]},{"name":"news","title":"新聞","url":"https://news.{{host}}/news/cat/headline","isNew":false,"blank":false,"enable":true,"subItems":[[{"name":"news_headline","title":"頭條","url":"https://news.{{host}}/news/cat/headline","blank":false,"enable":true,"highlight":false},{"name":"news_trending","title":"人氣","url":"https://news.{{host}}/trending","blank":false,"enable":true,"highlight":false},{"name":"news_24h","title":"主編精選","url":"https://news.{{host}}/news/cat/news24h","blank":false,"enable":true,"highlight":false},{"name":"news_project","title":"專題","url":"https://news.{{host}}/projects/cat/all","blank":false,"enable":true,"highlight":true},{"name":"news_celebrity_area","title":"新視界","url":"https://news.{{host}}/news/cat/celebrity_area","blank":false,"enable":true,"highlight":false},{"name":"news_mag","title":"雜誌","url":"https://news.{{host}}/news/cat/mag","blank":false,"enable":true,"highlight":false}],[{"name":"news_twStock","title":"台股","url":"https://news.{{host}}/news/cat/tw_stock","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_twStock_tw_marco","title":"台灣政經","url":"https://news.{{host}}/news/cat/tw_macro","blank":false,"enable":true,"highlight":false},{"name":"news_twStock_quo","title":"台股盤勢","url":"https://news.{{host}}/news/cat/tw_quo","blank":false,"enable":true,"highlight":false},{"name":"news_twStock_news","title":"台股新聞","url":"https://news.{{host}}/news/cat/tw_stock_news","blank":false,"enable":true,"highlight":false},{"name":"news_twStock_tw_bull","title":"台股公告","url":"https://news.{{host}}/news/cat/tw_bull","blank":false,"enable":true,"highlight":false},{"name":"news_twStock_eme_bull","title":"興櫃公告","url":"https://news.{{host}}/news/cat/eme_bull","blank":false,"enable":true,"highlight":false},{"name":"news_twStock_calc","title":"台股表格","url":"https://news.{{host}}/news/cat/tw_calc","blank":false,"enable":true,"highlight":false},{"name":"news_twStock_report","title":"專家觀點","url":"https://news.{{host}}/news/cat/stock_report","blank":false,"enable":true,"highlight":false}]}],[{"name":"news_wdStock","title":"國際股","url":"https://news.{{host}}/news/cat/wd_stock","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_usStock","title":"美股","url":"https://news.{{host}}/news/cat/us_stock","blank":false,"enable":true,"highlight":false},{"name":"news_usStock_live","title":"美股雷達","url":"https://news.{{host}}/news/cat/us_stock_live","blank":false,"enable":true,"highlight":false},{"name":"news_usStock_enu_asia","title":"歐亞股","url":"https://news.{{host}}/news/cat/eu_asia_stock","blank":false,"enable":true,"highlight":false},{"name":"news_usStock_wd_marco","title":"國際政經","url":"https://news.{{host}}/news/cat/wd_macro","blank":false,"enable":true,"highlight":false}]}],[{"name":"news_cnStock","title":"陸港股","url":"https://news.{{host}}/news/cat/cn_stock","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_cnStock_cn_marco","title":"大陸政經","url":"https://news.{{host}}/news/cat/cn_macro","blank":false,"enable":true,"highlight":false},{"name":"news_cnStock_hk","title":"港股","url":"https://news.{{host}}/news/cat/hk_stock","blank":false,"enable":true,"highlight":false},{"name":"news_cnStock_sh","title":"A股","url":"https://news.{{host}}/news/cat/sh_stock","blank":false,"enable":true,"highlight":false}]}],[{"name":"news_bc","title":"區塊鏈","url":"https://news.{{host}}/news/cat/bc","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_bc_crypto","title":"幣圈","url":"https://news.{{host}}/news/cat/bc_crypto","blank":false,"enable":true,"highlight":false},{"name":"news_bc_news","title":"鏈文","url":"https://news.{{host}}/news/cat/bc_news","blank":false,"enable":true,"highlight":false},{"name":"news_bc_tutorial","title":"新手村","url":"https://news.{{host}}/news/cat/bc_tutorial","blank":false,"enable":true,"highlight":false},{"name":"news_bc_live","title":"快訊","url":"https://news.{{host}}/news/cat/bc_live","blank":false,"enable":true,"highlight":false}]},{"name":"news_forex","title":"外匯","url":"https://news.{{host}}/news/cat/forex","blank":false,"enable":true,"highlight":false}],[{"name":"news_future","title":"期貨","url":"https://news.{{host}}/news/cat/future","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_future_index","title":"指數","url":"https://news.{{host}}/news/cat/index_futures","blank":false,"enable":true,"highlight":false},{"name":"news_future_stock","title":"股票","url":"https://news.{{host}}/news/cat/stock_futures","blank":false,"enable":true,"highlight":false},{"name":"news_future_energy","title":"能源","url":"https://news.{{host}}/news/cat/energy","blank":false,"enable":true,"highlight":false},{"name":"news_future_bond","title":"債券","url":"https://news.{{host}}/news/cat/futu_bond","blank":false,"enable":true,"highlight":false},{"name":"news_future_produce","title":"農作","url":"https://news.{{host}}/news/cat/futu_produce","blank":false,"enable":true,"highlight":false},{"name":"news_future_metals","title":"黃金","url":"https://news.{{host}}/news/cat/precious_metals","blank":false,"enable":true,"highlight":false}]}],[{"name":"news_house","title":"房產","url":"https://news.{{host}}/news/cat/cnyeshouse","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_house_cn","title":"大陸房市","url":"https://news.{{host}}/news/cat/cn_housenews","blank":false,"enable":true,"highlight":false},{"name":"news_house_hk","title":"香港房市","url":"https://news.{{host}}/news/cat/hk_housenews","blank":false,"enable":true,"highlight":false},{"name":"news_house_tw","title":"台灣房市","url":"https://news.{{host}}/news/cat/tw_housenews","blank":false,"enable":true,"highlight":false},{"name":"news_house_wd","title":"海外房市","url":"https://news.{{host}}/news/cat/wd_housenews","blank":false,"enable":true,"highlight":false}]}],[{"name":"news_money","title":"理財","url":"https://news.{{host}}/news/cat/tw_money","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_money_fund","title":"基金","url":"https://news.{{host}}/news/cat/fund","blank":false,"enable":true,"highlight":false},{"name":"news_money_insurance","title":"保險","url":"https://news.{{host}}/news/cat/tw_insurance","blank":false,"enable":true,"highlight":false},{"name":"news_money_morningstar","title":"晨星專欄","url":"https://news.{{host}}/news/cat/morningstar","blank":false,"enable":true,"highlight":false},{"name":"news_money_spending","title":"消費","url":"https://news.{{host}}/news/cat/spending","blank":false,"enable":true,"highlight":false}]}],[{"name":"news_report","title":"研究報告","url":"https://news.{{host}}/news/cat/report","blank":false,"enable":true,"highlight":false,"subItems":[{"name":"news_report_fund","title":"基金研報","url":"https://news.{{host}}/news/cat/fund_comment","blank":false,"enable":true,"highlight":false},{"name":"news_report_tw","title":"台股研報","url":"https://news.{{host}}/news/cat/tw_report","blank":false,"enable":true,"highlight":false},{"name":"news_report_global","title":"國際股研報","url":"https://news.{{host}}/news/cat/global_report","blank":false,"enable":true,"highlight":false},{"name":"news_report_forex","title":"外匯研報","url":"https://news.{{host}}/news/cat/fx_report","blank":false,"enable":true,"highlight":false},{"name":"news_report_morningstar","title":"晨星專欄","url":"https://news.{{host}}/news/cat/morningstar","blank":false,"enable":true,"highlight":false}]}]]},{"name":"twStock","title":"台股","url":"https://www.{{host}}/twstock/index.htm","isNew":false,"blank":false,"enable":true,"subItems":[[{"name":"twStock_stock","title":"台股","url":"https://www.{{host}}/twstock/index.htm","blank":false,"enable":true,"subItems":[{"name":"twStock_stock_myTag","title":"追蹤","url":"https://www.{{host}}/member/mytag/all","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_news","title":"新聞","url":"http://news.{{host}}/news/cat/tw_stock_news","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_market","title":"大盤","url":"https://stock.{{host}}","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_profile","title":"類股","url":"https://www.{{host}}/twstock/Index2Real_idx.htm","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_ranking","title":"盤後統計","url":"http://www.{{host}}/twstock/ranking2.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_report","title":"研究報告","url":"https://news.{{host}}/news/cat/tw_report","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_post","title":"公告","url":"https://news.{{host}}/news/cat/announcement","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_calendar","title":"行事曆","url":"https://www.{{host}}/twstock/board/board.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_stock_talk","title":"股市talk","url":"https://stock.{{host}}","blank":false,"enable":true,"highlight":false}]}],[{"name":"twStock_futures","title":"台期指","url":"https://www.{{host}}/twfutures/index.htm","blank":false,"enable":true,"subItems":[{"name":"twStock_futures_news","title":"新聞","url":"https://news.{{host}}/news/cat/tw_quo","blank":false,"enable":true,"highlight":false},{"name":"twStock_futures_report","title":"研究報告","url":"https://news.{{host}}/news/cat/tw_report","blank":false,"enable":true,"highlight":false},{"name":"twStock_futures_global","title":"全球股市期指","url":"http://www.{{host}}/twfutures/global_future.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"twStock_presh","title":"興櫃","url":"http://www.{{host}}/presh/index.htm","blank":false,"enable":true,"subItems":[{"name":"twStock_presh_news","title":"興櫃新聞","url":"http://news.{{host}}/news/cat/tw_stock_news","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_emergingPrice","title":"興櫃報價","url":"http://www.{{host}}/presh/emerging_price.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_stockList","title":"個股","url":"http://www.{{host}}/twstock/stock_astock.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_industry","title":"類股產業","url":"https://www.{{host}}/presh/emerging_stock_list.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_ranking","title":"排行榜","url":"http://www.{{host}}/presh/ranking/ranking_up.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_institutional","title":"法人進出","url":"http://www.{{host}}/presh/institutional/institutional.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_emergingPreIpo","title":"準上櫃上市","url":"http://www.{{host}}/presh/emerging/emerging_preipo.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_schedule","title":"行事曆","url":"http://www.{{host}}/presh/steatement/steatement.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_presh_emergingRoom","title":"興櫃教室","url":"http://www.{{host}}/presh/school/emerging_room.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"twStock_pre","title":"未上市","url":"http://www.{{host}}/pre/index.htm","blank":false,"enable":true,"subItems":[{"name":"twStock_pre_hotNews","title":"未上市最新消息","url":"https://www.{{host}}/pre/hotnews.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_pre_news","title":"未上市新聞","url":"https://news.{{host}}/news/cat/tw_stock_news","blank":false,"enable":true,"highlight":false},{"name":"twStock_pre_rank","title":"未上市熱門排行榜","url":"https://www.{{host}}/pre/rank.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_pre_aStock","title":"個股查詢","url":"http://www.{{host}}/pre/astock.aspx","blank":false,"enable":true,"highlight":false},{"name":"twStock_pre_putOrder","title":"線上掛單","url":"https://www.berich.com.tw/AG/Cnyes2/ToOrder/PutOrder.asp","blank":true,"enable":true,"highlight":false},{"name":"twStock_pre_ranking2","title":"未上市掛單排行","url":"https://www.{{host}}/pre/rank2.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"twStock_putOrder","title":"台股下單","url":"https://stock.{{host}}/market/TWS:TSE01:INDEX","blank":true,"enable":true,"subItems":[]},{"name":"twStock_aStock","title":"個股","url":"https://www.{{host}}/twstock/stock_astock.aspx","blank":false,"enable":true,"subItems":[]},{"name":"twStock_my_stock","title":"自選股","url":"https://www.{{host}}/member/portfolios","blank":false,"enable":true,"subItems":[]},{"name":"twStock_stockQ","title":"StockQ","url":"https://www.{{host}}/stockQ","blank":false,"enable":true,"subItems":[]}]]},{"name":"usStock","title":"美股","url":"https://www.{{host}}/usstock","isNew":false,"blank":false,"enable":true,"subItems":[[{"name":"usStock_news","title":"新聞","url":"https://news.{{host}}/news/cat/us_stock","blank":false,"enable":true,"subItems":[]},{"name":"usStock_etfs","title":"ETFs","url":"https://www.{{host}}/archive/usastock/ETF/ETFs.htm","blank":false,"enable":true,"subItems":[]},{"name":"usStock_adrs","title":"ADRs","url":"https://www.{{host}}/archive/usastock/adr/adrindex.aspx","blank":false,"enable":true,"subItems":[]}],[{"name":"usStock_profile","title":"類股","url":"https://www.{{host}}/usastock/sector.aspx","blank":false,"enable":true,"subItems":[]},{"name":"usStock_aStock","title":"個股","url":"https://www.{{host}}/usastock/usastock_stock.aspx","blank":false,"enable":true,"subItems":[]},{"name":"usStock_ranking","title":"排行榜","url":"https://www.{{host}}/usastock/Rankings/Screener.aspx","blank":false,"enable":true,"subItems":[]}],[{"name":"usStock_report","title":"研究報告","url":"https://news.{{host}}/news/cat/global_report","blank":false,"enable":true,"subItems":[]},{"name":"usStock_schedule","title":"行事曆","url":"https://www.{{host}}/usastock/UsaSchedule/steatement.aspx","blank":false,"enable":true,"subItems":[]},{"name":"usStock_myStock","title":"自選股","url":"https://www.{{host}}/member/portfolios","blank":false,"enable":true,"subItems":[]}]]},{"name":"cnStock","title":"陸港股","url":"https://www.{{host}}/cnstock","isNew":false,"blank":false,"enable":false,"subItems":[[{"name":"cnStock_news","title":"新聞評論","url":"https://www.{{host}}/cnstock/news","blank":false,"enable":true,"subItems":[]},{"name":"cnStock_aStock","title":"個股報價","url":"https://www.{{host}}/cnstock/sh/600519","blank":false,"enable":true,"subItems":[]},{"name":"cnStock_prediction","title":"個股預測","url":"https://www.{{host}}/cnstock/sh/600519/predict","blank":false,"enable":true,"subItems":[]}],[{"name":"cnStock_ipo","title":"IPO","url":"https://www.{{host}}/cnstock/ipo","blank":false,"enable":true,"subItems":[]},{"name":"cnStock_etf","title":"ETF","url":"https://www.{{host}}/cnstock/etf","blank":false,"enable":true,"subItems":[]},{"name":"cnStock_warrant","title":"權證","url":"https://www.{{host}}/cnstock/warrant","blank":false,"enable":true,"subItems":[]}],[{"name":"cnStock_shStock","title":"陸股","url":"https://www.{{host}}/shstock","blank":false,"enable":true,"subItems":[]},{"name":"cnStock_classroom","title":"陸港股教室","url":"https://www.{{host}}/cnstock/classroom","blank":false,"enable":true,"subItems":[]},{"name":"cnStock_portfolios","title":"自選股","url":"https://www.{{host}}/member/portfolios","blank":false,"enable":true,"subItems":[]}]]},{"name":"fund","title":"基金","url":"https://fund.{{host}}","isNew":false,"blank":false,"enable":true,"subItems":[[{"name":"fund_myFundList","title":"基金自選","url":"https://invest.{{host}}/my/fundsList","blank":false,"enable":true,"subItems":[]},{"name":"fund_search","title":"基金搜尋","url":"https://fund.{{host}}/search/","blank":false,"enable":true,"subItems":[]},{"name":"fund_dividend","title":"配息專區","url":"https://fund.{{host}}/dividend/index.htm","blank":false,"enable":true,"subItems":[]}],[{"name":"fund_myFund","title":"我的基金","url":"https://fund.{{host}}/MyFunds.aspx","blank":false,"enable":true,"subItems":[{"name":"fund_myFund_Investment","title":"投資組合分析","url":"https://fund.{{host}}/myInvestment/myInvestment.aspx","blank":false,"enable":true,"highlight":false},{"name":"fund_myFund_calcMyFund","title":"基金透視鏡","url":"https://fund.{{host}}/calcmyfundHTML5.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"fund_ranking","title":"基金排行","url":"https://fund.{{host}}/ranking/index.htm","blank":false,"enable":true,"subItems":[{"name":"fund_ranking_sectorRanking","title":"組別分類排行","url":"https://fund.{{host}}/sector-ranking/index.htm","blank":false,"enable":true,"highlight":false},{"name":"fund_ranking_sectorRankingYearly","title":"組別年度績效排行","url":"https://fund.{{host}}/sector-ranking-yearly/index.htm","blank":false,"enable":true,"highlight":false},{"name":"fund_ranking_popular","title":"熱門基金排行","url":"https://fund.{{host}}/popular/index.htm","blank":false,"enable":true,"highlight":false}]}],[{"name":"fund_fixedIncome","title":"債券專區","url":"https://fund.{{host}}/Fixedincome/","blank":false,"enable":true,"subItems":[{"name":"fund_fixedIncome_ranking","title":"債券基金排行","url":"http://fund.{{host}}/Fixedincome/index.aspx","blank":false,"enable":true,"highlight":false},{"name":"fund_fixedIncome_search","title":"債券基金搜尋器","url":"https://fund.{{host}}/Fixedincome/search.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"fund_report","title":"研究報告","url":"https://news.{{host}}/news/cat/fund_comment","blank":false,"enable":true,"subItems":[{"name":"fund_report_fundComment","title":"基金研報","url":"https://news.{{host}}/news/cat/fund_comment","blank":false,"enable":true,"highlight":false}]}],[{"name":"fund_platform","title":"基金交易平台","url":"https://www.anuefund.com/?utm_source=cnyes&utm_medium=fundchannel_menu","blank":true,"enable":true,"subItems":[{"name":"fund_platform_radar","title":"投資雷達","url":"https://blog.anuefund.com/?utm_source=cnyes&utm_medium=fundchannel_menu_radar","blank":true,"enable":true,"highlight":false},{"name":"fund_platform_ai","title":"AI理財","url":"https://www.anuefund.com/EC/ROBO/?utm_source=cnyes&utm_medium=fundchannel_menu_robo","blank":true,"enable":true,"highlight":false},{"name":"fund_platform_vfund","title":"主題投資","url":"https://www.anuefund.com/EC/Vfund/?utm_source=cnyes&utm_medium=fundchannel_menu_vfund","blank":true,"enable":true,"highlight":false},{"name":"fund_platform_app","title":"買基金App","url":"https://www.anuefund.com/launch/join_APP/?utm_source=cnyes&utm_medium=fundchannel_menu_app","blank":true,"enable":true,"highlight":false}]}]]},{"name":"forex","title":"外匯","url":"https://www.{{host}}/forex/","isNew":false,"blank":false,"enable":true,"subItems":[[{"name":"forex_news","title":"新聞","url":"https://news.{{host}}/news/cat/forex","blank":false,"enable":true,"subItems":[]},{"name":"forex_reuters","title":"路透即時外匯","url":"https://www.{{host}}/forex/reuters","blank":false,"enable":true,"subItems":[]},{"name":"forex_majorForex","title":"主要匯率","url":"https://www.{{host}}/archive/forex/major.aspx","blank":false,"enable":true,"subItems":[]},{"name":"forex_crossForex","title":"交叉匯率","url":"https://www.{{host}}/forex/crosslist","blank":false,"enable":true,"subItems":[]}],[{"name":"forex_twd","title":"新台幣","url":"https://www.{{host}}/forex/twd","blank":false,"enable":true,"subItems":[]},{"name":"forex_rmb","title":"人民幣","url":"https://www.{{host}}/forex/rmb","blank":false,"enable":true,"subItems":[]},{"name":"forex_report","title":"研報","url":"https://news.{{host}}/news/cat/fx_report","blank":false,"enable":true,"subItems":[]},{"name":"forex_bankMoneyExchange","title":"銀行換匯","url":"https://forex.cnyes.com/currency/USD/TWD/bank","blank":false,"enable":true,"subItems":[]}]]},{"name":"global","title":"全球","url":"https://invest.{{host}}/indices/major","isNew":false,"blank":false,"enable":true,"subItems":[[{"name":"global_stockQ","title":"StockQ","url":"https://www.{{host}}/stockQ","blank":false,"enable":true,"subItems":[{"name":"global_stockQ_globalIndex","title":"全球指數","url":"https://www.{{host}}/stockQ#GlobalIndex","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_futuresIndex","title":"期指指數","url":"https://www.{{host}}/stockQ#FuturesIndex","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_mainForex","title":"主要匯率","url":"https://www.{{host}}/stockQ#MainForex","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_taiForex","title":"兌台匯率","url":"https://www.{{host}}/stockQ#TaiForex","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_commodity","title":"商品期貨","url":"https://www.{{host}}/stockQ#Commodity","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_bonds","title":"公債市場","url":"https://www.{{host}}/stockQ#Bonds","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_risk","title":"風險指標","url":"https://www.{{host}}/stockQ#Risk","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_loan","title":"拆放款","url":"https://www.{{host}}/stockQ#Loan","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_energy","title":"國際能源","url":"https://www.{{host}}/stockQ#Energy","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_heavyMetal","title":"貴重金屬","url":"https://www.{{host}}/stockQ#HeavyMetal","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_basicMetal","title":"基本金屬","url":"https://www.{{host}}/stockQ#BasicMetal","blank":false,"enable":true,"highlight":false},{"name":"global_stockQ_agriculture","title":"農牧產品","url":"https://www.{{host}}/stockQ#Agriculture","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_international","title":"國際股","url":"https://invest.{{host}}/indices/major","blank":false,"enable":true,"subItems":[{"name":"global_international_news","title":"新聞","url":"https://news.{{host}}/news/cat/wd_stock","blank":false,"enable":true,"highlight":false},{"name":"global_international_mainIndex","title":"主要指數","url":"https://invest.{{host}}/indices/major","blank":false,"enable":true,"highlight":false},{"name":"global_international_allIndex","title":"全部指數","url":"https://www.{{host}}/global/IndexImmediateQuotedPrice/002/QuotationPrice.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_international_asiaIndex","title":"亞洲指數","url":"https://www.{{host}}/global/IndexImmediateQuotedPrice/003/QuotationPrice.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_international_europeIndex","title":"歐洲指數","url":"https://www.{{host}}/global/IndexImmediateQuotedPrice/004/QuotationPrice.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_international_americaIndex","title":"美洲指數","url":"https://www.{{host}}/global/IndexImmediateQuotedPrice/005/QuotationPrice.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_international_globalTechStock","title":"全球科技龍頭股","url":"https://www.{{host}}/usastock/usatechstock.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_international_globalIndustStock","title":"全球傳產龍頭股","url":"https://www.{{host}}/usastock/usainduststock.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_international_globalTime","title":"股市交易時間","url":"https://www.{{host}}/economy/indicator/GlobalTime/GlobalTime_Major.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_international_talk","title":"股市Talk","url":"https://global-stock.{{host}}","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_futures","title":"國際期貨","url":"https://www.{{host}}/futures/index.htm","blank":false,"enable":true,"subItems":[{"name":"global_futures_news","title":"商品新聞","url":"https://news.{{host}}/news/cat/future","blank":false,"enable":true,"highlight":false},{"name":"global_futures_indexFuture","title":"指數期貨","url":"http://www.{{host}}/futures/indexftr.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_price","title":"商品期貨","url":"http://www.{{host}}/futures/price.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_ranking","title":"商品績效排行","url":"http://www.{{host}}/futures/rank1.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_energy","title":"能源","url":"http://www.{{host}}/futures/energy.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_heavyMetal","title":"貴重金屬","url":"http://www.{{host}}/futures/heavymetal.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_basicMetal","title":"基本金屬","url":"http://www.{{host}}/futures/basicmetal.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_agricultural","title":"農產品","url":"http://www.{{host}}/futures/agricultural.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_forex","title":"外匯","url":" https://www.{{host}}/archive/forex/closePrice.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_material","title":"原物料","url":"http://www.{{host}}/futures/material.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_futures_contract","title":"商品合約規格","url":"http://www.{{host}}/futures/contract.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_japan","title":"日股","url":"http://www.{{host}}/JP/index.htm","blank":false,"enable":true,"subItems":[{"name":"global_japan_mainIndex","title":"日股指數","url":"http://www.{{host}}/JP/maindex1.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_japan_famous","title":"知名企業","url":"http://www.{{host}}/JP/famous.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_japan_fund","title":"日本基金","url":"https://fund.{{host}}/search/?investmentArea=A9","blank":false,"enable":true,"highlight":false},{"name":"global_japan_jpy","title":"日圓","url":"https://www.{{host}}/forex/jpy","blank":false,"enable":true,"highlight":false}]},{"name":"global_cnStock","title":"陸港股","url":"https://www.{{host}}/cnstock","blank":false,"enable":true,"subItems":[]}],[{"name":"global_bond","title":"債券","url":"https://www.{{host}}/bond/index.htm","blank":false,"enable":true,"subItems":[{"name":"global_bond_news","title":"債券新聞","url":"https://news.{{host}}/news/cat/futu_bond","blank":false,"enable":true,"highlight":false},{"name":"global_bond_taiwan","title":"台灣債券","url":"https://www.{{host}}/bond/twBondMarket1.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_bond_international","title":"國際債券","url":"http://www.{{host}}/bond/intBondMarket1.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_bond_intLoan","title":"國際拆放款","url":"http://www.{{host}}/bond/intLoan1.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_bond_calculation","title":"債券試算","url":"http://www.{{host}}/bond/bondCalculationJS.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_bond_classrooms","title":"債券教室","url":"http://www.{{host}}/bond/bondClass1.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_gold","title":"黃金","url":"http://www.{{host}}/gold/index.htm","blank":false,"enable":true,"subItems":[{"name":"global_gold_news","title":"黃金新聞","url":"https://news.{{host}}/news/cat/precious_metals","blank":false,"enable":true,"highlight":false},{"name":"global_gold_fund","title":"ETFs/基金","url":"http://www.{{host}}/gold/GoldFund.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_gold_stock","title":"相關個股","url":"http://www.{{host}}/gold/GoldStock.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_gold_classrooms","title":"黃金教室","url":"http://www.{{host}}/gold/ClassRoom.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_gold_contract","title":"黃金合約","url":"http://www.{{host}}/gold/Taifex.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_centralBank","title":"全球央行","url":"http://www.{{host}}/CentralBank/index.htm","blank":false,"enable":true,"subItems":[{"name":"global_centralBank_interest","title":"基準利率","url":"https://www.{{host}}/CentralBank/interest1.htm","blank":false,"enable":true,"highlight":false},{"name":"global_centralBank_intLoan","title":"拆款利率","url":"http://www.{{host}}/CentralBank/intLoan.htm","blank":false,"enable":true,"highlight":false},{"name":"global_centralBank_sovRatingAll","title":"主權評級","url":"http://www.{{host}}/CentralBank/SovRatingAll.htm","blank":false,"enable":true,"highlight":false},{"name":"global_centralBank_curCodity","title":"貨幣商品","url":"http://www.{{host}}/CentralBank/curCodity.htm","blank":false,"enable":true,"highlight":false},{"name":"global_centralBank_cenBanks","title":"各國央行","url":"http://www.{{host}}/CentralBank/cenBanks.htm","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_economyIndicator","title":"經濟指標","url":"https://www.{{host}}/economy/indicator/Page/schedule.aspx","blank":false,"enable":true,"subItems":[{"name":"global_economyIndicator_calendar","title":"金融行事曆","url":"http://www.{{host}}/economy/indicator/EconomicsCalendar/Calendar.aspx","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_bankService","title":"銀行服務","url":"https://www.{{host}}/money/BankService.aspx","blank":false,"enable":true,"subItems":[{"name":"global_bankService_calculation","title":"試算工具","url":"http://www.{{host}}/money/BankCalculation.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_bankService_publicRate","title":"牌告利率","url":"http://www.{{host}}/money/PublicRate.htm","blank":false,"enable":true,"highlight":false},{"name":"global_bankService_valutaDepositRate","title":"外幣存款利率","url":"http://www.{{host}}/money/ValutaDepositRate.htm","blank":false,"enable":true,"highlight":false},{"name":"global_bankService_depositRate","title":"存款利率","url":"http://www.{{host}}/money/DepositRate.htm","blank":false,"enable":true,"highlight":false},{"name":"global_bankService_usuryRate","title":"放款利率","url":"http://www.{{host}}/money/UsuryRate.htm","blank":false,"enable":true,"highlight":false},{"name":"global_bankService_bankMoneyExchange","title":"銀行換匯","url":"http://forex.{{host}}/currency/USD/TWD/bank","blank":false,"enable":true,"highlight":false},{"name":"global_bankService_bankMoneyExchangeCompareTable","title":"銀行換匯比較表","url":"https://forex.{{host}}/currency/USD/TWD/bank","blank":false,"enable":true,"highlight":false}]}],[{"name":"global_fixedIncome","title":"固定收益","url":"https://www.{{host}}/fixedincome/index.htm","blank":false,"enable":true,"subItems":[{"name":"global_fixedIncome_yieldRate","title":"股票殖利率","url":"http://www.{{host}}/fixedincome/Page/securitiesYield_currentYield.aspx","blank":false,"enable":true,"highlight":false},{"name":"global_fixedIncome_etfScreener","title":"固定收益 ETF","url":"http://www.{{host}}/fixedincome/Page/Etf_Screener.htm","blank":false,"enable":true,"highlight":false},{"name":"global_fixedIncome_bond","title":"債券","url":"http://www.{{host}}/fixedincome/Page/Bond.htm","blank":false,"enable":true,"highlight":false},{"name":"global_fixedIncome_tax","title":"相關稅務","url":"http://www.{{host}}/fixedincome/Page/tax.htm","blank":false,"enable":true,"highlight":false},{"name":"global_fixedIncome_compare","title":"商品比較","url":"http://www.{{host}}/fixedincome/Page/AllCompare.htm","blank":false,"enable":true,"highlight":false}]}]]},{"name":"crypto","title":"虛擬貨幣","url":"https://crypto.{{host}}","isNew":false,"blank":false,"enable":true,"subItems":[]},{"name":"anueBuy","title":"鉅亨買","url":"","isNew":true,"blank":false,"enable":true,"subItems":[[{"name":"anueBuy_twStock","title":"買台股","url":"","blank":false,"enable":true,"subItems":[{"name":"anueBuy_twStock_sinopac","title":"永豐金 - 豐存股","url":"https://campaign.cnyes.com/topics/sinopacsectwstock","blank":true,"enable":true,"highlight":true}]},{"name":"anueBuy_usStock","title":"買美港股","url":"","blank":false,"enable":true,"subItems":[{"name":"anueBuy_usStock_sinopac","title":"永豐金 - 1111狂歡祭","url":"https://campaign.cnyes.com/topics/sinopacsecusstock","blank":true,"enable":true,"highlight":true}]}],[{"name":"anueBuy_fund","title":"買基金","url":"","blank":true,"enable":true,"subItems":[{"name":"anueBuy_fund_anue","title":"鉅亨買基金","url":"https://www.anuefund.com/Index.aspx?utm_source=cnyes&utm_medium=channel_mainpage","blank":true,"enable":true,"highlight":true},{"name":"anueBuy_fund_login","title":"帳戶登入","url":"https://www.anuefund.com/Login.aspx?proType=anue&utm_source=cnyes&utm_medium=channel_login_test","blank":true,"enable":true,"highlight":false},{"name":"anueBuy_fund_register","title":"免費開戶","url":"https://www.anuefund.com/FundSpec/OpenAcct/?proType=anue&utm_source=cnyes&utm_medium=channel_newuser_test","blank":true,"enable":true,"highlight":false},{"name":"anueBuy_fund_catalogue","title":"基金申購","url":"https://www.anuefund.com/Fund/Catalogue.aspx?utm_source=cnyes&utm_medium=channel_newbuy_test","blank":true,"enable":true,"highlight":false},{"name":"anueBuy_fund_promo","title":"最新優惠","url":"https://www.anuefund.com/launch/memberpromo/?utm_source=cnyes&utm_medium=channel_preferential","blank":true,"enable":true,"highlight":false}]}],[{"name":"anueBuy_virtualCoin","title":"買虛擬貨幣","url":"","blank":true,"enable":true,"subItems":[{"name":"anueBuy_virtualCoin_ace","title":"ACE王牌交易所 - 台幣買賣","url":"https://campaign.cnyes.com/topics/anuecrypto/?utm_source=cnyes&utm_medium=header#dictionary_ace","blank":true,"enable":true,"highlight":true},{"name":"anueBuy_virtualCoin_pionex","title":"派網 - 網格交易機器人","url":"https://campaign.cnyes.com/topics/anuecrypto/?utm_source=cnyes&utm_medium=header#dictionary_pionex","blank":true,"enable":true,"highlight":true},{"name":"anueBuy_virtualCoin_bincentive","title":"Bincentive - 專家理財","url":"https://campaign.cnyes.com/topics/anuecrypto/?utm_source=cnyes&utm_medium=header#dictionary_bincentive","blank":true,"enable":true,"highlight":true},{"name":"anueBuy_virtualCoin_binance","title":"幣安 - 最大交易所","url":"https://campaign.cnyes.com/topics/anuecrypto/?utm_source=cnyes&utm_medium=header#dictionary_binance","blank":true,"enable":true,"highlight":true},{"name":"anueBuy_virtualCoin_pokket","title":"Pokket - 多元存幣 穩收高息","url":"https://campaign.cnyes.com/topics/anuecrypto/?utm_source=cnyes&utm_medium=header#dictionary_pokket","blank":true,"enable":true,"highlight":true}]}]]},{"name":"invest","title":"老司機","url":"https://invest.{{host}}","isNew":false,"blank":false,"enable":false,"subItems":[]},{"name":"hao","title":"鉅亨號","url":"https://hao.{{host}}","isNew":true,"blank":false,"enable":true,"subItems":[]},{"name":"subscribe","title":"訂閱","url":"https://www.{{host}}/anuestore","isNew":true,"blank":false,"enable":true,"subItems":[[{"name":"subscribe_video","title":"影音","url":"","blank":true,"enable":true,"subItems":[{"name":"subscribe_video_course","title":"投資駕訓班","url":"https://www.{{host}}/video/course/all","blank":false,"enable":true,"highlight":false},{"name":"subscribe_video_program","title":"直播節目","url":"https://www.{{host}}/video/program/allen_see_the_world","blank":false,"enable":true,"highlight":false},{"name":"subscribe_video_litv","title":"免費看片","url":"https://www.{{host}}/video/litv","blank":false,"enable":true,"highlight":false}]}],[{"name":"subscribe_store","title":"鉅亨投資商城","url":"https://www.{{host}}/anuestore","blank":true,"enable":true,"subItems":[{"name":"subscribe_store_notifications","title":"活動講座","url":"https://www.{{host}}/anuestore/notifications","blank":false,"enable":true,"highlight":false}]}]]}] /***/ }), /***/ 2: /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! Copyright (c) 2016 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ /* global define */ (function () { 'use strict'; var hasOwn = {}.hasOwnProperty; function classNames () { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === 'string' || argType === 'number') { classes.push(this && this[arg] || arg); } else if (Array.isArray(arg)) { classes.push(classNames.apply(this, arg)); } else if (argType === 'object') { for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(this && this[key] || key); } } } } return classes.join(' '); } if (typeof module !== 'undefined' && module.exports) { module.exports = classNames; } else if (true) { // register as 'classnames', consistent with npm package name !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { return classNames; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else { window.classNames = classNames; } }()); /***/ }), /***/ 20: /***/ (function(module, exports) { // removed by extract-text-webpack-plugin module.exports = {"wrapperWidth":"1200px","screenSizeSm":"321px","screenSizeMd":"768px","screenSizeMl":"990px","screenSizeLg":"1024px","screenSizeXl":"1200px","screenSizeXXl":"1360px","icon-template":"_aaBGP","anue-search-result":"_3RffD","content-rows":"_ROk_h","row":"_2q1sD","icon--hot":"_oBnHd","anue-new-search-result":"_1iXAk","icon--time":"_CLiKU","section":"_1rK69","mark":"_1Hocp","empty":"_Qb08q","desktop":"_1zi9t","current-search":"_3UODZ","hot-tags":"_8YczV","limit-length":"_Ln_aR","result":"_qNeiO","title":"_2k0-p","summary":"_1iIba","icon-cross":"_25Jm7","content-cols":"_3Mxpd","col":"_nk_ej","avatar":"_3kV9G","name":"_NWqu6","sub-title":"_1vV3r","perf":"_MWDCy","red":"_2LbmQ","green":"_2xSXQ","search-result-content-wrapper":"_Qpfo6","display":"_37iOW","search-result-content-wrapper__header":"_GAt7c","hide":"_23l58","time":"_2yIpV"}; /***/ }), /***/ 21: /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_21__; /***/ }), /***/ 26: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var getCategory = exports.getCategory = function getCategory(item) { var mtype = item.mtype, type = item.type, market = item.market, objectType = item.objectType; if (objectType === 'FUND') { return '基金'; } switch (mtype) { case 'STOCK': { if (type === 'COMMON') { switch (market) { case 'TWS': case 'TWG': return '台股'; case 'USS': return '美股'; case 'HKS': case 'CNS': return '陸港股'; default: return ''; } } else { return 'ETF'; } } case 'FOREX': { if (market === 'CC') { return '加密貨幣'; } return '外匯'; } case 'FUTURES': return '期貨'; case 'INDEX': return '指數'; case 'EOD': return 'EOD'; // eslint-disable-next-line no-fallthrough default: return ''; } }; var getExchange = exports.getExchange = function getExchange(item) { var mtype = item.mtype, exchange = item.exchange, market = item.market, objectType = item.objectType; if (objectType === 'FUND') { return ''; } switch (mtype) { case 'STOCK': case 'FUTURES': return exchange; case 'FOREX': if (market === 'CC') { return exchange; } return ''; case 'INDEX': case 'EOD': default: return ''; } }; exports.default = { getCategory: getCategory, getExchange: getExchange }; /***/ }), /***/ 268: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(269); /***/ }), /***/ 269: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _AnueNavigator = __webpack_require__(270); var _AnueNavigator2 = _interopRequireDefault(_AnueNavigator); var _AnueNavigator3 = __webpack_require__(272); var _AnueNavigator4 = _interopRequireDefault(_AnueNavigator3); var _version = __webpack_require__(66); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var Component = (0, _version.compare)('16.8.0', _react2.default.version) ? _AnueNavigator2.default : _AnueNavigator4.default; exports.default = Component; /***/ }), /***/ 270: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /* eslint-disable no-nested-ternary */ var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _raf = __webpack_require__(53); var _raf2 = _interopRequireDefault(_raf); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _propTypes3 = __webpack_require__(6); var _gaDataset = __webpack_require__(3); var _gaDataset2 = _interopRequireDefault(_gaDataset); var _view = __webpack_require__(135); var _view2 = _interopRequireDefault(_view); var _anueLink = __webpack_require__(7); var _anueLink2 = _interopRequireDefault(_anueLink); var _vars = __webpack_require__(82); var _AnueSearch = __webpack_require__(54); var _AnueSearch2 = _interopRequireDefault(_AnueSearch); var _AnueSubMenu = __webpack_require__(271); var _AnueSubMenu2 = _interopRequireDefault(_AnueSubMenu); var _navs = __webpack_require__(191); var _navs2 = _interopRequireDefault(_navs); var _AnueNavigator = __webpack_require__(85); var _AnueNavigator2 = _interopRequireDefault(_AnueNavigator); var _constants = __webpack_require__(84); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var cx = _bind2.default.bind(_AnueNavigator2.default); function checkIsFixedHeader(fixedHeaderType) { return fixedHeaderType !== _constants.FIXED_HEADER_NONE; } function convertPxToNumber(size) { return parseInt(size.replace('px', ''), 10); } var AnueNavigator = function AnueNavigator(_ref) { var channelName = _ref.channelName, logoUrl = _ref.logoUrl, navs = _ref.navs, searchKeyword = _ref.searchKeyword, enableSearchBar = _ref.enableSearchBar, dataPrefix = _ref.dataPrefix, fixedHeaderType = _ref.fixedHeaderType, accountComponent = _ref.accountComponent, switchVersionComponent = _ref.switchVersionComponent, apiEnv = _ref.apiEnv, hideCountsWhenSearchExpand = _ref.hideCountsWhenSearchExpand; var _useState = (0, _react.useState)(false), _useState2 = _slicedToArray(_useState, 2), fixed = _useState2[0], setFixed = _useState2[1]; var _useState3 = (0, _react.useState)(-1), _useState4 = _slicedToArray(_useState3, 2), currentChannelIndex = _useState4[0], setCurrentChannelIndex = _useState4[1]; var _useState5 = (0, _react.useState)(false), _useState6 = _slicedToArray(_useState5, 2), isExpandSearchInput = _useState6[0], setIsExpandSearchInput = _useState6[1]; var _useState7 = (0, _react.useState)(false), _useState8 = _slicedToArray(_useState7, 2), isExpandAnimationStart = _useState8[0], setIsExpandAnimationStart = _useState8[1]; var headerRef = (0, _react.useRef)(); var fixedStateRef = (0, _react.useRef)(fixed); var nextStateAnimationFrameIdRef = (0, _react.useRef)(); var tabletLandscapeModeRef = (0, _react.useRef)(); var tabletVerticalModeRef = (0, _react.useRef)(); var enableSearchInputRef = (0, _react.useRef)(false); var _useView = (0, _view2.default)(), _useView2 = _slicedToArray(_useView, 1), screenWidth = _useView2[0]; var anueUrl = new _anueLink2.default(apiEnv); // 當畫面介在 768 ~ 1200 之間,搜尋框是縮小的 var tabletLandscapeSize = (0, _react.useMemo)(function () { return convertPxToNumber(_vars.screenSizeMd); }, [_vars.screenSizeMd]); var tabletVerticalSize = (0, _react.useMemo)(function () { return convertPxToNumber(_vars.screenSizeLg); }, [_vars.screenSizeLg]); var desktopMinimalVerticalSize = (0, _react.useMemo)(function () { return convertPxToNumber(_vars.screenSizeXl); }, [_vars.screenSizeXl]); tabletVerticalModeRef.current = screenWidth > tabletLandscapeSize && screenWidth <= desktopMinimalVerticalSize; tabletLandscapeModeRef.current = screenWidth <= tabletLandscapeSize; var channels = navs != null ? navs : _navs2.default; var hideCountInDesktop = hideCountsWhenSearchExpand[0] || 6; var hideCountInTablet = hideCountsWhenSearchExpand[1] || 4; var hideCounts = screenWidth <= tabletVerticalSize ? hideCountInDesktop : hideCountInTablet; var setNextState = function setNextState(state) { if (nextStateAnimationFrameIdRef.current) { _raf2.default.cancel(nextStateAnimationFrameIdRef.current); } nextStateAnimationFrameIdRef.current = (0, _raf2.default)(function () { nextStateAnimationFrameIdRef.current = null; fixedStateRef.current = state; setFixed(function (prevState) { return !prevState; }); }); }; /** * 監聽畫面捲動,為了處理 Heder 固定於最上端的排列 */ var scrollHandler = function scrollHandler() { var scrollY = 'scrollY' in window ? window.scrollY : document.documentElement.scrollTop; var isFixed = checkIsFixedHeader(fixedHeaderType); if (isFixed) { if (scrollY > _constants.DISTANCE_OVER_HEADER && !fixedStateRef.current) { setNextState(true); } else if (scrollY <= _constants.DISTANCE_OVER_HEADER && fixedStateRef.current) { setNextState(false); } } }; /** * 點擊搜尋框的放大鏡圖示 */ var searchIconClickHandler = function searchIconClickHandler() { if (!enableSearchBar) return; if (tabletVerticalModeRef.current || tabletLandscapeModeRef.current) { enableSearchInputRef.current = !enableSearchInputRef.current; } }; /** * 點擊搜尋框,啟動搜尋框展開/縮回效果 */ var onEnableSearchInput = function onEnableSearchInput(enabled) { if (!enableSearchBar) return; if (tabletVerticalModeRef.current || tabletLandscapeModeRef.current) { enableSearchInputRef.current = enabled; setIsExpandAnimationStart(true); } }; var searchInputFocusHandler = function searchInputFocusHandler() { if (!enableSearchInputRef.current) { onEnableSearchInput(true); } }; var restoreSearchInputHandler = function restoreSearchInputHandler() { if (enableSearchInputRef.current) { onEnableSearchInput(false); } }; /** * 搜尋框展開動畫效果結束 */ var animationEndHandler = function animationEndHandler() { setIsExpandSearchInput(function (prevState) { return !prevState; }); setIsExpandAnimationStart(false); }; /** * Accessing React State in Event Listeners with useState and useRef hooks * https://medium.com/geographit/accessing-react-state-in-event-listeners-with-usestate-and-useref-hooks-8cceee73c559 */ (0, _react.useEffect)(function () { var isFixedHeader = checkIsFixedHeader(fixedHeaderType); if (isFixedHeader) { if (typeof window !== 'undefined') { window.addEventListener('scroll', scrollHandler); // The clicked event of AnueSearch is set to stopPropagation. // So click the anywhere outside of AnueSearch will hide the AnueRealtimeResult. window.addEventListener('click', restoreSearchInputHandler); } } return function () { if (isFixedHeader) { if (typeof window !== 'undefined') { window.removeEventListener('scroll', scrollHandler); window.removeEventListener('click', restoreSearchInputHandler); } } }; }, []); var channelMouseEnterHandler = function channelMouseEnterHandler(index) { return setCurrentChannelIndex(index); }; var renderNavigatorChannels = function renderNavigatorChannels() { return channels.map(function (channel, index) { if (!channel.enable) return null; var haveSubMenus = channel.subItems.length > 0; var isActive = index === currentChannelIndex; var needHide = enableSearchInputRef.current && index < hideCounts; var isCurrentNav = channelName === channel.title; var link = channel.url !== '' ? anueUrl.generateLink(channel.url) : ''; var channelRef = (0, _react.useRef)(); return _react2.default.createElement( 'li', { key: channel.name, ref: channelRef, className: cx({ hide: needHide, active: isActive, current: isCurrentNav }), onMouseEnter: function onMouseEnter() { return channelMouseEnterHandler(index); }, onMouseLeave: function onMouseLeave() { return channelMouseEnterHandler(-1); } }, _react2.default.createElement( 'div', null, needHide ? _react2.default.createElement( 'span', null, channel.title ) : link !== '' ? _react2.default.createElement( 'a', _extends({ href: link, target: channel.blank ? '_blank' : '_self', rel: 'noopener noreferrer' }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Nav', action: 'click', label: channel.title })), _react2.default.createElement( 'span', { className: cx({ new: channel.isNew }) }, channel.title ) ) : _react2.default.createElement( 'span', { className: cx('no-link', { new: channel.isNew }) }, channel.title ) ), headerRef && haveSubMenus && _react2.default.createElement(_AnueSubMenu2.default, { key: channel.name + '_sub_menus', parentName: channel.title, headerRef: headerRef, parentRef: channelRef, data: channel.subItems || [], expandSearchBar: isExpandSearchInput, apiEnv: apiEnv }) ); }); }; var searchInputWrapStyle = null; var searchInputStyle = null; var channelUnfoldStyle = null; // 1024 尺寸時 if (tabletVerticalModeRef.current || tabletLandscapeModeRef.current) { var searchInputWidth = tabletLandscapeModeRef.current ? 270 : 314; searchInputWrapStyle = enableSearchInputRef.current ? { position: 'absolute', right: 0, width: searchInputWidth + 'px', maxWidth: '314px', transition: 'width 0.2s' } : null; // 利用 text-indent 來達成隱藏 placeholder 的效果 searchInputStyle = enableSearchInputRef.current ? { textIndent: '2px' } : null; channelUnfoldStyle = enableSearchInputRef.current ? cx('moveLeft', 'expansion') : isExpandSearchInput ? cx('moveRight') : null; } var searchIconStyle = { top: '3px', width: '24px', height: '24px' }; var indexUrl = logoUrl !== '' ? logoUrl : anueUrl.wwwChannelLink; return _react2.default.createElement( _react2.default.Fragment, null, fixed && _react2.default.createElement('div', { className: cx('anue-navigator-wrapper') }), _react2.default.createElement( 'nav', { className: cx('anue-navigator-wrapper', { sticky: fixed }) }, _react2.default.createElement( 'header', { ref: headerRef, className: cx('main-header') }, _react2.default.createElement( 'div', { className: cx('channel-bar') }, _react2.default.createElement('a', _extends({ href: indexUrl, className: cx('logo') }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Logo', action: 'click', label: 'home' }))), _react2.default.createElement( 'div', { className: cx('channel-items', { mask: isExpandAnimationStart }) }, _react2.default.createElement( 'ul', { className: channelUnfoldStyle, onAnimationEnd: animationEndHandler }, renderNavigatorChannels() ) ) ), enableSearchBar && _react2.default.createElement( 'div', { className: cx('search-bar') }, _react2.default.createElement(_AnueSearch2.default, { apiEnv: apiEnv, enableNewStyle: true, placeholder: '\u641C\u5C0B\u65B0\u805E\u3001\u884C\u60C5\u4EE3\u78BC\u6216\u540D\u7A31', shouldAlwaysDisplayInput: true, onIconClick: searchIconClickHandler, onInputFocus: searchInputFocusHandler, customWrapperStyles: searchInputWrapStyle, customInputStyles: searchInputStyle, customIconStyles: searchIconStyle, defaultValue: searchKeyword, theme: 'desktop' }) ), _react2.default.createElement( 'div', { className: cx('info-bar') }, accountComponent && accountComponent, switchVersionComponent && switchVersionComponent ) ) ) ); }; AnueNavigator.defaultProps = { channelName: '首頁', logoUrl: '', navs: null, searchKeyword: '', // channelComponent: null, dataPrefix: ['data-global-ga'], enableSearchBar: true, accountComponent: null, switchVersionComponent: null, fixedHeaderType: _constants.FIXED_HEADER_FULL, hideCountsWhenSearchExpand: [6, 3] }; exports.default = AnueNavigator; /***/ }), /***/ 271: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /* eslint-disable react/no-array-index-key */ var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _lodash = __webpack_require__(18); var _lodash2 = _interopRequireDefault(_lodash); var _gaDataset = __webpack_require__(3); var _gaDataset2 = _interopRequireDefault(_gaDataset); var _anueLink = __webpack_require__(7); var _anueLink2 = _interopRequireDefault(_anueLink); var _iconArrowLeft = __webpack_require__(83); var _iconArrowLeft2 = _interopRequireDefault(_iconArrowLeft); var _iconArrowRight = __webpack_require__(190); var _iconArrowRight2 = _interopRequireDefault(_iconArrowRight); var _constants = __webpack_require__(84); var _AnueNavigator = __webpack_require__(85); var _AnueNavigator2 = _interopRequireDefault(_AnueNavigator); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var cx = _bind2.default.bind(_AnueNavigator2.default); var AnueSubMenu = function AnueSubMenu(_ref) { var data = _ref.data, parentName = _ref.parentName, headerRef = _ref.headerRef, parentRef = _ref.parentRef, apiEnv = _ref.apiEnv, dataPrefix = _ref.dataPrefix, expandSearchBar = _ref.expandSearchBar; var ref = (0, _react.useRef)(); var menusRef = (0, _react.useRef)(); var offsetRef = (0, _react.useRef)(); var _useState = (0, _react.useState)({ left: false, right: false }), _useState2 = _slicedToArray(_useState, 2), needShowArrow = _useState2[0], setNeedShowArrow = _useState2[1]; var anueUrl = new _anueLink2.default(apiEnv); /** * 對應設計稿,次選單的呈現主要有三種狀況 * 1. 如果滑出的選單置中情況下,會超出 header 的邊界 (1200, 1024),則直接對齊邊界 * 2. 如果滑出的選單置中情況下,不會超出 header 的邊界,則置中對齊 * 3. 如果選單本身的寬度就已經超過 header (1200, 1024)時,則超出邊界全版顯示 * 設計稿: https://zpl.io/aMy3zN3 */ var handlePosition = function handlePosition() { var needRestore = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; if (!ref.current) return; // 當樣式設定 `display: none` 時,該物件本身的寬高都是為 0,是不會被繪製出來的 // 所以先將物件顯示在畫面上,讓 Browser 可以繪製出選單的寬度和位置 // 之後再將物件隱藏 // ref.current.style.display = 'flex'; if (needRestore) { ref.current.style.width = 'auto'; setNeedShowArrow(function (prevState) { return _extends({}, prevState, { left: false, right: false }); }); } var paddingValue = 16; // 上層 Header,用來判斷內容區域的邊界值和寬度 var headerBoundary = headerRef.current.getBoundingClientRect(); // 上層 Channel 物件,用來計算次選單顯示座標定位 var parentBoundary = parentRef.current.getBoundingClientRect(); // 次選單物件,用來取得目前選單寬度和預設顯示座標 var subMenuBoundary = ref.current.getBoundingClientRect(); // 次選單寬度超出 header 的邊界,全版顯示 if (subMenuBoundary.width >= headerBoundary.width) { var isOverScreenWidth = subMenuBoundary.width - document.documentElement.offsetWidth >= 0; // 顯示滿版情況下的左右箭頭 if (isOverScreenWidth) { setNeedShowArrow(function (prevState) { return _extends({}, prevState, { right: true }); }); // 次選單需要滿版顯示 offsetRef.current = { left: '-' + parentBoundary.x + 'px', width: document.documentElement.offsetWidth + 'px' }; } else { // 當次選單寬度超出 header 寬度時,但沒有超出螢幕寬度時,採置中對齊 - [QA-1647] var subMenuCenterPosition = Math.abs(parentBoundary.x - headerBoundary.x) + Math.round((subMenuBoundary.width - headerBoundary.width) / 2); offsetRef.current = { left: '-' + subMenuCenterPosition + 'px' }; } } else { var subMenuAndHeaderPositionDiff = Math.abs(parentBoundary.x - headerBoundary.x); if (subMenuAndHeaderPositionDiff > 0) { var subMenuPosition = Math.round(subMenuBoundary.width / 2) - paddingValue * 2; offsetRef.current = subMenuAndHeaderPositionDiff < subMenuPosition ? { left: '-' + subMenuAndHeaderPositionDiff + 'px' } : { left: '-' + subMenuPosition + 'px' }; } } // ref.current.style.display = ''; }; /** * 畫面 Resize 需重新計算次選單的座標位置 */ (0, _react.useEffect)(function () { window.addEventListener('resize', (0, _lodash2.default)(handlePosition, 200)); return function () { return window.removeEventListener('resize', handlePosition); }; }, []); /** * 配合主導覽列上的搜尋框展開,需要重新計算次選單的座標位置 */ (0, _react.useEffect)(function () { handlePosition(false); }, [expandSearchBar]); /** * 次選單項目超出畫面時的左右移動處理 */ var moveSubMenuHandler = function moveSubMenuHandler(direction) { var currentDistance = menusRef.current.scrollLeft; var needMoveCount = Math.ceil(menusRef.current.scrollWidth / menusRef.current.offsetWidth) - 1; var moveDistance = (menusRef.current.scrollWidth - menusRef.current.offsetWidth) / needMoveCount; currentDistance = direction === _constants.DIRECTION.RIGHT ? currentDistance + moveDistance : currentDistance - moveDistance; menusRef.current.scrollLeft = currentDistance; if (currentDistance > 0) { setNeedShowArrow(function (prevState) { return _extends({}, prevState, { left: true }); }); } else if (currentDistance <= 0) { setNeedShowArrow(function (prevState) { return _extends({}, prevState, { left: false }); }); } var currentScrollWidth = menusRef.current.offsetWidth + currentDistance; if (currentScrollWidth < menusRef.current.scrollWidth) { setNeedShowArrow(function (prevState) { return _extends({}, prevState, { right: true }); }); } else if (currentScrollWidth >= menusRef.current.scrollWidth) { setNeedShowArrow(function (prevState) { return _extends({}, prevState, { right: false }); }); } }; /** * React events are actually Synthetic Events, not Native Events. * Event delegation: React doesn't actually attach event handlers to the nodes themselves. * When React starts up, it starts listening for all events at the top level using a single event listener. * When a component is mounted or unmounted, the event handlers are simply added or removed from an internal mapping. * When an event occurs, React knows how to dispatch it using this mapping. * When there are no event handlers left in the mapping, * React's event handlers are simple no-ops. * * Use `Event.stopImmediatePropagation` * * https://stackoverflow.com/questions/36316846/react-onclick-and-preventdefault-link-refresh-redirect */ var onMoveSubMenuLeft = function onMoveSubMenuLeft(e) { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); moveSubMenuHandler(_constants.DIRECTION.LEFT); }; var onMoveSubMenuRight = function onMoveSubMenuRight(e) { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); moveSubMenuHandler(_constants.DIRECTION.RIGHT); }; /** * 展開第二層選單項目 * 淺灰色連結 */ var renderSubSecondMenuItems = function renderSubSecondMenuItems(parent, first, second) { // parentName 是配合靜態頁面生成使用,靜態生成時無法動態取得 parentRef 的值,因為是在 Server 端生成,不是在 Browser 上建立 var rootTitle = parentName || parentRef && parentRef.current && parentRef.current.children[0].innerText; var items = parent.subItems; var secondMenus = items.map(function (item, index) { return _react2.default.createElement( 'li', { key: 'sub_main_menu_' + first + '_' + second + '_' + index }, _react2.default.createElement( 'a', _extends({ className: cx({ highlight: item.highlight }), href: anueUrl.generateLink(item.url), target: item.blank ? '_blank' : '_self', rel: 'noopener noreferrer' }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Nav', action: 'click', label: rootTitle + '_' + parent.title + '_' + item.title })), item.title ) ); }); return _react2.default.createElement( 'ul', { className: cx('channel-item-sub-menu-second') }, secondMenus ); }; /** * 顯示每一欄的第一層選單項目 * 粗體連結 */ var renderSubMainMenuItems = function renderSubMainMenuItems(items, first) { if (items.length <= 0) return []; // parentName 是配合靜態頁面生成使用,靜態生成時無法動態取得 parentRef 的值,因為是在 Server 端生成,不是在 Browser 上建立 var rootTitle = parentName || parentRef && parentRef.current && parentRef.current.children[0].innerText; return items.map(function (item, index) { var haveSecondMenu = item.subItems && item.subItems.length > 0; return _react2.default.createElement( 'li', { key: 'sub_main_menu_' + first + '_' + index }, item.url !== '' ? _react2.default.createElement( 'a', _extends({ className: cx({ highlight: item.highlight }), href: anueUrl.generateLink(item.url), target: item.blank ? '_blank' : '_self', rel: 'noopener noreferrer' }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Nav', action: 'click', label: rootTitle + '_' + item.title })), item.title ) : item.title, haveSecondMenu && renderSubSecondMenuItems(item, first, index) ); }); }; /** * 依照第一層的 UL 個數,建立次選單中的欄 */ var renderSubMainMenuColumn = function renderSubMainMenuColumn() { if (data.length <= 0) return []; return data.map(function (menu, index) { return _react2.default.createElement( 'ul', { key: 'sub_main_menu_' + index }, renderSubMainMenuItems(menu, index) ); }); }; return _react2.default.createElement( 'div', { ref: ref, className: cx('channel-item-sub-menu'), style: offsetRef.current }, needShowArrow.left && _react2.default.createElement( 'div', { className: cx('channel-item-sub-menu-arrow', 'left') }, _react2.default.createElement('img', { src: _iconArrowLeft2.default, alt: 'Previous', onClick: onMoveSubMenuLeft }) ), _react2.default.createElement( 'div', { ref: menusRef, className: cx('channel-item-sub-menus') }, renderSubMainMenuColumn() ), needShowArrow.right && _react2.default.createElement( 'div', { className: cx('channel-item-sub-menu-arrow', 'right') }, _react2.default.createElement('img', { src: _iconArrowRight2.default, alt: 'Next', onClick: onMoveSubMenuRight }) ) ); }; AnueSubMenu.defaultProps = { parentName: '', dataPrefix: ['data-global-ga'], expandSearchBar: false }; exports.default = AnueSubMenu; /***/ }), /***/ 272: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _raf = __webpack_require__(53); var _raf2 = _interopRequireDefault(_raf); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _lodash = __webpack_require__(18); var _lodash2 = _interopRequireDefault(_lodash); var _propTypes3 = __webpack_require__(6); var _gaDataset = __webpack_require__(3); var _gaDataset2 = _interopRequireDefault(_gaDataset); var _anueLink = __webpack_require__(7); var _anueLink2 = _interopRequireDefault(_anueLink); var _vars = __webpack_require__(82); var _AnueSearch = __webpack_require__(54); var _AnueSearch2 = _interopRequireDefault(_AnueSearch); var _AnueSubMenu = __webpack_require__(273); var _AnueSubMenu2 = _interopRequireDefault(_AnueSubMenu); var _navs = __webpack_require__(191); var _navs2 = _interopRequireDefault(_navs); var _AnueNavigator = __webpack_require__(85); var _AnueNavigator2 = _interopRequireDefault(_AnueNavigator); var _constants = __webpack_require__(84); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable no-nested-ternary */ var cx = _bind2.default.bind(_AnueNavigator2.default); function checkIsFixedHeader(fixedHeaderType) { return fixedHeaderType !== _constants.FIXED_HEADER_NONE; } function convertPxToNumber(size) { return parseInt(size.replace('px', ''), 10); } var AnueNavigator = function (_Component) { _inherits(AnueNavigator, _Component); function AnueNavigator(props) { _classCallCheck(this, AnueNavigator); var _this = _possibleConstructorReturn(this, (AnueNavigator.__proto__ || Object.getPrototypeOf(AnueNavigator)).call(this, props)); _this.onEnableSearchInput = function (enabled) { var enableSearchBar = _this.props.enableSearchBar; if (!enableSearchBar) return; if (_this.tabletVerticalMode || _this.tabletLandscapeMode) { _this.enableSearchInput = enabled; _this.setState({ isExpandAnimationStart: true }); } }; _this.setNextState = function (state) { if (_this.nextStateAnimationFrameId) { _raf2.default.cancel(_this.nextStateAnimationFrameId); } _this.nextStateAnimationFrameId = (0, _raf2.default)(function () { _this.nextStateAnimationFrameId = null; _this.fixedState = state; _this.setState(function (prevState) { return _extends({}, prevState, { fixed: !prevState.fixed }); }); }); }; _this.screenResizeHandler = function () { if (document && document.documentElement) { _this.screenWidth = document.documentElement.offsetWidth; var tabletLandscapeSize = convertPxToNumber(_vars.screenSizeMd); var desktopMinimalVerticalSize = convertPxToNumber(_vars.screenSizeXl); _this.tabletVerticalMode = _this.screenWidth > tabletLandscapeSize && _this.screenWidth <= desktopMinimalVerticalSize; _this.tabletLandscapeMode = _this.screenWidth <= tabletLandscapeSize; } }; _this.scrollHandler = function () { var fixedHeaderType = _this.props.fixedHeaderType; var scrollTop = document ? document.documentElement.scrollTop : 0; var scrollY = 'scrollY' in window ? window.scrollY : scrollTop; var isFixed = checkIsFixedHeader(fixedHeaderType); if (isFixed) { if (scrollY > _constants.DISTANCE_OVER_HEADER && !_this.fixedState) { _this.setNextState(true); } else if (scrollY <= _constants.DISTANCE_OVER_HEADER && _this.fixedState) { _this.setNextState(false); } } }; _this.searchIconClickHandler = function () { var enableSearchBar = _this.props.enableSearchBar; if (!enableSearchBar) return; if (_this.tabletVerticalMode || _this.tabletLandscapeMode) { _this.enableSearchInput = !_this.enableSearchInput; } }; _this.searchInputFocusHandler = function () { if (!_this.enableSearchInput) { _this.onEnableSearchInput(true); } }; _this.restoreSearchInputHandler = function () { if (_this.enableSearchInput) { _this.onEnableSearchInput(false); } }; _this.animationEndHandler = function () { _this.setState(function (prevState) { return _extends({}, prevState, { isExpandSearchInput: !prevState.isExpandSearchInput, isExpandAnimationStart: false }); }); }; _this.channelMouseEnterHandler = function (index) { _this.setState({ currentChannelIndex: index }); }; _this.renderNavigatorChannels = function () { return _this.channels.map(function (channel, index) { if (!channel.enable) return null; var _this$props = _this.props, channelName = _this$props.channelName, dataPrefix = _this$props.dataPrefix, apiEnv = _this$props.apiEnv; var _this$state = _this.state, isExpandSearchInput = _this$state.isExpandSearchInput, currentChannelIndex = _this$state.currentChannelIndex; var haveSubMenus = channel.subItems.length > 0; var isActive = index === currentChannelIndex; var needHide = _this.enableSearchInput && index < _this.hideCounts; var isCurrentNav = channelName === channel.title; var link = channel.url !== '' ? _this.anueUrl.generateLink(channel.url) : ''; var setChannelRef = function setChannelRef(element) { if (element !== null) { _this.channelRef[index] = { current: element }; } }; return _react2.default.createElement( 'li', { key: channel.name, ref: setChannelRef, className: cx({ hide: needHide, active: isActive, current: isCurrentNav }), onMouseEnter: function onMouseEnter() { return _this.channelMouseEnterHandler(index); }, onMouseLeave: function onMouseLeave() { return _this.channelMouseEnterHandler(-1); } }, _react2.default.createElement( 'div', null, needHide ? _react2.default.createElement( 'span', null, channel.title ) : link !== '' ? _react2.default.createElement( 'a', _extends({ href: link, target: channel.blank ? '_blank' : '_self', rel: 'noopener noreferrer' }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Nav', action: 'click', label: channel.title })), _react2.default.createElement( 'span', { className: cx({ new: channel.isNew }) }, channel.title ) ) : _react2.default.createElement( 'span', { className: cx('no-link', { new: channel.isNew }) }, channel.title ) ), _this.headerRef && haveSubMenus && _react2.default.createElement(_AnueSubMenu2.default, { key: channel.name + '_sub_menus', parentName: channel.title, headerRef: _this.headerRef, parentRef: _this.channelRef[index], data: channel.subItems || [], expandSearchBar: isExpandSearchInput, apiEnv: apiEnv }) ); }); }; _this.state = { fixed: false, currentChannelIndex: -1, isExpandSearchInput: false, isExpandAnimationStart: false }; // 使用比 React 16.2 還舊的版本,你可以使用這個不同的方式並把 ref 當作另個有名字的 prop 來傳進去 // https://zh-hant.reactjs.org/docs/refs-and-the-dom.html#callback-refs _this.setHeaderRef = function (element) { _this.headerRef = { current: element }; }; _this.fixedState = _this.state.fixed; _this.nextStateAnimationFrameId = null; _this.tabletVerticalMode = null; _this.tabletLandscapeMode = null; _this.enableSearchInput = false; _this.anueUrl = new _anueLink2.default(_this.props.apiEnv); _this.screenWidth = typeof document !== 'undefined' ? document.documentElement.offsetWidth : 1200; _this.channels = _this.props.navs != null ? _this.props.navs : _navs2.default; _this.channelRef = new Array(_this.channels.length); return _this; } _createClass(AnueNavigator, [{ key: 'componentDidMount', value: function componentDidMount() { var _props = this.props, hideCountsWhenSearchExpand = _props.hideCountsWhenSearchExpand, fixedHeaderType = _props.fixedHeaderType; // 當畫面介在 768 ~ 1200 之間,搜尋框是縮小的 var tabletLandscapeSize = convertPxToNumber(_vars.screenSizeMd); var tabletVerticalSize = convertPxToNumber(_vars.screenSizeLg); var desktopMinimalVerticalSize = convertPxToNumber(_vars.screenSizeXl); var hideCountInDesktop = hideCountsWhenSearchExpand[0] || 6; var hideCountInTablet = hideCountsWhenSearchExpand[1] || 4; this.hideCounts = this.screenWidth <= tabletVerticalSize ? hideCountInDesktop : hideCountInTablet; this.isFixedHeader = checkIsFixedHeader(fixedHeaderType); this.tabletVerticalMode = this.screenWidth > tabletLandscapeSize && this.screenWidth <= desktopMinimalVerticalSize; this.tabletLandscapeMode = this.screenWidth <= tabletLandscapeSize; if (this.isFixedHeader) { if (typeof window !== 'undefined') { window.addEventListener('scroll', this.scrollHandler); // The clicked event of AnueSearch is set to stopPropagation. // So click the anywhere outside of AnueSearch will hide the AnueRealtimeResult. window.addEventListener('click', this.restoreSearchInputHandler); } } window.addEventListener('resize', (0, _lodash2.default)(this.screenResizeHandler, 200)); } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { if (this.isFixedHeader) { if (typeof window !== 'undefined') { window.removeEventListener('scroll', this.scrollHandler); window.removeEventListener('click', this.restoreSearchInputHandler); } } window.removeEventListener('resize', (0, _lodash2.default)(this.screenResizeHandler, 200)); } /** * 點擊搜尋框,啟動搜尋框展開/縮回效果 */ /** * 監聽畫面捲動,為了處理 Heder 固定於最上端的排列 */ /** * 點擊搜尋框的放大鏡圖示 */ /** * 搜尋框展開動畫效果結束 */ }, { key: 'render', value: function render() { var _props2 = this.props, searchKeyword = _props2.searchKeyword, accountComponent = _props2.accountComponent, switchVersionComponent = _props2.switchVersionComponent, apiEnv = _props2.apiEnv, dataPrefix = _props2.dataPrefix, logoUrl = _props2.logoUrl, enableSearchBar = _props2.enableSearchBar; var _state = this.state, isExpandAnimationStart = _state.isExpandAnimationStart, isExpandSearchInput = _state.isExpandSearchInput, fixed = _state.fixed; var searchInputWrapStyle = null; var searchInputStyle = null; var channelUnfoldStyle = null; // 1024 尺寸時 if (this.tabletVerticalMode || this.tabletLandscapeMode) { var searchInputWidth = this.tabletLandscapeMode ? 270 : 314; searchInputWrapStyle = this.enableSearchInput ? { position: 'absolute', right: 0, width: searchInputWidth + 'px', maxWidth: '314px', transition: 'width 0.2s' } : null; // 利用 text-indent 來達成隱藏 placeholder 的效果 searchInputStyle = this.enableSearchInput ? { textIndent: '2px' } : null; channelUnfoldStyle = this.enableSearchInput ? cx('moveLeft', 'expansion') : isExpandSearchInput ? cx('moveRight') : null; } var searchIconStyle = { top: '3px', width: '24px', height: '24px' }; var indexUrl = logoUrl !== '' ? logoUrl : this.anueUrl.wwwChannelLink; return _react2.default.createElement( 'div', { className: cx('react-fragment') }, fixed && _react2.default.createElement('div', { className: cx('anue-navigator-wrapper') }), _react2.default.createElement( 'nav', { className: cx('anue-navigator-wrapper', { sticky: fixed }) }, _react2.default.createElement( 'header', { ref: this.setHeaderRef, className: cx('main-header') }, _react2.default.createElement( 'div', { className: cx('channel-bar') }, _react2.default.createElement('a', _extends({ href: indexUrl, className: cx('logo') }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Logo', action: 'click', label: 'home' }))), _react2.default.createElement( 'div', { className: cx('channel-items', { mask: isExpandAnimationStart }) }, _react2.default.createElement( 'ul', { className: channelUnfoldStyle, onAnimationEnd: this.animationEndHandler }, this.renderNavigatorChannels() ) ) ), enableSearchBar && _react2.default.createElement( 'div', { className: cx('search-bar') }, _react2.default.createElement(_AnueSearch2.default, { apiEnv: apiEnv, enableNewStyle: true, placeholder: '\u641C\u5C0B\u65B0\u805E\u3001\u884C\u60C5\u4EE3\u78BC\u6216\u540D\u7A31', shouldAlwaysDisplayInput: true, onIconClick: this.searchIconClickHandler, onInputFocus: this.searchInputFocusHandler, customWrapperStyles: searchInputWrapStyle, customInputStyles: searchInputStyle, customIconStyles: searchIconStyle, defaultValue: searchKeyword, theme: 'desktop' }) ), _react2.default.createElement( 'div', { className: cx('info-bar') }, accountComponent && accountComponent, switchVersionComponent && switchVersionComponent ) ) ) ); } }]); return AnueNavigator; }(_react.Component); AnueNavigator.defaultProps = { channelName: '首頁', logoUrl: '', navs: null, searchKeyword: '', // channelComponent: null, dataPrefix: ['data-global-ga'], enableSearchBar: true, accountComponent: null, switchVersionComponent: null, fixedHeaderType: _constants.FIXED_HEADER_FULL, hideCountsWhenSearchExpand: [6, 3] }; exports.default = AnueNavigator; /***/ }), /***/ 273: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _lodash = __webpack_require__(18); var _lodash2 = _interopRequireDefault(_lodash); var _gaDataset = __webpack_require__(3); var _gaDataset2 = _interopRequireDefault(_gaDataset); var _anueLink = __webpack_require__(7); var _anueLink2 = _interopRequireDefault(_anueLink); var _iconArrowLeft = __webpack_require__(83); var _iconArrowLeft2 = _interopRequireDefault(_iconArrowLeft); var _iconArrowRight = __webpack_require__(190); var _iconArrowRight2 = _interopRequireDefault(_iconArrowRight); var _constants = __webpack_require__(84); var _AnueNavigator = __webpack_require__(85); var _AnueNavigator2 = _interopRequireDefault(_AnueNavigator); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable react/no-array-index-key */ var cx = _bind2.default.bind(_AnueNavigator2.default); var AnueSubMenu = function (_Component) { _inherits(AnueSubMenu, _Component); function AnueSubMenu(props) { _classCallCheck(this, AnueSubMenu); var _this = _possibleConstructorReturn(this, (AnueSubMenu.__proto__ || Object.getPrototypeOf(AnueSubMenu)).call(this, props)); _this.onMoveSubMenuLeft = function (e) { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); _this.moveSubMenuHandler(_constants.DIRECTION.LEFT); }; _this.onMoveSubMenuRight = function (e) { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); _this.moveSubMenuHandler(_constants.DIRECTION.RIGHT); }; _this.handlePosition = function () { var needRestore = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; var _this$props = _this.props, headerRef = _this$props.headerRef, parentRef = _this$props.parentRef; if (!_this.ref.current) return; if (needRestore) { _this.ref.current.style.width = 'auto'; _this.setState({ needShowLeftArrow: false, needShowRightArrow: false }); } var paddingValue = 16; // 上層 Header,用來判斷內容區域的邊界值和寬度 var headerBoundary = headerRef.current.getBoundingClientRect(); // 上層 Channel 物件,用來計算次選單顯示座標定位 var parentBoundary = parentRef && parentRef.current ? parentRef.current.getBoundingClientRect() : { x: 0 }; // 次選單物件,用來取得目前選單寬度和預設顯示座標 var subMenuBoundary = _this.ref.current.getBoundingClientRect(); // 次選單寬度超出 header 的邊界,全版顯示 if (subMenuBoundary.width >= headerBoundary.width) { var isOverScreenWidth = subMenuBoundary.width - document.documentElement.offsetWidth >= 0; // 顯示滿版情況下的左右箭頭 if (isOverScreenWidth) { _this.setState(function (prevState) { return _extends({}, prevState, { needShowRightArrow: true }); }); // 次選單需要滿版顯示 _this.offset = { left: '-' + parentBoundary.x + 'px', width: document.documentElement.offsetWidth + 'px' }; } else { // 當次選單寬度超出 header 寬度時,但沒有超出螢幕寬度時,採置中對齊 - [QA-1647] var subMenuCenterPosition = Math.abs(parentBoundary.x - headerBoundary.x) + Math.round((subMenuBoundary.width - headerBoundary.width) / 2); _this.offset = { left: '-' + subMenuCenterPosition + 'px' }; } } else { var subMenuAndHeaderPositionDiff = Math.abs(parentBoundary.x - headerBoundary.x); if (subMenuAndHeaderPositionDiff > 0) { var subMenuPosition = Math.round(subMenuBoundary.width / 2) - paddingValue * 2; _this.offset = subMenuAndHeaderPositionDiff < subMenuPosition ? { left: '-' + subMenuAndHeaderPositionDiff + 'px' } : { left: '-' + subMenuPosition + 'px' }; } } }; _this.moveSubMenuHandler = function (direction) { var currentDistance = _this.menusRef.current.scrollLeft; var needMoveCount = Math.ceil(_this.menusRef.current.scrollWidth / _this.menusRef.current.offsetWidth) - 1; var moveDistance = (_this.menusRef.current.scrollWidth - _this.menusRef.current.offsetWidth) / needMoveCount; currentDistance = direction === _constants.DIRECTION.RIGHT ? currentDistance + moveDistance : currentDistance - moveDistance; _this.menusRef.current.scrollLeft = currentDistance; if (currentDistance > 0) { _this.setState(function (prevState) { return _extends({}, prevState, { needShowLeftArrow: true }); }); } else if (currentDistance <= 0) { _this.setState(function (prevState) { return _extends({}, prevState, { needShowLeftArrow: false }); }); } var currentScrollWidth = _this.menusRef.current.offsetWidth + currentDistance; if (currentScrollWidth < _this.menusRef.current.scrollWidth) { _this.setState(function (prevState) { return _extends({}, prevState, { needShowRightArrow: true }); }); } else if (currentScrollWidth >= _this.menusRef.current.scrollWidth) { _this.setState(function (prevState) { return _extends({}, prevState, { needShowRightArrow: false }); }); } }; _this.renderSubSecondMenuItems = function (parent, first, second) { var _this$props2 = _this.props, parentRef = _this$props2.parentRef, dataPrefix = _this$props2.dataPrefix, parentName = _this$props2.parentName; // parentName 是配合靜態頁面生成使用,靜態生成時無法動態取得 parentRef 的值,因為是在 Server 端生成,不是在 Browser 上建立 var rootTitle = parentName || parentRef && parentRef.current && parentRef.current.children[0].innerText; var items = parent.subItems; var secondMenus = items.map(function (item, index) { return _react2.default.createElement( 'li', { key: 'sub_main_menu_' + first + '_' + second + '_' + index }, _react2.default.createElement( 'a', _extends({ className: cx({ highlight: item.highlight }), href: _this.anueUrl.generateLink(item.url), target: item.blank ? '_blank' : '_self', rel: 'noopener noreferrer' }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Nav', action: 'click', label: rootTitle + '_' + parent.title + '_' + item.title })), item.title ) ); }); return _react2.default.createElement( 'ul', { className: cx('channel-item-sub-menu-second') }, secondMenus ); }; _this.renderSubMainMenuItems = function (items, first) { if (items.length <= 0) return []; var _this$props3 = _this.props, parentRef = _this$props3.parentRef, dataPrefix = _this$props3.dataPrefix, parentName = _this$props3.parentName; // parentName 是配合靜態頁面生成使用,靜態生成時無法動態取得 parentRef 的值,因為是在 Server 端生成,不是在 Browser 上建立 var rootTitle = parentName || parentRef && parentRef.current && parentRef.current.children[0].innerText; return items.map(function (item, index) { var haveSecondMenu = item.subItems && item.subItems.length > 0; return _react2.default.createElement( 'li', { key: 'sub_main_menu_' + first + '_' + index }, item.url !== '' ? _react2.default.createElement( 'a', _extends({ className: cx({ highlight: item.highlight }), href: _this.anueUrl.generateLink(item.url), target: item.blank ? '_blank' : '_self', rel: 'noopener noreferrer' }, (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Nav', action: 'click', label: rootTitle + '_' + item.title })), item.title ) : item.title, haveSecondMenu && _this.renderSubSecondMenuItems(item, first, index) ); }); }; _this.renderSubMainMenuColumn = function () { var data = _this.props.data; if (data.length <= 0) return []; return data.map(function (menu, index) { return _react2.default.createElement( 'ul', { key: 'sub_main_menu_' + index }, _this.renderSubMainMenuItems(menu, index) ); }); }; _this.setRef = function (element) { _this.ref = { current: element }; }; _this.setMenusRef = function (element) { _this.menusRef = { current: element }; }; _this.offset = null; _this.state = { needShowLeftArrow: false, needShowRightArrow: false }; _this.anueUrl = new _anueLink2.default(_this.props.apiEnv); return _this; } /** * 畫面 Resize 需重新計算次選單的座標位置 */ _createClass(AnueSubMenu, [{ key: 'componentDidMount', value: function componentDidMount() { window.addEventListener('resize', (0, _lodash2.default)(this.handlePosition, 200)); this.handlePosition(); } /** * 配合主導覽列上的搜尋框展開,需要重新計算次選單的座標位置 */ }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevProps) { if (prevProps.expandSearchBar !== this.props.expandSearchBar) { this.handlePosition(false); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { window.removeEventListener('resize', this.handlePosition); } /** * React events are actually Synthetic Events, not Native Events. * Event delegation: React doesn't actually attach event handlers to the nodes themselves. * When React starts up, it starts listening for all events at the top level using a single event listener. * When a component is mounted or unmounted, the event handlers are simply added or removed from an internal mapping. * When an event occurs, React knows how to dispatch it using this mapping. * When there are no event handlers left in the mapping, * React's event handlers are simple no-ops. * * Use `Event.stopImmediatePropagation` * * https://stackoverflow.com/questions/36316846/react-onclick-and-preventdefault-link-refresh-redirect */ /** * 對應設計稿,次選單的呈現主要有三種狀況 * 1. 如果滑出的選單置中情況下,會超出 header 的邊界 (1200, 1024),則直接對齊邊界 * 2. 如果滑出的選單置中情況下,不會超出 header 的邊界,則置中對齊 * 3. 如果選單本身的寬度就已經超過 header (1200, 1024)時,則超出邊界全版顯示 * 設計稿: https://zpl.io/aMy3zN3 */ /** * 次選單項目超出畫面時的左右移動處理 */ /** * 展開第二層選單項目 * 淺灰色連結 */ /** * 顯示每一欄的第一層選單項目 * 粗體連結 */ /** * 依照第一層的 UL 個數,建立次選單中的欄 */ }, { key: 'render', value: function render() { var _state = this.state, needShowLeftArrow = _state.needShowLeftArrow, needShowRightArrow = _state.needShowRightArrow; return _react2.default.createElement( 'div', { ref: this.setRef, className: cx('channel-item-sub-menu'), style: this.offset }, needShowLeftArrow && _react2.default.createElement( 'div', { className: cx('channel-item-sub-menu-arrow', 'left') }, _react2.default.createElement('img', { src: _iconArrowLeft2.default, alt: 'Previous', onClick: this.onMoveSubMenuLeft }) ), _react2.default.createElement( 'div', { ref: this.setMenusRef, className: cx('channel-item-sub-menus') }, this.renderSubMainMenuColumn() ), needShowRightArrow && _react2.default.createElement( 'div', { className: cx('channel-item-sub-menu-arrow', 'right') }, _react2.default.createElement('img', { src: _iconArrowRight2.default, alt: 'Next', onClick: this.onMoveSubMenuRight }) ) ); } }]); return AnueSubMenu; }(_react.Component); AnueSubMenu.defaultProps = { parentName: '', dataPrefix: ['data-global-ga'], expandSearchBar: false }; exports.default = AnueSubMenu; /***/ }), /***/ 3: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var gaDataset = function gaDataset(_ref) { var _ref$dataPrefix = _ref.dataPrefix, dataPrefix = _ref$dataPrefix === undefined ? ['data-global-ga'] : _ref$dataPrefix, category = _ref.category, action = _ref.action, label = _ref.label; if (dataPrefix.length === 0 || !dataPrefix) { return null; } var gaRegExp = /^data-.*ga$/; // format restriction var eventsObj = dataPrefix.reduce(function (p, prefix) { var _p = p; if (gaRegExp.test(prefix)) { _p[prefix + '-category'] = category; _p[prefix + '-action'] = action; _p[prefix + '-label'] = label; } return _p; }, {}); return eventsObj; }; exports.default = gaDataset; /***/ }), /***/ 30: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _AnueSearchInput = __webpack_require__(41); var _AnueSearchInput2 = _interopRequireDefault(_AnueSearchInput); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var cx = _bind2.default.bind(_AnueSearchInput2.default); var AnueSearchInput = function (_React$Component) { _inherits(AnueSearchInput, _React$Component); function AnueSearchInput(props) { _classCallCheck(this, AnueSearchInput); var _this = _possibleConstructorReturn(this, (AnueSearchInput.__proto__ || Object.getPrototypeOf(AnueSearchInput)).call(this, props)); _this.setInputDefaultValue = function (value) { _this.setState({ value: value }); }; _this.handleChange = function (e) { var onInputChange = _this.props.onInputChange; var value = e.target.value; _this.setState({ value: value }); onInputChange(value); }; _this.handleClickIcon = function () { var _this$props = _this.props, onIconClick = _this$props.onIconClick, shouldAlwaysDisplayInput = _this$props.shouldAlwaysDisplayInput, onDisplayChange = _this$props.onDisplayChange; var _this$state = _this.state, value = _this$state.value, shouldDisplayInput = _this$state.shouldDisplayInput; onIconClick(value); if (!shouldAlwaysDisplayInput) { _this.setState({ shouldDisplayInput: !shouldDisplayInput }); onDisplayChange(!shouldDisplayInput); } }; _this.handleBackIcon = function () { var _this$props2 = _this.props, onDisplayChange = _this$props2.onDisplayChange, onInputChange = _this$props2.onInputChange, onBackIconClick = _this$props2.onBackIconClick; _this.setState({ shouldDisplayInput: false, value: '' }); onBackIconClick(); onInputChange(''); onDisplayChange(false); }; _this.handleKeyDown = function (e) { if (e.keyCode === 13) { var onInputPressEnter = _this.props.onInputPressEnter; var value = _this.state.value; if (value) { onInputPressEnter(value); } } }; _this.handleResetValue = function () { var onInputChange = _this.props.onInputChange; _this.setState({ value: '' }); onInputChange(''); }; _this.state = { value: props.defaultValue || '', shouldDisplayInput: props.shouldAlwaysDisplayInput || props.theme !== 'mobile' }; return _this; } _createClass(AnueSearchInput, [{ key: 'componentDidUpdate', value: function componentDidUpdate(prevProps) { if (this.props.defaultValue && prevProps.defaultValue !== this.props.defaultValue) { this.setInputDefaultValue(this.props.defaultValue); } } }, { key: 'render', value: function render() { var _props = this.props, placeholder = _props.placeholder, onInputFocus = _props.onInputFocus, onInputBlur = _props.onInputBlur, customAttribute = _props.customAttribute, customWrapperStyles = _props.customWrapperStyles, customInputStyles = _props.customInputStyles, customIconStyles = _props.customIconStyles, theme = _props.theme, customInputClassName = _props.customInputClassName, shouldDisplayBackIcon = _props.shouldDisplayBackIcon; var _state = this.state, shouldDisplayInput = _state.shouldDisplayInput, value = _state.value; var showClearBtn = value; return _react2.default.createElement( 'div', { className: cx('anue-search-input--wrapper', theme, customInputClassName), style: customWrapperStyles }, shouldDisplayBackIcon && _react2.default.createElement('div', { className: cx('back-icon', theme, { display: shouldDisplayInput }), onClick: this.handleBackIcon }), _react2.default.createElement('input', _extends({ className: cx('anue-search-input', theme, { display: shouldDisplayInput }), value: value, onChange: this.handleChange, onFocus: onInputFocus, onBlur: onInputBlur, onKeyDown: this.handleKeyDown, style: customInputStyles, placeholder: placeholder }, customAttribute)), _react2.default.createElement('div', { className: cx('search-icon', theme), onClick: this.handleClickIcon, style: customIconStyles }), showClearBtn && _react2.default.createElement('div', { className: cx('clear-icon', theme), onClick: this.handleResetValue }) ); } }]); return AnueSearchInput; }(_react2.default.Component); AnueSearchInput.defaultProps = { customAttribute: null, customWrapperStyles: null, customInputStyles: null, customIconStyles: null, shouldAlwaysDisplayInput: false, shouldDisplayBackIcon: false, theme: null, // mobile | desktop placeholder: '搜尋新聞、代碼或名稱', defaultValue: null, customInputClassName: null, onDisplayChange: function onDisplayChange() {}, onIconClick: function onIconClick() {}, onBackIconClick: function onBackIconClick() {}, onInputChange: function onInputChange() {}, onInputFocus: function onInputFocus() {}, onInputBlur: function onInputBlur() {}, onInputPressEnter: function onInputPressEnter() {} }; exports.default = AnueSearchInput; /***/ }), /***/ 31: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _SearchResultContentWrapper = __webpack_require__(42); var _SearchResultContentWrapper2 = _interopRequireDefault(_SearchResultContentWrapper); var _propTypes3 = __webpack_require__(6); var _AnueSearchRealtimeResult = __webpack_require__(20); var _AnueSearchRealtimeResult2 = _interopRequireDefault(_AnueSearchRealtimeResult); var _anueSearch = __webpack_require__(26); var _helpers = __webpack_require__(43); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // import LazyImage from '../LazyImage/LazyImage'; // import AnueLink from '../../utils/anueLink'; // import { numSignHelper } from '../../utils/num'; /* eslint-disable no-trailing-spaces */ var cx = _bind2.default.bind(_AnueSearchRealtimeResult2.default); // const anueUtilLink = new AnueLink('prod'); // import { driverNameEllipsisHelper, newsPublishedDateHelper } from './helpers'; // import oldDriverIcon from '../../assets/icon-default-driver.svg'; var MAX_RECENT_SEARCH = 5; var MAX_SEARCH_NEWS = 2; function AnueSearchRealtimeResult(_ref) { var hotTags = _ref.hotTags, hotTrades = _ref.hotTrades, recentSearch = _ref.recentSearch, tradeResult = _ref.tradeResult, newsResult = _ref.newsResult, searchString = _ref.searchString, env = _ref.env, customWrapperStyles = _ref.customWrapperStyles, onHotTagClick = _ref.onHotTagClick, onRecentSearchRowClick = _ref.onRecentSearchRowClick, onRecentSearchRowRemoveClick = _ref.onRecentSearchRowRemoveClick, onRecentSearchRemoveAllClick = _ref.onRecentSearchRemoveAllClick, onResultSearchRowClick = _ref.onResultSearchRowClick, enableNewStyle = _ref.enableNewStyle; // const defaultSearchPageLink = anueUtilLink.generateSearchResultLink({ // keyword: searchString, // }); // const searchPageLink = searchResultPageLink || defaultSearchPageLink; var getCode = function getCode(symbol) { var symbolSplit = String(symbol).split(':'); if (!symbolSplit || symbolSplit.length < 2) { return null; } return symbolSplit[1]; }; var renderHotTags = function renderHotTags() { return ( // Display nothing if receive a empty array _react2.default.createElement( _SearchResultContentWrapper2.default, { title: enableNewStyle ? '熱搜' : null, isLoaded: hotTags && hotTags.length > 0, env: env }, _react2.default.createElement( 'div', { className: cx('hot-tags') }, _react2.default.createElement( 'div', { className: cx({ hide: enableNewStyle }) }, _react2.default.createElement( 'p', null, '\u71B1\u641C\uFF1A' ) ), _react2.default.createElement( 'div', null, hotTags && hotTags.map(function (tag) { var handleClick = function handleClick() { return onHotTagClick(tag); }; return _react2.default.createElement( 'a', { key: tag.tagName, href: tag.link, onClick: handleClick }, tag.tagName ); }) ) ) ) ); }; var renderHotTrades = function renderHotTrades() { return ( // Display nothing if receive a empty array _react2.default.createElement( _SearchResultContentWrapper2.default, { title: '\u71B1\u9580\u884C\u60C5', isLoaded: hotTrades && hotTrades.length > 0, env: env }, _react2.default.createElement( 'div', { className: cx('content-rows') }, hotTrades && hotTrades.map(function (trade, i) { var code = getCode(trade.symbol); var display = trade.displayName || code; return display && trade.link ? // eslint-disable-next-line react/no-array-index-key _react2.default.createElement( 'a', { key: 'hot-trade' + i, className: cx('row', 'icon--hot'), href: trade.link }, display ) : null; }) ) ) ); }; var renderRecentSearch = function renderRecentSearch() { return ( // Display nothing if receive a empty array _react2.default.createElement( _SearchResultContentWrapper2.default, { title: '\u6700\u8FD1\u641C\u5C0B', headerActionName: '\u5168\u90E8\u522A\u9664', isLoaded: recentSearch && recentSearch.length > 0, onHeaderActionClick: onRecentSearchRemoveAllClick, env: env }, _react2.default.createElement( 'div', { className: cx('content-rows') }, recentSearch && recentSearch.slice(0, MAX_RECENT_SEARCH).map(function (search, i) { var handleClickRow = function handleClickRow() { return onRecentSearchRowClick(search.keyword); }; var handleClickRemove = function handleClickRemove() { return onRecentSearchRowRemoveClick(search.keyword); }; return ( // eslint-disable-next-line react/no-array-index-key _react2.default.createElement( 'div', { key: 'recent-search' + i, className: cx('row', 'limit-length', { 'icon--time': !enableNewStyle }) }, _react2.default.createElement( 'a', { onClick: handleClickRow }, search.keyword ), _react2.default.createElement('p', { className: cx('icon-cross'), onClick: handleClickRemove }) ) ); }) ) ) ); }; // const renderDrivers = (driverList, isSearchResult) => ( // // isSearchResult ? Display the default message if receive a empty array : // Display nothing if receive a empty array // <SearchResultContentWrapper // title="基金老司機" // isLoaded={isSearchResult ? driverList : driverList && driverList.length > 0} // isCols // env={env} // > // <div className={cx('content-cols')}> // {driverList && driverList.length > 0 ? ( // driverList.map((driver, i) => ( // <a // // eslint-disable-next-line react/no-array-index-key // key={`driver${i}`} // className={cx('col')} // href={driver.link} // onClick={isSearchResult ? onResultSearchRowClick : null} // > // <div className={cx('avatar')}> // <LazyImage isRounded src={driver.avatarPicture || oldDriverIcon} /> // </div> // <p // className={cx('mark', 'name')} // dangerouslySetInnerHTML={{ // __html: driverNameEllipsisHelper(driver.driverName), // }} // /> // <span className={cx('sub-title')}>一年績效</span> // <span // className={cx('perf', { // red: driver.return1year > 0, // green: driver.return1year < 0, // })} // > // {driver.return1year != null // ? numSignHelper(driver.return1year.toFixed(2), { // isPercentage: true, // }) // : '----'} // </span> // </a> // )) // ) : ( // <div className={cx('empty')}>沒有符合搜尋條件的資料</div> // )} // </div> // </SearchResultContentWrapper> // ); var renderSearchTradeResult = function renderSearchTradeResult() { return ( // Display the default message if receive a empty array. _react2.default.createElement( _SearchResultContentWrapper2.default, { title: '\u884C\u60C5', isLoaded: tradeResult, more: '\u770B\u66F4\u591A', keyword: searchString, env: env }, _react2.default.createElement( 'div', { className: cx('content-rows') }, tradeResult && tradeResult.length > 0 ? tradeResult.map(function (trade, i) { var category = (0, _anueSearch.getCategory)(trade); var exchange = (0, _anueSearch.getExchange)(trade); var info = [category, exchange].filter(function (v) { return !!v; }).join('-'); return ( // eslint-disable-next-line react/no-array-index-key _react2.default.createElement( 'a', { key: 'trade' + i, className: cx('row', 'result'), href: trade.link, onClick: onResultSearchRowClick }, _react2.default.createElement( 'p', { className: cx('title') }, _react2.default.createElement('span', { className: cx('mark'), dangerouslySetInnerHTML: { __html: trade.code } }), _react2.default.createElement( 'small', null, info ) ), _react2.default.createElement( 'p', { className: cx('summary') }, _react2.default.createElement('span', { className: cx('mark'), dangerouslySetInnerHTML: { __html: trade.chName } }), _react2.default.createElement('span', { className: cx('mark'), dangerouslySetInnerHTML: { __html: trade.enName } }) ) ) ); }) : _react2.default.createElement( 'div', { className: cx('empty') }, '\u6C92\u6709\u7B26\u5408\u641C\u5C0B\u689D\u4EF6\u7684\u8CC7\u6599' ) ) ) ); }; var renderSearchNewsResult = function renderSearchNewsResult() { return ( // Display the default message if receive a empty array. _react2.default.createElement( _SearchResultContentWrapper2.default, { title: '\u65B0\u805E', isLoaded: newsResult, more: '\u770B\u66F4\u591A', keyword: searchString, env: env }, _react2.default.createElement( 'div', { className: cx('content-rows') }, newsResult && newsResult.length > 0 ? newsResult.slice(0, MAX_SEARCH_NEWS).map(function (n, i) { return ( // eslint-disable-next-line react/no-array-index-key _react2.default.createElement( 'a', { key: 'news' + i, className: cx('row', 'result'), href: n.link, onClick: onResultSearchRowClick }, _react2.default.createElement( 'p', { className: cx('title') }, _react2.default.createElement('span', { className: cx('mark'), dangerouslySetInnerHTML: { __html: n.title } }) ), _react2.default.createElement( 'p', { className: cx('summary') }, _react2.default.createElement( 'span', { className: cx('time') }, (0, _helpers.newsPublishedDateHelper)(n.publishAt) ), !enableNewStyle && _react2.default.createElement( 'span', null, n.summary ) ) ) ); }) : _react2.default.createElement( 'div', { className: cx('empty') }, '\u6C92\u6709\u7B26\u5408\u641C\u5C0B\u689D\u4EF6\u7684\u8CC7\u6599' ) ) ) ); }; var resultWrapperClassName = enableNewStyle ? 'anue-new-search-result' : 'anue-search-result'; return _react2.default.createElement( 'div', { className: cx(resultWrapperClassName), style: customWrapperStyles }, searchString ? _react2.default.createElement( 'div', { className: cx('search-sections', 'section') }, renderSearchTradeResult(), renderSearchNewsResult() ) : _react2.default.createElement( 'div', { className: cx('hot-sections', 'section') }, renderHotTags(), renderHotTrades(), renderRecentSearch() ) ); } AnueSearchRealtimeResult.defaultProps = { hotTags: null, hotTrades: null, hotDrivers: null, recentSearch: null, tradeResult: null, newsResult: null, driversResult: null, searchTradeResult: null, searchDriverResult: null, searchNewsResult: null, searchString: null, customWrapperStyles: null, // searchResultPageLink: null, onHotTagClick: function onHotTagClick() {}, onRecentSearchRowClick: function onRecentSearchRowClick() {}, onRecentSearchRowRemoveClick: function onRecentSearchRowRemoveClick() {}, onRecentSearchRemoveAllClick: function onRecentSearchRemoveAllClick() {}, onResultSearchRowClick: function onResultSearchRowClick() {}, enableNewStyle: false }; exports.default = AnueSearchRealtimeResult; /***/ }), /***/ 32: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _regenerator = __webpack_require__(16); var _regenerator2 = _interopRequireDefault(_regenerator); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _axios = __webpack_require__(21); var _axios2 = _interopRequireDefault(_axios); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var AnueApiFetch = function () { function AnueApiFetch() { _classCallCheck(this, AnueApiFetch); this.instance = _axios2.default.create(); this.instance.interceptors.request.use(function (config) { config.headers['content-type'] = 'application/json'; // eslint-disable-line no-param-reassign // custom header: https://cnyesrd.atlassian.net/wiki/spaces/PS/pages/682622993/API config.headers['X-platform'] = 'WEB'; // eslint-disable-line no-param-reassign return config; }, function (error) { return Promise.reject(error); }); } _createClass(AnueApiFetch, [{ key: 'get', value: function () { var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(url, callback) { var rawResult; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return this.instance.request(url); case 2: rawResult = _context.sent; if (callback) callback(rawResult); return _context.abrupt('return', rawResult); case 5: case 'end': return _context.stop(); } } }, _callee, this); })); function get(_x, _x2) { return _ref.apply(this, arguments); } return get; }() }]); return AnueApiFetch; }(); exports.default = AnueApiFetch; /***/ }), /***/ 39: /***/ (function(module, exports, __webpack_require__) { /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // This method of obtaining a reference to the global object needs to be // kept identical to the way it is obtained in runtime.js var g = (function() { return this })() || Function("return this")(); // Use `getOwnPropertyNames` because not all browsers support calling // `hasOwnProperty` on the global `self` object in a worker. See #183. var hadRuntime = g.regeneratorRuntime && Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0; // Save the old regeneratorRuntime in case it needs to be restored later. var oldRuntime = hadRuntime && g.regeneratorRuntime; // Force reevalutation of runtime.js. g.regeneratorRuntime = undefined; module.exports = __webpack_require__(40); if (hadRuntime) { // Restore the original runtime. g.regeneratorRuntime = oldRuntime; } else { // Remove the global property added by runtime.js. try { delete g.regeneratorRuntime; } catch(e) { g.regeneratorRuntime = undefined; } } /***/ }), /***/ 40: /***/ (function(module, exports) { /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ !(function(global) { "use strict"; var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined; // More compressible than void 0. var $Symbol = typeof Symbol === "function" ? Symbol : {}; var iteratorSymbol = $Symbol.iterator || "@@iterator"; var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; var inModule = typeof module === "object"; var runtime = global.regeneratorRuntime; if (runtime) { if (inModule) { // If regeneratorRuntime is defined globally and we're in a module, // make the exports object identical to regeneratorRuntime. module.exports = runtime; } // Don't bother evaluating the rest of this file if the runtime was // already defined globally. return; } // Define the runtime globally (as expected by generated code) as either // module.exports (if we're in a module) or a new, empty object. runtime = global.regeneratorRuntime = inModule ? module.exports : {}; function wrap(innerFn, outerFn, self, tryLocsList) { // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; var generator = Object.create(protoGenerator.prototype); var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next, // .throw, and .return methods. generator._invoke = makeInvokeMethod(innerFn, self, context); return generator; } runtime.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion // record like context.tryEntries[i].completion. This interface could // have been (and was previously) designed to take a closure to be // invoked without arguments, but in all the cases we care about we // already have an existing method we want to call, so there's no need // to create a new function object. We can even get away with assuming // the method takes exactly one argument, since that happens to be true // in every case, so we don't have to touch the arguments object. The // only additional allocation required is the completion record, which // has a stable shape and so hopefully should be cheap to allocate. function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } var GenStateSuspendedStart = "suspendedStart"; var GenStateSuspendedYield = "suspendedYield"; var GenStateExecuting = "executing"; var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as // breaking out of the dispatch switch statement. var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and // .constructor.prototype properties for functions that return Generator // objects. For full spec compliance, you may wish to configure your // minifier not to mangle the names of these two functions. function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that // don't natively support it. var IteratorPrototype = {}; IteratorPrototype[iteratorSymbol] = function () { return this; }; var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { // This environment has a native %IteratorPrototype%; use it instead // of the polyfill. IteratorPrototype = NativeIteratorPrototype; } var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; GeneratorFunctionPrototype.constructor = GeneratorFunction; GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; // Helper for defining the .next, .throw, and .return methods of the // Iterator interface in terms of a single ._invoke method. function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function(method) { prototype[method] = function(arg) { return this._invoke(method, arg); }; }); } runtime.isGeneratorFunction = function(genFun) { var ctor = typeof genFun === "function" && genFun.constructor; return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can // do is to check its .name property. (ctor.displayName || ctor.name) === "GeneratorFunction" : false; }; runtime.mark = function(genFun) { if (Object.setPrototypeOf) { Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { genFun.__proto__ = GeneratorFunctionPrototype; if (!(toStringTagSymbol in genFun)) { genFun[toStringTagSymbol] = "GeneratorFunction"; } } genFun.prototype = Object.create(Gp); return genFun; }; // Within the body of any async function, `await x` is transformed to // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test // `hasOwn.call(value, "__await")` to determine if the yielded value is // meant to be awaited. runtime.awrap = function(arg) { return { __await: arg }; }; function AsyncIterator(generator) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if (record.type === "throw") { reject(record.arg); } else { var result = record.arg; var value = result.value; if (value && typeof value === "object" && hasOwn.call(value, "__await")) { return Promise.resolve(value.__await).then(function(value) { invoke("next", value, resolve, reject); }, function(err) { invoke("throw", err, resolve, reject); }); } return Promise.resolve(value).then(function(unwrapped) { // When a yielded Promise is resolved, its final value becomes // the .value of the Promise<{value,done}> result for the // current iteration. If the Promise is rejected, however, the // result for this iteration will be rejected with the same // reason. Note that rejections of yielded Promises are not // thrown back into the generator function, as is the case // when an awaited Promise is rejected. This difference in // behavior between yield and await is important, because it // allows the consumer to decide what to do with the yielded // rejection (swallow it and continue, manually .throw it back // into the generator, abandon iteration, whatever). With // await, by contrast, there is no opportunity to examine the // rejection reason outside the generator function, so the // only option is to throw it from the await expression, and // let the generator function handle the exception. result.value = unwrapped; resolve(result); }, reject); } } var previousPromise; function enqueue(method, arg) { function callInvokeWithMethodAndArg() { return new Promise(function(resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = // If enqueue has been called before, then we want to wait until // all previous Promises have been resolved before calling invoke, // so that results are always delivered in the correct order. If // enqueue has not been called before, then it is important to // call invoke immediately, without waiting on a callback to fire, // so that the async generator function has the opportunity to do // any necessary setup in a predictable way. This predictability // is why the Promise constructor synchronously invokes its // executor callback, and why async functions synchronously // execute code before the first await. Since we implement simple // async functions in terms of async generators, it is especially // important to get this right, even though it requires care. previousPromise ? previousPromise.then( callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later // invocations of the iterator. callInvokeWithMethodAndArg ) : callInvokeWithMethodAndArg(); } // Define the unified helper method that is used to implement .next, // .throw, and .return (see defineIteratorMethods). this._invoke = enqueue; } defineIteratorMethods(AsyncIterator.prototype); AsyncIterator.prototype[asyncIteratorSymbol] = function () { return this; }; runtime.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of // AsyncIterator objects; they just return a Promise for the value of // the final result produced by the iterator. runtime.async = function(innerFn, outerFn, self, tryLocsList) { var iter = new AsyncIterator( wrap(innerFn, outerFn, self, tryLocsList) ); return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. : iter.next().then(function(result) { return result.done ? result.value : iter.next(); }); }; function makeInvokeMethod(innerFn, self, context) { var state = GenStateSuspendedStart; return function invoke(method, arg) { if (state === GenStateExecuting) { throw new Error("Generator is already running"); } if (state === GenStateCompleted) { if (method === "throw") { throw arg; } // Be forgiving, per 25.3.3.3.3 of the spec: // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume return doneResult(); } context.method = method; context.arg = arg; while (true) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if (context.method === "next") { // Setting context._sent for legacy support of Babel's // function.sent implementation. context.sent = context._sent = context.arg; } else if (context.method === "throw") { if (state === GenStateSuspendedStart) { state = GenStateCompleted; throw context.arg; } context.dispatchException(context.arg); } else if (context.method === "return") { context.abrupt("return", context.arg); } state = GenStateExecuting; var record = tryCatch(innerFn, self, context); if (record.type === "normal") { // If an exception is thrown from innerFn, we leave state === // GenStateExecuting and loop back for another invocation. state = context.done ? GenStateCompleted : GenStateSuspendedYield; if (record.arg === ContinueSentinel) { continue; } return { value: record.arg, done: context.done }; } else if (record.type === "throw") { state = GenStateCompleted; // Dispatch the exception by looping back around to the // context.dispatchException(context.arg) call above. context.method = "throw"; context.arg = record.arg; } } }; } // Call delegate.iterator[context.method](context.arg) and handle the // result, either by returning a { value, done } result from the // delegate iterator, or by modifying context.method and context.arg, // setting context.delegate to null, and returning the ContinueSentinel. function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (method === undefined) { // A .throw or .return when the delegate iterator has no .throw // method always terminates the yield* loop. context.delegate = null; if (context.method === "throw") { if (delegate.iterator.return) { // If the delegate iterator has a return method, give it a // chance to clean up. context.method = "return"; context.arg = undefined; maybeInvokeDelegate(delegate, context); if (context.method === "throw") { // If maybeInvokeDelegate(context) changed context.method from // "return" to "throw", let that override the TypeError below. return ContinueSentinel; } } context.method = "throw"; context.arg = new TypeError( "The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if (record.type === "throw") { context.method = "throw"; context.arg = record.arg; context.delegate = null; return ContinueSentinel; } var info = record.arg; if (! info) { context.method = "throw"; context.arg = new TypeError("iterator result is not an object"); context.delegate = null; return ContinueSentinel; } if (info.done) { // Assign the result of the finished delegate to the temporary // variable specified by delegate.resultName (see delegateYield). context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield). context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the // exception, let the outer generator proceed normally. If // context.method was "next", forget context.arg since it has been // "consumed" by the delegate iterator. If context.method was // "return", allow the original .return call to continue in the // outer generator. if (context.method !== "return") { context.method = "next"; context.arg = undefined; } } else { // Re-yield the result returned by the delegate method. return info; } // The delegate iterator is finished, so forget it and continue with // the outer generator. context.delegate = null; return ContinueSentinel; } // Define Generator.prototype.{next,throw,return} in terms of the // unified ._invoke helper method. defineIteratorMethods(Gp); Gp[toStringTagSymbol] = "Generator"; // A Generator should always return itself as the iterator object when the // @@iterator function is called on it. Some browsers' implementations of the // iterator prototype chain incorrectly implement this, causing the Generator // object to not be returned from this call. This ensures that doesn't happen. // See https://github.com/facebook/regenerator/issues/274 for more details. Gp[iteratorSymbol] = function() { return this; }; Gp.toString = function() { return "[object Generator]"; }; function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; if (1 in locs) { entry.catchLoc = locs[1]; } if (2 in locs) { entry.finallyLoc = locs[2]; entry.afterLoc = locs[3]; } this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal"; delete record.arg; entry.completion = record; } function Context(tryLocsList) { // The root entry object (effectively a try statement without a catch // or a finally block) gives us a place to store values thrown from // locations where there is no enclosing try statement. this.tryEntries = [{ tryLoc: "root" }]; tryLocsList.forEach(pushTryEntry, this); this.reset(true); } runtime.keys = function(object) { var keys = []; for (var key in object) { keys.push(key); } keys.reverse(); // Rather than returning an object with a next method, we keep // things simple and return the next function itself. return function next() { while (keys.length) { var key = keys.pop(); if (key in object) { next.value = key; next.done = false; return next; } } // To avoid creating an additional object, we just hang the .value // and .done properties off the next function object itself. This // also ensures that the minifier will not anonymize the function. next.done = true; return next; }; }; function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); } if (typeof iterable.next === "function") { return iterable; } if (!isNaN(iterable.length)) { var i = -1, next = function next() { while (++i < iterable.length) { if (hasOwn.call(iterable, i)) { next.value = iterable[i]; next.done = false; return next; } } next.value = undefined; next.done = true; return next; }; return next.next = next; } } // Return an iterator with no values. return { next: doneResult }; } runtime.values = values; function doneResult() { return { value: undefined, done: true }; } Context.prototype = { constructor: Context, reset: function(skipTempReset) { this.prev = 0; this.next = 0; // Resetting context._sent for legacy support of Babel's // function.sent implementation. this.sent = this._sent = undefined; this.done = false; this.delegate = null; this.method = "next"; this.arg = undefined; this.tryEntries.forEach(resetTryEntry); if (!skipTempReset) { for (var name in this) { // Not sure about the optimal order of these conditions: if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { this[name] = undefined; } } } }, stop: function() { this.done = true; var rootEntry = this.tryEntries[0]; var rootRecord = rootEntry.completion; if (rootRecord.type === "throw") { throw rootRecord.arg; } return this.rval; }, dispatchException: function(exception) { if (this.done) { throw exception; } var context = this; function handle(loc, caught) { record.type = "throw"; record.arg = exception; context.next = loc; if (caught) { // If the dispatched exception was caught by a catch block, // then let that catch block handle the exception normally. context.method = "next"; context.arg = undefined; } return !! caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { // Exception thrown outside of any try block that could handle // it, so set the completion value of the entire function to // throw the exception. return handle("end"); } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else { throw new Error("try statement without catch or finally"); } } } }, abrupt: function(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { // Ignore the finally entry if control is not jumping to a // location outside the try/catch block. finallyEntry = null; } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel; } return this.complete(record); }, complete: function(record, afterLoc) { if (record.type === "throw") { throw record.arg; } if (record.type === "break" || record.type === "continue") { this.next = record.arg; } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end"; } else if (record.type === "normal" && afterLoc) { this.next = afterLoc; } return ContinueSentinel; }, finish: function(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel; } } }, "catch": function(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } // The context.catch method must only be called with a location // argument that corresponds to a known catch block. throw new Error("illegal catch attempt"); }, delegateYield: function(iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { // Deliberately forget the last sent value so that we don't // accidentally pass it on to the delegate. this.arg = undefined; } return ContinueSentinel; } }; })( // In sloppy mode, unbound `this` refers to the global object, fallback to // Function constructor if we're in global strict mode. That is sadly a form // of indirect eval which violates Content Security Policy. (function() { return this })() || Function("return this")() ); /***/ }), /***/ 41: /***/ (function(module, exports) { // removed by extract-text-webpack-plugin module.exports = {"wrapperWidth":"1200px","screenSizeSm":"321px","screenSizeMd":"768px","screenSizeMl":"990px","screenSizeLg":"1024px","screenSizeXl":"1200px","screenSizeXXl":"1360px","anue-search-input--wrapper":"_2FuhZ","search-icon":"_1TJnw","anue-new-search-input--wrapper":"_3k0Sm","clear-icon":"_2ajF-","back-icon":"_3FFxo","mobile":"_1q3Tm","display":"_2TQmr","test1":"_3p1bb","test2":"_3OSc-","anue-search-input":"_2GtYE","desktop":"_1xlWU"}; /***/ }), /***/ 42: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SearchResultContentWrapper; var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _AnueSearchRealtimeResult = __webpack_require__(20); var _AnueSearchRealtimeResult2 = _interopRequireDefault(_AnueSearchRealtimeResult); var _anueLink = __webpack_require__(7); var _anueLink2 = _interopRequireDefault(_anueLink); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var cx = _bind2.default.bind(_AnueSearchRealtimeResult2.default); function SearchResultContentWrapper(_ref) { var title = _ref.title, headerActionName = _ref.headerActionName, onHeaderActionClick = _ref.onHeaderActionClick, isLoaded = _ref.isLoaded, children = _ref.children, more = _ref.more, keyword = _ref.keyword, env = _ref.env; var anueUtilLink = new _anueLink2.default(env); var link = anueUtilLink.generateSearchMoreLink({ title: title, keyword: keyword }); return _react2.default.createElement( 'div', { className: cx('search-result-content-wrapper', { display: isLoaded }) }, title && _react2.default.createElement( 'div', { className: cx('search-result-content-wrapper__header') }, _react2.default.createElement( 'p', null, title ), more && _react2.default.createElement( 'a', { href: link }, more ), headerActionName && _react2.default.createElement( 'span', { onClick: onHeaderActionClick }, headerActionName ) ), children ); } SearchResultContentWrapper.defaultProps = { title: null, headerActionName: null, onHeaderActionClick: function onHeaderActionClick() {}, onRowActionClick: function onRowActionClick() {}, isLoaded: false, isCols: false, children: null, more: null, keyword: null }; /***/ }), /***/ 43: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ZERO_CHART_CODE_AT = '0'.charCodeAt(); var NINE_CHART_CODE_AT = '9'.charCodeAt(); var FIRST_ALPHABET_CHART_CODE_AT = 'a'.charCodeAt(); var LAST_ALPHABET_CHART_CODE_AT = 'z'.charCodeAt(); var FIRST_CAPITAL_ALPHABET_CHART_CODE_AT = 'A'.charCodeAt(); var LAST_CAPITAL_ALPHABET_CHART_CODE_AT = 'Z'.charCodeAt(); var MAX_TEXT_LENGTH = 24; var findMarkTagIdx = exports.findMarkTagIdx = function findMarkTagIdx(string) { var startRegex = string.match('<mark>'); var endRegex = string.replace('<mark>', '').match('</mark>'); var markStartIdx = startRegex && startRegex.index; var markEndIdx = endRegex && endRegex.index; return { markStartIdx: markStartIdx, markEndIdx: markEndIdx }; }; var driverNameEllipsisHelper = exports.driverNameEllipsisHelper = function driverNameEllipsisHelper(htmlString) { if (!htmlString) { return null; } var lengthCount = 0; var map = ['<mark>', '</mark>']; var stringArry = htmlString.split(/<\/?mark>/); var next = []; for (var i = 0; i < stringArry.length; i++) { var currentChunk = stringArry[i]; for (var j = 0; j < currentChunk.length; j++) { var c = currentChunk[j].charCodeAt(); if (ZERO_CHART_CODE_AT <= c && NINE_CHART_CODE_AT >= c || FIRST_ALPHABET_CHART_CODE_AT <= c && LAST_ALPHABET_CHART_CODE_AT >= c) { // eslint-disable-next-line no-param-reassign lengthCount += 1; } else if (FIRST_CAPITAL_ALPHABET_CHART_CODE_AT <= c && LAST_CAPITAL_ALPHABET_CHART_CODE_AT >= c) { // eslint-disable-next-line no-param-reassign lengthCount += 1.5; } else { // eslint-disable-next-line no-param-reassign lengthCount += 2; } if (lengthCount >= MAX_TEXT_LENGTH) { break; } next.push(currentChunk[j]); } if (i !== stringArry.length - 1) { next.push(map[i % 2]); } if (lengthCount >= MAX_TEXT_LENGTH) { break; } } return lengthCount >= MAX_TEXT_LENGTH ? next.join('') + '...' : next.join(''); }; var newsPublishedDateHelper = exports.newsPublishedDateHelper = function newsPublishedDateHelper(phpTs) { var ts = phpTs * 1000; var hoursBackTimestamp = Date.now() - ts; if (hoursBackTimestamp < 24 * 60 * 60 * 1000) { return Math.floor(hoursBackTimestamp / (60 * 60 * 1000)) + ' \u5C0F\u6642\u524D'; } var d = new Date(ts); return d.getFullYear() + '/' + (d.getMonth() + 1) + '/' + d.getDate(); }; /***/ }), /***/ 44: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AnueCookie; var SEARCH_HISTORY_STORED_COOKIE_NAME = 'anue.search.history'; function AnueCookie(env) { var isProd = env === 'prod'; var cookieDomain = isProd ? '.cnyes.com' : '.cnyes.cool'; var getSearchCookies = function getSearchCookies() { var history = ('; ' + document.cookie).split('; ' + SEARCH_HISTORY_STORED_COOKIE_NAME + '=').pop().split(';').shift(); var _history = []; if (history) { try { _history = JSON.parse(history); } catch (e) { console.log('the stored values has incorrect format. Store the new value and truncate the old data', e); _history = []; } } return _history; }; return { getSearchCookies: getSearchCookies, setSearchCookies: function setSearchCookies(_ref) { var string = _ref.string, _ref$shouldDelete = _ref.shouldDelete, shouldDelete = _ref$shouldDelete === undefined ? false : _ref$shouldDelete, _ref$cookieLimit = _ref.cookieLimit, cookieLimit = _ref$cookieLimit === undefined ? 5 : _ref$cookieLimit; var next = getSearchCookies(); var legalSearchStr = string; if (!legalSearchStr) { return; } if (legalSearchStr.length > 30) { legalSearchStr = legalSearchStr.substring(0, 30); } if (next.length > 0) { if (shouldDelete && next.indexOf(legalSearchStr) > -1) { next.splice(next.indexOf(legalSearchStr), 1); } else if (next.indexOf(legalSearchStr) > -1) { // Do nothing if the keyword is duplicated. return; } else { next.push(legalSearchStr); } while (next.length > cookieLimit) { next.shift(); } document.cookie = SEARCH_HISTORY_STORED_COOKIE_NAME + '=' + JSON.stringify(next) + '; domain=' + cookieDomain + '; path=/'; } else { document.cookie = SEARCH_HISTORY_STORED_COOKIE_NAME + '=' + JSON.stringify([legalSearchStr]) + '; domain=' + cookieDomain + '; path=/'; } }, removeSearchCookies: function removeSearchCookies() { document.cookie = SEARCH_HISTORY_STORED_COOKIE_NAME + '=' + JSON.stringify([]) + '; domain=' + cookieDomain + '; path=/'; }, cookieDomain: cookieDomain }; } /***/ }), /***/ 5: /***/ (function(module, exports) { var g; // This works in non-strict mode g = (function() { return this; })(); try { // This works if eval is allowed (see CSP) g = g || Function("return this")() || (1,eval)("this"); } catch(e) { // This works if the window reference is available if(typeof window === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; /***/ }), /***/ 53: /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {var now = __webpack_require__(58) , root = typeof window === 'undefined' ? global : window , vendors = ['moz', 'webkit'] , suffix = 'AnimationFrame' , raf = root['request' + suffix] , caf = root['cancel' + suffix] || root['cancelRequest' + suffix] for(var i = 0; !raf && i < vendors.length; i++) { raf = root[vendors[i] + 'Request' + suffix] caf = root[vendors[i] + 'Cancel' + suffix] || root[vendors[i] + 'CancelRequest' + suffix] } // Some versions of FF have rAF but not cAF if(!raf || !caf) { var last = 0 , id = 0 , queue = [] , frameDuration = 1000 / 60 raf = function(callback) { if(queue.length === 0) { var _now = now() , next = Math.max(0, frameDuration - (_now - last)) last = next + _now setTimeout(function() { var cp = queue.slice(0) // Clear queue here to prevent // callbacks from appending listeners // to the current frame's queue queue.length = 0 for(var i = 0; i < cp.length; i++) { if(!cp[i].cancelled) { try{ cp[i].callback(last) } catch(e) { setTimeout(function() { throw e }, 0) } } } }, Math.round(next)) } queue.push({ handle: ++id, callback: callback, cancelled: false }) return id } caf = function(handle) { for(var i = 0; i < queue.length; i++) { if(queue[i].handle === handle) { queue[i].cancelled = true } } } } module.exports = function(fn) { // Wrap in a new function to prevent // `cancel` potentially being assigned // to the native rAF function return raf.call(root, fn) } module.exports.cancel = function() { caf.apply(root, arguments) } module.exports.polyfill = function(object) { if (!object) { object = root; } object.requestAnimationFrame = raf object.cancelAnimationFrame = caf } /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) /***/ }), /***/ 54: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _regenerator = __webpack_require__(16); var _regenerator2 = _interopRequireDefault(_regenerator); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); var _bind = __webpack_require__(2); var _bind2 = _interopRequireDefault(_bind); var _AnueSearchInput = __webpack_require__(30); var _AnueSearchInput2 = _interopRequireDefault(_AnueSearchInput); var _AnueSearchRealtimeResult = __webpack_require__(31); var _AnueSearchRealtimeResult2 = _interopRequireDefault(_AnueSearchRealtimeResult); var _AnueApiFetch = __webpack_require__(32); var _AnueApiFetch2 = _interopRequireDefault(_AnueApiFetch); var _helpers = __webpack_require__(62); var _helpers2 = _interopRequireDefault(_helpers); var _debounce = __webpack_require__(63); var _debounce2 = _interopRequireDefault(_debounce); var _AnueSearch = __webpack_require__(64); var _AnueSearch2 = _interopRequireDefault(_AnueSearch); var _anueLink = __webpack_require__(7); var _anueLink2 = _interopRequireDefault(_anueLink); var _anueCookie = __webpack_require__(44); var _anueCookie2 = _interopRequireDefault(_anueCookie); var _gaDataset = __webpack_require__(3); var _gaDataset2 = _interopRequireDefault(_gaDataset); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable space-infix-ops */ var cx = _bind2.default.bind(_AnueSearch2.default); var AnueSearch = function (_Component) { _inherits(AnueSearch, _Component); function AnueSearch(props) { var _this2 = this; _classCallCheck(this, AnueSearch); var _this = _possibleConstructorReturn(this, (AnueSearch.__proto__ || Object.getPrototypeOf(AnueSearch)).call(this, props)); _this.getSearchHistory = function () { var history = _this.anueCookieSingleton.getSearchCookies(); _this.setState({ recentSearch: _this.dataHelpers.recentSearchDataHelper(history) }); }; _this.storeSearchHistory = function (string, shouldDelete) { var _this$props = _this.props, maxRecentHistory = _this$props.maxRecentHistory, apiEnv = _this$props.apiEnv; _this.anueCookieSingleton.setSearchCookies({ string: string, shouldDelete: shouldDelete, cookieLimit: maxRecentHistory, env: apiEnv }); _this.getSearchHistory(); }; _this.removeAllTags = function () { var apiEnv = _this.props.apiEnv; _this.anueCookieSingleton.removeSearchCookies({ env: apiEnv }); _this.getSearchHistory(); }; _this.handleClickRecentTag = function (tagName) { var aink = _this.props.aink; var link = _this.anueUrlSingleton.generateSearchResultLink({ keyword: tagName, backLink: aink }); location.href = link; }; _this.handleClickHotTag = function (tag) { if (tag && tag.tagName) { var keyword = tag.tagName; _this.inputRef.value = keyword; _this.inputRef.focus(); _this.handleSearchChange(keyword); } }; _this.handleClickRemoveTag = function (tagName) { _this.storeSearchHistory(tagName, true); }; _this.handleFetch = (0, _debounce2.default)(_asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee() { var searchString, rawResult, result; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: searchString = _this.state.searchString; _context.next = 3; return _this.request.get('' + _this.anueUrlSingleton.anueSearchAllApiUrl + encodeURIComponent(searchString)); case 3: rawResult = _context.sent; result = _this.dataHelpers.searchTradesResponseHelper(rawResult); if (result && (result.quoteFunds || result.news || result.oldDrivers)) { _this.setState({ tradeResult: result.quoteFunds, newsResult: result.news, driversResult: result.oldDrivers }); } case 6: case 'end': return _context.stop(); } } }, _callee, _this2); })), 250); _this.handleSearchChange = function (value) { var _this$props2 = _this.props, onInputChange = _this$props2.onInputChange, dataPrefix = _this$props2.dataPrefix; _this.setState({ searchString: value }); onInputChange(value); _this.handleFetch(); (0, _gaDataset2.default)({ dataPrefix: dataPrefix, category: 'Searchall', action: 'click', label: value }); }; _this.handlePressEnter = function () { var _this$props3 = _this.props, onInputPressEnter = _this$props3.onInputPressEnter, aink = _this$props3.aink; var searchString = _this.state.searchString; onInputPressEnter(); if (!!searchString && typeof window !== 'undefined') { _this.storeSearchHistory(searchString); var link = _this.anueUrlSingleton.generateSearchResultLink({ keyword: searchString, backLink: aink }); location.href = link; } }; _this.handleClickSearchIcon = function () { var _this$props4 = _this.props, onIconClick = _this$props4.onIconClick, aink = _this$props4.aink; var _this$state = _this.state, searchString = _this$state.searchString, hover = _this$state.hover; onIconClick(); if (!!searchString && typeof window !== 'undefined') { _this.storeSearchHistory(searchString); var link = _this.anueUrlSingleton.generateSearchResultLink({ keyword: searchString, backLink: aink }); location.href = link; } if (hover) { _this.setState({ hover: false }); } }; _this.handleClickBackIcon = function () { var onBackIconClick = _this.props.onBackIconClick; _this.setState({ hover: false }); onBackIconClick(); }; _this.handleClickResultRow = function () { var searchString = _this.state.searchString; if (!!searchString && typeof window !== 'undefined') { _this.storeSearchHistory(searchString); } }; _this.handleSearchOnFocus = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2() { var onInputFocus, _this$state2, hotTags, hotTrades, hotDrivers, _hotTrades, _hotTags, _hotDrivers; return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: onInputFocus = _this.props.onInputFocus; _this$state2 = _this.state, hotTags = _this$state2.hotTags, hotTrades = _this$state2.hotTrades, hotDrivers = _this$state2.hotDrivers; _this.setState({ hover: true }); onInputFocus(); if (!(!hotTags && !hotTrades && !hotDrivers)) { _context2.next = 16; break; } _context2.next = 7; return _this.request.get(_this.anueUrlSingleton.hotTradesApiUrl); case 7: _hotTrades = _context2.sent; _context2.next = 10; return _this.request.get(_this.anueUrlSingleton.hotTagsApiUrl); case 10: _hotTags = _context2.sent; _context2.next = 13; return _this.request.get(_this.anueUrlSingleton.hotDriversApiUrl); case 13: _hotDrivers = _context2.sent; _this.getSearchHistory(); _this.setState({ hotTags: _this.dataHelpers.hotTagsResponseHelper(_hotTags), hotTrades: _this.dataHelpers.hotTradesResponseHelper(_hotTrades), hotDrivers: _this.dataHelpers.hotDriversResponseHelper(_hotDrivers) }); case 16: case 'end': return _context2.stop(); } } }, _callee2, _this2); })); _this.handleHideSearchResult = function () { var hover = _this.state.hover; if (hover) { _this.setState({ hover: false }); } }; _this.handleSearchOnBlur = function () { var onInputBlur = _this.props.onInputBlur; onInputBlur(); }; _this.handleStopWrapperClickPropagation = function (e) { e.stopPropagation(); }; var defaultSearchString = props.defaultValue || ''; if (typeof window !== 'undefined' && props.defaultValue === null) { var keywordQueryStringRegex = location.search && decodeURIComponent(location.search).match(/keyword=([^&]*)/); if (keywordQueryStringRegex && keywordQueryStringRegex[1]) { defaultSearchString = keywordQueryStringRegex[1]; } } _this.state = { isInputHidden: false, isInputFocus: false, hotTags: null, hotTrades: null, recentSearch: null, hotDrivers: null, searchString: defaultSearchString, tradeResult: null, newsResult: null, driversResult: null, hover: false }; _this.request = new _AnueApiFetch2.default(); _this.anueUrlSingleton = new _anueLink2.default(props.apiEnv); _this.anueCookieSingleton = new _anueCookie2.default(props.apiEnv); _this.dataHelpers = (0, _helpers2.default)(_this.anueUrlSingleton); return _this; } _createClass(AnueSearch, [{ key: 'componentDidMount', value: function componentDidMount() { if (typeof window !== 'undefined') { // The clicked event of AnueSearch is set to stopPropagation. // So click the anywhere outside of AnueSearch will hide the AnueRealtimeResult. window.addEventListener('click', this.handleHideSearchResult); } } }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevPrev, prevState) { var theme = this.props.theme; var hover = this.state.hover; if (typeof window !== 'undefined' && prevState.hover !== hover) { var bodyStyles = document.body.style; var screenWidth = window.innerWidth || document.documentElement.clientWidth; var isSmallMode = theme === 'mobile' || screenWidth < _AnueSearch2.default.mobileScreenWidth; if (hover && isSmallMode) { document.body.style.overflowY = 'hidden'; } else if (bodyStyles) { document.body.style.overflowY = 'auto'; } } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { window.removeEventListener('click', this.handleHideSearchResult); } }, { key: 'render', value: function render() { var _this3 = this; var _props = this.props, theme = _props.theme, shouldAlwaysDisplayInput = _props.shouldAlwaysDisplayInput, shouldDisplayBackIcon = _props.shouldDisplayBackIcon, placeholder = _props.placeholder, customAttribute = _props.customAttribute, customWrapperStyles = _props.customWrapperStyles, customInputWrapperStyles = _props.customInputWrapperStyles, customResultWrapperStyles = _props.customResultWrapperStyles, customInputStyles = _props.customInputStyles, customIconStyles = _props.customIconStyles, onSearchVisibilityChange = _props.onSearchVisibilityChange, aink = _props.aink, enableNewStyle = _props.enableNewStyle, apiEnv = _props.apiEnv; var _state = this.state, hotTags = _state.hotTags, hotTrades = _state.hotTrades, hotDrivers = _state.hotDrivers, recentSearch = _state.recentSearch, searchString = _state.searchString, hover = _state.hover, tradeResult = _state.tradeResult, newsResult = _state.newsResult, driversResult = _state.driversResult; var searchResultLink = this.anueUrlSingleton.generateSearchResultLink({ keyword: searchString, backLink: aink }); var searchClassName = 'anue-search'; var customInputClassName = null; if (enableNewStyle) { searchClassName = 'anue-new-search'; customInputClassName = 'anue-new-search-input--wrapper'; } return _react2.default.createElement( 'div', { className: cx(searchClassName, theme), style: customWrapperStyles, onClick: this.handleStopWrapperClickPropagation }, _react2.default.createElement( 'div', { className: cx('input-wrapper', { active: hover }) }, _react2.default.createElement(_AnueSearchInput2.default, { theme: theme, placeholder: placeholder, onInputChange: this.handleSearchChange, onInputFocus: this.handleSearchOnFocus, onInputBlur: this.handleSearchOnBlur, onInputPressEnter: this.handlePressEnter, onIconClick: this.handleClickSearchIcon, onBackIconClick: this.handleClickBackIcon, shouldAlwaysDisplayInput: shouldAlwaysDisplayInput || !!searchString, shouldDisplayBackIcon: shouldDisplayBackIcon, defaultValue: searchString, customWrapperStyles: customInputWrapperStyles, customInputStyles: customInputStyles, customIconStyles: customIconStyles, onDisplayChange: onSearchVisibilityChange, enableNewStyle: enableNewStyle, customInputClassName: customInputClassName, customAttribute: _extends({}, customAttribute, { ref: function ref(input) { _this3.inputRef = input; } }) }) ), _react2.default.createElement( 'div', { className: cx('search-result', theme, { display: hover }) }, _react2.default.createElement(_AnueSearchRealtimeResult2.default, { hotTags: hotTags, hotTrades: hotTrades, hotDrivers: hotDrivers, recentSearch: recentSearch, searchString: searchString, tradeResult: tradeResult, newsResult: newsResult, driversResult: driversResult, onHotTagClick: this.handleClickHotTag, onRecentSearchRowClick: this.handleClickRecentTag, onRecentSearchRowRemoveClick: this.handleClickRemoveTag, onRecentSearchRemoveAllClick: this.removeAllTags, onResultSearchRowClick: this.handleClickResultRow, customWrapperStyles: customResultWrapperStyles, searchResultPageLink: searchResultLink, enableNewStyle: enableNewStyle, env: apiEnv }) ) ); } }]); return AnueSearch; }(_react.Component); AnueSearch.defaultProps = { maxRecentHistory: 10, theme: null, customAttribute: null, customWrapperStyles: null, customInputWrapperStyles: null, customResultWrapperStyles: null, customInputStyles: null, customIconStyles: null, customResultClassName: null, shouldAlwaysDisplayInput: false, shouldDisplayBackIcon: false, placeholder: '搜尋新聞、代碼或名稱', onIconClick: function onIconClick() {}, onBackIconClick: function onBackIconClick() {}, onInputChange: function onInputChange() {}, onInputFocus: function onInputFocus() {}, onInputBlur: function onInputBlur() {}, onInputPressEnter: function onInputPressEnter() {}, onSearchVisibilityChange: function onSearchVisibilityChange() {}, apiEnv: 'prod', aink: null, defaultValue: null, enableNewStyle: false, dataPrefix: ['data-global-ga'] }; exports.default = AnueSearch; /***/ }), /***/ 58: /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {// Generated by CoffeeScript 1.12.2 (function() { var getNanoSeconds, hrtime, loadTime, moduleLoadTime, nodeLoadTime, upTime; if ((typeof performance !== "undefined" && performance !== null) && performance.now) { module.exports = function() { return performance.now(); }; } else if ((typeof process !== "undefined" && process !== null) && process.hrtime) { module.exports = function() { return (getNanoSeconds() - nodeLoadTime) / 1e6; }; hrtime = process.hrtime; getNanoSeconds = function() { var hr; hr = hrtime(); return hr[0] * 1e9 + hr[1]; }; moduleLoadTime = getNanoSeconds(); upTime = process.uptime() * 1e9; nodeLoadTime = moduleLoadTime - upTime; } else if (Date.now) { module.exports = function() { return Date.now() - loadTime; }; loadTime = Date.now(); } else { module.exports = function() { return new Date().getTime() - loadTime; }; loadTime = new Date().getTime(); } }).call(this); //# sourceMappingURL=performance-now.js.map /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(19))) /***/ }), /***/ 6: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.newsResultType = exports.tradeResultType = exports.recentSearchType = exports.hotDriversType = exports.hotTradesType = exports.hotTagsType = exports.adProfileType = exports.newsItemType = exports.userProfileType = exports.authType = exports.locationShape = exports.footerNavItem = exports.catNavsType = exports.catNavItemShape = exports.catNavSubItemShape = exports.navsMobileType = exports.navItemMobileShape = exports.navItemMobilShape = exports.accountNavsType = exports.accountNavItemShape = exports.navsType = exports.navItemShape = exports.navUrlShape = exports.navDownloadType = exports.navDownloadShape = exports.requestType = undefined; var _propTypes = __webpack_require__(1); var _propTypes2 = _interopRequireDefault(_propTypes); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var requestType = exports.requestType = _propTypes2.default.func; /* eslint-disable import/prefer-default-export */ var navDownloadShape = exports.navDownloadShape = _propTypes2.default.shape({ title: _propTypes2.default.string.isRequired, url: _propTypes2.default.string.isRequired }); var navDownloadType = exports.navDownloadType = _propTypes2.default.arrayOf(navDownloadShape); var navUrlShape = exports.navUrlShape = _propTypes2.default.shape({ title: _propTypes2.default.string.isRequired, url: _propTypes2.default.string.isRequired }); var navItemShape = exports.navItemShape = _propTypes2.default.shape({ title: _propTypes2.default.string.isRequired, url: _propTypes2.default.string, isNew: _propTypes2.default.bool, leftList: _propTypes2.default.arrayOf(navUrlShape), rightListTitle: _propTypes2.default.string, rightList: _propTypes2.default.arrayOf(navUrlShape) }); var navsType = exports.navsType = _propTypes2.default.arrayOf(navItemShape); var accountNavItemShape = exports.accountNavItemShape = _propTypes2.default.shape({ id: _propTypes2.default.string.isRequired, title: _propTypes2.default.string.isRequired, defaultUrl: _propTypes2.default.string.isRequired, notify: _propTypes2.default.arrayOf(_propTypes2.default.shape({ id: _propTypes2.default.string.isRequired, gotoUrl: _propTypes2.default.string.isRequired })) }); var accountNavsType = exports.accountNavsType = _propTypes2.default.arrayOf(accountNavItemShape); var navItemMobilShape = exports.navItemMobilShape = _propTypes2.default.shape({ name: _propTypes2.default.string.isRequired, title: _propTypes2.default.string.isRequired, url: _propTypes2.default.string.isRequired, external: _propTypes2.default.bool }); var navItemMobileShape = exports.navItemMobileShape = _propTypes2.default.shape({ name: _propTypes2.default.string.isRequired, title: _propTypes2.default.string.isRequired, items: _propTypes2.default.arrayOf(navItemMobilShape), url: _propTypes2.default.string }); var navsMobileType = exports.navsMobileType = _propTypes2.default.arrayOf(navItemMobileShape); var catNavSubItemShape = exports.catNavSubItemShape = _propTypes2.default.shape({ name: _propTypes2.default.string, url: _propTypes2.default.string, title: _propTypes2.default.string, external: _propTypes2.default.bool }); var catNavItemShape = exports.catNavItemShape = _propTypes2.default.shape({ name: _propTypes2.default.string.isRequired, url: _propTypes2.default.string.isRequired, title: _propTypes2.default.string.isRequired, external: _propTypes2.default.bool, subItems: _propTypes2.default.arrayOf(catNavSubItemShape) }); var catNavsType = exports.catNavsType = _propTypes2.default.arrayOf(catNavItemShape); var footerNavItem = exports.footerNavItem = _propTypes2.default.shape({ title: _propTypes2.default.string.isRequired, name: _propTypes2.default.string.isRequired, url: _propTypes2.default.string, onClick: _propTypes2.default.func }); var locationShape = exports.locationShape = _propTypes2.default.shape({ key: _propTypes2.default.string, pathname: _propTypes2.default.string, search: _propTypes2.default.string, hash: _propTypes2.default.string, state: _propTypes2.default.object }); var authType = exports.authType = _propTypes2.default.shape({ init: _propTypes2.default.func.isRequired, loginFB: _propTypes2.default.func.isRequired, loginGoogle: _propTypes2.default.func.isRequired, logout: _propTypes2.default.func.isRequired, showLogin: _propTypes2.default.func.isRequired, hideLogin: _propTypes2.default.func.isRequired, getToken: _propTypes2.default.func.isRequired, refreshToken: _propTypes2.default.func.isRequired, getProfile: _propTypes2.default.func.isRequired }); var userProfileType = exports.userProfileType = _propTypes2.default.shape({ uid: _propTypes2.default.string.isRequired, name: _propTypes2.default.string.isRequired, nickname: _propTypes2.default.string, email: _propTypes2.default.string, avatar: _propTypes2.default.string.isRequired, gender: _propTypes2.default.oneOf(['', 'male', 'female']), vip: _propTypes2.default.oneOf([0, 1]) }); var newsItemType = exports.newsItemType = _propTypes2.default.shape({ newsId: _propTypes2.default.number.isRequired, title: _propTypes2.default.string.isRequired, hasCoverPhoto: _propTypes2.default.oneOf([0, 1]).isRequired, coverSrc: _propTypes2.default.shape({ m: _propTypes2.default.shape({ src: _propTypes2.default.string }), l: _propTypes2.default.shape({ src: _propTypes2.default.string }), xl: _propTypes2.default.shape({ src: _propTypes2.default.string }) }) }); var adProfileType = exports.adProfileType = _propTypes2.default.shape({ name: _propTypes2.default.string.isRequired, path: _propTypes2.default.string.isRequired, hideOnInitial: _propTypes2.default.bool }); var hotTagsType = exports.hotTagsType = _propTypes2.default.shape({ tagName: _propTypes2.default.string, link: _propTypes2.default.string }); var hotTradesType = exports.hotTradesType = _propTypes2.default.shape({ localName: _propTypes2.default.string, link: _propTypes2.default.string }); var hotDriversType = exports.hotDriversType = _propTypes2.default.shape({ avatarPicture: _propTypes2.default.string, driverId: _propTypes2.default.string, driverName: _propTypes2.default.string, return1year: _propTypes2.default.number, link: _propTypes2.default.string }); var recentSearchType = exports.recentSearchType = _propTypes2.default.shape({ keyword: _propTypes2.default.string, link: _propTypes2.default.string }); var tradeResultType = exports.tradeResultType = _propTypes2.default.shape({ market: _propTypes2.default.string, code: _propTypes2.default.string, type: _propTypes2.default.string, mtype: _propTypes2.default.string, symbol: _propTypes2.default.string, chName: _propTypes2.default.string, enName: _propTypes2.default.string, exchange: _propTypes2.default.string, link: _propTypes2.default.string }); var newsResultType = exports.newsResultType = _propTypes2.default.shape({ newsId: _propTypes2.default.string, title: _propTypes2.default.string, summary: _propTypes2.default.string, publishAt: _propTypes2.default.number, link: _propTypes2.default.string }); /***/ }), /***/ 62: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SearchResultHelper; var _idx = __webpack_require__(17); var _idx2 = _interopRequireDefault(_idx); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function SearchResultHelper(urlHelper) { var generateFundLink = urlHelper.generateFundLink, generateStockLinkBySymbol = urlHelper.generateStockLinkBySymbol, driverPageLink = urlHelper.driverPageLink, newsDetailLink = urlHelper.newsDetailLink; var generateTradeSearchLink = function generateTradeSearchLink(item, type) { var link = void 0; switch (type) { case 'FUND': link = generateFundLink(item.displayNameLocal || item.displayName, item.cnyesId); break; case 'QUOTE': default: link = generateStockLinkBySymbol(item.symbol, item.type); } return link; }; var hotTagsResponseHelper = function hotTagsResponseHelper(data) { var items = (0, _idx2.default)(data, function (_) { return _.data.items; }); if (!items) return []; return items.map(function (tag) { return { tagName: tag.tag, link: null }; }); }; var hotDriverDataHelper = function hotDriverDataHelper(items) { if (!items) return []; return items.map(function (driver) { return { avatarPicture: driver.avatarPicture, driverId: driver.driverId, driverName: driver.nickname, return1year: driver.return1year || driver.return1Year, link: driverPageLink + '/' + driver.driverId }; }); }; var hotDriversResponseHelper = function hotDriversResponseHelper(data) { var items = (0, _idx2.default)(data, function (_) { return _.data.items; }); if (!items) return []; return hotDriverDataHelper(items); }; var hotTradesResponseHelper = function hotTradesResponseHelper(data) { var items = (0, _idx2.default)(data, function (_) { return _.data.data; }); if (!items) return []; return items.map(function (trade) { if (trade.market === 'FUND' && !trade.cnyesId) { // eslint-disable-next-line no-param-reassign trade.cnyesId = trade.symbol; } return { symbol: trade.symbol, displayName: trade.displayName, link: generateTradeSearchLink(trade, trade.market) }; }); }; var recentSearchDataHelper = function recentSearchDataHelper(keywordArr) { if (!keywordArr) return []; return keywordArr.reverse().map(function (keyword) { return { keyword: keyword }; }); }; var searchTradesResponseHelper = function searchTradesResponseHelper(data) { var items = (0, _idx2.default)(data, function (_) { return _.data.data; }); var quoteFunds = []; var news = []; var oldDrivers = []; if (!items) { return null; } quoteFunds = items.quoteFunds && items.quoteFunds.map(function (trade) { return { objectType: trade.objectType, market: trade.market, code: trade.code || trade.displayNameLocal, type: trade.type, mtype: trade.mtype, symbol: trade.symbol, chName: trade.chName, enName: trade.enName || trade.displayName, exchange: trade.exchange, link: generateTradeSearchLink(trade, trade.objectType) }; }); news = items.news && items.news.map(function (n) { return { newsId: n.newsId, title: n.title, summary: n.summary, publishAt: n.publishAt, link: newsDetailLink + '/' + n.newsId }; }); oldDrivers = hotDriverDataHelper(items.oldDrivers); return { quoteFunds: quoteFunds, news: news, oldDrivers: oldDrivers }; }; return { generateTradeSearchLink: generateTradeSearchLink, hotTagsResponseHelper: hotTagsResponseHelper, hotDriverDataHelper: hotDriverDataHelper, hotDriversResponseHelper: hotDriversResponseHelper, hotTradesResponseHelper: hotTradesResponseHelper, recentSearchDataHelper: recentSearchDataHelper, searchTradesResponseHelper: searchTradesResponseHelper }; } /***/ }), /***/ 63: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = debounce; function debounce(fn, threshold) { var interval = void 0; return function callback() { var _arguments = arguments; clearTimeout(interval); interval = setTimeout(function () { interval = null; // eslint-disable-next-line fn(_arguments); }, threshold); }; } /***/ }), /***/ 64: /***/ (function(module, exports) { // removed by extract-text-webpack-plugin module.exports = {"wrapperWidth":"1200px","screenSizeSm":"321px","screenSizeMd":"768px","screenSizeMl":"990px","screenSizeLg":"1024px","screenSizeXl":"1200px","screenSizeXXl":"1360px","mobileScreenWidth":"768px","anue-search":"_1sdVe","anue-new-search":"_3V1QF","search-result":"_2wJdR","display":"_1CLsH","input-wrapper":"_2cmuD","active":"_2mEwc"}; /***/ }), /***/ 66: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable import/prefer-default-export */ var compare = exports.compare = function compare(oldVer, newVer) { var oldParts = oldVer.split('.'); var newParts = newVer.split('.'); for (var i = 0; i < newParts.length; i++) { var a = +newParts[i]; // parse int var b = +oldParts[i]; // parse int if (a > b) return true; if (a < b) return false; } return false; }; /***/ }), /***/ 7: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AnueLink; /* eslint-disable no-useless-escape */ /** * Get the corresponding url. * @param {*} env prod | stage | beta | int */ function AnueLink(env) { var isProd = env === 'prod'; var isApiProd = env !== 'int' && env !== 'beta'; var cnyesBaseUrl = isProd ? 'cnyes.com' : env + '.cnyes.cool'; var cookieDomain = isProd ? '.cnyes.com' : '.cnyes.cool'; var apiBaseUrl = isApiProd ? 'cnyes.com' : env + '.cnyes.cool'; var wwwChannelLink = 'https://www.' + cnyesBaseUrl; var newsChannelLink = 'https://news.' + cnyesBaseUrl; var cryptoChannelLink = 'https://crypto.' + cnyesBaseUrl; var fundChannelLink = 'https://fund.' + cnyesBaseUrl; var stockTalk = 'https://stock.' + cnyesBaseUrl; var globalStockTalk = 'https://global-stock.' + cnyesBaseUrl; var invest = 'https://invest.' + cnyesBaseUrl; var desktopFundsSearch = fundChannelLink + '/search'; var mobileFundsSearch = invest + '/funds/search'; var loginLink = 'https://login.' + cnyesBaseUrl; var anueHaoLink = 'https://hao.cnyes.com'; var forexChannelLink = wwwChannelLink + '/forex/reuters'; var forexCrossListLink = wwwChannelLink + '/forex/crosslist'; var cryptoChannelBTCLink = cryptoChannelLink + '/BTC/24h'; var wdStockNewsLink = newsChannelLink + '/news/cat/wd_stock'; var forexNewsLink = newsChannelLink + '/news/cat/forex'; var cryptoNewsLink = newsChannelLink + '/news/cat/bc_virtual'; var bcNewsLink = newsChannelLink + '/news/cat/bc'; var fundNewsLink = newsChannelLink + '/news/cat/fund'; var twStockNewsLink = newsChannelLink + '/news/cat/tw_stock'; var usStockNewsLink = newsChannelLink + '/news/cat/us_stock'; var cnStockNewsLink = newsChannelLink + '/news/cat/cn_stock'; var topTopicsNewsLink = newsChannelLink + '/news/cat/topTopics'; var magNewsLink = newsChannelLink + '/news/cat/mag'; var projectNewsLink = newsChannelLink + '/projects/cat/all'; var driverFundDetailLink = invest + '/funds/detail'; var driverPageLink = invest + '/drivers'; var driverSearchLink = invest + '/drivers/search'; var forexDetailPageLink = invest + '/forex/detail'; var newsTagLink = newsChannelLink + '/tag'; var newsDetailLink = newsChannelLink + '/news/id'; var hotTagsApiUrl = 'https://api.' + apiBaseUrl + '/api/v1/news/recommend/tags'; var hotDriversApiUrl = 'https://driver.api.' + apiBaseUrl + '/driver/api/v1/drivers?order=1y&sort=desc&page=1&size=3'; var hotTradesApiUrl = 'https://ws.api.' + apiBaseUrl + '/ws/api/v1/ga/pageViewHot'; // limit the categories for first version var anueSearchAllCategory = 'TW,FUND,US,CC,INDEX,FUTURE,ETF,FX,EOD,CHK'; var anueSearchAllApiUrl = 'https://ess.api.' + apiBaseUrl + '/ess/api/v1/siteSearch/main?category=' + anueSearchAllCategory + '&limit=5&q='; var logoWallApiUrl = 'https://api.' + apiBaseUrl + '/media/api/v1/logowalls/'; // .net link only have prod env var archiveStockQLink = 'https://money.cnyes.com/archive/StockQ.aspx'; var wdStockChannelLink = 'https://www.cnyes.com/global/IndexImmediateQuotedPrice/'; var archiveUSStock = 'https://www.cnyes.com/archive/usastock/'; var archiveTWStock = 'https://www.cnyes.com/archive/twstock'; var archiveTWGStock = 'https://www.cnyes.com/archive/presh'; var newsAppDownloadLink = 'https://www.cnyes.com/mobile/index_app.htm'; var feedbackLink = 'https://docs.google.com/forms/d/1QvhPSjjG-vrxPUvpzGd2uYmFiIs1cMu1luFAwSonm6U/viewform'; var feedbackEntryUrlId = '1831304503'; var toUrlParams = function toUrlParams(params) { return Object.keys(params).filter(function (key) { return !!params[key]; }).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); }).join('&'); }; /** * https://cnyesrd.atlassian.net/wiki/spaces/PS/pages/637993057 * symbol = [market]:[xxx]:[mType] * objectType: 主要用來區分是否為基金商品 *exception: /ga/pageViewHot 回覆在 market 欄位而非 objectType * type: 無法從 symbol 區分出來的細分類, 如 ETF */ return { generateStockLinkBySymbol: function generateStockLinkBySymbol(symbol, type) { var symbolSplit = String(symbol).split(':'); if (!symbolSplit || symbolSplit.length < 2) { return ''; } // GF:symbol:FUTURES, TWF:symbol:FUTURES if ((symbolSplit[0] === 'TWF' || symbolSplit[0] === 'GF') && symbolSplit[2] === 'FUTURES') { return invest + '/futures/' + symbolSplit[0] + '/' + symbolSplit[1]; } // GI:symbol:INDEX, TWS:symbol:INDEX if ((symbolSplit[0] === 'TWS' || symbolSplit[0] === 'GI') && symbolSplit[2] === 'INDEX') { return invest + '/index/' + symbolSplit[0] + '/' + symbolSplit[1]; } if ((symbolSplit[0] === 'TWS' || symbolSplit[0] === 'TWG') && symbolSplit[2] === 'STOCK') { return invest + '/twstock/' + symbolSplit[0] + '/' + symbolSplit[1]; } if ((symbolSplit[0] === 'CNS' || symbolSplit[0] === 'HKS') && symbolSplit[2] === 'STOCK') { return globalStockTalk + '/market/' + symbol; } // USS:symbol:STOCK,type:ETF // [ANUE-5745] 美股ETF內頁資訊較美股少,ETF/US直接改都去美股內頁usstock // e.g. /ETF/US/detail/QQQ to /usstock/detail/QQQ if (symbolSplit[0] === 'USS' && symbolSplit[2] === 'STOCK') { if (type && type === 'ETF') { return invest + '/usstock/detail/' + symbolSplit[1]; } return invest + '/usstock/detail/' + symbolSplit[1]; } if (symbolSplit[0] === 'FX') { return forexDetailPageLink + '/' + symbolSplit[1] + '/overview'; } if (symbolSplit[0] === 'EOD') { return invest + '/eod/detail/' + symbolSplit[1]; } if (symbolSplit[0] === 'CC' && symbolSplit[1]) { var crypto = symbolSplit[1]; return cryptoChannelLink + '/' + crypto; } return ''; }, generateFundLink: function generateFundLink(displayName, cnyesId) { var fundName = ('' + displayName).replace(/<(?:.|\n)*?>/gm, ''); return driverFundDetailLink + '/' + encodeURIComponent(fundName) + '/' + cnyesId; }, generateFundSaleLink: function generateFundSaleLink(_ref) { var forSale = _ref.forSale, displayNameLocal = _ref.displayNameLocal, cnyesId = _ref.cnyesId, source = _ref.source, medium = _ref.medium, campaign = _ref.campaign; var paramList = []; var params = { utm_source: source, utm_medium: medium, utm_campaign: campaign }; Object.keys(params).forEach(function (p) { if (params[p]) { paramList.push(p + '=' + params[p]); } }); if (forSale === 1) { var url = invest + '/funds/order/' + encodeURIComponent(displayNameLocal) + '/' + cnyesId; if (paramList.length > 0) { url += '?' + paramList.join('&'); } return url; } return ''; }, generateETFLink: function generateETFLink(symbol) { var symbolSplit = String(symbol).split(':'); if (!symbolSplit || symbolSplit.length < 2) { return ''; } if (symbolSplit[0] === 'TWS' && symbolSplit[2] === 'STOCK') { return stockTalk + '/market/TWS:' + symbolSplit[1] + ':' + symbolSplit[2]; } // [ANUE-5745] 美股ETF內頁資訊較美股少,ETF/US直接改都去美股內頁usstock // e.g. /etf/us/detail/QQQ to /usstock/detail/QQQ if (symbolSplit[0] === 'USS' && symbolSplit[2] === 'STOCK') { return invest + '/usstock/detail/' + symbolSplit[1]; } return ''; }, generateSearchResultLink: function generateSearchResultLink(_ref2) { var keyword = _ref2.keyword, backLink = _ref2.backLink; var params = { keyword: keyword, aink: backLink }; return wwwChannelLink + '/search/all?' + toUrlParams(params); }, generateSearchMoreLink: function generateSearchMoreLink(_ref3) { var title = _ref3.title, keyword = _ref3.keyword; var params = { keyword: keyword }; var type = title === '行情' ? 'quote' : 'news'; return wwwChannelLink + '/search/' + type + '?' + toUrlParams(params); }, generateForexLink: function generateForexLink(symbol) { var symbolSplit = String(symbol).split(':'); if (!symbolSplit || symbolSplit.length < 2) { return ''; } if (symbolSplit[0] === 'FX') { return forexDetailPageLink + '/' + symbolSplit[1] + '/overview'; } return ''; }, generateFeedbackLink: function generateFeedbackLink() { var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var entryUrl = url; if (!url && typeof window !== 'undefined') { entryUrl = window.location.href; } return feedbackLink + '?usp=pp_url&entry.' + feedbackEntryUrlId + '=' + encodeURIComponent(entryUrl); }, generateLink: function generateLink() { var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var domain = cnyesBaseUrl; return url.replace('{{host}}', domain); }, // compareIsTheSameLink: (original = '/') => { // if (original == null || original === '') return false; // const originalURL = new URL(original); // const originalPath = originalURL ? originalURL.pathname : '/'; // const currentPath = typeof window !== 'undefined' ? window.location.pathname : '/'; // return originalPath.toString() === currentPath.toString(); // }, cnyesBaseUrl: cnyesBaseUrl, cookieDomain: cookieDomain, wwwChannelLink: wwwChannelLink, newsChannelLink: newsChannelLink, cryptoChannelLink: cryptoChannelLink, fundChannelLink: fundChannelLink, stockTalk: stockTalk, globalStockTalk: globalStockTalk, invest: invest, forexChannelLink: forexChannelLink, forexCrossListLink: forexCrossListLink, cryptoChannelBTCLink: cryptoChannelBTCLink, wdStockNewsLink: wdStockNewsLink, forexNewsLink: forexNewsLink, cryptoNewsLink: cryptoNewsLink, bcNewsLink: bcNewsLink, fundNewsLink: fundNewsLink, twStockNewsLink: twStockNewsLink, usStockNewsLink: usStockNewsLink, cnStockNewsLink: cnStockNewsLink, wdStockChannelLink: wdStockChannelLink, topTopicsNewsLink: topTopicsNewsLink, magNewsLink: magNewsLink, projectNewsLink: projectNewsLink, archiveStockQLink: archiveStockQLink, archiveUSStock: archiveUSStock, archiveTWStock: archiveTWStock, archiveTWGStock: archiveTWGStock, driverFundDetailLink: driverFundDetailLink, driverPageLink: driverPageLink, driverSearchLink: driverSearchLink, newsTagLink: newsTagLink, newsDetailLink: newsDetailLink, hotTagsApiUrl: hotTagsApiUrl, hotDriversApiUrl: hotDriversApiUrl, anueSearchAllApiUrl: anueSearchAllApiUrl, hotTradesApiUrl: hotTradesApiUrl, toUrlParams: toUrlParams, desktopFundsSearch: desktopFundsSearch, mobileFundsSearch: mobileFundsSearch, anueSearchAllCategory: anueSearchAllCategory, newsAppDownloadLink: newsAppDownloadLink, feedbackLink: feedbackLink, anueHaoLink: anueHaoLink, logoWallApiUrl: logoWallApiUrl, loginLink: loginLink }; } /***/ }), /***/ 82: /***/ (function(module, exports) { // removed by extract-text-webpack-plugin module.exports = {"wrapperWidth":"1200px","screenSizeSm":"321px","screenSizeMd":"768px","screenSizeMl":"990px","screenSizeLg":"1024px","screenSizeXl":"1200px","screenSizeXXl":"1360px"}; /***/ }), /***/ 83: /***/ (function(module, exports) { module.exports = "https://sfiles.cnyes.cool/fe-common/8d7ec61e/19c0ad3fc8f84d49d494708243cd664c.svg"; /***/ }), /***/ 84: /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable import/prefer-default-export */ var FIXED_HEADER_NONE = exports.FIXED_HEADER_NONE = 'FIXED_HEADER_NONE'; var FIXED_HEADER_FULL = exports.FIXED_HEADER_FULL = 'FIXED_HEADER_FULL'; var DISTANCE_OVER_HEADER = exports.DISTANCE_OVER_HEADER = 0; var DIRECTION = exports.DIRECTION = { RIGHT: 'right', LEFT: 'left' }; /***/ }), /***/ 85: /***/ (function(module, exports) { // removed by extract-text-webpack-plugin module.exports = {"wrapperWidth":"1200px","screenSizeSm":"321px","screenSizeMd":"768px","screenSizeMl":"990px","screenSizeLg":"1024px","screenSizeXl":"1200px","screenSizeXXl":"1360px","anue-navigator-wrapper":"_3nhjS","main-header":"_1bCtE","channel-bar":"_3mQGn","channel-items":"_17iYW","channel-item-sub-menu":"_2OAQZ","search-bar":"_zqLHb","info-bar":"_zPOSK","switch-options":"_3cE7f","icon":"_3Sads","channel-item-sub-menus":"_24TsG","channel-item-sub-menu-second":"_3PL09","logo":"_1qDww","mask":"_3sJWu","moveLeft":"_27u8n","moveRight":"_2Tuk2","unfold-search-animation-1200":"_1OJNA","expansion":"_1zoUI","collapse-search-animation-1200":"_1FlMp","unfold-search-animation-1024":"_28rUj","collapse-search-animation-1024":"_3VhnJ","unfold-search-animation-768":"_bP614","collapse-search-animation-768":"_1sHvW","no-link":"_yMFjw","new":"_3bf2a","active":"_pyF9U","current":"_o2fzP","hide":"_33qTU","highlight":"_2XVFQ","channel-item-sub-menu-arrow":"_2BwsZ","left":"_39Ecp","right":"_2keIi","expand":"_17IWc","switch-button":"_1JOJ7","sticky":"_3tAML","react-fragment":"__jZ92"}; /***/ }) /******/ }); });