问:
Display: none on Deck.gl React component causes huge performance issue
EDIT: This issue is specific to this setup. Please use the code from here if you wish to help. Thanks!

I am using Deck.gl with react to display a map. When I try to hide the map with display: none it starts to freeze up my whole computer. I have worked around this by using visibility: collapse instead, but I would like to know why display: none causes this problem.

The console starts perpetually filling up with warnings:

```<code>luma: Device pixel ratio clamped context.js:202:84
Error: WebGL warning: clear: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawElements: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once) bundle.min.js line 15214 > eval:32:191695
Error: WebGL warning: drawingBufferWidth: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 15214 > eval:32:60490
Source map error: Error: NetworkError when attempting to fetch resource.
Resource URL: webpack:///./node_modules/@luma.gl/webgl/dist/esm/context/context.js?
Source Map URL: context.js.map
Error: WebGL warning: drawingBufferWidth: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18246x6954 was too large, but resize to 9123x3477 succeeded. bundle.min.js line 15214 > eval:32:60490
</code>```

I took a look at performance with the React profiler:
React Profiler output

In every commit that takes longer to process than normal, it shows AutoSizer taking a long time to render.

Reproducing the problem:

Node version: v10.16.3

Run create-react-app my-app.

Copy code below.

Apply display: none on any element containing the map, including the elements rendered by Deck.gl.

WARNING: Reproducing this issue takes up a lot of resources and might crash your computer!

The code

index.tsx

```<code>import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import 'mapbox-gl/dist/mapbox-gl.css';
import {GeoMapChart} from './GeoMapChart'

ReactDOM.render(<GeoMapChart />, document.getElementById('root'));

serviceWorker.unregister();
</code>```

GeoMapChart.tsx

```<code>import * as React from 'react';
import DeckGL from '@deck.gl/react';
import {StaticMap} from 'react-map-gl';

export function GeoMapChart() {

    const [viewState, setViewState] = React.useState(INITIAL_VIEW_STATE);

    return (
            <DeckGL viewState={viewState} controller={true} width={'100%'} height={'100%'} layers={[]}  onViewStateChange={
                ({viewState, oldViewState, interactionState}) => {
                    const newViewState = {...viewState};
                    setViewState(newViewState);
                }}>

                <StaticMap width={'100%'} height={'100%'} mapStyle={MAPBOX_BASE_LAYER}/>
            </DeckGL>
    )
}

const MAX_ZOOM = 19;
const MIN_ZOOM = 2;
const INITIAL_VIEW_STATE = {
    latitude: 37.77,
    longitude: -122.42,
    zoom: 5,
    bearing: 0,
    pitch: 0,
    maxZoom: MAX_ZOOM,
    minZoom: MIN_ZOOM
};

const BASEMAP_TILE_SOURCE_NAME = 'simple-tiles';
const BASEMAP_TILE_SERVERS = [
    'http://a.tile.osm.org/{z}/{x}/{y}.png',
    'http://b.tile.osm.org/{z}/{x}/{y}.png',
    'http://c.tile.osm.org/{z}/{x}/{y}.png',
    //'//stamen-tiles-a.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
    //'//stamen-tiles-b.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
    //'//stamen-tiles-c.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
];
const BASEMAP_ATTRIBUTION = `Map tiles by <a href="http://stamen.com">Stamen Design</a>, under
<a href="http://creativecommons.org/licenses/by/3.0"> CC BY 3.0</a>. Data by
<a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">
ODbL</a>.`.replace(/\n/gm, '');
const COMMON_LAYER_CONFIG = {
    minZoom: 2,
    maxZoom: 17, // New data will be requested until this level
    pixelScaleFactor: 8,
    tileSize: 256,
    isTms: true,
    topoLayerClusteringSwithLevel: 13,
    maxVisibleRasterLayers: 3,
    maxConfigurableLayers: 26,
};
const MAP_CONFIG = {
    MIN_ZOOM: 1,
    MAX_ZOOM: 18,
    INITIAL_ZOOM: 9,
    SHOW_TILE_BOUNDARIES: false,
    DRAG_ROTATE: false,
    ZOOM_NO_DATA: 2,
    SEARCH_DEFAULT_ZOOM: 14,
};

const MAPBOX_BASE_LAYER = {
    version: 8,
    sources: {
        [BASEMAP_TILE_SOURCE_NAME]: {
            type: 'raster',
            tiles: BASEMAP_TILE_SERVERS,
            tileSize: COMMON_LAYER_CONFIG.tileSize,
            attribution: BASEMAP_ATTRIBUTION,
        }
    },
    layers: [
        {
            id: BASEMAP_TILE_SOURCE_NAME,
            type: 'raster',
            source: BASEMAP_TILE_SOURCE_NAME,
            minzoom: MAP_CONFIG.MIN_ZOOM,
            maxzoom: MAP_CONFIG.MAX_ZOOM,
        }
    ],
};
</code>```

index.html

```<code><!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />

  <title>Deck.gl performance issue</title>
</head>

<body>
  <div id="root"></div>

</body>

</html>
</code>```

package.json

```<code>{
    "name": "NOT_PUBLIC",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@types/lodash": "^4.14.149",
        "@types/node": "13.1.8",
        "@types/react": "16.8.3",
        "@types/react-dom": "16.0.11",
        "@types/react-router-dom": "5.1.3",
        "axios": "0.19.0",
        "deck.gl": "7.3.7",
        "jss": "10.0.0-alpha.3",
        "lodash": "4.17.15",
        "react": "16.8.5",
        "react-dom": "16.8.5",
        "react-map-gl": "5.1.3",
        "react-router-dom": "5.1.2"
    },
    "scripts": {
        "start": "webpack-dev-server --mode development --hot",
        "build": "webpack --mode production",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": "react-app"
    },
    "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
    ],
    "devDependencies": {
        "@danmarshall/deckgl-typings": "^3.4.3",
        "@types/react-map-gl": "^5.0.3",
        "@types/uuid": "^3.4.6",
        "awesome-typescript-loader": "^5.2.1",
        "babel-jest": "^23.6.0",
        "css-loader": "^2.1.0",
        "enzyme": "^3.8.0",
        "enzyme-adapter-react-16": "^1.7.1",
        "enzyme-to-json": "^3.3.5",
        "html-loader": "^0.5.5",
        "html-webpack-plugin": "^3.2.0",
        "jest": "^23.6.0",
        "node-sass": "^4.11.0",
        "react-scripts": "2.1.2",
        "react-test-renderer": "^16.7.0",
        "sass-loader": "^7.1.0",
        "source-map-loader": "^0.2.4",
        "style-loader": "^0.23.1",
        "typescript": "3.7.4",
        "webpack": "^4.28.1",
        "webpack-cli": "^3.2.1",
        "webpack-dev-server": "^3.1.14"
    },
    "jest": {
        "snapshotSerializers": [
            "enzyme-to-json/serializer"
        ]
    }
}
</code>```

webpack.config.js

```<code>const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.tsx',
  devServer: {
    port: 9012,
    historyApiFallback: true,
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },
  output: {
    path: path.join(__dirname, '/dist'),
    filename: 'bundle.min.js'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'awesome-typescript-loader'
      },
      {
        test:/\.css$/,
        use:['style-loader','css-loader', 'sass-loader']
      },
      {
        test: /\.scss$/,
        use:["css-loader",'sass-loader']
      },
      {
        test: /\.(?:png|jpg|svg)$/,
        loader: 'url-loader'

    },
    {
      test: /\.(ico|jpeg|gif|eot|otf|webp|ttf|woff|woff2)(\?.*)?$/,
      loader: 'file-loader'

  },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: '!!html-loader!./src/index.html'
    }),

  ]
}
</code>```

tsconfig.json

```<code>{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": false,
        "module": "commonjs",
        "target": "es6",
        "jsx": "react",
        // "suppressImplicitAnyIndexErrors": true,
    },
    "include": [
        "./src/**/*"
    ]
}
</code>```

答:
Upgrading all my dependencies to the latest version solved my issue.
Sorry but I couldn't be bothered to pinpoint which package was causing the issue. Maybe I'll spend the time on it later in life.
Also on typescript@3.7.5 compiler option skipLibCheck: true is needed.

Node version 12.16.0

package.json:

```<code>{
    "name": "NOT_PUBLIC",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@eds/vanilla": "3.4.0",
        "@types/lodash": "^4.14.149",
        "@types/node": "13.7.4",
        "@types/react": "16.9.20",
        "@types/react-dom": "16.9.5",
        "@types/react-redux": "7.1.7",
        "@types/react-router-dom": "5.1.3",
        "axios": "0.19.2",
        "d3": "5.15.0",
        "deck.gl": "^8.0.15",
        "dragula": "3.7.2",
        "immer": "5.3.6",
        "jss": "10.0.4",
        "lodash": "4.17.15",
        "react": "16.12.0",
        "react-dom": "16.12.0",
        "react-map-gl": "5.2.3",
        "react-redux": "7.2.0",
        "react-router-dom": "5.1.2",
        "redux": "4.0.5",
        "redux-thunk": "2.3.0"
    },
    "scripts": {
        "start": "webpack-dev-server --mode development --open --hot",
        "build": "webpack --mode production",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": "react-app"
    },
    "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
    ],
    "devDependencies": {
        "@types/react-map-gl": "^5.2.0",
        "@types/uuid": "^3.4.7",
        "awesome-typescript-loader": "^5.2.1",
        "babel-jest": "^25.1.0",
        "css-loader": "^3.4.2",
        "enzyme": "^3.11.0",
        "enzyme-adapter-react-16": "^1.15.2",
        "enzyme-to-json": "^3.4.4",
        "html-loader": "^0.5.5",
        "html-webpack-plugin": "^3.2.0",
        "jest": "^25.1.0",
        "node-sass": "^4.13.1",
        "react-scripts": "3.4.0",
        "react-test-renderer": "^16.12.0",
        "sass-loader": "^8.0.2",
        "source-map-loader": "^0.2.4",
        "style-loader": "^1.1.3",
        "typescript": "3.7.5",
        "webpack": "^4.41.6",
        "webpack-cli": "^3.3.11",
        "webpack-dev-server": "^3.10.3"
    },
    "jest": {
        "snapshotSerializers": [
            "enzyme-to-json/serializer"
        ]
    }
}
</code>```

Body:
EDIT: This issue is specific to this setup. Please use the code from here if you wish to help. Thanks!

I am using Deck.gl with react to display a map. When I try to hide the map with display: none it starts to freeze up my whole computer. I have worked around this by using visibility: collapse instead, but I would like to know why display: none causes this problem.

The console starts perpetually filling up with warnings:

luma: Device pixel ratio clamped context.js:202:84
Error: WebGL warning: clear: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawElements: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once) bundle.min.js line 15214 > eval:32:191695
Error: WebGL warning: drawingBufferWidth: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 15214 > eval:32:60490
Source map error: Error: NetworkError when attempting to fetch resource.
Resource URL: webpack:///./node_modules/@luma.gl/webgl/dist/esm/context/context.js?
Source Map URL: context.js.map
Error: WebGL warning: drawingBufferWidth: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18246x6954 was too large, but resize to 9123x3477 succeeded. bundle.min.js line 15214 > eval:32:60490

I took a look at performance with the React profiler:
React Profiler output

In every commit that takes longer to process than normal, it shows AutoSizer taking a long time to render.

Reproducing the problem:

Node version: v10.16.3

Run create-react-app my-app.

Copy code below.

Apply display: none on any element containing the map, including the elements rendered by Deck.gl.

WARNING: Reproducing this issue takes up a lot of resources and might crash your computer!

The code

index.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import 'mapbox-gl/dist/mapbox-gl.css';
import {GeoMapChart} from './GeoMapChart'

ReactDOM.render(<GeoMapChart />, document.getElementById('root'));

serviceWorker.unregister();

GeoMapChart.tsx

import * as React from 'react';
import DeckGL from '@deck.gl/react';
import {StaticMap} from 'react-map-gl';

export function GeoMapChart() {

    const [viewState, setViewState] = React.useState(INITIAL_VIEW_STATE);

    return (
            <DeckGL viewState={viewState} controller={true} width={'100%'} height={'100%'} layers={[]}  onViewStateChange={
                ({viewState, oldViewState, interactionState}) => {
                    const newViewState = {...viewState};
                    setViewState(newViewState);
                }}>

                <StaticMap width={'100%'} height={'100%'} mapStyle={MAPBOX_BASE_LAYER}/>
            </DeckGL>
    )
}

const MAX_ZOOM = 19;
const MIN_ZOOM = 2;
const INITIAL_VIEW_STATE = {
    latitude: 37.77,
    longitude: -122.42,
    zoom: 5,
    bearing: 0,
    pitch: 0,
    maxZoom: MAX_ZOOM,
    minZoom: MIN_ZOOM
};

const BASEMAP_TILE_SOURCE_NAME = 'simple-tiles';
const BASEMAP_TILE_SERVERS = [
    'http://a.tile.osm.org/{z}/{x}/{y}.png',
    'http://b.tile.osm.org/{z}/{x}/{y}.png',
    'http://c.tile.osm.org/{z}/{x}/{y}.png',
    //'//stamen-tiles-a.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
    //'//stamen-tiles-b.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
    //'//stamen-tiles-c.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
];
const BASEMAP_ATTRIBUTION = `Map tiles by Stamen Design, under
 CC BY 3.0. Data by
OpenStreetMap, under
ODbL.`.replace(/\n/gm, '');
const COMMON_LAYER_CONFIG = {
    minZoom: 2,
    maxZoom: 17, // New data will be requested until this level
    pixelScaleFactor: 8,
    tileSize: 256,
    isTms: true,
    topoLayerClusteringSwithLevel: 13,
    maxVisibleRasterLayers: 3,
    maxConfigurableLayers: 26,
};
const MAP_CONFIG = {
    MIN_ZOOM: 1,
    MAX_ZOOM: 18,
    INITIAL_ZOOM: 9,
    SHOW_TILE_BOUNDARIES: false,
    DRAG_ROTATE: false,
    ZOOM_NO_DATA: 2,
    SEARCH_DEFAULT_ZOOM: 14,
};

const MAPBOX_BASE_LAYER = {
    version: 8,
    sources: {
        [BASEMAP_TILE_SOURCE_NAME]: {
            type: 'raster',
            tiles: BASEMAP_TILE_SERVERS,
            tileSize: COMMON_LAYER_CONFIG.tileSize,
            attribution: BASEMAP_ATTRIBUTION,
        }
    },
    layers: [
        {
            id: BASEMAP_TILE_SOURCE_NAME,
            type: 'raster',
            source: BASEMAP_TILE_SOURCE_NAME,
            minzoom: MAP_CONFIG.MIN_ZOOM,
            maxzoom: MAP_CONFIG.MAX_ZOOM,
        }
    ],
};

index.html

<!DOCTYPE html>

  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />

  <title>Deck.gl performance issue</title>

package.json

{
    "name": "NOT_PUBLIC",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@types/lodash": "^4.14.149",
        "@types/node": "13.1.8",
        "@types/react": "16.8.3",
        "@types/react-dom": "16.0.11",
        "@types/react-router-dom": "5.1.3",
        "axios": "0.19.0",
        "deck.gl": "7.3.7",
        "jss": "10.0.0-alpha.3",
        "lodash": "4.17.15",
        "react": "16.8.5",
        "react-dom": "16.8.5",
        "react-map-gl": "5.1.3",
        "react-router-dom": "5.1.2"
    },
    "scripts": {
        "start": "webpack-dev-server --mode development --hot",
        "build": "webpack --mode production",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": "react-app"
    },
    "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
    ],
    "devDependencies": {
        "@danmarshall/deckgl-typings": "^3.4.3",
        "@types/react-map-gl": "^5.0.3",
        "@types/uuid": "^3.4.6",
        "awesome-typescript-loader": "^5.2.1",
        "babel-jest": "^23.6.0",
        "css-loader": "^2.1.0",
        "enzyme": "^3.8.0",
        "enzyme-adapter-react-16": "^1.7.1",
        "enzyme-to-json": "^3.3.5",
        "html-loader": "^0.5.5",
        "html-webpack-plugin": "^3.2.0",
        "jest": "^23.6.0",
        "node-sass": "^4.11.0",
        "react-scripts": "2.1.2",
        "react-test-renderer": "^16.7.0",
        "sass-loader": "^7.1.0",
        "source-map-loader": "^0.2.4",
        "style-loader": "^0.23.1",
        "typescript": "3.7.4",
        "webpack": "^4.28.1",
        "webpack-cli": "^3.2.1",
        "webpack-dev-server": "^3.1.14"
    },
    "jest": {
        "snapshotSerializers": [
            "enzyme-to-json/serializer"
        ]
    }
}

webpack.config.js

const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.tsx',
  devServer: {
    port: 9012,
    historyApiFallback: true,
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },
  output: {
    path: path.join(__dirname, '/dist'),
    filename: 'bundle.min.js'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'awesome-typescript-loader'
      },
      {
        test:/\.css$/,
        use:['style-loader','css-loader', 'sass-loader']
      },
      {
        test: /\.scss$/,
        use:["css-loader",'sass-loader']
      },
      {
        test: /\.(?:png|jpg|svg)$/,
        loader: 'url-loader'

    },
    {
      test: /\.(ico|jpeg|gif|eot|otf|webp|ttf|woff|woff2)(\?.*)?$/,
      loader: 'file-loader'

  },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: '!!html-loader!./src/index.html'
    }),

  ]
}

tsconfig.json

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": false,
        "module": "commonjs",
        "target": "es6",
        "jsx": "react",
        // "suppressImplicitAnyIndexErrors": true,
    },
    "include": [
        "./src/**/*"
    ]
}

Body:
Upgrading all my dependencies to the latest version solved my issue.
Sorry but I couldn't be bothered to pinpoint which package was causing the issue. Maybe I'll spend the time on it later in life.
Also on typescript@3.7.5 compiler option skipLibCheck: true is needed.

Node version 12.16.0

package.json:

{
    "name": "NOT_PUBLIC",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@eds/vanilla": "3.4.0",
        "@types/lodash": "^4.14.149",
        "@types/node": "13.7.4",
        "@types/react": "16.9.20",
        "@types/react-dom": "16.9.5",
        "@types/react-redux": "7.1.7",
        "@types/react-router-dom": "5.1.3",
        "axios": "0.19.2",
        "d3": "5.15.0",
        "deck.gl": "^8.0.15",
        "dragula": "3.7.2",
        "immer": "5.3.6",
        "jss": "10.0.4",
        "lodash": "4.17.15",
        "react": "16.12.0",
        "react-dom": "16.12.0",
        "react-map-gl": "5.2.3",
        "react-redux": "7.2.0",
        "react-router-dom": "5.1.2",
        "redux": "4.0.5",
        "redux-thunk": "2.3.0"
    },
    "scripts": {
        "start": "webpack-dev-server --mode development --open --hot",
        "build": "webpack --mode production",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": "react-app"
    },
    "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
    ],
    "devDependencies": {
        "@types/react-map-gl": "^5.2.0",
        "@types/uuid": "^3.4.7",
        "awesome-typescript-loader": "^5.2.1",
        "babel-jest": "^25.1.0",
        "css-loader": "^3.4.2",
        "enzyme": "^3.11.0",
        "enzyme-adapter-react-16": "^1.15.2",
        "enzyme-to-json": "^3.4.4",
        "html-loader": "^0.5.5",
        "html-webpack-plugin": "^3.2.0",
        "jest": "^25.1.0",
        "node-sass": "^4.13.1",
        "react-scripts": "3.4.0",
        "react-test-renderer": "^16.12.0",
        "sass-loader": "^8.0.2",
        "source-map-loader": "^0.2.4",
        "style-loader": "^1.1.3",
        "typescript": "3.7.5",
        "webpack": "^4.41.6",
        "webpack-cli": "^3.3.11",
        "webpack-dev-server": "^3.10.3"
    },
    "jest": {
        "snapshotSerializers": [
            "enzyme-to-json/serializer"
        ]
    }
}


来源: stackexchange

问:
Calling a function within ReReplace function
Is there a way to write in coldfusion something like:

```<code>< cfset ReReplace(value,"&#\d+;","#decodeHtmlEntity(\1)#", "all") >
</code>```

Thanks a lot

答:
Have you tried simply using URLDecode(value)?

Or if you specifically only want to decode the numeric html codes, then

```<code><cfset myVar = ReReplace(value,"(&##[\d+];)",urlDecode('\1'), "all") >
</code>```

will do what you need.

To explain what it is doing :

I've replaced the PHP decodeHTMLEntity function with the CFML version.

If you want to use back references you need to specify the capture groups in the regex pattern.

you need to double up those #'s to escape them, otherwise CF will be looking for a close # that it will never find.

ContentLicense: CC BY-SA 3.0

Body:
Is there a way to write in coldfusion something like:

< cfset ReReplace(value,"&#\d+;","#decodeHtmlEntity(\1)#", "all") >

Thanks a lot

Body:
Have you tried simply using URLDecode(value)?

Or if you specifically only want to decode the numeric html codes, then

<cfset myVar = ReReplace(value,"(&##[\d+];)",urlDecode('\1'), "all") >

will do what you need.

To explain what it is doing :

I've replaced the PHP decodeHTMLEntity function with the CFML version.

If you want to use back references you need to specify the capture groups in the regex pattern.

you need to double up those #'s to escape them, otherwise CF will be looking for a close # that it will never find.


问:
How can I use multiple refs for an array of elements with hooks?
As far as I understood I can use refs for a single element like this:

const { useRef, useState, useEffect } = React;

const App = () => {
  const elRef = useRef();
  const [elWidth, setElWidth] = useState();

  useEffect(() => {
    setElWidth(elRef.current.offsetWidth);
  }, []);

  return (

        Width is: {elWidth}

  );
};

ReactDOM.render(
  <App />,
  document.getElementById("root")
);```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div></code>```

How can I implement this for an array of elements? Obviously not like that: (I knew it even I did not try it:)

const { useRef, useState, useEffect } = React;

const App = () => {
  const elRef = useRef();
  const [elWidth, setElWidth] = useState();

  useEffect(() => {
    setElWidth(elRef.current.offsetWidth);
  }, []);

  return (

      {[1, 2, 3].map(el => (
        <div ref={elRef} style={{ width: `${el * 100}px` }}>
          Width is: {elWidth}

      ))}

  );
};

ReactDOM.render(
  <App />,
  document.getElementById("root")
);```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div></code>```

I have seen this and hence this. But, I'm still confused about how to implement that suggestion for this simple case.

答:
We can't use state because we need the ref to be available before the render method is called.
We can't call useRef an arbitrary number of times, but we can call it once:

Assuming arr is a prop with the array of things:

```<code>const refs = useRef([]);
// free any refs that we're not using anymore
refs.current = refs.current.slice(0, arr.length);
// initialize any new refs
for (let step = refs.current.length; step < arr.length; step++) {
    refs.current[step] = createRef();
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
As far as I understood I can use refs for a single element like this:

const { useRef, useState, useEffect } = React;

const App = () => {
  const elRef = useRef();
  const [elWidth, setElWidth] = useState();

  useEffect(() => {
    setElWidth(elRef.current.offsetWidth);
  }, []);

  return (

        Width is: {elWidth}

  );
};

ReactDOM.render(
  <App />,
  document.getElementById("root")
);

How can I implement this for an array of elements? Obviously not like that: (I knew it even I did not try it:)

const { useRef, useState, useEffect } = React;

const App = () => {
  const elRef = useRef();
  const [elWidth, setElWidth] = useState();

  useEffect(() => {
    setElWidth(elRef.current.offsetWidth);
  }, []);

  return (

      {[1, 2, 3].map(el => (
        <div ref={elRef} style={{ width: `${el * 100}px` }}>
          Width is: {elWidth}

      ))}

  );
};

ReactDOM.render(
  <App />,
  document.getElementById("root")
);

I have seen this and hence this. But, I'm still confused about how to implement that suggestion for this simple case.

Body:
We can't use state because we need the ref to be available before the render method is called.
We can't call useRef an arbitrary number of times, but we can call it once:

Assuming arr is a prop with the array of things:

const refs = useRef([]);
// free any refs that we're not using anymore
refs.current = refs.current.slice(0, arr.length);
// initialize any new refs
for (let step = refs.current.length; step < arr.length; step++) {
    refs.current[step] = createRef();
}


问:
Webpack not serving css file
I am fairly new to webpack 4 and struggling to get my head around why I can not serve my css files.
I essentially start my dev server using
npm start
I can then serve my javascript using
http://localhost:9000/js/app.bundle.js
but when i try doing the same for my css file it gives a 404
http://localhost:9000/css/app.css

My complete config is

```<code>const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode:  'development',
  entry: {
    app: ['./src/js/main.js','./src/scss/style.scss'],
    admin: ['./src/js/admin.js', './src/scss/admin.scss']

  },
  output: {
    filename: 'js/[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [

      {
        test: /\.(sa|sc|c)ss$/,
        use: [
            MiniCssExtractPlugin.loader,
          {
          loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
            options: {
              plugins: function () {
                return [
                  require('autoprefixer')
                ];
              }
            }
          },
          {
          loader: 'sass-loader',
          }
        ]
      },
      {
        test: /\.(svg|jpg|png|gif)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'assets/img/[name].[ext]',
          }
        }
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: {
          loader: 'url-loader',
          options: {
            name: 'assets/fonts/[name].[ext]',
          }
        }
      },
    ],
  },

  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: "/css/[name].css",
    }),
    new CopyPlugin([
      {from: './src/img', to: 'img'},
      {from: './src/icon', to: 'icon'},
      {from: './src/fonts', to: 'fonts'},
    ]),
  ],
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    port: 9000
  },
};
</code>```

when i run npm run build i see the files in there correct subdirectories
i.e.

```<code>/dist/css/app.css
/dist/css/admin.css
/dist/js/app.bundle.js
/dist/js/admin.bundle.js

</code>```

If I take the CleanWebpackPlugin()  out run npm run build then npm start the file is served, but I do not understand why it can not serve this when it runs in memory.

It also works make the following change

```<code>new MiniCssExtractPlugin({
      filename: "/css/[name].css",  Remove this
      filename: "[name].css"  Add this
    }),
</code>```

However then I do not get the subdirectory structure I want.

答:
So it looks like everything i had is ok i just needed to remove the /

eg

```<code>new MiniCssExtractPlugin({
      filename: "/css/[name].css",  replace this line
      filename: "css/[name].css"  with this line
    }),
</code>```

Title: Webpack not serving css file

Body:
I am fairly new to webpack 4 and struggling to get my head around why I can not serve my css files.
I essentially start my dev server using
npm start
I can then serve my javascript using
http://localhost:9000/js/app.bundle.js
but when i try doing the same for my css file it gives a 404
http://localhost:9000/css/app.css

My complete config is

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode:  'development',
  entry: {
    app: ['./src/js/main.js','./src/scss/style.scss'],
    admin: ['./src/js/admin.js', './src/scss/admin.scss']

  },
  output: {
    filename: 'js/[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [

      {
        test: /\.(sa|sc|c)ss$/,
        use: [
            MiniCssExtractPlugin.loader,
          {
          loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
            options: {
              plugins: function () {
                return [
                  require('autoprefixer')
                ];
              }
            }
          },
          {
          loader: 'sass-loader',
          }
        ]
      },
      {
        test: /\.(svg|jpg|png|gif)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'assets/img/[name].[ext]',
          }
        }
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: {
          loader: 'url-loader',
          options: {
            name: 'assets/fonts/[name].[ext]',
          }
        }
      },
    ],
  },

  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: "/css/[name].css",
    }),
    new CopyPlugin([
      {from: './src/img', to: 'img'},
      {from: './src/icon', to: 'icon'},
      {from: './src/fonts', to: 'fonts'},
    ]),
  ],
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    port: 9000
  },
};

when i run npm run build i see the files in there correct subdirectories
i.e.

/dist/css/app.css
/dist/css/admin.css
/dist/js/app.bundle.js
/dist/js/admin.bundle.js

If I take the CleanWebpackPlugin()  out run npm run build then npm start the file is served, but I do not understand why it can not serve this when it runs in memory.

It also works make the following change

new MiniCssExtractPlugin({
      filename: "/css/[name].css",  Remove this
      filename: "[name].css"  Add this
    }),

However then I do not get the subdirectory structure I want.

Body:
So it looks like everything i had is ok i just needed to remove the /

eg

new MiniCssExtractPlugin({
      filename: "/css/[name].css",  replace this line
      filename: "css/[name].css"  with this line
    }),


问:
TypeError: 'bool' object is not iterable eventhough using another variable
First post ever :)
I know that the if statement returns a Boolean value. But I am not using it to iterate a list, I'm using x. I just want all other variables (type = IntVar) to be set to 0 except for i which has to remain 1. Thanks in advance, my first ever time here...

```<code>def clear():
    variables=[var, var0, var1, var2, var3, var4,var5,var6, var7, var8]
    for i in variables:
        if i.get() == 1:
            x = variables.index(i)
            for y in variables in range(0,x-1) and range(x,9):
                y.set(0)
</code>```

My original code is 500 lines long so not ideal to post it full here.
Full traceback:

```<code>Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Thomas Jence\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "G:\Mrs. Odewale\Computing coursework\options.py", line 187, in clear9
    for y in variables in range(0,x-1) and range(x,9):
TypeError: 'bool' object is not iterable
</code>```

答:
```<code>for y in variables in range(0,x-1) and range(x,9):
</code>```

is interpreted as (split up with parentheses and by line to make groupings clear):

```<code>for y in (
          variables in (
                        range(0, x-1) and range(x,9)
                                                    )
                                                     ):
</code>```

The innermost parentheses then determine if range(0, x-1) is empty or not, and use it if it's not, and use range(x,9) if it is. The next layer then tests if variables is in the "winning" range. Then you effectively do:

```<code>for y in False:
</code>```

because variables is a list, so it's definitely not in any range.

I don't know what you're trying to do, but you need to reconsider that line.

Body:
First post ever :)
I know that the if statement returns a Boolean value. But I am not using it to iterate a list, I'm using x. I just want all other variables (type = IntVar) to be set to 0 except for i which has to remain 1. Thanks in advance, my first ever time here...

def clear():
    variables=[var, var0, var1, var2, var3, var4,var5,var6, var7, var8]
    for i in variables:
        if i.get() == 1:
            x = variables.index(i)
            for y in variables in range(0,x-1) and range(x,9):
                y.set(0)

My original code is 500 lines long so not ideal to post it full here.
Full traceback:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Thomas Jence\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "G:\Mrs. Odewale\Computing coursework\options.py", line 187, in clear9
    for y in variables in range(0,x-1) and range(x,9):
TypeError: 'bool' object is not iterable

Body:
for y in variables in range(0,x-1) and range(x,9):

is interpreted as (split up with parentheses and by line to make groupings clear):

for y in (
          variables in (
                        range(0, x-1) and range(x,9)
                                                    )
                                                     ):

The innermost parentheses then determine if range(0, x-1) is empty or not, and use it if it's not, and use range(x,9) if it is. The next layer then tests if variables is in the "winning" range. Then you effectively do:

for y in False:

because variables is a list, so it's definitely not in any range.

I don't know what you're trying to do, but you need to reconsider that line.


问:
How to copy multiple (specific) selected sheets to new workbook
I have searched for hours but with no luck.
I want to copy multiple sheets from a file to a new workbook.  Not all sheets but just the ones that I have selected. My selection could be different each time I perform this exercise. The scenario is that I have a master reporting file with say 25 sheets each with a different report. I want to open the file and select reports to send to a user.  I will select say 5 specific reports e.g. sheets 1,10,15,18 and 20 I then want to copy them to a new workbook so I can email them to my customer. Ideally I would paste them into new workbook at values only to remove all formulas and links from reports being sent to customer. The following code works great for a single sheet:

```<code>ThisWorkbook.ActiveSheet.Copy _
Before:=Workbooks.Add.Worksheets(1)
</code>```

What I would like to do is to change the word 'ActiveSheet' to 'SelectedSheets' and keep all else the same.  This does not work. Am I missing something simple?

I have tried to:
a: change code as above
b: record a macro copying selected sheets and using the code (but it provides code for specific sheet names such as sheet2 and sheet3.  This will not work as I need to it be code that works with whatever sheets I select.
c: searched internet for hours. Generally provides as advice on working with all sheets, working with a pre-defined set of selected sheets, working with pre-defined selection using arrays, code to select sheets based on common characteristics e.g. select all sheets with name "R1" in it.

答:
Since there are two distinct requirements here (Copy selected sheets only, and copy values only), I'd suggest looping over the selected sheets, and copy the data one sheet at a time. You may want to copy formatting as well

Some notes:

Since you want to act on Selected sheets, using ActiveWindow is appropriate here

As you want only values in the destination sheet, I'd avoid a simple Copy Paste as that would copy Formulas, Conditional Formatting, Named Range definitions, any VBA in the sheet module and potentially other stuff too, which you would have to then remove.  Paste only what you want to.

Don't forget the Sheet Names

Column Widths can be PasteSpecial'd as well if required

There is no xlPasteRowHeights so if that's required you'll need to code it longhand

```<code>Sub Demo()
    Dim wb As Workbook
    Dim wks As Sheets
    Dim wsDest As Worksheet
    Dim wsSrc As Worksheet
    Dim rng As Range

    ' reference selected sheets
    Set wks = ActiveWindow.SelectedSheets
    'deselect multiple sheets so Copy will work
    wks.Item(1).Select

    'create new book with one sheet
    Set wb = Application.Workbooks.Add(xlWBATWorksheet)

    'reference that sheet
    Set wsDest = wb.Worksheets(1)

    ' loop selected sheets
    For Each wsSrc In wks
        'rename sheet
        wsDest.Name = wsSrc.Name
        ' copy values and formats
        Set rng = wsSrc.UsedRange
        rng.Copy
        With wsDest.Cells(rng.Row, rng.Column) ' Used Range might not start at A1
            .PasteSpecial xlPasteValues
            .PasteSpecial xlPasteFormats      ' optional, if required
            .PasteSpecial xlPasteColumnWidths ' optional, if required
            .Cells.FormatConditions.Delete    ' optional, if CF is not required
        End With

        ' add another sheet if required
        If Not wsSrc Is wks.Item(wks.Count) Then
            Set wsDest = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
        End If
    Next

    wb.SaveAs "C:\Your\Path\To\YourFileName.xlsx", xlWorkbookDefault ' or other format
End Sub
</code>```

Body:
I have searched for hours but with no luck.
I want to copy multiple sheets from a file to a new workbook.  Not all sheets but just the ones that I have selected. My selection could be different each time I perform this exercise. The scenario is that I have a master reporting file with say 25 sheets each with a different report. I want to open the file and select reports to send to a user.  I will select say 5 specific reports e.g. sheets 1,10,15,18 and 20 I then want to copy them to a new workbook so I can email them to my customer. Ideally I would paste them into new workbook at values only to remove all formulas and links from reports being sent to customer. The following code works great for a single sheet:

ThisWorkbook.ActiveSheet.Copy _
Before:=Workbooks.Add.Worksheets(1)

What I would like to do is to change the word 'ActiveSheet' to 'SelectedSheets' and keep all else the same.  This does not work. Am I missing something simple?

I have tried to:
a: change code as above
b: record a macro copying selected sheets and using the code (but it provides code for specific sheet names such as sheet2 and sheet3.  This will not work as I need to it be code that works with whatever sheets I select.
c: searched internet for hours. Generally provides as advice on working with all sheets, working with a pre-defined set of selected sheets, working with pre-defined selection using arrays, code to select sheets based on common characteristics e.g. select all sheets with name "R1" in it.

Body:
Since there are two distinct requirements here (Copy selected sheets only, and copy values only), I'd suggest looping over the selected sheets, and copy the data one sheet at a time. You may want to copy formatting as well

Some notes:

Since you want to act on Selected sheets, using ActiveWindow is appropriate here

As you want only values in the destination sheet, I'd avoid a simple Copy Paste as that would copy Formulas, Conditional Formatting, Named Range definitions, any VBA in the sheet module and potentially other stuff too, which you would have to then remove.  Paste only what you want to.

Don't forget the Sheet Names

Column Widths can be PasteSpecial'd as well if required

There is no xlPasteRowHeights so if that's required you'll need to code it longhand

Sub Demo()
    Dim wb As Workbook
    Dim wks As Sheets
    Dim wsDest As Worksheet
    Dim wsSrc As Worksheet
    Dim rng As Range

    ' reference selected sheets
    Set wks = ActiveWindow.SelectedSheets
    'deselect multiple sheets so Copy will work
    wks.Item(1).Select

    'create new book with one sheet
    Set wb = Application.Workbooks.Add(xlWBATWorksheet)

    'reference that sheet
    Set wsDest = wb.Worksheets(1)

    ' loop selected sheets
    For Each wsSrc In wks
        'rename sheet
        wsDest.Name = wsSrc.Name
        ' copy values and formats
        Set rng = wsSrc.UsedRange
        rng.Copy
        With wsDest.Cells(rng.Row, rng.Column) ' Used Range might not start at A1
            .PasteSpecial xlPasteValues
            .PasteSpecial xlPasteFormats      ' optional, if required
            .PasteSpecial xlPasteColumnWidths ' optional, if required
            .Cells.FormatConditions.Delete    ' optional, if CF is not required
        End With

        ' add another sheet if required
        If Not wsSrc Is wks.Item(wks.Count) Then
            Set wsDest = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
        End If
    Next

    wb.SaveAs "C:\Your\Path\To\YourFileName.xlsx", xlWorkbookDefault ' or other format
End Sub


问:
Text to Speech API (AVSpeechSynthesisVoice) broken in iOS 13 GM
Update

I installed the iOS 13 GM on a different device, and did not encounter this issue. So I'm no longer sure if this is specific to the iOS 13 GM, or something about the way I installed it. On the first device (an iPhone X), I did an upgrade (via the "Option Key + Check for Update Button" in iTunes). On the second device (an iPhone SE), I did a full restore. Not sure yet what caused it to get into this state.

Original Question

AVSpeechSynthesisVoice.speechVoices() reports that there are no voices available when I run it on my device with the iOS 13 GM. And indeed, when I try to load a voice using AVSpeechSynthesisVoice(identifier:) it always returns nil. It works in the simulator. I don't believe this was an issue with the previous betas, and it seems to work in iOS 13.1 beta 2 and 3.

Has anyone encountered this, and figured out any sort of workaround? I don't see any documentation of an intentional change to this behavior, so I suspect this is a bug. I intend to file a radar. But that won't help me for the impending release of iOS 13.

This behavior is reproducible in a newly created Single View project, with the following trivial viewDidLoad function added to the included view controller.

```<code>override func viewDidLoad() {
    super.viewDidLoad()

    let voices = AVSpeechSynthesisVoice.speechVoices()
    print("Voice Count: \(voices.count)")
}
</code>```

The output is very long:

```<code>2019-09-11 10:43:09.370992-0400 SpeechTest[1617:412065] Creating client/daemon connection: C591307C-313E-4B5F-91A8-184B7E662819
2019-09-11 10:43:09.396250-0400 SpeechTest[1617:412065] Got the query meta data reply for: com.apple.MobileAsset.MacinTalkVoiceAssets, response: 0
2019-09-11 10:43:09.397519-0400 SpeechTest[1617:412065] Consumed extension
2019-09-11 10:43:09.401982-0400 SpeechTest[1617:412065] Got the query meta data reply for: com.apple.MobileAsset.MacinTalkVoiceAssets, response: 0
Voice Count: 0
2019-09-11 10:43:09.435890-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.445269-0400 SpeechTest[1617:412066] Consumed extension
2019-09-11 10:43:09.468849-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.499573-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.520244-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.GryphonVoice, response: 0
2019-09-11 10:43:09.545243-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CustomVoice, response: 0
2019-09-11 10:43:09.549941-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CombinedVocalizerVoices, response: 2
2019-09-11 10:43:09.550075-0400 SpeechTest[1617:412066] [AXTTSCommon] Error running custom voice query XML not present
2019-09-11 10:43:09.569114-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.599459-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.630763-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.650161-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.GryphonVoice, response: 0
2019-09-11 10:43:09.666885-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CustomVoice, response: 0
2019-09-11 10:43:09.671279-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CombinedVocalizerVoices, response: 2
2019-09-11 10:43:09.671412-0400 SpeechTest[1617:412066] [AXTTSCommon] Error running custom voice query XML not present
...
</code>```

It repeats those last 7 lines 39 times, presumably corresponding to the 39 voices it's supposed to know about.

答:
This didn't crash my app but caused a memory leak every time AVSpeechSynthesizer was declared. I solved this by declaring the AVSpeechSynthesizer as a global variable</p>

```<code>static let synth = AVSpeechSynthesizer()
</code>```

Body:
Update

I installed the iOS 13 GM on a different device, and did not encounter this issue. So I'm no longer sure if this is specific to the iOS 13 GM, or something about the way I installed it. On the first device (an iPhone X), I did an upgrade (via the "Option Key + Check for Update Button" in iTunes). On the second device (an iPhone SE), I did a full restore. Not sure yet what caused it to get into this state.

Original Question

AVSpeechSynthesisVoice.speechVoices() reports that there are no voices available when I run it on my device with the iOS 13 GM. And indeed, when I try to load a voice using AVSpeechSynthesisVoice(identifier:) it always returns nil. It works in the simulator. I don't believe this was an issue with the previous betas, and it seems to work in iOS 13.1 beta 2 and 3.

Has anyone encountered this, and figured out any sort of workaround? I don't see any documentation of an intentional change to this behavior, so I suspect this is a bug. I intend to file a radar. But that won't help me for the impending release of iOS 13.

This behavior is reproducible in a newly created Single View project, with the following trivial viewDidLoad function added to the included view controller.

override func viewDidLoad() {
    super.viewDidLoad()

    let voices = AVSpeechSynthesisVoice.speechVoices()
    print("Voice Count: \(voices.count)")
}

The output is very long:

2019-09-11 10:43:09.370992-0400 SpeechTest[1617:412065] Creating client/daemon connection: C591307C-313E-4B5F-91A8-184B7E662819
2019-09-11 10:43:09.396250-0400 SpeechTest[1617:412065] Got the query meta data reply for: com.apple.MobileAsset.MacinTalkVoiceAssets, response: 0
2019-09-11 10:43:09.397519-0400 SpeechTest[1617:412065] Consumed extension
2019-09-11 10:43:09.401982-0400 SpeechTest[1617:412065] Got the query meta data reply for: com.apple.MobileAsset.MacinTalkVoiceAssets, response: 0
Voice Count: 0
2019-09-11 10:43:09.435890-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.445269-0400 SpeechTest[1617:412066] Consumed extension
2019-09-11 10:43:09.468849-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.499573-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.520244-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.GryphonVoice, response: 0
2019-09-11 10:43:09.545243-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CustomVoice, response: 0
2019-09-11 10:43:09.549941-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CombinedVocalizerVoices, response: 2
2019-09-11 10:43:09.550075-0400 SpeechTest[1617:412066] [AXTTSCommon] Error running custom voice query XML not present
2019-09-11 10:43:09.569114-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.599459-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.630763-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServicesVocalizerVoice, response: 0
2019-09-11 10:43:09.650161-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.GryphonVoice, response: 0
2019-09-11 10:43:09.666885-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CustomVoice, response: 0
2019-09-11 10:43:09.671279-0400 SpeechTest[1617:412066] Got the query meta data reply for: com.apple.MobileAsset.VoiceServices.CombinedVocalizerVoices, response: 2
2019-09-11 10:43:09.671412-0400 SpeechTest[1617:412066] [AXTTSCommon] Error running custom voice query XML not present
...

It repeats those last 7 lines 39 times, presumably corresponding to the 39 voices it's supposed to know about.

Body:
This didn't crash my app but caused a memory leak every time AVSpeechSynthesizer was declared. I solved this by declaring the AVSpeechSynthesizer as a global variable

static let synth = AVSpeechSynthesizer()


问:
How to know which category is clicked on a stacked bar chart in amcharts?
I have a stacked bar chart and assigned a click listener on it to know which item was clicked.

```<code>series.columns.template.events.on("hit", function(ev) {
    console.log(ev.target);
}, this);
</code>```

but in the corresponding target.dataItem json i am unable to find any field that has the category clicked. Only the year and the numerical value is available. How to get the actual legend categories?

Codepen implementation

答:
You can access the series information through target.dataItem.component. This will contain the series information used to populate the legend, such as the name.

```<code>series.columns.template.events.on("hit", function(ev) {
    console.log(ev.target.dataItem.component.name);
}, this);
</code>```

Demo below:

// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end

// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);

// Add data
chart.data = [{
  "year": "2016",
  "europe": 2.5,
  "namerica": 2.5,
  "asia": 2.1,
  "lamerica": 0.3,
  "meast": 0.2,
  "africa": 0.1
}, {
  "year": "2017",
  "europe": 2.6,
  "namerica": 2.7,
  "asia": 2.2,
  "lamerica": 0.3,
  "meast": 0.3,
  "africa": 0.1
}, {
  "year": "2018",
  "europe": 2.8,
  "namerica": 2.9,
  "asia": 2.4,
  "lamerica": 0.3,
  "meast": 0.3,
  "africa": 0.1
}];

chart.legend = new am4charts.Legend();
chart.legend.position = "right";

// Create axes
var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "year";
categoryAxis.renderer.grid.template.opacity = 0;

var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
valueAxis.min = 0;
valueAxis.renderer.grid.template.opacity = 0;
valueAxis.renderer.ticks.template.strokeOpacity = 0.5;
valueAxis.renderer.ticks.template.stroke = am4core.color("#495C43");
valueAxis.renderer.ticks.template.length = 10;
valueAxis.renderer.line.strokeOpacity = 0.5;
valueAxis.renderer.baseGrid.disabled = true;
valueAxis.renderer.minGridDistance = 40;

// Create series
function createSeries(field, name) {
  var series = chart.series.push(new am4charts.ColumnSeries());
  series.dataFields.valueX = field;
  series.dataFields.categoryY = "year";
  series.stacked = true;
  series.name = name;

  var labelBullet = series.bullets.push(new am4charts.LabelBullet());
  labelBullet.locationX = 0.5;
  labelBullet.label.text = "{valueX}";
  labelBullet.label.fill = am4core.color("#fff");

   series.columns.template.events.on("hit", function(ev) {
        console.log(ev.target.dataItem.component.name);
    }, this);
}

createSeries("europe", "Europe");
createSeries("namerica", "North America");
createSeries("asia", "Asia");
createSeries("lamerica", "Latin America");
createSeries("meast", "Middle East");
createSeries("africa", "Africa");```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#chartdiv {
  width: 100%;
  height: 500px;
}</code>```

```

Body:
I have a stacked bar chart and assigned a click listener on it to know which item was clicked.

series.columns.template.events.on("hit", function(ev) {
    console.log(ev.target);
}, this);

but in the corresponding target.dataItem json i am unable to find any field that has the category clicked. Only the year and the numerical value is available. How to get the actual legend categories?

Codepen implementation

Body:
You can access the series information through target.dataItem.component. This will contain the series information used to populate the legend, such as the name.

series.columns.template.events.on("hit", function(ev) {
    console.log(ev.target.dataItem.component.name);
}, this);

Demo below:

// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end

// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);

// Add data
chart.data = [{
  "year": "2016",
  "europe": 2.5,
  "namerica": 2.5,
  "asia": 2.1,
  "lamerica": 0.3,
  "meast": 0.2,
  "africa": 0.1
}, {
  "year": "2017",
  "europe": 2.6,
  "namerica": 2.7,
  "asia": 2.2,
  "lamerica": 0.3,
  "meast": 0.3,
  "africa": 0.1
}, {
  "year": "2018",
  "europe": 2.8,
  "namerica": 2.9,
  "asia": 2.4,
  "lamerica": 0.3,
  "meast": 0.3,
  "africa": 0.1
}];

chart.legend = new am4charts.Legend();
chart.legend.position = "right";

// Create axes
var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "year";
categoryAxis.renderer.grid.template.opacity = 0;

var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
valueAxis.min = 0;
valueAxis.renderer.grid.template.opacity = 0;
valueAxis.renderer.ticks.template.strokeOpacity = 0.5;
valueAxis.renderer.ticks.template.stroke = am4core.color("#495C43");
valueAxis.renderer.ticks.template.length = 10;
valueAxis.renderer.line.strokeOpacity = 0.5;
valueAxis.renderer.baseGrid.disabled = true;
valueAxis.renderer.minGridDistance = 40;

// Create series
function createSeries(field, name) {
  var series = chart.series.push(new am4charts.ColumnSeries());
  series.dataFields.valueX = field;
  series.dataFields.categoryY = "year";
  series.stacked = true;
  series.name = name;

  var labelBullet = series.bullets.push(new am4charts.LabelBullet());
  labelBullet.locationX = 0.5;
  labelBullet.label.text = "{valueX}";
  labelBullet.label.fill = am4core.color("#fff");

   series.columns.template.events.on("hit", function(ev) {
        console.log(ev.target.dataItem.component.name);
    }, this);
}

createSeries("europe", "Europe");
createSeries("namerica", "North America");
createSeries("asia", "Asia");
createSeries("lamerica", "Latin America");
createSeries("meast", "Middle East");
createSeries("africa", "Africa");

#chartdiv {
  width: 100%;
  height: 500px;
}

<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>


问:
nginx as PHP service entrypoint

Question

The main question here - how to serve static assets included with /vendor/ prefix in URL with separate nginx config location?

Desired behavior is - nginx as root entrypoint that apply SSL certificate, then it serve static assets and all other requests are handled by php interpreter.

答:
You can achieve what you want with a simple config like:

```<code>location / {
    # This is cool because no PHP is touched for static content.
    # include the "?$args" part so non-default permalinks doesn't break when using query string
    try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php-fpm/example.com.sock;
}
</code>```

But if you want to get ultimate performance, see this article on try_files drawbacks and how to configure NGINX without it.

Title: nginx as PHP service entrypoint

Body:
You can achieve what you want with a simple config like:

location / {
    # This is cool because no PHP is touched for static content.
    # include the "?$args" part so non-default permalinks doesn't break when using query string
    try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php-fpm/example.com.sock;
}

But if you want to get ultimate performance, see this article on try_files drawbacks and how to configure NGINX without it.


问:
Recyclerview not updating in coroutine
hi I'm getting information from web with jsoup and coroutine and I want to show data in recyclerview
All the information is well received but the RecyclerView does not show anything and the view is not updated

```<code>fun myCoroutine(): ArrayList<DataModel> {
        val listx = arrayListOf<DataModel>()

        GlobalScope.launch { // launch new coroutine in background and continue
            Log.d("asdasdasd", "start")
            var doc: Document = Jsoup.connect("http://5743.zanjan.medu.ir").timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
            val table: Elements = doc.select("table[class=\"table table-striped table-hover\"]")
            for (myTable in table) {
                val rows: Elements = myTable.select("tr")
                for (i in 1 until rows.size) {
                    val row: Element = rows.get(i)
                    val cols: Elements = row.select("td")
                    val href: Elements = row.select("a")
                    val strhref: String = href.attr("href")
                    listx.add(DataModel(cols.get(2).text(),strhref))
                    Log.d("asdasf",cols.get(2).text())
                }
            }
        }
        return listx
}

 private fun getData() {
        itemsData = ArrayList()

        itemsData = myCoroutine()
        adapter.notifyDataSetChanged()
        adapter = RVAdapter(itemsData)
    }
</code>```

and this is oncreate

```<code>var itemsData = ArrayList<DataModel>()

        adapter = RVAdapter(itemsData)
        val llm = LinearLayoutManager(this)

        itemsrv.setHasFixedSize(true)
        itemsrv.layoutManager = llm
        getData()
        itemsrv.adapter = adapter
</code>```

答: This code has numerous bugs (getData, for instance, never sets the adapter onto the RecyclerView), but the biggest issue is that you're not actually waiting for listx to be populated - you're returning it immediately before it's populated.  You need to either move the population of the adapter to the coroutine and run that part on the UI thread dispatcher, or use a callback, or dispatch it to the UI thread.  Launching a coroutine and returning immediately doesn't make the data get populated when something tries to use it.

Title: Recyclerview not updating in coroutine

Body:
hi I'm getting information from web with jsoup and coroutine and I want to show data in recyclerview
All the information is well received but the RecyclerView does not show anything and the view is not updated

fun myCoroutine(): ArrayList<DataModel> {
        val listx = arrayListOf<DataModel>()

        GlobalScope.launch { // launch new coroutine in background and continue
            Log.d("asdasdasd", "start")
            var doc: Document = Jsoup.connect("http://5743.zanjan.medu.ir").timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
            val table: Elements = doc.select("table[class=\"table table-striped table-hover\"]")
            for (myTable in table) {
                val rows: Elements = myTable.select("tr")
                for (i in 1 until rows.size) {
                    val row: Element = rows.get(i)
                    val cols: Elements = row.select("td")
                    val href: Elements = row.select("a")
                    val strhref: String = href.attr("href")
                    listx.add(DataModel(cols.get(2).text(),strhref))
                    Log.d("asdasf",cols.get(2).text())
                }
            }
        }
        return listx
}

 private fun getData() {
        itemsData = ArrayList()

        itemsData = myCoroutine()
        adapter.notifyDataSetChanged()
        adapter = RVAdapter(itemsData)
    }

and this is oncreate

var itemsData = ArrayList<DataModel>()

        adapter = RVAdapter(itemsData)
        val llm = LinearLayoutManager(this)

        itemsrv.setHasFixedSize(true)
        itemsrv.layoutManager = llm
        getData()
        itemsrv.adapter = adapter


问:
Using luigi.LocalTarget with PdfPages in python3
The below code snippet worked fine for python2, but does not work for python3. This code snippet is intended to allow for a luigi workflow to write to a multipage PDF, while still using the LocalTarget context manager that allows for atomicity.

```<code>import luigi
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

test = luigi.LocalTarget('test.pdf')
with test.open('wb') as fh, PdfPages(fh) as outf:
    plt = plt.plot([1, 2, 3], [4, 5, 6])
</code>```

This works in python2, but in python3 leads to the error:

```<code>---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-ba62e5b716d2> in <module>
----> 1 with test.open('wb') as fh, PdfPages(fh) as outf:
      2     plt = plt.plot([1, 2, 3], [4, 5, 6])

~/miniconda3/envs/cat3.7/lib/python3.7/site-packages/matplotlib/backends/backend_pdf.py in __init__(self, filename, keep_empty, metadata)
   2386
   2387         """
-> 2388         self._file = PdfFile(filename, metadata=metadata)
   2389         self.keep_empty = keep_empty
   2390

~/miniconda3/envs/cat3.7/lib/python3.7/site-packages/matplotlib/backends/backend_pdf.py in __init__(self, filename, metadata)
    445         self.fh = fh
    446         self.currentstream = None  # stream object to write to, if any
--> 447         fh.write(b"%PDF-1.4\n")    # 1.4 is the first version to have alpha
    448         # Output some eight-bit chars as a comment so various utilities
    449         # recognize the file as binary by looking at the first few

TypeError: write() argument must be str, not bytes
</code>```

How can I retain this atomic functionality in python3?

答:
Sorry, I know this isn't the answer you're looking for, but I found this line in the Luigi repository in the definition of LocalTarget:

```<code>def open(self, mode='r'):
    rwmode = mode.replace('b', '').replace('t', '')
    ...
</code>```

https://github.com/spotify/luigi/blob/master/luigi/local_target.py#L159

It seems that they are not doing byte writing whatsoever (at least in the current version). I would definitely bring this up with them in the Github Issues.

Body:
The below code snippet worked fine for python2, but does not work for python3. This code snippet is intended to allow for a luigi workflow to write to a multipage PDF, while still using the LocalTarget context manager that allows for atomicity.

import luigi
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

test = luigi.LocalTarget('test.pdf')
with test.open('wb') as fh, PdfPages(fh) as outf:
    plt = plt.plot([1, 2, 3], [4, 5, 6])

This works in python2, but in python3 leads to the error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-ba62e5b716d2> in <module>
----> 1 with test.open('wb') as fh, PdfPages(fh) as outf:
      2     plt = plt.plot([1, 2, 3], [4, 5, 6])

~/miniconda3/envs/cat3.7/lib/python3.7/site-packages/matplotlib/backends/backend_pdf.py in __init__(self, filename, keep_empty, metadata)
   2386
   2387         """
-> 2388         self._file = PdfFile(filename, metadata=metadata)
   2389         self.keep_empty = keep_empty
   2390

~/miniconda3/envs/cat3.7/lib/python3.7/site-packages/matplotlib/backends/backend_pdf.py in __init__(self, filename, metadata)
    445         self.fh = fh
    446         self.currentstream = None  # stream object to write to, if any
--> 447         fh.write(b"%PDF-1.4\n")    # 1.4 is the first version to have alpha
    448         # Output some eight-bit chars as a comment so various utilities
    449         # recognize the file as binary by looking at the first few

TypeError: write() argument must be str, not bytes

How can I retain this atomic functionality in python3?

Body:
Sorry, I know this isn't the answer you're looking for, but I found this line in the Luigi repository in the definition of LocalTarget:

def open(self, mode='r'):
    rwmode = mode.replace('b', '').replace('t', '')
    ...

https://github.com/spotify/luigi/blob/master/luigi/local_target.py#L159

It seems that they are not doing byte writing whatsoever (at least in the current version). I would definitely bring this up with them in the Github Issues.


问:
problem using substring to see if a string contain the substring in a batch file
I am a beginner in batch and I have found a problem that I can't resolve.
the batch file is just a little script to make using "youtube-dl" (a command-lines tool for downloading youtube videos) more practical (the folder "youtube-dl.exe" is in is in PATH)

```<code>setlocal enableextensions enabledelayedexpansion
set /p url=url :
set /p qual="quality (360/720 = 1/0) : "
if %qual%==0 (
    set qual=22
) else (
    set qual=18
)
cd C:\Users\theo\Videos
if not %url:&list=%==%url% (
    set /p v="video or playlist ? (V/P)"
    if %v%==P (
        youtube-dl.exe -f %qual% --yes-playlist "%url%"
    ) else (
        youtube-dl.exe -f %qual% --no-playlist "%url%"
    )
) else (
    youtube-dl.exe -f %qual% --no-playlist "%url%"
)
endlocal
cmd /k
</code>```

the cmd window close instantly when the second if statement is reached and I just can't figure what is wrong !

EDIT: the solution of Jeb worked ^^

答:
Always enclose your variables in IF statements.

That's necessary for two reasons.

It avoids syntax errors, when the variable is empty, contains spaces, other delimiters or special characters like &|<>....

It avoids problems with variable modifier syntax, like search/replace !var:search=replace! or substring syntax !var:~<start>,<size>!

Delayed expansion

Your second problem is that percent expansion occurs when a block is parsed before it is even executed.

Therefor if %v%==P ... never expands to the value of the entered v, instead it was expanded probably to nothing.

In blocks (or better, always) use delayed expansion.

```<code>if not "!url:&list=!" == "!url!" (
    set /p v="video or playlist ? (V/P)"
    if "!v!" == "P" (
        youtube-dl.exe -f !qual! --yes-playlist "!url!"
    ) else (
...
</code>```

Body:
I am a beginner in batch and I have found a problem that I can't resolve.
the batch file is just a little script to make using "youtube-dl" (a command-lines tool for downloading youtube videos) more practical (the folder "youtube-dl.exe" is in is in PATH)

setlocal enableextensions enabledelayedexpansion
set /p url=url :
set /p qual="quality (360/720 = 1/0) : "
if %qual%==0 (
    set qual=22
) else (
    set qual=18
)
cd C:\Users\theo\Videos
if not %url:&list=%==%url% (
    set /p v="video or playlist ? (V/P)"
    if %v%==P (
        youtube-dl.exe -f %qual% --yes-playlist "%url%"
    ) else (
        youtube-dl.exe -f %qual% --no-playlist "%url%"
    )
) else (
    youtube-dl.exe -f %qual% --no-playlist "%url%"
)
endlocal
cmd /k

the cmd window close instantly when the second if statement is reached and I just can't figure what is wrong !

EDIT: the solution of Jeb worked ^^

Body:
Always enclose your variables in IF statements.

That's necessary for two reasons.

It avoids syntax errors, when the variable is empty, contains spaces, other delimiters or special characters like &|<>....

It avoids problems with variable modifier syntax, like search/replace !var:search=replace! or substring syntax !var:~<start>,<size>!

Delayed expansion

Your second problem is that percent expansion occurs when a block is parsed before it is even executed.

Therefor if %v%==P ... never expands to the value of the entered v, instead it was expanded probably to nothing.

In blocks (or better, always) use delayed expansion.

if not "!url:&list=!" == "!url!" (
    set /p v="video or playlist ? (V/P)"
    if "!v!" == "P" (
        youtube-dl.exe -f !qual! --yes-playlist "!url!"
    ) else (
...


问:
Why does this function throw an error when using the includes method?
I'm having trouble figuring out why this function throws an error when it reaches the 'includes' method, when console logging whitelist, it shows that it is an array, when i use the includes method, it is throwing an error, cannot read property includes of undefined

```<code>const test = (body, ...whitelists) => {
  const bodies = whitelists.map(({ type = null, whitelist }) => {
    console.log('whitelist ', whitelist)

    const whitelistedBody = Object.entries(body).reduce(
      (newBody, [key, value]) => {
        console.log('KEY ', key)
        console.log('whitelist ', whitelists)

        if (whitelist.includes(key)) {
          newBody[key] = value;
        }

        console.log('newBody ', newBody)
        return newBody;
      },
      {}
    );

    return { type, body: whitelistedBody };
  });

  return (
    bodies.find(({ body }) => Object.keys(body).length) || {
      body: {},
      type: null,
    }
  );
};

test({firstKey: '123'}, ['firstKey']);
</code>```

答:
This can be closed, its actually my fault, I mistakenly passed in an array for the 2nd argument of the function call, where it should be an object.  Also, includes should've been called on whitelist and not whitelists.

In actuality it looks like test({firstKey:'123'}, {whitelist: ['firstKey']})

Body:
I'm having trouble figuring out why this function throws an error when it reaches the 'includes' method, when console logging whitelist, it shows that it is an array, when i use the includes method, it is throwing an error, cannot read property includes of undefined

const test = (body, ...whitelists) => {
  const bodies = whitelists.map(({ type = null, whitelist }) => {
    console.log('whitelist ', whitelist)

    const whitelistedBody = Object.entries(body).reduce(
      (newBody, [key, value]) => {
        console.log('KEY ', key)
        console.log('whitelist ', whitelists)

        if (whitelist.includes(key)) {
          newBody[key] = value;
        }

        console.log('newBody ', newBody)
        return newBody;
      },
      {}
    );

    return { type, body: whitelistedBody };
  });

  return (
    bodies.find(({ body }) => Object.keys(body).length) || {
      body: {},
      type: null,
    }
  );
};

test({firstKey: '123'}, ['firstKey']);


问:
How can I stop my animation from running when stoprun = 1?
I have tried th1.join but that didn't work and I don't know what else to try.

Also, I need it to be a single function

Here is my code:

https://repl.it/@JamesGordon1/JuicyScentedCrypto
(sorry too long to post)

答:
On Linux it works for me only if I add two things

I have to set stoprun = 1 after loop

```<code>c = InKey()
while not c == 27:
    c = InKey()

stoprun = 1 # set after loop
</code>```

I have to use print() in thread - probably it needs \n (or it simply needs this IO function to change running thread)

```<code>if stoprun == 1: # True
    print()  # have to send `\n`
    return
</code>```

I don't know why it is needed but threads in Python doesn't run at the same time - one thread is bloking other thereads - and maybe these elements stops one thread and let to run other thread.

Of course it needs also global stoprun inside stop()

```<code>from threading import Thread

import time
import sys
import os

# --- classes ---

class _GetCh:
    def __init__(self):
      try:
        self.impl = _GetChWindows()
      except ImportError:
        try:
          self.impl = _GetChMacCarbon()
        except ImportError:
          self.impl = _GetChUnix()
    def __call__(self):
      return self.impl()

class _GetChWindows:
    def __init__(self):
      import msvcrt
    def __call__(self):
      import msvcrt
      if msvcrt.kbhit():
        while msvcrt.kbhit():
          ch = msvcrt.getch()
        while ch in b'\x00\xe0':
          msvcrt.getch()
          ch = msvcrt.getch()
        return ord( ch.decode() )
      else:
        return -1

class _GetChMacCarbon:
    def __init__(self):
      import Carbon
      Carbon.Evt
    def __call__(self):
      import Carbon
      if Carbon.Evt.EventAvail(0x0008)[0]==0:
        return ""
      else:
        (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
        return msg & 0x000000FF

class _GetChUnix:
    def __init__(self):
      import tty, sys, termios
    def __call__(self):
      import sys, tty, termios
      fd = sys.stdin.fileno()
      old_settings = termios.tcgetattr(fd)
      try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
      finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
      return ord(ch)

InKey = _GetCh()

# --- main ---

stoprun = 0 # False

def load_animation():
  load_str = "starting your console application "
  ls_len = len(load_str)
  animation = "|/-\\"
  anicount = 0
  i = 0
  while True:
    time.sleep(0.075)
    load_str_list = list(load_str)
    x = ord(load_str_list[i])
    y = 0
    if x != 32 and x != 46:
      if x>90:
        y = x-32
      else:
        y = x + 32
      load_str_list[i]= chr(y)
    res =''
    for j in range(ls_len):
      res = res + load_str_list[j]
    sys.stdout.write("\r"+res + animation[anicount])
    sys.stdout.flush()
    load_str = res
    anicount = (anicount + 1)% 4
    i =(i + 1)% ls_len
    if stoprun == 1: # True
        print()  # have to send `\n`
        return

def stop():
  global stoprun

  print ("Press Esc to exit")

  c = InKey()
  while not c == 27:
    c = InKey()

  stoprun = 1 # have to be after loop

  return

th1 = Thread(target=load_animation)
th1.start()
stop()
#th1.join()
</code>```

Body:
On Linux it works for me only if I add two things

I have to set stoprun = 1 after loop

c = InKey()
while not c == 27:
    c = InKey()

stoprun = 1 # set after loop

I have to use print() in thread - probably it needs \n (or it simply needs this IO function to change running thread)

if stoprun == 1: # True
    print()  # have to send `\n`
    return

I don't know why it is needed but threads in Python doesn't run at the same time - one thread is bloking other thereads - and maybe these elements stops one thread and let to run other thread.

Of course it needs also global stoprun inside stop()

from threading import Thread

import time
import sys
import os

# --- classes ---

class _GetCh:
    def __init__(self):
      try:
        self.impl = _GetChWindows()
      except ImportError:
        try:
          self.impl = _GetChMacCarbon()
        except ImportError:
          self.impl = _GetChUnix()
    def __call__(self):
      return self.impl()

class _GetChWindows:
    def __init__(self):
      import msvcrt
    def __call__(self):
      import msvcrt
      if msvcrt.kbhit():
        while msvcrt.kbhit():
          ch = msvcrt.getch()
        while ch in b'\x00\xe0':
          msvcrt.getch()
          ch = msvcrt.getch()
        return ord( ch.decode() )
      else:
        return -1

class _GetChMacCarbon:
    def __init__(self):
      import Carbon
      Carbon.Evt
    def __call__(self):
      import Carbon
      if Carbon.Evt.EventAvail(0x0008)[0]==0:
        return ""
      else:
        (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
        return msg & 0x000000FF

class _GetChUnix:
    def __init__(self):
      import tty, sys, termios
    def __call__(self):
      import sys, tty, termios
      fd = sys.stdin.fileno()
      old_settings = termios.tcgetattr(fd)
      try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
      finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
      return ord(ch)

InKey = _GetCh()

# --- main ---

stoprun = 0 # False

def load_animation():
  load_str = "starting your console application "
  ls_len = len(load_str)
  animation = "|/-\\"
  anicount = 0
  i = 0
  while True:
    time.sleep(0.075)
    load_str_list = list(load_str)
    x = ord(load_str_list[i])
    y = 0
    if x != 32 and x != 46:
      if x>90:
        y = x-32
      else:
        y = x + 32
      load_str_list[i]= chr(y)
    res =''
    for j in range(ls_len):
      res = res + load_str_list[j]
    sys.stdout.write("\r"+res + animation[anicount])
    sys.stdout.flush()
    load_str = res
    anicount = (anicount + 1)% 4
    i =(i + 1)% ls_len
    if stoprun == 1: # True
        print()  # have to send `\n`
        return

def stop():
  global stoprun

  print ("Press Esc to exit")

  c = InKey()
  while not c == 27:
    c = InKey()

  stoprun = 1 # have to be after loop

  return

th1 = Thread(target=load_animation)
th1.start()
stop()
#th1.join()


问:
git log: parsing who worked on the repository and when
I'd like to create some statistics for open source projects. I'd like to extract the information when a certain person started to work on a git repository and when they finished on it... or the first and the last commit by an author, with a date.

I can manually extract this information from git log output. However, is there a git built-in way, or one-liner shell script that would help me to analyse this.

Find all repo authors from git log

Get their first and last commit date

答:
Here's something to get you started, it will list the authors and how many commits from each

git log --format='%aN <%aE>' | awk '{arr[$0]++} END{for (i in arr){print arr[i], i;}}' | sort -rn


问:
Swift guard statement doesn't return when content is nil
I am writing the code for sign up and register user view. it should check if textfield is nil before it run more code.

guard let a = b else{/* code when b is nil*/return}

I know guard statement should return if b is nil
In my coding b is nil however it didn't return not sure why. Also I printout the content it does look like nil to me. Thank you

Here is the coding

class userLoginView: UIViewController {

```<code>let realm = try! Realm()
var email:String?
var password:String?
var userResult:Results<userInfo>?
var logedin:Bool = false

@IBOutlet weak var emailtextfile: UITextField!
@IBOutlet weak var passwordtextfile: UITextField!
@IBOutlet weak var errorMessage: UILabel!

@IBOutlet weak var fnametext: UITextField!
@IBOutlet weak var lnametext: UITextField!
@IBOutlet weak var emailsigntext: UITextField!
@IBOutlet weak var signpasstext: UITextField!
@IBOutlet weak var passagaintext: UITextField!
@IBOutlet weak var contractortext: UITextField? = nil
@IBOutlet weak var signError: UILabel!

@IBAction func loginButton(_ sender: Any) {

    guard email == emailtextfile!.text,
        password == passwordtextfile!.text else{
            errorMessage?.text = "Please fill in your email and password"
            return
    }
    if checkUser(_email: email ?? "", _pass: password ?? "" ){
        logedin = true
        if let adminView = self.storyboard?.instantiateViewController(withIdentifier: "adminView") as? adminviewController{
            self.navigationController?.pushViewController(adminView, animated: true)
            UserDefaults.standard.set(email, forKey: "email")
            UserDefaults.standard.set(password, forKey: "password")

        }
    }else{
        errorMessage?.text = "Email or Password doesn't match our record"
    }
}

@IBAction func signupsegues(_ sender: UIButton!) {
    if let signupview =  storyboard?.instantiateViewController(withIdentifier: "signupView"){
            navigationController?.pushViewController(signupview, animated: true)
        }
}

@IBAction func signmeup(_ sender: UIButton!) {

    let contractor = contractortext?.text ?? ""
    guard let email = emailsigntext.text else{
        signError?.text = "Please fill in email"
        return}
    guard let fname = fnametext.text else{
        signError?.text = "Please fill in first name"
        return}
    guard let lname = lnametext.text else{
        signError?.text = "Please fill in last name"
        return}
    guard let pass = signpasstext.text else{
        signError?.text = "Please fill password"
        return}
    guard let passagain = passagaintext.text else{
        signError?.text = "Please fill confirm password"
            return
    }

    do{
        print("pass:" + pass)
        print("passagain" + passagain)
        print("email:" + email)
        print("fname:" + fname)
        print("lname:" + lname)

    try signupUser(_email: email, _firstname: fname, _lastName: lname, _password: pass, _comfirmpass: passagain, _contractor: contractor)
    }catch{
        print("some error")
    }
}

@IBAction func forgotButton(_ sender: Any) {
}

override func viewDidLoad() {
    super.viewDidLoad()

    userResult = realm.objects(userInfo.self)

}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
func checkUser(_email:String, _pass:String) -> Bool {
    var checked:Bool = false
    let userrecord = userResult?.filter("userEmail = %@", email!)
    let emailrecord = userrecord?.first?.userEmail
    let passrecord = userrecord?.first?.userPass

    if (email == emailrecord && password == passrecord){
        checked = true
    }else {checked = false}
    return checked
}

func signupUser(_email:String!,_firstname:String!,_lastName:String!,_password:String!,_comfirmpass:String!,_contractor:String?) throws ->Void {

    if _password.elementsEqual(_comfirmpass) {
        let temp = userInfo(value: [_email!,_password!,_firstname!,_lastName!,_contractor ?? "",false])

        try realm.write {
                realm.add(temp)
        }
    }else{
        signError?.text = "password does not match"}

}
</code>```

}

答:
You may be using the pattern incorrectly. You should be using guard let ... to test for non-nil values.

If you have a property

var email: String? // nil

then

guard email == emailtextfile!.text ... will pass if both strings are nil.

To test that both the string is not nil, and that it is equal to your variable, you should be using

```<code>guard let email = emailTextFile?.text, self.email == email, ... else {
    // stuff if email is nil
    return
}
// stuff to do if email has a value and is equal to the value in the textfield
...
</code>```

If you're testing for non-nil, non-empty strings, try guard let email = ..., !email.isEmpty ... else { ... } as suggested in the comments in your question.

Also note there is no need to force-unwrap your textfield.  emailTextField?.text will do.

Just looking at the API, UITextfield.text is @"" by default, which bridges to an empty string in Swift.

Body:
I am writing the code for sign up and register user view. it should check if textfield is nil before it run more code.

guard let a = b else{/* code when b is nil*/return}

I know guard statement should return if b is nil
In my coding b is nil however it didn't return not sure why. Also I printout the content it does look like nil to me. Thank you

Here is the coding

class userLoginView: UIViewController {

let realm = try! Realm()
var email:String?
var password:String?
var userResult:Results<userInfo>?
var logedin:Bool = false

@IBOutlet weak var emailtextfile: UITextField!
@IBOutlet weak var passwordtextfile: UITextField!
@IBOutlet weak var errorMessage: UILabel!

@IBOutlet weak var fnametext: UITextField!
@IBOutlet weak var lnametext: UITextField!
@IBOutlet weak var emailsigntext: UITextField!
@IBOutlet weak var signpasstext: UITextField!
@IBOutlet weak var passagaintext: UITextField!
@IBOutlet weak var contractortext: UITextField? = nil
@IBOutlet weak var signError: UILabel!

@IBAction func loginButton(_ sender: Any) {

    guard email == emailtextfile!.text,
        password == passwordtextfile!.text else{
            errorMessage?.text = "Please fill in your email and password"
            return
    }
    if checkUser(_email: email ?? "", _pass: password ?? "" ){
        logedin = true
        if let adminView = self.storyboard?.instantiateViewController(withIdentifier: "adminView") as? adminviewController{
            self.navigationController?.pushViewController(adminView, animated: true)
            UserDefaults.standard.set(email, forKey: "email")
            UserDefaults.standard.set(password, forKey: "password")

        }
    }else{
        errorMessage?.text = "Email or Password doesn't match our record"
    }
}

@IBAction func signupsegues(_ sender: UIButton!) {
    if let signupview =  storyboard?.instantiateViewController(withIdentifier: "signupView"){
            navigationController?.pushViewController(signupview, animated: true)
        }
}

@IBAction func signmeup(_ sender: UIButton!) {

    let contractor = contractortext?.text ?? ""
    guard let email = emailsigntext.text else{
        signError?.text = "Please fill in email"
        return}
    guard let fname = fnametext.text else{
        signError?.text = "Please fill in first name"
        return}
    guard let lname = lnametext.text else{
        signError?.text = "Please fill in last name"
        return}
    guard let pass = signpasstext.text else{
        signError?.text = "Please fill password"
        return}
    guard let passagain = passagaintext.text else{
        signError?.text = "Please fill confirm password"
            return
    }

    do{
        print("pass:" + pass)
        print("passagain" + passagain)
        print("email:" + email)
        print("fname:" + fname)
        print("lname:" + lname)

    try signupUser(_email: email, _firstname: fname, _lastName: lname, _password: pass, _comfirmpass: passagain, _contractor: contractor)
    }catch{
        print("some error")
    }
}

@IBAction func forgotButton(_ sender: Any) {
}

override func viewDidLoad() {
    super.viewDidLoad()

    userResult = realm.objects(userInfo.self)

}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
func checkUser(_email:String, _pass:String) -> Bool {
    var checked:Bool = false
    let userrecord = userResult?.filter("userEmail = %@", email!)
    let emailrecord = userrecord?.first?.userEmail
    let passrecord = userrecord?.first?.userPass

    if (email == emailrecord && password == passrecord){
        checked = true
    }else {checked = false}
    return checked
}

func signupUser(_email:String!,_firstname:String!,_lastName:String!,_password:String!,_comfirmpass:String!,_contractor:String?) throws ->Void {

    if _password.elementsEqual(_comfirmpass) {
        let temp = userInfo(value: [_email!,_password!,_firstname!,_lastName!,_contractor ?? "",false])

        try realm.write {
                realm.add(temp)
        }
    }else{
        signError?.text = "password does not match"}

}

}

Body:
You may be using the pattern incorrectly. You should be using guard let ... to test for non-nil values.

If you have a property

var email: String? // nil

then

guard email == emailtextfile!.text ... will pass if both strings are nil.

To test that both the string is not nil, and that it is equal to your variable, you should be using

guard let email = emailTextFile?.text, self.email == email, ... else {
    // stuff if email is nil
    return
}
// stuff to do if email has a value and is equal to the value in the textfield
...

If you're testing for non-nil, non-empty strings, try guard let email = ..., !email.isEmpty ... else { ... } as suggested in the comments in your question.

Also note there is no need to force-unwrap your textfield.  emailTextField?.text will do.

Just looking at the API, UITextfield.text is @"" by default, which bridges to an empty string in Swift.