问:
React Router V5 not rendering route when clicking Link, but back and forward buttons work?
What seems like a simple integration with react-router-dom has unexpected results. When I click on links in the sidebar, the Link component works correctly by generating the url ie. localhost:3000/about, but I remain on the previous viewing page. When I click on forward and back buttons, the Route renders the correct component.

I am using Webpack, Typescript but don't think those should be affecting anything.

"react": "^16.12.0",

"react-router-dom": "^5.1.2"

```<code>    //App Component
    import * as React from 'react';
    import { BrowserRouter as Router, Link, Route } from 'react-router-dom';

    import Sidebar from './Sidebar';
    import Home from './Home';
    import About from './About';
    import Work from './Work';
    import Contact from './Contact';
    import Skills from './Skills';

    const App: React.FC = () => {
      return (
        <Router>
          <div className="main-container">
            <Sidebar />
            <Route exact path="/"><Home /></Route>
            <Route path="/about"><About /></Route>
            <Route path="/skills" component={Skills}></Route>
            <Route path="/work" component={Work}></Route>
            <Route path="/contact" component={Contact}></Route>
          </div>
        </Router>
      );
    };
</code>```

```<code>    //Sidebar Component
    import * as React from 'react';
    import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

    import HomeIcon from '@material-ui/icons/Home';
    import FaceIcon from '@material-ui/icons/Face';
    import WorkIcon from '@material-ui/icons/Work';
    import CodeIcon from '@material-ui/icons/Code';
    import MailOutlineIcon from '@material-ui/icons/MailOutline';

    const Sidebar: React.FC = props => {
      return (
        <Router>
          <nav className="nav-container ">
            <Link to={'/'}><HomeIcon /></Link>
            <Link to={'/about'}><FaceIcon /></Link>
            <Link to={'/skills'}><CodeIcon /></Link>
            <Link to={'/work'}><WorkIcon /></Link>
            <Link to={'/contact'}><MailOutlineIcon /></Link>
          </nav>
        </Router>
      );
    };
</code>```

答:
It's because your Sidebar component is wrapped in its own Router. You want your Links and Routes to share the same parent Router. Remove your Sidebar Router and it should fix your problem.</p>

```<code>    const Sidebar: React.FC = props => {
      return (
          <nav className="nav-container ">
            <Link to={'/'}><HomeIcon /></Link>
            <Link to={'/about'}><FaceIcon /></Link>
            <Link to={'/skills'}><CodeIcon /></Link>
            <Link to={'/work'}><WorkIcon /></Link>
            <Link to={'/contact'}><MailOutlineIcon /></Link>
          </nav>
      );
    };
</code>```

Body:
What seems like a simple integration with react-router-dom has unexpected results. When I click on links in the sidebar, the Link component works correctly by generating the url ie. localhost:3000/about, but I remain on the previous viewing page. When I click on forward and back buttons, the Route renders the correct component.

I am using Webpack, Typescript but don't think those should be affecting anything.

"react": "^16.12.0",

"react-router-dom": "^5.1.2"

    //App Component
    import * as React from 'react';
    import { BrowserRouter as Router, Link, Route } from 'react-router-dom';

    import Sidebar from './Sidebar';
    import Home from './Home';
    import About from './About';
    import Work from './Work';
    import Contact from './Contact';
    import Skills from './Skills';

    const App: React.FC = () => {
      return (
        <Router>

            <Sidebar />
            <Route exact path="/"><Home /></Route>
            <Route path="/about"><About /></Route>
            <Route path="/skills" component={Skills}></Route>
            <Route path="/work" component={Work}></Route>
            <Route path="/contact" component={Contact}></Route>

        </Router>
      );
    };

    //Sidebar Component
    import * as React from 'react';
    import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

    import HomeIcon from '@material-ui/icons/Home';
    import FaceIcon from '@material-ui/icons/Face';
    import WorkIcon from '@material-ui/icons/Work';
    import CodeIcon from '@material-ui/icons/Code';
    import MailOutlineIcon from '@material-ui/icons/MailOutline';

    const Sidebar: React.FC = props => {
      return (
        <Router>

            <Link to={'/'}><HomeIcon /></Link>
            <Link to={'/about'}><FaceIcon /></Link>
            <Link to={'/skills'}><CodeIcon /></Link>
            <Link to={'/work'}><WorkIcon /></Link>
            <Link to={'/contact'}><MailOutlineIcon /></Link>

        </Router>
      );
    };

Body:
It's because your Sidebar component is wrapped in its own Router. You want your Links and Routes to share the same parent Router. Remove your Sidebar Router and it should fix your problem.

    const Sidebar: React.FC = props => {
      return (
          <nav className="nav-container ">
            <Link to={'/'}><HomeIcon /></Link>
            <Link to={'/about'}><FaceIcon /></Link>
            <Link to={'/skills'}><CodeIcon /></Link>
            <Link to={'/work'}><WorkIcon /></Link>
            <Link to={'/contact'}><MailOutlineIcon /></Link>
          </nav>
      );
    };


来源: stackexchange

问:
Question about customizing spring security 2.0.4
Hi all I have the following requirement: The user will login to the system using olny his/her password and redirected to different pages depending his/her role (roles are DENTIST,DOCTOR,PHARMASIST).Are there any resources on how to use spring sequirity with  one-field login form and multiple default-target-urls? Any help would be really appriciated because googling the subject wasn't very useful... Thanx in advance</p>

答: You can override determineTargetURL()

ContentLicense: CC BY-SA 3.0

Body: You can override determineTargetURL()


问:
Does including ncurses.h in C programming also include stdio.h?
I was studying up on ncurses.h because I am trying to learn a bit of design aspects for c, and stumbled across a statement saying that stdio.h is inside of ncurses

```<code>  #include <ncurses.h>        /*ncurses.h includes stdio.h*/
</code>```

Is this true? If so, can someone explain to me why, and if that means I don't have to ever include it again?

Also, does this cause any issues because I am not exactly defining it in a regular sense

答:
In general, even if one header includes another as part of its implementation, you should always trust the C standard and the documentation of whatever API you're using. If it says that a certain header file is the one that contains a certain item, or it says that in order to access a certain item, include this header, you should follow that.

It's not harmful to include the same file multiple times if it has include guards (i.e. #pragma once or #ifndef _HEADER_NAME ... #endif)

You're technically relying on an implementation detail if you omit an include that the C standard (or API documentation) says is the correct file to include for a certain declaration or definition. That means that the next version of your compiler or library could very well remove that convenient nested include that makes your program a couple of lines shorter.

ContentLicense: CC BY-SA 4.0

Body:
I was studying up on ncurses.h because I am trying to learn a bit of design aspects for c, and stumbled across a statement saying that stdio.h is inside of ncurses

  #include <ncurses.h>        /*ncurses.h includes stdio.h*/

Is this true? If so, can someone explain to me why, and if that means I don't have to ever include it again?

Also, does this cause any issues because I am not exactly defining it in a regular sense


问:
can TypeScript restrict keyof to a list of properties of a particular type?
so, I want to write a generic method. For the sake of the question, let's say I want to concatenate 2 string properties from 2 different objects of the same type.

```<code>function concat<T>(target1: T, target2: T, key: keyof T): string {
  return target1[key] + target2[key];
}
</code>```

The above fails to compile because the compiler has no indication that I want to restrict key to only be the list of properties of type string.

Is this not currently supported in TypeScript?

I know I can do runtime checks, but I want compile-time checks for this one.

答:
You want a three parameter generic here. One for each input, and one for the key.

```<code>type CommonKey<A, B> = keyof A & keyof B

function concat<A, B, K extends CommonKey<A, B>>(
  target1: A,
  target2: B,
  key: K
): string {
  return `${target1[key]}${target2[key]}`
}
</code>```

This defines the key as both a key of A and B, meaning that it must satisfy both.

To constrain it further to only string values, you need to use a mapped type with a condition to test for its type.

```<code>// This type returns all keys that have a value of type string
type StringKeyOf<T> = {
    // for all keys in T
    [K in keyof T]:

        // if the value of this key is a string, keep it. Else, discard it
        T[K] extends string ? K : never

// Get the union type of the remaining values.
}[keyof T]

// Only allow common keys of both objects.
type CommonKey<A, B> = StringKeyOf<A> & StringKeyOf<B>

function concat<
    A,
    B,
    K extends CommonKey<A, B>
>(target1: A, target2: B, key: K): string {
    return `${target1[key]}${target2[key]}`
}
</code>```

Now this will give a type error, because age is a number.

```<code>concat(
    { name: 'a', age: 12 human: 'maybe?' },
    { name: 'b', age: 8, dog: true },
    'age' // Type error

)
</code>```

Body:
so, I want to write a generic method. For the sake of the question, let's say I want to concatenate 2 string properties from 2 different objects of the same type.

function concat<T>(target1: T, target2: T, key: keyof T): string {
  return target1[key] + target2[key];
}

The above fails to compile because the compiler has no indication that I want to restrict key to only be the list of properties of type string.

Is this not currently supported in TypeScript?

I know I can do runtime checks, but I want compile-time checks for this one.

Body:
You want a three parameter generic here. One for each input, and one for the key.

type CommonKey<A, B> = keyof A & keyof B

function concat<A, B, K extends CommonKey<A, B>>(
  target1: A,
  target2: B,
  key: K
): string {
  return `${target1[key]}${target2[key]}`
}

This defines the key as both a key of A and B, meaning that it must satisfy both.

To constrain it further to only string values, you need to use a mapped type with a condition to test for its type.

// This type returns all keys that have a value of type string
type StringKeyOf<T> = {
    // for all keys in T
    [K in keyof T]:

        // if the value of this key is a string, keep it. Else, discard it
        T[K] extends string ? K : never

// Get the union type of the remaining values.
}[keyof T]

// Only allow common keys of both objects.
type CommonKey<A, B> = StringKeyOf<A> & StringKeyOf<B>

function concat<
    A,
    B,
    K extends CommonKey<A, B>
>(target1: A, target2: B, key: K): string {
    return `${target1[key]}${target2[key]}`
}

Now this will give a type error, because age is a number.

concat(
    { name: 'a', age: 12 human: 'maybe?' },
    { name: 'b', age: 8, dog: true },
    'age' // Type error

)


问:
Open Python IDLE in current virtual environment
Using the Windows command line, how can I open a Python file inside the current virtual environment that I am in?

For example, say I'm in my virtual environment:

```<code>(env) C:\MyFolder>
</code>```

and then I want to open my Python file:

```<code>(env) C:\MyFolder>mypythonfile.py
</code>```

The .py file will open in IDLE but not inside the (env) environment

答:
To achieve this via 3 steps:

Suppose that you are using windows system and have open a cmd window.

Activate your virtual environment:
venv/Scripts/activate  (venv is the path of your virtual environemnt)

You could use this command "where python" to check if your virtual environment is activated. If success, it should point to your virtual environment path at the first line.

Launch idle within your virtual environment:
python -m idlelib.idle

A IDLE window should be popped up. You can check if this is within the virtual environment by import a package only installed in the virtual environment but not in the local python.

Now from the idle open the file that you want to edit:
Click 'File - Open' in sequence, and then choose the file.

Now you can just try to press 'F5', you will see this file would be run in the virtual idle.

Body:
Using the Windows command line, how can I open a Python file inside the current virtual environment that I am in?

For example, say I'm in my virtual environment:

(env) C:\MyFolder>

and then I want to open my Python file:

(env) C:\MyFolder>mypythonfile.py

The .py file will open in IDLE but not inside the (env) environment


问:
regex pattern to tokenize sentence while stripping end punctuation?
I need to make a regex pattern that can tokenize a sentence with that also has punctuation tokenized separately, except for acronyms, contractions, and hyphens.

```<code>"This is a test sentence. I won't write this sentence. J. Smith lives in the U.S.A. and it is nice there."
</code>```

should return as

```<code>["This" "is" "a" "test" "sentence" "." "I" "won't" "write" "this" "sentence" "." "J." "Smith" "lives"
 "in" "the" "U.S.A." "and" "it" "is" "nice" "there" ."]
</code>```

My code currently is:

```<code>tokens = re.findall(r'((\.\s)|(\S+))', sentence)
</code>```

But this doesn't work correctly. It matches the period at the end of words as part of the word.

答:
You can use [^\s.]{2,}|(?:\w|\.)+ for tokenizing this particular example, but as Ryan mentions, without a natural language toolkit, this is an exercise in futility.

This regex enables two cases to be matched:

[^\s.]{2,} match 2 or more consecutive non-space, non-literal period characters

(?:\w|\.)+ match one or more consecutive word characters or literal periods

Usage:

```<code>import re

s = """This is a test sentence.
I won't write this sentence. J. Smith lives in the U.S.A.  and it is nice there.
"""

for token in re.findall(r"[^\s.]{2,}|(?:\w|\.)+", s):
    print(repr(token))
</code>```

Output:

'This'
'is'
'a'
'test'
'sentence'
'.'
'I'
"won't"
'write'
'this'
'sentence'
'.'
'J.'
'Smith'
'lives'
'in'
'the'
'U.S.A.'
'and'
'it'
'is'
'nice'
'there'
'.'
```

Body:
I need to make a regex pattern that can tokenize a sentence with that also has punctuation tokenized separately, except for acronyms, contractions, and hyphens.

"This is a test sentence. I won't write this sentence. J. Smith lives in the U.S.A. and it is nice there."

should return as

["This" "is" "a" "test" "sentence" "." "I" "won't" "write" "this" "sentence" "." "J." "Smith" "lives"
 "in" "the" "U.S.A." "and" "it" "is" "nice" "there" ."]

My code currently is:

tokens = re.findall(r'((\.\s)|(\S+))', sentence)

But this doesn't work correctly. It matches the period at the end of words as part of the word.

Body:
You can use [^\s.]{2,}|(?:\w|\.)+ for tokenizing this particular example, but as Ryan mentions, without a natural language toolkit, this is an exercise in futility.

This regex enables two cases to be matched:

[^\s.]{2,} match 2 or more consecutive non-space, non-literal period characters

(?:\w|\.)+ match one or more consecutive word characters or literal periods

Usage:

import re

s = """This is a test sentence.
I won't write this sentence. J. Smith lives in the U.S.A.  and it is nice there.
"""

for token in re.findall(r"[^\s.]{2,}|(?:\w|\.)+", s):
    print(repr(token))

Output:

'This'
'is'
'a'
'test'
'sentence'
'.'
'I'
"won't"
'write'
'this'
'sentence'
'.'
'J.'
'Smith'
'lives'
'in'
'the'
'U.S.A.'
'and'
'it'
'is'
'nice'
'there'
'.'


问:
How to exclude sitemesh filter when resolving error in spring?
I have a Sitemesh filter that will decorate pages. I have configured a Spring's exceptionResolver so that all the error will go to a view called error which is then pointed to WEB-INF/jsp/error.jsp through InternalResourceViewResolver.

Now the error page is decorated by sitemesh and I would like to exclude it from decoration. Using <exclude> tag of sitemesh decorator.xml does not work. Because the incoming url may be something as normal as /app/login.html and sitemesh already catch it and decorate it.

I notice that in Spring if I have a @ResponseBody for ajax request, it would by pass Sitemesh's decoration. I wonder how it works? Can I make something in the errorResolver to bypass sitemesh also?

答:
It can be done by imlementing own exceptionResolver, streaming output manually and return null ModelAndView

```<code>public class MyExceptionResolver extends SimpleMappingExceptionResolver{
public ModelAndView resolveException(HttpServletRequest request,
        HttpServletResponse response, Object handler, Exception ex) {

    //other things like logging...
    RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/error.jsp");
    try {
        dispatcher.forward(request, response);
        response.getOutputStream().flush();
    } catch (ServletException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
    return null;
}
</code>```

Body:
It can be done by imlementing own exceptionResolver, streaming output manually and return null ModelAndView

public class MyExceptionResolver extends SimpleMappingExceptionResolver{
public ModelAndView resolveException(HttpServletRequest request,
        HttpServletResponse response, Object handler, Exception ex) {

    //other things like logging...
    RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/error.jsp");
    try {
        dispatcher.forward(request, response);
        response.getOutputStream().flush();
    } catch (ServletException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
    return null;
}


问:
Spring Boot - Ambiguous Mapping
Pulling my hair out over this one, makes absolutely no sense

```<code>@RestController("/firmwareAShkcwdsdskl")
public class FirmwareController {
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Result> createNewFirmwareVersion(DetailedFirmwareVersionRequest detailedFirmwareVersionRequest) {
    // Code Block
    }
}
</code>```

```<code>
@RestController("/jobs/firmwareUpgrade")
public class FirmwareUpgradeController {
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Result> createNewJob(DetailedFirmwareUpgradeRequest detailedFirmwareUpgradeRequest) {
    // Code Block
    }
}
</code>```

Attempting to start my Spring Boot application with these two controllers is throwing the following error

```<code>Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map '/jobs/firmwareUpgrade' method
eshepherd.admin.api.controller.FirmwareUpgradeController#createNewJob(DetailedFirmwareUpgradeRequest)
to {POST , produces [application/json]}: There is already '/firmwareAShkcwdsdskl' bean method
eshepherd.admin.api.controller.FirmwareController#createNewFirmwareVersion(DetailedFirmwareVersionRequest) mapped.
</code>```

The class name, method name, request mapping and parameters are all unique, I just don't understand it.

As you can tell I've descended into pure frustration trying all kinds of string changes to just get it to work initially, but if anyone could help me identify the problem I'd be extremely grateful.

Edit: Using Spring-Boot 2.2.4

答:
As you mentioned in your own answer: Yes, you misunderstood. This is an easy one to confuse.

@RestController's value is the component name, not the request mapping path. Take a look at the source for org.springframework.web.bind.annotation.RestController#value.

It is very similar to org.springframework.stereotype.Component#value and the others in org.springframework.stereotype (in spring-context). You have have the correct annotations now:

@RestController
@RequestMapping("/firmware")
public class FirmwareRestController {
    // ...
}
```

Title: Spring Boot - Ambiguous Mapping

Body:
Pulling my hair out over this one, makes absolutely no sense

@RestController("/firmwareAShkcwdsdskl")
public class FirmwareController {
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Result> createNewFirmwareVersion(DetailedFirmwareVersionRequest detailedFirmwareVersionRequest) {
    // Code Block
    }
}

@RestController("/jobs/firmwareUpgrade")
public class FirmwareUpgradeController {
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Result> createNewJob(DetailedFirmwareUpgradeRequest detailedFirmwareUpgradeRequest) {
    // Code Block
    }
}

Attempting to start my Spring Boot application with these two controllers is throwing the following error

Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map '/jobs/firmwareUpgrade' method
eshepherd.admin.api.controller.FirmwareUpgradeController#createNewJob(DetailedFirmwareUpgradeRequest)
to {POST , produces [application/json]}: There is already '/firmwareAShkcwdsdskl' bean method
eshepherd.admin.api.controller.FirmwareController#createNewFirmwareVersion(DetailedFirmwareVersionRequest) mapped.

The class name, method name, request mapping and parameters are all unique, I just don't understand it.

As you can tell I've descended into pure frustration trying all kinds of string changes to just get it to work initially, but if anyone could help me identify the problem I'd be extremely grateful.

Edit: Using Spring-Boot 2.2.4


问:
How to stop/kill airflow scheduler started in daemon mode
I and new to airflow and accidentally started airflow scheduler in daemon mode. Now, I want to kill the scheduler and possibly restart it. I tried doing

```<code>    sudo kill -9 <list of pids>
    pkill <name>
</code>```

nothing is happening. When I run

```<code>    ps aux | grep 'airflow scheduler'
</code>```

I see these entries:

```<code>    user1   2907  6.0  1.0 329788 62996 ?        Sl   17:37   1:26 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D
    user1   2909  0.0  0.9 327576 58948 ?        Sl   17:37   0:00 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D
    user1   2910  0.0  0.9 327576 58944 ?        Sl   17:37   0:00 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D
    user1   2911  0.0  0.9 327576 58944 ?        Sl   17:37   0:00 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D
</code>```

...and so on for 35 lines with different pids.

Any recommendation as to how I can stop/kill airflow scheduler without restarting my machine. I have also checked the pid file for scheduler and tried killing that pid but no effects.

Any help is appreciated. Thanks!

答:
cd ~/airflow
cat airflow-scheduler.pid | xargs kill
```

Body:
I and new to airflow and accidentally started airflow scheduler in daemon mode. Now, I want to kill the scheduler and possibly restart it. I tried doing

    sudo kill -9 <list of pids>
    pkill <name>

nothing is happening. When I run

    ps aux | grep 'airflow scheduler'

I see these entries:

    user1   2907  6.0  1.0 329788 62996 ?        Sl   17:37   1:26 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D
    user1   2909  0.0  0.9 327576 58948 ?        Sl   17:37   0:00 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D
    user1   2910  0.0  0.9 327576 58944 ?        Sl   17:37   0:00 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D
    user1   2911  0.0  0.9 327576 58944 ?        Sl   17:37   0:00 /users/user1/anaconda2/bin/python /users/user1/anaconda2/bin/airflow scheduler -D

...and so on for 35 lines with different pids.

Any recommendation as to how I can stop/kill airflow scheduler without restarting my machine. I have also checked the pid file for scheduler and tried killing that pid but no effects.

Any help is appreciated. Thanks!


问:
How to create a text made of glass in canvas with refraction and reflection?
What I'd like to achieve is close to this there. You can also just take a look at those screenshots.

The actual result

Notice how the refraction is evolving as the page scrolls down/up. Scrolling, there is also a source of light going right to left.

After scrolling

Ideally I'd like the text to have that transparent glass reflective aspect like on the example provided. But also, to refract what is behind, which does not seem to be the case here. Indeed, when the canvas is left alone, the refraction still happens, so i suspect the effects is done knowing what would be displayed in the background. As for me, I'd like to refract whats behind dynamically. Yet again i'm thinking that i might have been achieved this way for a reason, maybe performance issue

All non canvas elements removed

Indeed, it looks like it it based from the background, but the background is not within the canvas. Also, as you can see, on the next picture, the refraction effect is still hapenning even though the background is removed.

Refraction

The source of light is still there and i suspect it's using some kind of ray casting/ray tracing method. I'm not at all familiar with drawing in the canvas (except using p5.js for simple things),and it took me a long time to find ray tracing with no idea of what i'm looking for.

.... Questions ....

How do i get the glass transparent reflective aspect on the text ? Should it be achieve with graphic design tools ? (I don't know how to get an object (see screenshot below) that seem to have the texture bind afterwards.I'm not even sure if i'm using the right vocabulary but assuming I am, I don't know how to make such texture.)
text object no "texture"

How to refract everything that would be placed behind the glass object? (Before I came to the conclusion that I needed to use canvas, not just because I found this exemple, but also because of other considerations related to the project I'm working on. I've invest a lot of time learning suffisant svg to achieve what you can see on the next screenshot,and failed to achieve what was aimed. I'm not willing to do so the same with ray casting thus my third question. I hope it's understandable...Still the refracted part is there but looks a lot less realistic than in the provided example.)
SVG

Is ray casting/ray tracing is the right path to dig in for achieving the refraction ? Will it be okay to use if its ray tracing every objects behind.

Thanks for your time and concern.

答:
Reflection and Refraction

There are so many tutorials online to achieve this FX I can not see the point in repeating them.

This answer presents an approximation using a normal map in place of a 3D model, and flat texture maps to represent the reflection and refraction maps, rather than 3D textures traditionally used to get reflections and refraction.

Generating a normal map.

The snippet below generates a normal map from input text with various options. The process is reasonably quick (not real time) and will be the stand in for a 3D model in the webGL rendering solution.

It first creates a height map of the text, adds some smoothing, then converts the map to a normal map.

text.addEventListener("keyup", createNormalMap)
createNormalMap();
function createNormalMap(){
text.focus();
  setTimeout(() => {
    const can = normalMapText(text.value, "Arial Black", 96, 8, 2, 0.1, true, "round");
    result.innerHTML = "";
    result.appendChild(can);
  }, 0);
}

function normalMapText(text, font, size, bevel, smooth = 0, curve = 0.5, smoothNormals = true, corners = "round") {
    const canvas = document.createElement("canvas");
    const mask = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    const ctxMask = mask.getContext("2d");
    ctx.font = size + "px " + font;
    const tw = ctx.measureText(text).width;
    const cx = (mask.width = canvas.width = tw + bevel * 3) / 2;
    const cy = (mask.height = canvas.height = size + bevel * 3) / 2;
    ctx.font = size + "px " + font;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.lineJoin = corners;
    const step = 255 / (bevel + 1);
    var j, i = 0, val = step;
    while (i < bevel) {
        ctx.lineWidth = bevel - i;
        const v = ((val / 255) ** curve) * 255;
        ctx.strokeStyle = `rgb(${v},${v},${v})`;
        ctx.strokeText(text, cx, cy);
        i++;
        val += step;
    }
    ctx.fillStyle = "#FFF";
    ctx.fillText(text, cx, cy);
    if (smooth >= 1) {
        ctxMask.drawImage(canvas, 0, 0);
        ctx.filter = "blur(" + smooth + "px)";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "destination-in";
        ctx.filter = "none";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "source-over";
    }

    const w = canvas.width, h = canvas.height, w4 = w << 2;
    const imgData = ctx.getImageData(0,0,w,h);
    const d = imgData.data;
    const heightBuf = new Uint8Array(w * h);
    j = i = 0;
    while (i < d.length) {
        heightBuf[j++] = d[i]
        i += 4;
    }
    var x, y, xx, yy, zz, xx1, yy1, zz1, xx2, yy2, zz2, dist;
    i = 0;
    for(y = 0; y < h; y ++){
        for(x = 0; x < w; x ++){
            if(d[i + 3]) { // only pixels with alpha > 0
                const idx = x + y * w;
                const x1 = 1;
                const z1 = heightBuf[idx - 1] === undefined ? 0 : heightBuf[idx - 1] - heightBuf[idx];
                const y1 = 0;
                const x2 = 0;
                const z2 = heightBuf[idx - w] === undefined ? 0 : heightBuf[idx - w] - heightBuf[idx];
                const y2 = -1;
                const x3 = 1;
                const z3 = heightBuf[idx - w - 1] === undefined ? 0 : heightBuf[idx - w - 1] - heightBuf[idx];
                const y3 = -1;
                xx = y3 * z2 - z3 * y2
                yy = z3 * x2 - x3 * z2
                zz = x3 * y2 - y3 * x2
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                xx /= dist;
                yy /= dist;
                zz /= dist;
                xx1 = y1 * z3 - z1 * y3
                yy1 = z1 * x3 - x1 * z3
                zz1 = x1 * y3 - y1 * x3
                dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5;
                xx += xx1 / dist;
                yy += yy1 / dist;
                zz += zz1 / dist;

                if (smoothNormals) {
                    const x1 = 2;
                    const z1 = heightBuf[idx - 2] === undefined ? 0 : heightBuf[idx - 2] - heightBuf[idx];
                    const y1 = 0;
                    const x2 = 0;
                    const z2 = heightBuf[idx - w * 2] === undefined ? 0 : heightBuf[idx - w * 2] - heightBuf[idx];
                    const y2 = -2;
                    const x3 = 2;
                    const z3 = heightBuf[idx - w * 2 - 2] === undefined ? 0 : heightBuf[idx - w * 2 - 2] - heightBuf[idx];
                    const y3 = -2;
                    xx2 = y3 * z2 - z3 * y2
                    yy2 = z3 * x2 - x3 * z2
                    zz2 = x3 * y2 - y3 * x2
                    dist = (xx2 * xx2 + yy2 * yy2 + zz2 * zz2) ** 0.5 * 2;
                    xx2 /= dist;
                    yy2 /= dist;
                    zz2 /= dist;
                    xx1 = y1 * z3 - z1 * y3
                    yy1 = z1 * x3 - x1 * z3
                    zz1 = x1 * y3 - y1 * x3
                    dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5 * 2;
                    xx2 += xx1 / dist;
                    yy2 += yy1 / dist;
                    zz2 += zz1 / dist;
                    xx += xx2;
                    yy += yy2;
                    zz += zz2;
                }
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                d[i+0] = ((xx / dist) + 1.0) * 128;
                d[i+1] = ((yy / dist) + 1.0) * 128;
                d[i+2] = 255  - ((zz / dist) + 1.0) * 128;
            }

            i += 4;
        }
    }
    ctx.putImageData(imgData, 0, 0);
    return canvas;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><input id="text" type="text" value="Normal Map" />
<div id="result"></div></code>```

Approximation

To render the text we need to create some shaders. As we are using a normal map the vertex shader can be very simple.

Vertex shader

We are using a quad to render the whole canvas. The vertex shader outputs the 4 corners and converts each corner to a texture coordinate.

```<code>#version 300 es
in vec2 vert;
out vec2 texCoord;
void main() {
    texCoord = vert * 0.5 + 0.5;
    gl_Position = vec4(verts, 1, 1);
}
</code>```

Fragment shader

The fragment shader has 3 texture inputs. The normal map, and the reflection and refraction maps.

The fragment shader first works out if the pixel is part of the background, or on the text. If on the text it converts the RGB texture normal into a vector normal.

It then uses vector addition to get the reflected and refracted textures. Mixing those textures by the normal maps z value. In effect refraction is strongest when the normal is facing up and reflection strongest when normal facing away

```<code>#version 300 es
uniform sampler2D normalMap;
uniform sampler2D refractionMap;
uniform sampler2D reflectionMap;

in vec2 texCoord;
out vec4 pixel;
void main() {
    vec4 norm = texture(normalMap, texCoord);
    if (norm.a > 0) {
        vec3 normal = normalize(norm.rgb - 0.5);
        vec2 tx1 = textCoord + normal.xy * 0.1;
        vec2 tx2 = textCoord - normal.xy * 0.2;
        pixel = vec4(mix(texture(refractionMap, tx2).rgb, texture(reflectionMap, tx1).rgb, abs(normal.z)), norm.a);
    } else {
        pixel = texture(refactionMap, texCoord);
    }
}
</code>```

That is the most basic form that will give the impression of reflection and refraction.

Example NOT REAL reflection refraction.

The example is a little more complex as the various textures have different sizes and thus need to be scaled in the fragment shader to be the correct size.

I have also added some tinting to both the refraction and reflections and mixed the reflection via a curve.

The background is scrolled to the mouse position. To match a background on the page you would move the canvas over the background.

There are a few #defines in the frag shader to control the settings. You could make them uniforms, or constants.

mixCurve controls the mix of reflect refract textures. Values < 1  > 0 ease out refraction, values > 1 ease out the reflection.

The normal map is one to one with rendered pixels. As 2D canvas rendering is rather poor quality you can get a better result by over sampling the normal map in the fragment shader.

const vertSrc = `#version 300 es
in vec2 verts;
out vec2 texCoord;
void main() {
    texCoord = verts * vec2(0.5, -0.5) + 0.5;
    gl_Position = vec4(verts, 1, 1);
}
`
const fragSrc = `#version 300 es
precision highp float;
#define refractStrength 0.1
#define reflectStrength 0.2
#define refractTint vec3(1,0.95,0.85)
#define reflectTint vec3(1,1.25,1.42)
#define mixCurve 0.3

uniform sampler2D normalMap;
uniform sampler2D refractionMap;
uniform sampler2D reflectionMap;
uniform vec2 scrolls;
in vec2 texCoord;
out vec4 pixel;
void main() {
    vec2 nSize = vec2(textureSize(normalMap, 0));
    vec2 scaleCoords = nSize / vec2(textureSize(refractionMap, 0));
    vec2 rCoord = (texCoord - scrolls) * scaleCoords;
    vec4 norm = texture(normalMap, texCoord);
    if (norm.a > 0.99) {
        vec3 normal = normalize(norm.rgb - 0.5);
        vec2 tx1 = rCoord + normal.xy * scaleCoords * refractStrength;
        vec2 tx2 = rCoord - normal.xy * scaleCoords * reflectStrength;
        vec3 c1 = texture(refractionMap, tx1).rgb * refractTint;
        vec3 c2 = texture(reflectionMap, tx2).rgb * reflectTint;
        pixel = vec4(mix(c2, c1, abs(pow(normal.z,mixCurve))), 1.0);
    } else {
        pixel = texture(refractionMap, rCoord);
    }
}
`

var program, loc;
function normalMapText(text, font, size, bevel, smooth = 0, curve = 0.5, smoothNormals = true, corners = "round") {
    const canvas = document.createElement("canvas");
    const mask = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    const ctxMask = mask.getContext("2d");
    ctx.font = size + "px " + font;
    const tw = ctx.measureText(text).width;
    const cx = (mask.width = canvas.width = tw + bevel * 3) / 2;
    const cy = (mask.height = canvas.height = size + bevel * 3) / 2;
    ctx.font = size + "px " + font;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.lineJoin = corners;
    const step = 255 / (bevel + 1);
    var j, i = 0, val = step;
    while (i < bevel) {
        ctx.lineWidth = bevel - i;
        const v = ((val / 255) ** curve) * 255;
        ctx.strokeStyle = `rgb(${v},${v},${v})`;
        ctx.strokeText(text, cx, cy);
        i++;
        val += step;
    }
    ctx.fillStyle = "#FFF";
    ctx.fillText(text, cx, cy);
    if (smooth >= 1) {
        ctxMask.drawImage(canvas, 0, 0);
        ctx.filter = "blur(" + smooth + "px)";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "destination-in";
        ctx.filter = "none";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "source-over";
    }

    const w = canvas.width, h = canvas.height, w4 = w << 2;
    const imgData = ctx.getImageData(0,0,w,h);
    const d = imgData.data;
    const heightBuf = new Uint8Array(w * h);
    j = i = 0;
    while (i < d.length) {
        heightBuf[j++] = d[i]
        i += 4;
    }
    var x, y, xx, yy, zz, xx1, yy1, zz1, xx2, yy2, zz2, dist;
    i = 0;
    for(y = 0; y < h; y ++){
        for(x = 0; x < w; x ++){
            if(d[i + 3]) { // only pixels with alpha > 0
                const idx = x + y * w;
                const x1 = 1;
                const z1 = heightBuf[idx - 1] === undefined ? 0 : heightBuf[idx - 1] - heightBuf[idx];
                const y1 = 0;
                const x2 = 0;
                const z2 = heightBuf[idx - w] === undefined ? 0 : heightBuf[idx - w] - heightBuf[idx];
                const y2 = -1;
                const x3 = 1;
                const z3 = heightBuf[idx - w - 1] === undefined ? 0 : heightBuf[idx - w - 1] - heightBuf[idx];
                const y3 = -1;
                xx = y3 * z2 - z3 * y2
                yy = z3 * x2 - x3 * z2
                zz = x3 * y2 - y3 * x2
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                xx /= dist;
                yy /= dist;
                zz /= dist;
                xx1 = y1 * z3 - z1 * y3
                yy1 = z1 * x3 - x1 * z3
                zz1 = x1 * y3 - y1 * x3
                dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5;
                xx += xx1 / dist;
                yy += yy1 / dist;
                zz += zz1 / dist;

                if (smoothNormals) {
                    const x1 = 2;
                    const z1 = heightBuf[idx - 2] === undefined ? 0 : heightBuf[idx - 2] - heightBuf[idx];
                    const y1 = 0;
                    const x2 = 0;
                    const z2 = heightBuf[idx - w * 2] === undefined ? 0 : heightBuf[idx - w * 2] - heightBuf[idx];
                    const y2 = -2;
                    const x3 = 2;
                    const z3 = heightBuf[idx - w * 2 - 2] === undefined ? 0 : heightBuf[idx - w * 2 - 2] - heightBuf[idx];
                    const y3 = -2;
                    xx2 = y3 * z2 - z3 * y2
                    yy2 = z3 * x2 - x3 * z2
                    zz2 = x3 * y2 - y3 * x2
                    dist = (xx2 * xx2 + yy2 * yy2 + zz2 * zz2) ** 0.5 * 2;
                    xx2 /= dist;
                    yy2 /= dist;
                    zz2 /= dist;
                    xx1 = y1 * z3 - z1 * y3
                    yy1 = z1 * x3 - x1 * z3
                    zz1 = x1 * y3 - y1 * x3
                    dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5 * 2;
                    xx2 += xx1 / dist;
                    yy2 += yy1 / dist;
                    zz2 += zz1 / dist;
                    xx += xx2;
                    yy += yy2;
                    zz += zz2;
                }
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                d[i+0] = ((xx / dist) + 1.0) * 128;
                d[i+1] = ((yy / dist) + 1.0) * 128;
                d[i+2] = 255  - ((zz / dist) + 1.0) * 128;
            }

            i += 4;
        }
    }
    ctx.putImageData(imgData, 0, 0);
    return canvas;
}
function createChecker(size, width, height) {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    canvas.width = width * size;
    canvas.height = height * size;
    for(var y = 0; y < size; y ++) {
        for(var x = 0; x < size; x ++) {
            const xx = x * width;
            const yy = y * height;
            ctx.fillStyle ="#888";
            ctx.fillRect(xx,yy,width,height);
            ctx.fillStyle ="#DDD";
            ctx.fillRect(xx,yy,width/2,height/2);
            ctx.fillRect(xx+width/2,yy+height/2,width/2,height/2);
        }
    }
    return canvas;
}

const mouse = {x:0, y:0};
addEventListener("mousemove",e => {mouse.x = e.pageX; mouse.y = e.pageY });
var normMap = normalMapText("GLASSY", "Arial Black", 128, 24, 1, 0.1, true, "round");
canvas.width = normMap.width;
canvas.height = normMap.height;
const locations = {updates: []};
const fArr = arr => new Float32Array(arr);
const gl = canvas.getContext("webgl2", {premultipliedAlpha: false, antialias: false, alpha: false});
const textures = {};
setup();
function texture(gl, image, {min = "LINEAR", mag = "LINEAR", wrapX = "REPEAT", wrapY = "REPEAT"} = {}) {
    const texture = gl.createTexture();
    target = gl.TEXTURE_2D;
    gl.bindTexture(target, texture);
    gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl[min]);
    gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl[mag]);
    gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl[wrapX]);
    gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl[wrapY]);
    gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    return texture;
}
function bindTexture(texture, unit) {
    gl.activeTexture(gl.TEXTURE0 + unit);
    gl.bindTexture(gl.TEXTURE_2D, texture);
}
function Location(name, data, type = "fv", autoUpdate = true) {
    const glUpdateCall = gl["uniform" + data.length + type].bind(gl);
    const loc = gl.getUniformLocation(program, name);
    locations[name] = {data, update() {glUpdateCall(loc, data)}};
    autoUpdate && locations.updates.push(locations[name]);
    return locations[name];
}
function compileShader(src, type, shader = gl.createShader(type)) {
    gl.shaderSource(shader, src);
    gl.compileShader(shader);
    return shader;
}
function setup() {
    program = gl.createProgram();
    gl.attachShader(program, compileShader(vertSrc, gl.VERTEX_SHADER));
    gl.attachShader(program, compileShader(fragSrc, gl.FRAGMENT_SHADER));
    gl.linkProgram(program);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0,1,2,0,2,3]), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ARRAY_BUFFER, fArr([-1,-1,1,-1,1,1,-1,1]), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(loc = gl.getAttribLocation(program, "verts"));
    gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
    gl.useProgram(program);
    Location("scrolls", [0, 0]);
    Location("normalMap", [0], "i", false).update();
    Location("refractionMap", [1], "i", false).update();
    Location("reflectionMap", [2], "i", false).update();
    textures.norm = texture(gl,normMap);
    textures.reflect = texture(gl,createChecker(8,128,128));
    textures.refract = texture(gl,createChecker(8,128,128));
    gl.viewport(0, 0, normMap.width, normMap.height);
    bindTexture(textures.norm, 0);
    bindTexture(textures.reflect, 1);
    bindTexture(textures.refract, 2);
    loop();
}
function draw() {
    for(const l of locations.updates) { l.update() }
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
}
function loop() {
    locations.scrolls.data[0]  = -1 + mouse.x / canvas.width;
    locations.scrolls.data[1]  = -1 + mouse.y / canvas.height;
    draw();
    requestAnimationFrame(loop);
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>canvas {
    position: absolute;
    top: 0px;
    left: 0px;
}</code>```

<canvas id="canvas"></canvas>```

Personally I find this FX more visually pleasing than simulations based on real lighting models. Though keep in mind THIS IS NOT Refraction or Reflections.

Body:
Reflection and Refraction

There are so many tutorials online to achieve this FX I can not see the point in repeating them.

This answer presents an approximation using a normal map in place of a 3D model, and flat texture maps to represent the reflection and refraction maps, rather than 3D textures traditionally used to get reflections and refraction.

Generating a normal map.

The snippet below generates a normal map from input text with various options. The process is reasonably quick (not real time) and will be the stand in for a 3D model in the webGL rendering solution.

It first creates a height map of the text, adds some smoothing, then converts the map to a normal map.

text.addEventListener("keyup", createNormalMap)
createNormalMap();
function createNormalMap(){
text.focus();
  setTimeout(() => {
    const can = normalMapText(text.value, "Arial Black", 96, 8, 2, 0.1, true, "round");
    result.innerHTML = "";
    result.appendChild(can);
  }, 0);
}

function normalMapText(text, font, size, bevel, smooth = 0, curve = 0.5, smoothNormals = true, corners = "round") {
    const canvas = document.createElement("canvas");
    const mask = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    const ctxMask = mask.getContext("2d");
    ctx.font = size + "px " + font;
    const tw = ctx.measureText(text).width;
    const cx = (mask.width = canvas.width = tw + bevel * 3) / 2;
    const cy = (mask.height = canvas.height = size + bevel * 3) / 2;
    ctx.font = size + "px " + font;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.lineJoin = corners;
    const step = 255 / (bevel + 1);
    var j, i = 0, val = step;
    while (i < bevel) {
        ctx.lineWidth = bevel - i;
        const v = ((val / 255) ** curve) * 255;
        ctx.strokeStyle = `rgb(${v},${v},${v})`;
        ctx.strokeText(text, cx, cy);
        i++;
        val += step;
    }
    ctx.fillStyle = "#FFF";
    ctx.fillText(text, cx, cy);
    if (smooth >= 1) {
        ctxMask.drawImage(canvas, 0, 0);
        ctx.filter = "blur(" + smooth + "px)";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "destination-in";
        ctx.filter = "none";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "source-over";
    }

    const w = canvas.width, h = canvas.height, w4 = w << 2;
    const imgData = ctx.getImageData(0,0,w,h);
    const d = imgData.data;
    const heightBuf = new Uint8Array(w * h);
    j = i = 0;
    while (i < d.length) {
        heightBuf[j++] = d[i]
        i += 4;
    }
    var x, y, xx, yy, zz, xx1, yy1, zz1, xx2, yy2, zz2, dist;
    i = 0;
    for(y = 0; y < h; y ++){
        for(x = 0; x < w; x ++){
            if(d[i + 3]) { // only pixels with alpha > 0
                const idx = x + y * w;
                const x1 = 1;
                const z1 = heightBuf[idx - 1] === undefined ? 0 : heightBuf[idx - 1] - heightBuf[idx];
                const y1 = 0;
                const x2 = 0;
                const z2 = heightBuf[idx - w] === undefined ? 0 : heightBuf[idx - w] - heightBuf[idx];
                const y2 = -1;
                const x3 = 1;
                const z3 = heightBuf[idx - w - 1] === undefined ? 0 : heightBuf[idx - w - 1] - heightBuf[idx];
                const y3 = -1;
                xx = y3 * z2 - z3 * y2
                yy = z3 * x2 - x3 * z2
                zz = x3 * y2 - y3 * x2
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                xx /= dist;
                yy /= dist;
                zz /= dist;
                xx1 = y1 * z3 - z1 * y3
                yy1 = z1 * x3 - x1 * z3
                zz1 = x1 * y3 - y1 * x3
                dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5;
                xx += xx1 / dist;
                yy += yy1 / dist;
                zz += zz1 / dist;

                if (smoothNormals) {
                    const x1 = 2;
                    const z1 = heightBuf[idx - 2] === undefined ? 0 : heightBuf[idx - 2] - heightBuf[idx];
                    const y1 = 0;
                    const x2 = 0;
                    const z2 = heightBuf[idx - w * 2] === undefined ? 0 : heightBuf[idx - w * 2] - heightBuf[idx];
                    const y2 = -2;
                    const x3 = 2;
                    const z3 = heightBuf[idx - w * 2 - 2] === undefined ? 0 : heightBuf[idx - w * 2 - 2] - heightBuf[idx];
                    const y3 = -2;
                    xx2 = y3 * z2 - z3 * y2
                    yy2 = z3 * x2 - x3 * z2
                    zz2 = x3 * y2 - y3 * x2
                    dist = (xx2 * xx2 + yy2 * yy2 + zz2 * zz2) ** 0.5 * 2;
                    xx2 /= dist;
                    yy2 /= dist;
                    zz2 /= dist;
                    xx1 = y1 * z3 - z1 * y3
                    yy1 = z1 * x3 - x1 * z3
                    zz1 = x1 * y3 - y1 * x3
                    dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5 * 2;
                    xx2 += xx1 / dist;
                    yy2 += yy1 / dist;
                    zz2 += zz1 / dist;
                    xx += xx2;
                    yy += yy2;
                    zz += zz2;
                }
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                d[i+0] = ((xx / dist) + 1.0) * 128;
                d[i+1] = ((yy / dist) + 1.0) * 128;
                d[i+2] = 255  - ((zz / dist) + 1.0) * 128;
            }

            i += 4;
        }
    }
    ctx.putImageData(imgData, 0, 0);
    return canvas;
}

<input id="text" type="text" value="Normal Map" />
<div id="result"></div>

Approximation

To render the text we need to create some shaders. As we are using a normal map the vertex shader can be very simple.

Vertex shader

We are using a quad to render the whole canvas. The vertex shader outputs the 4 corners and converts each corner to a texture coordinate.

#version 300 es
in vec2 vert;
out vec2 texCoord;
void main() {
    texCoord = vert * 0.5 + 0.5;
    gl_Position = vec4(verts, 1, 1);
}

Fragment shader

The fragment shader has 3 texture inputs. The normal map, and the reflection and refraction maps.

The fragment shader first works out if the pixel is part of the background, or on the text. If on the text it converts the RGB texture normal into a vector normal.

It then uses vector addition to get the reflected and refracted textures. Mixing those textures by the normal maps z value. In effect refraction is strongest when the normal is facing up and reflection strongest when normal facing away

#version 300 es
uniform sampler2D normalMap;
uniform sampler2D refractionMap;
uniform sampler2D reflectionMap;

in vec2 texCoord;
out vec4 pixel;
void main() {
    vec4 norm = texture(normalMap, texCoord);
    if (norm.a > 0) {
        vec3 normal = normalize(norm.rgb - 0.5);
        vec2 tx1 = textCoord + normal.xy * 0.1;
        vec2 tx2 = textCoord - normal.xy * 0.2;
        pixel = vec4(mix(texture(refractionMap, tx2).rgb, texture(reflectionMap, tx1).rgb, abs(normal.z)), norm.a);
    } else {
        pixel = texture(refactionMap, texCoord);
    }
}

That is the most basic form that will give the impression of reflection and refraction.

Example NOT REAL reflection refraction.

The example is a little more complex as the various textures have different sizes and thus need to be scaled in the fragment shader to be the correct size.

I have also added some tinting to both the refraction and reflections and mixed the reflection via a curve.

The background is scrolled to the mouse position. To match a background on the page you would move the canvas over the background.

There are a few #defines in the frag shader to control the settings. You could make them uniforms, or constants.

mixCurve controls the mix of reflect refract textures. Values < 1  > 0 ease out refraction, values > 1 ease out the reflection.

The normal map is one to one with rendered pixels. As 2D canvas rendering is rather poor quality you can get a better result by over sampling the normal map in the fragment shader.

const vertSrc = `#version 300 es
in vec2 verts;
out vec2 texCoord;
void main() {
    texCoord = verts * vec2(0.5, -0.5) + 0.5;
    gl_Position = vec4(verts, 1, 1);
}
`
const fragSrc = `#version 300 es
precision highp float;
#define refractStrength 0.1
#define reflectStrength 0.2
#define refractTint vec3(1,0.95,0.85)
#define reflectTint vec3(1,1.25,1.42)
#define mixCurve 0.3

uniform sampler2D normalMap;
uniform sampler2D refractionMap;
uniform sampler2D reflectionMap;
uniform vec2 scrolls;
in vec2 texCoord;
out vec4 pixel;
void main() {
    vec2 nSize = vec2(textureSize(normalMap, 0));
    vec2 scaleCoords = nSize / vec2(textureSize(refractionMap, 0));
    vec2 rCoord = (texCoord - scrolls) * scaleCoords;
    vec4 norm = texture(normalMap, texCoord);
    if (norm.a > 0.99) {
        vec3 normal = normalize(norm.rgb - 0.5);
        vec2 tx1 = rCoord + normal.xy * scaleCoords * refractStrength;
        vec2 tx2 = rCoord - normal.xy * scaleCoords * reflectStrength;
        vec3 c1 = texture(refractionMap, tx1).rgb * refractTint;
        vec3 c2 = texture(reflectionMap, tx2).rgb * reflectTint;
        pixel = vec4(mix(c2, c1, abs(pow(normal.z,mixCurve))), 1.0);
    } else {
        pixel = texture(refractionMap, rCoord);
    }
}
`

var program, loc;
function normalMapText(text, font, size, bevel, smooth = 0, curve = 0.5, smoothNormals = true, corners = "round") {
    const canvas = document.createElement("canvas");
    const mask = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    const ctxMask = mask.getContext("2d");
    ctx.font = size + "px " + font;
    const tw = ctx.measureText(text).width;
    const cx = (mask.width = canvas.width = tw + bevel * 3) / 2;
    const cy = (mask.height = canvas.height = size + bevel * 3) / 2;
    ctx.font = size + "px " + font;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.lineJoin = corners;
    const step = 255 / (bevel + 1);
    var j, i = 0, val = step;
    while (i < bevel) {
        ctx.lineWidth = bevel - i;
        const v = ((val / 255) ** curve) * 255;
        ctx.strokeStyle = `rgb(${v},${v},${v})`;
        ctx.strokeText(text, cx, cy);
        i++;
        val += step;
    }
    ctx.fillStyle = "#FFF";
    ctx.fillText(text, cx, cy);
    if (smooth >= 1) {
        ctxMask.drawImage(canvas, 0, 0);
        ctx.filter = "blur(" + smooth + "px)";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "destination-in";
        ctx.filter = "none";
        ctx.drawImage(mask, 0, 0);
        ctx.globalCompositeOperation = "source-over";
    }

    const w = canvas.width, h = canvas.height, w4 = w << 2;
    const imgData = ctx.getImageData(0,0,w,h);
    const d = imgData.data;
    const heightBuf = new Uint8Array(w * h);
    j = i = 0;
    while (i < d.length) {
        heightBuf[j++] = d[i]
        i += 4;
    }
    var x, y, xx, yy, zz, xx1, yy1, zz1, xx2, yy2, zz2, dist;
    i = 0;
    for(y = 0; y < h; y ++){
        for(x = 0; x < w; x ++){
            if(d[i + 3]) { // only pixels with alpha > 0
                const idx = x + y * w;
                const x1 = 1;
                const z1 = heightBuf[idx - 1] === undefined ? 0 : heightBuf[idx - 1] - heightBuf[idx];
                const y1 = 0;
                const x2 = 0;
                const z2 = heightBuf[idx - w] === undefined ? 0 : heightBuf[idx - w] - heightBuf[idx];
                const y2 = -1;
                const x3 = 1;
                const z3 = heightBuf[idx - w - 1] === undefined ? 0 : heightBuf[idx - w - 1] - heightBuf[idx];
                const y3 = -1;
                xx = y3 * z2 - z3 * y2
                yy = z3 * x2 - x3 * z2
                zz = x3 * y2 - y3 * x2
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                xx /= dist;
                yy /= dist;
                zz /= dist;
                xx1 = y1 * z3 - z1 * y3
                yy1 = z1 * x3 - x1 * z3
                zz1 = x1 * y3 - y1 * x3
                dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5;
                xx += xx1 / dist;
                yy += yy1 / dist;
                zz += zz1 / dist;

                if (smoothNormals) {
                    const x1 = 2;
                    const z1 = heightBuf[idx - 2] === undefined ? 0 : heightBuf[idx - 2] - heightBuf[idx];
                    const y1 = 0;
                    const x2 = 0;
                    const z2 = heightBuf[idx - w * 2] === undefined ? 0 : heightBuf[idx - w * 2] - heightBuf[idx];
                    const y2 = -2;
                    const x3 = 2;
                    const z3 = heightBuf[idx - w * 2 - 2] === undefined ? 0 : heightBuf[idx - w * 2 - 2] - heightBuf[idx];
                    const y3 = -2;
                    xx2 = y3 * z2 - z3 * y2
                    yy2 = z3 * x2 - x3 * z2
                    zz2 = x3 * y2 - y3 * x2
                    dist = (xx2 * xx2 + yy2 * yy2 + zz2 * zz2) ** 0.5 * 2;
                    xx2 /= dist;
                    yy2 /= dist;
                    zz2 /= dist;
                    xx1 = y1 * z3 - z1 * y3
                    yy1 = z1 * x3 - x1 * z3
                    zz1 = x1 * y3 - y1 * x3
                    dist = (xx1 * xx1 + yy1 * yy1 + zz1 * zz1) ** 0.5 * 2;
                    xx2 += xx1 / dist;
                    yy2 += yy1 / dist;
                    zz2 += zz1 / dist;
                    xx += xx2;
                    yy += yy2;
                    zz += zz2;
                }
                dist = (xx * xx + yy * yy + zz * zz) ** 0.5;
                d[i+0] = ((xx / dist) + 1.0) * 128;
                d[i+1] = ((yy / dist) + 1.0) * 128;
                d[i+2] = 255  - ((zz / dist) + 1.0) * 128;
            }

            i += 4;
        }
    }
    ctx.putImageData(imgData, 0, 0);
    return canvas;
}
function createChecker(size, width, height) {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    canvas.width = width * size;
    canvas.height = height * size;
    for(var y = 0; y < size; y ++) {
        for(var x = 0; x < size; x ++) {
            const xx = x * width;
            const yy = y * height;
            ctx.fillStyle ="#888";
            ctx.fillRect(xx,yy,width,height);
            ctx.fillStyle ="#DDD";
            ctx.fillRect(xx,yy,width/2,height/2);
            ctx.fillRect(xx+width/2,yy+height/2,width/2,height/2);
        }
    }
    return canvas;
}

const mouse = {x:0, y:0};
addEventListener("mousemove",e => {mouse.x = e.pageX; mouse.y = e.pageY });
var normMap = normalMapText("GLASSY", "Arial Black", 128, 24, 1, 0.1, true, "round");
canvas.width = normMap.width;
canvas.height = normMap.height;
const locations = {updates: []};
const fArr = arr => new Float32Array(arr);
const gl = canvas.getContext("webgl2", {premultipliedAlpha: false, antialias: false, alpha: false});
const textures = {};
setup();
function texture(gl, image, {min = "LINEAR", mag = "LINEAR", wrapX = "REPEAT", wrapY = "REPEAT"} = {}) {
    const texture = gl.createTexture();
    target = gl.TEXTURE_2D;
    gl.bindTexture(target, texture);
    gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl[min]);
    gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl[mag]);
    gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl[wrapX]);
    gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl[wrapY]);
    gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    return texture;
}
function bindTexture(texture, unit) {
    gl.activeTexture(gl.TEXTURE0 + unit);
    gl.bindTexture(gl.TEXTURE_2D, texture);
}
function Location(name, data, type = "fv", autoUpdate = true) {
    const glUpdateCall = gl["uniform" + data.length + type].bind(gl);
    const loc = gl.getUniformLocation(program, name);
    locations[name] = {data, update() {glUpdateCall(loc, data)}};
    autoUpdate && locations.updates.push(locations[name]);
    return locations[name];
}
function compileShader(src, type, shader = gl.createShader(type)) {
    gl.shaderSource(shader, src);
    gl.compileShader(shader);
    return shader;
}
function setup() {
    program = gl.createProgram();
    gl.attachShader(program, compileShader(vertSrc, gl.VERTEX_SHADER));
    gl.attachShader(program, compileShader(fragSrc, gl.FRAGMENT_SHADER));
    gl.linkProgram(program);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0,1,2,0,2,3]), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ARRAY_BUFFER, fArr([-1,-1,1,-1,1,1,-1,1]), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(loc = gl.getAttribLocation(program, "verts"));
    gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
    gl.useProgram(program);
    Location("scrolls", [0, 0]);
    Location("normalMap", [0], "i", false).update();
    Location("refractionMap", [1], "i", false).update();
    Location("reflectionMap", [2], "i", false).update();
    textures.norm = texture(gl,normMap);
    textures.reflect = texture(gl,createChecker(8,128,128));
    textures.refract = texture(gl,createChecker(8,128,128));
    gl.viewport(0, 0, normMap.width, normMap.height);
    bindTexture(textures.norm, 0);
    bindTexture(textures.reflect, 1);
    bindTexture(textures.refract, 2);
    loop();
}
function draw() {
    for(const l of locations.updates) { l.update() }
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
}
function loop() {
    locations.scrolls.data[0]  = -1 + mouse.x / canvas.width;
    locations.scrolls.data[1]  = -1 + mouse.y / canvas.height;
    draw();
    requestAnimationFrame(loop);
}

canvas {
    position: absolute;
    top: 0px;
    left: 0px;
}

<canvas id="canvas"></canvas>

Personally I find this FX more visually pleasing than simulations based on real lighting models. Though keep in mind THIS IS NOT Refraction or Reflections.


问:
Resize images in HTML using Python- how do I do it properly?
I have 10 images embedded in a wordpress post. I took the html so that I could replace whatever width they all have initially, with a width of 260px (and the height should be scaled accordingly). I also wanted to all align them to the right, wrapping text.

What I did was copy some html to a text file:

```<code><img class="alignright wp-image-3087" src="https://wordpress-346062-1147012.cloudwaysapps.com/wp-content/uploads/2020/02/Signature-Design-By-Ashley-coffee-table-300x159.jpg" alt="Signature Design By Ashley coffee table" width="300" height="159" />
</code>```

The goal width and height: 260 px, 138 px. I know it just takes basic math, so I already know how to scale the image. But my problem lies in changing the values of the weight and height. Is there a built-in module for storing and modifying img attributes?

I already came up with a script to search and replace, but it's fixed. What if I had widths of 800, or 1254? I know I can't just use some hard-coded detector for that.

```<code>with open("unedited_html") as u:
    listofu = [line.rstrip('\n') for line in u]
unedited_html_contents = listofu[0]

infile = raw_input("Enter file name: ")
outfile = "resized_image_%s"%(infile)

checkWords = (old_dimensions) #not yet established, because this is unpredictable
repWords = (new_dimensions) #260, and whatever the height is

f1 = open(infile)
f2 = open(outfile,"w+")
for line in f1:
    for check, rep in zip(checkWords, repWords):
        line = line.replace(check, rep)
    f2.write(line)
f1.close()
f2.close()
</code>```

答:
SOLVED! I used BeautifulSoup and re.</p>

```<code>from bs4 import BeautifulSoup
import re

infile = raw_input("Enter file name: ")
outfile = "resized_image_%s"%(infile)
outfile2 = 'resized_image_2_%s'%(infile)

f1 = open(infile)

for line in f1:
    if any(re.findall(r'<img', str(line), re.IGNORECASE)) == True:
        soup = BeautifulSoup(line)
        img = soup.img
        old_width = float(img['width'])
        old_height = float(img['height'])
        img['height'] = int(260*(old_height/old_width))
        img['width'] = 260
        with open(outfile,'a') as o:
            o.write(unicode(soup))
    else:
        with open(outfile,'a') as o:
            o.write(unicode(line))
f1.close()

f2 = open(outfile)
f3 = open(outfile2,"w+")
for line in f2:
    if any(re.findall(r'<img', str(line), re.IGNORECASE)) == True:
        y = re.sub(r'alignnone','alignright',line)
        f3.write(unicode(y))
    else:
        f3.write(unicode(line))
f2.close()
f3.close()
</code>```

Body:
I have 10 images embedded in a wordpress post. I took the html so that I could replace whatever width they all have initially, with a width of 260px (and the height should be scaled accordingly). I also wanted to all align them to the right, wrapping text.

What I did was copy some html to a text file:

The goal width and height: 260 px, 138 px. I know it just takes basic math, so I already know how to scale the image. But my problem lies in changing the values of the weight and height. Is there a built-in module for storing and modifying img attributes?

I already came up with a script to search and replace, but it's fixed. What if I had widths of 800, or 1254? I know I can't just use some hard-coded detector for that.

with open("unedited_html") as u:
    listofu = [line.rstrip('\n') for line in u]
unedited_html_contents = listofu[0]

infile = raw_input("Enter file name: ")
outfile = "resized_image_%s"%(infile)

checkWords = (old_dimensions) #not yet established, because this is unpredictable
repWords = (new_dimensions) #260, and whatever the height is

f1 = open(infile)
f2 = open(outfile,"w+")
for line in f1:
    for check, rep in zip(checkWords, repWords):
        line = line.replace(check, rep)
    f2.write(line)
f1.close()
f2.close()

Body:
SOLVED! I used BeautifulSoup and re.

from bs4 import BeautifulSoup
import re

infile = raw_input("Enter file name: ")
outfile = "resized_image_%s"%(infile)
outfile2 = 'resized_image_2_%s'%(infile)

f1 = open(infile)

for line in f1:
    if any(re.findall(r'<img', str(line), re.IGNORECASE)) == True:
        soup = BeautifulSoup(line)
        img = soup.img
        old_width = float(img['width'])
        old_height = float(img['height'])
        img['height'] = int(260*(old_height/old_width))
        img['width'] = 260
        with open(outfile,'a') as o:
            o.write(unicode(soup))
    else:
        with open(outfile,'a') as o:
            o.write(unicode(line))
f1.close()

f2 = open(outfile)
f3 = open(outfile2,"w+")
for line in f2:
    if any(re.findall(r'<img', str(line), re.IGNORECASE)) == True:
        y = re.sub(r'alignnone','alignright',line)
        f3.write(unicode(y))
    else:
        f3.write(unicode(line))
f2.close()
f3.close()


问:
Xcode: Multiple Audio Files, Single Button
In Xcode 3.2.5 I would like to play multiple audio files in sequence (50+) from a single UIButton. I've tried several codes but they leak memory. Any suggestions? I'm still learning so please include header and implimentation file codes. My thanks in advance.</p>

答:
This is just conceptual, but what about (a) creating an array of sound names you want to play (this can be during runtime), in the proper order, then (b) writing a function where each soundHandler-type object checks to see where it is in the array; if it's not last it constructs a soundPlayer, loads the sound, plays and then calls the next soundHandler in the array. (If it's last it just constructs/loads/plays, and maybe notifies the parent that it's done.) Each soundHandler (I'm just making that up, you'll have to write it) then can dealloc itself when complete.

If you run into latency/loading issues, you could always have each soundHandler call n+2 in the array, and of course then check to see if it's penultimate instead of the end.

Is that more what you had in mind?


问:
Are point to site VPN clients supposed to support peered VNETs?
I have P2S SSTP connection to VNET1. VNET1 is peered to VNET2. VPN client does not add address space of VNET2 and hence routing from P2S client never works to VNET2. Are SSTP VPN clients supposed to be adding routes for all peered VNETs to installation file?</p>

答:
Yes, the VPN clients will get routes to the direct-peered VNets in the VPN client downloaded file. In this case, you need to configure Hub-spoke network topology in Azure.

To allow gateway traffic to flow from spoke to hub, and connect to remote networks, you must:

Configure the peering connection in the hub(have gateway subnet VNet1) to allow gateway transit.

Configure the peering connection in each spoke(no gateway subnet VNet2) to use remote gateways.

You could get more information from the step by step to work with P2S VPN in a similar scenario.


问:
Python PPTX Internal Hyperlink
I'm trying to use python-pptx to use a click action on a shape to go to another slide in the presentation.

Similar to this question:
Python PPTX Internal Hyperlinks workaround function

Unlike the other tutorials and guides I have seen, I am not looking to add a text run to my shape, my desired behavior is that clicking anywhere on the shape (which has no text) will result in the action behavior. Attempts to follow the guides and documentation have been unsuccessful. I'm able to grab the rId, but not able to add the attribute to the object to enable the linking.

```<code>rId = s1.part.relate_to(s3.part, RT.SLIDE)
#We want to make the entire shape have the linking behavior here
r = s1.placeholders[10].text_frame.paragraphs[0].add_run()
r.text = "Link to Slide 3"
rPr = r._r.get_or_add_rPr()

hlinkClick = rPr.add_hlinkClick(rId)
hlinkClick.set('action', 'ppaction://hlinksldjump')
</code>```

答:
This line of code should suffice:

shape.click_action.target_slide = destination
```

<p>Here's a small working example.</p>

<pre class="lang-py prettyprint-override"><code>from pptx import Presentation
from pptx.util import Inches
from pptx.enum.shapes import MSO_SHAPE

prs = Presentation()
layout = prs.slide_layouts[0]
source = prs.slides.add_slide(layout)
destination = prs.slides.add_slide(layout)

width = height = Inches(1.0)
shape = source.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, 0, 0, width, height)

# the linking part
shape.click_action.target_slide = destination

prs.save('linked_slide.pptx')
</code>```

The documentation also states some possible relative linking action (link to previous, next, first or last slide), but I didn't get this to work yet.

Title: Python PPTX Internal Hyperlink

Body:
I'm trying to use python-pptx to use a click action on a shape to go to another slide in the presentation.

Similar to this question:
Python PPTX Internal Hyperlinks workaround function

Unlike the other tutorials and guides I have seen, I am not looking to add a text run to my shape, my desired behavior is that clicking anywhere on the shape (which has no text) will result in the action behavior. Attempts to follow the guides and documentation have been unsuccessful. I'm able to grab the rId, but not able to add the attribute to the object to enable the linking.

rId = s1.part.relate_to(s3.part, RT.SLIDE)
#We want to make the entire shape have the linking behavior here
r = s1.placeholders[10].text_frame.paragraphs[0].add_run()
r.text = "Link to Slide 3"
rPr = r._r.get_or_add_rPr()

hlinkClick = rPr.add_hlinkClick(rId)
hlinkClick.set('action', 'ppaction://hlinksldjump')

Body:
This line of code should suffice:

shape.click_action.target_slide = destination

Here's a small working example.

from pptx import Presentation
from pptx.util import Inches
from pptx.enum.shapes import MSO_SHAPE

prs = Presentation()
layout = prs.slide_layouts[0]
source = prs.slides.add_slide(layout)
destination = prs.slides.add_slide(layout)

width = height = Inches(1.0)
shape = source.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, 0, 0, width, height)

# the linking part
shape.click_action.target_slide = destination

prs.save('linked_slide.pptx')

The documentation also states some possible relative linking action (link to previous, next, first or last slide), but I didn't get this to work yet.


问:
Can not load the `model1` function of the processR package in a Jupyter Notebook
I am very new to the whole R programming and trying to follow this tutorial, where the model1 function is used to find the Andrew F. Hayes correlation between three variables. As indicated in the tutorial I have the packages installed:

install.packages("devtools")

install.packages("processR")

devtools::install_github("markhwhiteii/processr")

I have also followed the steps:

set.seed(1839)
var1 <- rnorm(100)
cond <- rbinom(100, 1, .5)
var2 <- var1 * cond + rnorm(100)
df3 <- data.frame(var1, var2, cond)
head(df3)
```

<p>accordingly. However, when running:</p>

```mod1result <- model1(iv = "var1", dv = "var2", mod = "cond", data = df3)
```

<p>I get the error message:</p>

<blockquote>
  <p>Error in model1(iv = "var1", dv = "var2", mod = "cond", data = df3): could not find function "model1"
  Traceback:</p>
</blockquote>

<p>and running</p>

```mod1result <- processr::model1(iv = "var1", dv = "var2", mod = "cond", data = df3)
```

Error in loadNamespace(name): there is no package called ‘processr’
  Traceback:

The strange thing is that the same code just worked yesterday and now it doesn't. I would appreciate it if you could help me understand what is wrong and how I can resolve it.

P.S.1. I'm not sure what .libPaths() is but for some reason it returns two paths on my mac:

/usr/local/lib/R/3.6/site-library

/usr/local/Cellar/r/3.6.2/lib/R/library

does it mean that I have two installations of R and this is the main cause of the above issues?

P.S.2. OK. This seems to be Jupyter's fault as everything is just working fine in the terminal.

P.S.3. What seems to be working in the terminal is:

sudo r

devtools::install_github("markhwhiteii/processr")

library(processr) notice lower case r in the processr

P.S.4. I'm not sure if this is Jupyter's fault.

P.S.5. I tried installing the packages on Windows as well. It was even worse. I can't get passed the issue:

Error: Failed to install 'processr' from GitHub:
    (converted from warning) cannot remove the prior installation of package ‘digest’

I think maybe the key to solving this problem is to understand what is the difference between these packages:

install.packages("processR")

devtools::install_github("markhwhiteii/processr")

devtools::install_github("cardiomoon/processR")

答:
From the tutorial page you references, install processr (not processR) in the following way:

```<code># Run this if devtools isn't installed.
# install.packages("devtools")

# Run to install "processr"
devtools::install_github("markhwhiteii/processr")
</code>```

After that successfully completes, processr::model1 will be defined.

When running the code in this post it produces a result:

```<code>set.seed(1839)
var1 <- rnorm(100)
cond <- rbinom(100, 1, .5)
var2 <- var1 * cond + rnorm(100)
df3 <- data.frame(var1, var2, cond)
head(df3)

mod1result <- processr::model1(iv = "var1", dv = "var2", mod = "cond", data = df3)

mod1result
## # A tibble: 6 x 5
##   term          estimate std.error statistic       p.value
##   <chr>            <dbl>     <dbl>     <dbl>         <dbl>
## 1 intercept       0.133      0.146     0.916 0.362
## 2 var1            0.0696     0.156     0.445 0.657
## 3 cond           -0.173      0.200    -0.865 0.389
## 4 interaction     0.854      0.213     4.01  0.000118
## 5 when cond = 0   0.0696     0.156     0.445 0.657
## 6 when cond = 1   0.924      0.144     6.40  0.00000000577

</code>```

Body:
I am very new to the whole R programming and trying to follow this tutorial, where the model1 function is used to find the Andrew F. Hayes correlation between three variables. As indicated in the tutorial I have the packages installed:

install.packages("devtools")

install.packages("processR")

devtools::install_github("markhwhiteii/processr")

I have also followed the steps:

set.seed(1839)
var1 <- rnorm(100)
cond <- rbinom(100, 1, .5)
var2 <- var1 * cond + rnorm(100)
df3 <- data.frame(var1, var2, cond)
head(df3)

accordingly. However, when running:

mod1result <- model1(iv = "var1", dv = "var2", mod = "cond", data = df3)

I get the error message:

Error in model1(iv = "var1", dv = "var2", mod = "cond", data = df3): could not find function "model1"
  Traceback:

and running

mod1result <- processr::model1(iv = "var1", dv = "var2", mod = "cond", data = df3)

Error in loadNamespace(name): there is no package called ‘processr’
  Traceback:

The strange thing is that the same code just worked yesterday and now it doesn't. I would appreciate it if you could help me understand what is wrong and how I can resolve it.

P.S.1. I'm not sure what .libPaths() is but for some reason it returns two paths on my mac:

/usr/local/lib/R/3.6/site-library

/usr/local/Cellar/r/3.6.2/lib/R/library

does it mean that I have two installations of R and this is the main cause of the above issues?

P.S.2. OK. This seems to be Jupyter's fault as everything is just working fine in the terminal.

P.S.3. What seems to be working in the terminal is:

sudo r

devtools::install_github("markhwhiteii/processr")

library(processr) notice lower case r in the processr

P.S.4. I'm not sure if this is Jupyter's fault.

P.S.5. I tried installing the packages on Windows as well. It was even worse. I can't get passed the issue:

Error: Failed to install 'processr' from GitHub:
    (converted from warning) cannot remove the prior installation of package ‘digest’

I think maybe the key to solving this problem is to understand what is the difference between these packages:

install.packages("processR")

devtools::install_github("markhwhiteii/processr")

devtools::install_github("cardiomoon/processR")

Body:
From the tutorial page you references, install processr (not processR) in the following way:

# Run this if devtools isn't installed.
# install.packages("devtools")

# Run to install "processr"
devtools::install_github("markhwhiteii/processr")

After that successfully completes, processr::model1 will be defined.

When running the code in this post it produces a result:

set.seed(1839)
var1 <- rnorm(100)
cond <- rbinom(100, 1, .5)
var2 <- var1 * cond + rnorm(100)
df3 <- data.frame(var1, var2, cond)
head(df3)

mod1result <- processr::model1(iv = "var1", dv = "var2", mod = "cond", data = df3)

mod1result
## # A tibble: 6 x 5
##   term          estimate std.error statistic       p.value
##   <chr>            <dbl>     <dbl>     <dbl>         <dbl>
## 1 intercept       0.133      0.146     0.916 0.362
## 2 var1            0.0696     0.156     0.445 0.657
## 3 cond           -0.173      0.200    -0.865 0.389
## 4 interaction     0.854      0.213     4.01  0.000118
## 5 when cond = 0   0.0696     0.156     0.445 0.657
## 6 when cond = 1   0.924      0.144     6.40  0.00000000577


问:
Redirect API in PHP with POST data
I created a new API that receives XML data in POST and responds in XML. The link is

```<code>localhost/api/rate.php
</code>```

Now, users were already accessing the old version of this API using the following link,

```<code>localhost/rate.php
</code>```

I need to redirect to the new link when the user hits the old link and displays the response from the new API to the user.

If I user header(location) the POST data does not get sent to the new API, so I'm out of options.

答:
you could do like this:

your rate.php:

```<code><?php

function redirect($url) {
  $html = "<html><body><form id='form' action='$url' method='post'>";
  foreach ($_POST as $key => $value) {
    $html .= "<input type='hidden' name='$key' value='$value'>";
  }
  $html .= "</form><script>document.getElementById('form').submit();</script>";
  $html .= "</body></html>";
  print($html);
}

redirect('api/rate.php');
</code>```

or safer:

```<code>.htaccess file with:

RewriteEngine On
RewriteRule ^rate.php(.*)$ /api/rate.php$1 [R=302]
</code>```

Title: Redirect API in PHP with POST data

Body:
I created a new API that receives XML data in POST and responds in XML. The link is

localhost/api/rate.php

Now, users were already accessing the old version of this API using the following link,

localhost/rate.php

I need to redirect to the new link when the user hits the old link and displays the response from the new API to the user.

If I user header(location) the POST data does not get sent to the new API, so I'm out of options.

Body:
you could do like this:

your rate.php:

<?php

function redirect($url) {
  $html = "<html><body><form id='form' action='$url' method='post'>";
  foreach ($_POST as $key => $value) {
    $html .= "<input type='hidden' name='$key' value='$value'>";
  }
  $html .= "</form><script>document.getElementById('form').submit();</script>";
  $html .= "</body></html>";
  print($html);
}

redirect('api/rate.php');

or safer:

.htaccess file with:

RewriteEngine On
RewriteRule ^rate.php(.*)$ /api/rate.php$1 [R=302]


问:
Can't open InputStream on Intent.ACTION_OPEN_DOCUMENT_TREE result
So, I wan't to make a simple recording app in which a user can select their preferred save location.
I plan on getting the Uri of the selected dir via Intent.ACTION_OPEN_DOCUMENT_TREE, save and process it with InputStream and MediaRecorder.

When I try to process the Result in my onActivityResult,

```<code>    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == resources.getInteger(R.integer.request_code_preference_storage) &&
                resultCode == Activity.RESULT_OK){
            val uri = data!!.data
            val inputstream = InputStreamHelper.readTextFromUri(uri!!, context!!)
    }
</code>```

I get the following error:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/tree/primary:Download flg=0xc3 }} to activity {de.ur.mi.audidroid/de.ur.mi.audidroid.views.MainActivity}: java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/primary%3ADownload

I don't know why it won't take the uri. DocumentFile will take it without any complaints through DocumentFile.fromTreeUri(context!!,uri!!).

The InputStreamHelper is an object I basically copied directly from the documentation.

```<code>object InputStreamHelper{
fun readTextFromUri(uri: Uri, context: Context): String {
    val stringBuilder = StringBuilder()
    context.contentResolver.openInputStream(uri)?.use { inputStream ->
        BufferedReader(InputStreamReader(inputStream)).use { reader ->
            var line: String? = reader.readLine()
            while (line != null) {
                stringBuilder.append(line)
                line = reader.readLine()
            }
        }
    }
    return stringBuilder.toString()
}
}
</code>```

I'm confused and confounded. It's nothing complicated but I hit a roadblock.

答:
If you used ACTION_OPEN_DOCUMENT_TREE, that allows the user to pick a document tree, representing a collection of content. You cannot open an InputStream on that.

Perhaps you should be using ACTION_OPEN_DOCUMENT. This allows the user to pick an individual piece of content, and you can open an InputStream on that.

BTW, I think that you could replace that loop construct with:

```<code>return context.contentResolver.openInputStream(uri)?.use { it.reader().readLines() }
</code>```

Body:
So, I wan't to make a simple recording app in which a user can select their preferred save location.
I plan on getting the Uri of the selected dir via Intent.ACTION_OPEN_DOCUMENT_TREE, save and process it with InputStream and MediaRecorder.

When I try to process the Result in my onActivityResult,

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == resources.getInteger(R.integer.request_code_preference_storage) &&
                resultCode == Activity.RESULT_OK){
            val uri = data!!.data
            val inputstream = InputStreamHelper.readTextFromUri(uri!!, context!!)
    }

I get the following error:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/tree/primary:Download flg=0xc3 }} to activity {de.ur.mi.audidroid/de.ur.mi.audidroid.views.MainActivity}: java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/primary%3ADownload

I don't know why it won't take the uri. DocumentFile will take it without any complaints through DocumentFile.fromTreeUri(context!!,uri!!).

The InputStreamHelper is an object I basically copied directly from the documentation.

object InputStreamHelper{
fun readTextFromUri(uri: Uri, context: Context): String {
    val stringBuilder = StringBuilder()
    context.contentResolver.openInputStream(uri)?.use { inputStream ->
        BufferedReader(InputStreamReader(inputStream)).use { reader ->
            var line: String? = reader.readLine()
            while (line != null) {
                stringBuilder.append(line)
                line = reader.readLine()
            }
        }
    }
    return stringBuilder.toString()
}
}

I'm confused and confounded. It's nothing complicated but I hit a roadblock.

Body:
If you used ACTION_OPEN_DOCUMENT_TREE, that allows the user to pick a document tree, representing a collection of content. You cannot open an InputStream on that.

Perhaps you should be using ACTION_OPEN_DOCUMENT. This allows the user to pick an individual piece of content, and you can open an InputStream on that.

BTW, I think that you could replace that loop construct with:

return context.contentResolver.openInputStream(uri)?.use { it.reader().readLines() }


问:
firebase cannot determine project id
this is the request that I made using node

```<code>
// Initialize the default app
var admin = require('firebase-admin');

var app = admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  databaseURL: process.env.FIREBASE_DATABASE
});

console.log(process.env.FIREBASE_DATABASE);

router.post('/', (req, res, next) => {

    app.auth().getUserByEmail("j.100233260@gmail.com")
    .then(function(userRecord) {
            // See the UserRecord reference doc for the contents of userRecord.
            console.log('Successfully fetched user data:', userRecord.toJSON());
            res.json(userRecord.toJSON())
        })
        .catch(function(error) {
                console.log('Error fetching user data:', error);
                res.json(error)

            });

        }

        );
</code>```

I set the env var on my machine

for my firebase database I used env

given as

```<code>databaseURL: "https://fssssss.firebaseio.com",
</code>```

from the firebase admin GUI ,

the error in Postman when I request this route

```<code>{
    "code": "app/invalid-credential",
    "message": "Failed to determine project ID: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal metadata.google.internal:80. Error code: ENOTFOUND"
}
</code>```

I followed the docs and google returned no results, no idea what to do. thanks.

答:
This isn't working the way you expect:

```<code>admin.credential.applicationDefault()
</code>```

You can't use this on a server that you control without additional configuration.  This only works by itself when running on Google services when you want to use the default service account for your project.  When running on your own server, there is no default.  You have to be explicit and download service account credentials to use during initialization.  At the very least, you'll need to follow the instructions in the documentation:

To authenticate a service account and authorize it to access Firebase
  services, you must generate a private key file in JSON format.

To generate a private key file for your service account:

In the Firebase console, open Settings > Service Accounts.

Click Generate New Private Key, then confirm by clicking Generate Key.

Securely store the JSON file containing the key.

When authorizing via a service account, you have two choices for
  providing the credentials to your application. You can either set the
  GOOGLE_APPLICATION_CREDENTIALS environment variable, or you can
  explicitly pass the path to the service account key in code. The first
  option is more secure and is strongly recommended.

So you will need to download the service account file, set GOOGLE_APPLICATION_CREDENTIALS correctly, then your code will work.  The service account credentials are not optional.

Title: firebase cannot determine project id

Body:
this is the request that I made using node

// Initialize the default app
var admin = require('firebase-admin');

var app = admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  databaseURL: process.env.FIREBASE_DATABASE
});

console.log(process.env.FIREBASE_DATABASE);

router.post('/', (req, res, next) => {

    app.auth().getUserByEmail("j.100233260@gmail.com")
    .then(function(userRecord) {
            // See the UserRecord reference doc for the contents of userRecord.
            console.log('Successfully fetched user data:', userRecord.toJSON());
            res.json(userRecord.toJSON())
        })
        .catch(function(error) {
                console.log('Error fetching user data:', error);
                res.json(error)

            });

        }

        );

I set the env var on my machine

for my firebase database I used env

given as

databaseURL: "https://fssssss.firebaseio.com",

from the firebase admin GUI ,

the error in Postman when I request this route

{
    "code": "app/invalid-credential",
    "message": "Failed to determine project ID: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal metadata.google.internal:80. Error code: ENOTFOUND"
}

I followed the docs and google returned no results, no idea what to do. thanks.

Body:
This isn't working the way you expect:

admin.credential.applicationDefault()

You can't use this on a server that you control without additional configuration.  This only works by itself when running on Google services when you want to use the default service account for your project.  When running on your own server, there is no default.  You have to be explicit and download service account credentials to use during initialization.  At the very least, you'll need to follow the instructions in the documentation:

To authenticate a service account and authorize it to access Firebase
  services, you must generate a private key file in JSON format.

To generate a private key file for your service account:

In the Firebase console, open Settings > Service Accounts.

Click Generate New Private Key, then confirm by clicking Generate Key.

Securely store the JSON file containing the key.

When authorizing via a service account, you have two choices for
  providing the credentials to your application. You can either set the
  GOOGLE_APPLICATION_CREDENTIALS environment variable, or you can
  explicitly pass the path to the service account key in code. The first
  option is more secure and is strongly recommended.

So you will need to download the service account file, set GOOGLE_APPLICATION_CREDENTIALS correctly, then your code will work.  The service account credentials are not optional.


问:
MS Access Dropdown List/Combo Box
This should probably be pretty simple but my Google-Fu is as yet unable to find an answer. I simply want to create a dropdown list in Access so that upon selection I can perform some action based on the value of the selection. For instance, I have a list of people and I would like to populate the combo box so that their names appear in the list but the "value" is set to their ID (the primary key).</p>

答: OK, I figured it out even though it was a bit counter-intuitive. An Access Combobox can have as many values as you want (instead of just one key on value). By default all of the values are are shown in the list so you need to hide certain columns by setting their widths to 0. That is done via the ColumnsWidths property in the property pane. ColumnWidths takes a comma separated list of values which corresponds to the order of the columns in the list. I hope this helps someone.</p>

OwnerDisplayName: noblethrasher

ContentLicense: CC BY-SA 2.5

Title: MS Access Dropdown List/Combo Box

LastEditorDisplayName: Chris Ballance


问:
Change border from parent div by hovering the child div
I try to change the color of the border but nothing works out.
Is it even possible with css? I already found this: How to affect other elements when one element is hovered
and also How to style the parent element when hovering a child element?

Some java / jquery solution?

.wcppec-checkout-buttons {
  outline: 10px solid #ffc439;
  outline-offset: -10px;
}

#woo_pp_ec_button_cart {
  height: 44px;
}

#woo_pp_ec_button_cart:hover>.wcppec-checkout-buttons {
  outline: 10px solid #f1bb37;
  outline-offset: -10px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="wcppec-checkout-buttons">
  <div id="woo_pp_ec_button_cart">
  </div>
</div></code>```

答:
You can use this javascript

```<code>const child = document.getElementById("woo_pp_ec_button_cart");
child.onmouseover=function(){
    this.parentElement.style="outline:10px solid blue"
}
</code>```

Or if it works for you you can change the css to this

```<code>.wcppec-checkout-buttons:hover  {
    outline: 10px solid #f1bb37;
    outline-offset: -10px;
}
</code>```

Check which one works better for you.

Body:
You can use this javascript

const child = document.getElementById("woo_pp_ec_button_cart");
child.onmouseover=function(){
    this.parentElement.style="outline:10px solid blue"
}

Or if it works for you you can change the css to this

.wcppec-checkout-buttons:hover  {
    outline: 10px solid #f1bb37;
    outline-offset: -10px;
}

Check which one works better for you.


问:
Kubernetes pods graceful shutdown with TCP connections (Spring boot)
I am hosting my services on azure cloud, sometimes I get "BackendConnectionFailure" without any apparent reason, after investigation I found a correlation between this exception and autoscale (scaling down) almost at the same second in most of the cases.

According to documentation termination grace period by default is 30 seconds, which is the case. The pod will be marked terminating and the loadbalancer will not consider it anymore, so receiving no more requests. According to this if my service takes far less time than 30 seconds, I should not need prestop hook or any special implementation in my application (please correct me if I am wrong).

If the previous paragraph is correct, why does this exception occur relatively frequent? My thought is when the pod is marked terminating and the loadbalancer does not forward anymore requests to the pod while it should do.

Edit 1:

The Architecture is simply like this

Client -> Firewall(azure) -> API(azure APIM) -> Microservices(Spring boot) -> backend(third party) or azure RDB depending on the service

I think the Exception comes from APIM, I found two patterns for this exception:

Message   The underlying connection was closed: The connection was closed unexpectedly.
Exception type  BackendConnectionFailure
Failed method   forward-request

Response time  10.0 s

Message    The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.
Exception type  BackendConnectionFailure
Failed method   forward-request

Response time  3.6 ms

答:
Spring Boot doesn't do graceful termination by default.

The Spring Boot app and it's application container (not linux container) are in control of what happens to existing connections during the termination grace period. The protocols being used and how a client reacts to a "close" also have a part to play.

If you get to the end of the grace period, then everything gets a hard reset.

Kubernetes

When a pod is deleted in k8s, the Pod Endpoint removal from Services is triggered at the same time as the SIGTERM signal to the container(s).

At this point the cluster nodes will be reconfigured to remove any rules directing new traffic to the Pod. Any existing TCP connections to the Pod/containers will remain in connection tracking until they are closed (by the client, server or network stack).

For HTTP Keep Alive or HTTP/2 services, the client will continue hitting the same Pod Endpoint until it is told to close the connection (or it is forcibly reset)

App

The basic rules are, on SIGTERM the application should:

Allow running transactions to complete

Do any application cleanup required

Stop accepting new connections, just in case

Close any inactive connections it can (keep alive requests, websockets)

Some circumstances you might not be able to handle (depends on the client)

A keep alive connection that doesn't complete a request in the grace period, can't get a Connection: close header. It will need a TCP level FIN close.

A slow client with a long transfer, in a one way HTTP transfer these will have to be waited for or forcibly closed.

Although keepalive clients should respect a TCP FIN close, every client reacts differently. Microsoft APIM might be sensitive and produce the error even though there was no real world impact. It's best to load test your setup while scaling to see if there is a real world impact.

For more spring boot info see:

https://github.com/spring-projects/spring-boot/issues/4657
https://github.com/corentin59/spring-boot-graceful-shutdown
https://github.com/SchweizerischeBundesbahnen/springboot-graceful-shutdown