Support for new Twitch Helix API

Twitch will shut down API V5 on 12/31/2018. Until then TL has to switch to the new Helix API.
Difficulties:
The new API does not contain any information about the video quality or framerate. The quality selection would be gone. TL would only be capable of downloading source quality. It is how it is, unfortunately.
I got in contact with Twitch here:
https://discuss.dev.twitch.tv/t/get-qualities-of-videos/14633
But there is no guarantee this will happen anytime soon.

And how am I supposed to watch 1080p 60fps source quality on my little netbook from 2010 (2 cores 1 GHz each). Damn twitch...

@Z-brah If you want to wait like 20 hours until your 2010 toaster has re-encoded the video. Depending on the VOD length your machine will simply die 😄
TL does not re-encode anything at the moment, that's why the processing stage is very fast.

Well, they must implement it somehow for their own frontend. Looking at the API calls from twitch.tv now, and they're fetching from both the new and old API. For example this page fetches both of these:
https://api.twitch.tv/kraken/videos/v277382046
https://api.twitch.tv/api/videos/v277382046

@ihabunek Both of your urls point to the old API.
The new API is
https://api.twitch.tv/helix/........
and is queried with query parameters like
https://api.twitch.tv/helix/videos?id=277382046
The result is
{
    "data": [
        {
            "id": "277382046",
            "user_id": "25150991",
            "title": "Pokémon, then Darkest Dungeon! - @SleepCycles",
            "description": "",
            "created_at": "2018-06-25T13:06:13Z",
            "published_at": "2018-06-25T13:06:13Z",
            "url": "https://www.twitch.tv/videos/277382046",
            "thumbnail_url": "https://static-cdn.jtvnw.net/s3_vods/b53e3fb705f1175d79dc_sleepcycles_29228374208_895443551/thumb/thumb0-%{width}x%{height}.jpg",
            "viewable": "public",
            "view_count": 96,
            "language": "en",
            "type": "archive",
            "duration": "5h6m30s"
        }
    ],
    "pagination": {}
}

No sign of quality or framerate data...

My mistake, but my point stands. Currently twitch.tv itself is using the old API to get the available resolutions. They will need to either keep the old API endpoint alive, or add resolution data to the new API in order for their own web to work.

Sure, that's why I am waiting. The thing is, they could be using a private API in the end. We'll see how they are going to solve that. I think v5 will be supported longer than 2018. Helix is far from complete and there are many complaints about it. Somewhere I even found a forum post recommending longer support for v5.
So everybody can chill right now 😄

I see that when @Franiac contacted the twitch staff he did not link to this project, nor did they mention their true intentions.
I wonder if this was deliberate...

@TheSneakySniper How does this recognition contribute to this GitHub issue?

@xzion Ha! That's what I expected.

To re-encode video, there are free tools available. I use Avidemux tool because it's nice and easy editor. You can cut very fast videos and remove unwanted parts. And with filters, you can adjust video and resize it.
You can even make it with command line: http://www.avidemux.org/admWiki/doku.php?id=using:command_line_usage
So it's no need to make another encoder again and just get free tools for converting videos.

@MrDummyNL

"free to use" does not nessessarily mean "free to distribute".
There are many people out there that do not have avidemux and don't want it to be installed in addition to Twitch Leecher. (TL uses ffmpeg)

FYI: The new shutdown date is February 28, 2022.
https://blog.twitch.tv/en/2021/07/15/legacy-twitch-api-v5-shutdown-details-and-timeline/?utm_referrer=https://dev.twitch.tv/

I prepared myself a little bit for the Helix API swap. Apparently TL will need user login to work with Helix. The API requires either an user access token or an app access token. The latter is only designed to work with server-to-server communication since the creation of an app access token needs the client secret (not to be confused with the client id) and that is actually... yeah... secret, so I cannot put it into the TL source code.
So TL will ask for user login every time there is no valid user token available. Once logged in, TL will remember the token and try to validate it on the next start. If it is still valid, everything's cool, if not, the user needs to renew their login.
Also in order to retreive the available VOD resolutions TL needs to download the playlist summary file. So the resolution cannot be displayed in the search result view anymore. In the download view it will be available still, though.

Also the newly introduced rate limits on the API are designed "per user per client id" or "per app (client id)". So the login is actually beneficial because if we used an app access token, all TL users on the planet would share a single API rate bucket. That would end in amazingly long wait times between requests.

This is now completely implemented in the "helix" branch. I will merge it as soon as it is necessary.
Things that will not work anymore:

Show resultion in search results (now needs the playlist, but I cannot download it for every video in the results)
Show game icon in search results (the game is not part of the video anymore in helix)


mill: 0.11.11 -> 0.11.12

Automatic update generated by nixpkgs-update tools. This update was made based on information from https://github.com/com-lihaoyi/mill/releases.
meta.description for mill is: Build tool for Scala, Java and more
meta.homepage for mill is: https://com-lihaoyi.github.io/mill/
Updates performed

Version update

To inspect upstream changes

Release on GitHub

Compare changes on GitHub

Impact
Checks done

built on NixOS
The tests defined in passthru.tests, if any, passed
found 0.11.12 in filename of file in /nix/store/mq5s6qnb4zgw0i13l5wjmxj2r9ca8szd-mill-0.11.12

Rebuild report (if merged into master) (click to expand)

2 total rebuild path(s)

2 package rebuild(s)

First fifty rebuilds by attrpath

mill

Instructions to test this update (click to expand)

Either download from Cachix:
nix-store -r /nix/store/mq5s6qnb4zgw0i13l5wjmxj2r9ca8szd-mill-0.11.12 \
  --option binary-caches 'https://cache.nixos.org/ https://nix-community.cachix.org/' \
  --option trusted-public-keys '
  nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
  cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
  '

(The Cachix cache is only trusted for this store-path realization.)
For the Cachix download to work, your user must be in the trusted-users list or you can use sudo since root is effectively trusted.
Or, build yourself:
nix-build -A mill https://github.com/r-ryantm/nixpkgs/archive/8d70b14b21eacfc3af1e153b10344d89c70a87d3.tar.gz

Or:
nix build github:r-ryantm/nixpkgs/8d70b14b21eacfc3af1e153b10344d89c70a87d3#mill

After you've downloaded or built it, look at the files and if there are any, run the binaries:
ls -la /nix/store/mq5s6qnb4zgw0i13l5wjmxj2r9ca8szd-mill-0.11.12
ls -la /nix/store/mq5s6qnb4zgw0i13l5wjmxj2r9ca8szd-mill-0.11.12/bin

Pre-merge build results
We have automatically built all packages that will get rebuilt due to
this change.
This gives evidence on whether the upgrade will break dependent packages.
Note sometimes packages show up as failed to build independent of the
change, simply because they are already broken on the target branch.
Result of nixpkgs-review run on x86_64-linux 1

1 package built:

mill

Maintainer pings
cc @scalavision @ZenithalHourlyRate for testing.

[!TIP]
As a maintainer, if your package is located under pkgs/by-name/*, you can comment @NixOS/nixpkgs-merge-bot merge to automatically merge this update using the nixpkgs-merge-bot.

Add a :+1: reaction to pull requests you find important.

Result of nixpkgs-review pr 336256 run on aarch64-darwin 1

1 package built:

mill


[BUG] Azure Datalake Gen2 Java SDK FileClient sometimes appends lines of 0x00s

We have an application that appends a couple of hundred lines over a period of five minutes to a file in Azure Gen2 Datalake. The below code simulates the application.
We noticed that sometimes, a line of 0x00s written to the file instead of the text. No errors thrown.
public class AdlAppender {

    private static final String datalake = "<<datalake-name>>";
    private static final String url = "https://<<datalake-name>>.dfs.core.windows.net";
    private static final String key = "<<access-key>>";
    private static final String container = "<<container-name>>";
    private static final String fileName = "<<file-path>>";

    final DataLakeFileClient fileClient;

    public AdlAppender() {
        final StorageSharedKeyCredential credential = new StorageSharedKeyCredential(datalake, key);

        final DataLakeServiceClient dataLakeServiceClient = new DataLakeServiceClientBuilder()
            .endpoint(url)
            .credential(credential)
            .buildClient();

        final DataLakeFileSystemClient fileSystemClient = dataLakeServiceClient.getFileSystemClient(container);

        fileClient = fileSystemClient.createFile(fileName);
    }

    public long append(final String content, final long offset) {
        final byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
        final int length = bytes.length;
        final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);

        fileClient.append(inputStream, offset, length);

        final long updatedOffset = offset + length;
        fileClient.flush(updatedOffset);

        return updatedOffset;
    }
}

public class AdlAppenderTest {

    @Test
    public void testAppendFile() throws InterruptedException {
        final AdlAppender adlAppender = new AdlAppender();
        final String content = "The quick brown fox jumps over the lazy dog\n";
        final int size = content.length();
        long offset = 0;

        final int numLines = 200;
        final int duration = 5;
        for (int i = 1; i <= numLines; i++) {
            offset = adlAppender.append(content, offset);
            assert offset == size * i;

            Thread.sleep(duration * 60 * 1000 / numLines);
        }
    }
}

Hi @vida-bandara-by
Thank you for reporting this issue. I will take a look into what might be causing this issue.
Could you share the version of azure-storage-file-datalake you are using?

Hi @vida-bandara-by
Thank you for reporting this issue. I will take a look into what might be causing this issue.
Could you share the version of azure-storage-file-datalake you are using?

Could you also share how you notice that a line of 0x00s are getting appended to the file? Do you have code somewhere that checks by download the file or are you visually inspecting on azure portal?

Thank you very much @gapra-msft for looking into this.

Hi @vida-bandara-by
I ran your repro with the version you specified and I was able to repro the issue.
I suspect the issue is due to bad retry behavior in that version of datalake and before. We have since fixed the issue.
Could you please try using azure-storage-file-datalake version 12.1.2+ so you can pick up the fix?
Thanks

Thank you @gapra-msft ! Will update to the new version.

Hi @vida-bandara-by
Are you still seeing this issue? Feel free to close the issue once you've confirmed the fix!

Hi @gapra-msft , we rolled out the new version. Please allow me to watch it for a few days and then close the issue. Thank you again for your help with this matter!

We updated the version and observed for a week. Did not see the issue again. Thank you @gapra-msft ! Closing the issue.


Added TreeNode.is_bifurcating

Please complete the following checklist:

[x] I have read the contribution guidelines.

[ ] I have documented all public-facing changes in the changelog.

[ ] This pull request includes code, documentation, or other content derived from external source(s). If this is the case, ensure the external source's license is compatible with scikit-bio's license. Include the license in the licenses directory and add a comment in the code giving proper attribution. Ensure any other requirements set forth by the license and/or author are satisfied.

It is your responsibility to disclose code, documentation, or other content derived from external source(s). If you have questions about whether something can be included in the project or how to give proper attribution, include those questions in your pull request and a reviewer will assist you.

[x] This pull request does not include code, documentation, or other content derived from external source(s).

Note: This document may also be helpful to see some of the things code reviewers will be verifying when reviewing your pull request.

Hi @wasade I have benchmarked, and realized that the true bottleneck is non_tips, whereas the operator functions you suggested has minimum impact on the performance. Therefore, I have updated the PR to adopt your suggestion, with slight modifications. Here are the benchmarks:
Version 1:
if strict:
    for node in self.traverse(include_self=True):
        if node.children and len(node.children) != 2:
            return False
else:
    for node in self.traverse(include_self=True):
        if len(node.children) > 2:
            return False
return True

Version 2:
test = ne if strict else gt
for node in self.non_tips(include_self=True):
    if test(len(node.children), 2):
        return False
return True

Version 3:
test = ne if strict else gt
for node in self.traverse(include_self=True):
    if (children := node.children) and test(len(children), 2):
        return False
return True

Benchmarks on the 10.5k-tip tree:
v1: 1.83 ms ± 44.2 μs
v2: 3.66 ms ± 96.6 μs
v3: 1.88 ms ± 7.13 μs
v1, strict: 1.81 ms ± 7.42 μs
v2, strict: 3.61 ms ± 72.8 μs
v3, strict: 1.95 ms ± 42.2 μs


Release 3 5 0

Closes out Release 3.5

Hi @morarucostel created a PR for the 3.5.0 release. What are we missing from the documentation? Do we just raise GitHub issues and merge what we have?

Hey @tlawrie , your suggestion sounds very good to me.
I'll raise the issues to the missing documentation and tag the people responsible with those areas, assign them to 3.5.1 release. That would be:

Redesign the eventing library to support multiple Streams and Consumers to @corcoja
Update SendEmailWithPostmarkTemplate task to accept Message Stream to @tlawrie

I think we have only these two topics, the rests being fixed issues, which are not modifying the existing docs.
I'll open the above ones.

Ok. And do we need one for the Tekton upgrade version in the architecture?


[BUG] Cluster State API is undocumented and unavailable in clients

Describe the bug
Coming from https://github.com/opensearch-project/OpenSearch/issues/7066#issuecomment-1501541654
Internally to OpenSearch, the cluster state is retrieved by handling the ClusterStateAction / TransportClusterStateAction / ClusterStateRequest / ClusterStateResponse implementations.  The RestClusterStateAction exposes the API (?) as:

/_cluster/state
/_cluster/state/{metric}
/_cluster/state/{metric}/{indices}

However, there is no (0 / zero / null) documentation of this API on the OpenSearch website.  Entering "/_cluster/state" in the search bar at https://opensearch.org/ gives 17 responses, out of which zero contain the text "/_cluster/state".
Entering "/_cluster/state" and "OpenSearch" as key words into your favorite search engine give no results on https://opensearch.org/ (other than one of the previous 17 that doesn't actually include that text).  There are some third-party references to the API, a reference to the API at ElasticSearch, and inclusion as a "common" API request on AOS documentation page.
More importantly, this "API" is not accessible via OpenSearch clients.  Clients are spec-driven, but the Cluster APIs do not include it.  While it's possible to reverse-engineer the ClusterStateRequest to construct a raw endpoint for performRequest() on the clients, the returned response is just JSON and parsing it into a ClusterStateResponse is an exercise in futility.
Expected behavior

The API is documented on the OpenSearch website. (Definitely.)
The ClusterStateRequest/ClusterStateResponse objects are usable in OpenSearch clients in all languages. (Maybe not, see comments below.)

But, I wonder if we want to expose all _cluster/state API constructs to clients. I foresee lot of challenges:

To start with "custom" that you mentioned above. Plugins can add any custom data in cluster state and it would be breaking change if fromXContent is enforced. Also, plugins can choose not to send certain data in API response and mark it private.
Today, these internal data structures are updated just thinking about server side backward compatibility. Now changing anything in those structures could potentially break clients and would result in too much overhead.
If you look at the toXContent method of some of the classes you will notice, not all fields are serialized, only a subset which might not be sufficient to deserialize the object back to current ClusterState data structures. e.g. anywhere Index is serialized in routing information, only its name is serialized not Index UUID. Metadata classes have fromXContent already implemented as it is used to serde to and from disk as well.

I see this API more of helping in debugging and providing it as official Cluster APIs in client could cause lot of maintenance overhead. Until community feels the need with real use cases, we should refrain from exposing it.

Originally posted by @shwetathareja in https://github.com/opensearch-project/OpenSearch/issues/7066#issuecomment-1502961737

Should we move this to documentation-website as a documentation bug?

moving it to documentation-website repo as a documentation bug


Update examples for zkApp name change

Will be fixed by Martin's https://github.com/o1-labs/zkapp-cli/pull/152


Test

Deploy preview ready!
Built with commit 7fec5726c214017a8f4f87058cc4b8e41b34d048
https://deploy-preview-39--arnaudligny.netlify.com


Scalafmt .git-blame-ignore-revs

Continuation of https://github.com/schmitch/sbt-jib/pull/77

t4t


Support of api encryption

Hi,
its planned to support api encryption (Optional): Enable transport encryption of the API layer?
The password option is Deprecated.
https://esphome.io/components/api.html
password (Optional, Deprecated, string): The password to protect the API Server with. Defaults to no password. It is recommended to use the encryption -> key above instead of the the password.
Are you working on a new release? Last update was on 2021?

After the library migration in https://github.com/DrozmotiX/ioBroker.esphome/pull/167 this should not be that hard to implement.

After the library migration in #167 this should not be that hard to implement.

fix implemented

@DutchmanNL sorry to bother, where is this implemented - i can't seem to find a change? Do you only have the fix locally currently maybe?

@DutchmanNL sorry to bother, where is this implemented - i can't seem to find a change? Do you only have the fix locally currently maybe?

I See I was a little to quick closing this issue
Based on your PR the new APi dependency is integrated which supports encryption, but that's only backend also need to include it in adapter logic + admin settings
Reopen

Works perfect!

Works perfect!

Lovely thank you confirming!


add prefetch capability

This PR adds prefetch capability to the SMART app.  Right now it simply uses a hardcoded prefetch template from an example CDS service, contained in a json file, but in later work this can be switched to make a request to the CDS service (REMS admin) to retrieve the prefetch template.
The basic flow is that the prefetch template from the REMS admin contains the resources that are being requested for prefetch. The EHR (SMART app) then decides which of those requests it will fulfill.  As of right now it just defaults to fulfilling everything it can.  The requests are parsed and contextual information like the current patient/user are used to get pertinent information, and that information is put into the prefetch property of the hook.
This PR also adds some basic hook construction to support the prefetch functionality.  More work is needed to fully flesh out the hook construction.  But as it stands now, the hook is valid according to the CDS spec.

Thank you for fixing some of the bugs on my branch and building out this functionality


[v6] Normalization caret position is lost

Not sure if this should specifically be handled by redux-form, but the phone example with normalization loses the caret position when typing/deleting from the middle of the value
http://redux-form.com/6.0.0-rc.3/examples/normalizing/

I've had the same issue on my normalized input fields. I'm not sure if it's redux-form, react, or the normalization library.

I am having this same problem.  I believe it is caused by normalize replacing the inputs value which bumps the cursor to the end.

React is the one in charge of the cursor position (and it's a hard problem), so this might not be fixable, I'm afraid. Certainly not by this library.

This makes normalization really problematic, IMHO.
Is there any way to delay normalization until BLUR, meaning that the input text does not normalize until the user leaves the field?

Why wouldn't you want to normalize right away? Makes entering the input for users much easier if it's formatted automatically.

@brotzky, right, but the behavior of the caret in certain situations (as described in this issue) is a very bad UX and a no-go IMHO.
Any solution very welcome...

since opening this i've come to the conclusion that these are the pro-s and cons of using normalization. for the vast majority of cases a user either types the entire string at once or deletes the entire thing and re-types it in which case this problem does not resurface.
I personally chose to ignore the other group, but if you want, you can implement a combination of realtime + blur normalization based on the caret position
class NormalizedInput extends React.Component {

    state = { value: '' }

    constructor (props) {
        super(props);
        this.state.value = props.input.value;
    }

    componentWillReceiveProps (nextProps) {
        if (nextProps.input.value === this.props.input.value) return;
        this.setState({value: nextProps.input.value});
    }

    onChange (event) {
        const {target} = event;
        const {value} = target;
        this.setState({value});
        if (target.selectionStart !== value.length) return;
        this.props.input.onChange(event);
    }

    render () {
        const {input: {value, onChange, ...input}} = this.props;
        return

            <input type='text' {...input} value={this.state.value} onChange={::this.onChange} />;

props.input.value: {this.props.input.value}

state.value: {this.state.value}

    }
}

Usage:
const formatUppercase = str => str.toUpperCase();
<Field name='name' component={NormalizedInput} format={formatUppercase} />

This works as normalization will now be applied on blur (as default) and only be applied on change if the caret is at the end. This is the best middle-ground I could find between the two approaches.

for the vast majority of cases a user either types the entire string at once or deletes the entire thing and re-types it

So when you're filling a text field and then realize you made a typo in the middle of the text (not a rare situation IMHO), you go and clear the field and then type everything again?

This works as normalization will now be applied on blur (as default) and only be applied on change if the caret is at the end. This is the best middle-ground I could find between the two approaches.

Great solution! Just can't figure out where in that code snipped onChange will be called on blur.

@jampy I didn't realize you meant specifically the caret position bug. I was under the assumption that this happens because of React, not Redux Form.

the {...input} passes down redux-form's methods which includes the onBlur function. onBlur also changes the value which normalizes the field. So onChange is not directly called but the functionality of onChange is executed in the onBlur handler
To your first point, I guess it depends on what kind of normalization you use. This obviously discourages normalizing long inputs (like textareas or whatnot) but for things like phone numbers for example, the most common patter i've seen is to delete all the chars until the error or the entire thing.
If you want to really make it confusion proof, you can force the caret to always be at the end via js, just add target.selectionStart = value.length in the onChange handler.

The target.selectionStart = target.selectionEnd = value.length is very similar to a solution I used.
Instead of just using value.length, I calculate the distance from the end the caret is for the original value, then use that to set the distance from the end for the parsed value. This prevents the cursor from jumping to unexpected places if the parsing function reduces character length, e.g:
val => val.split('a').join('') // caret jumps farther forward than it should

...or increases character length:
val => val.split('a').join('aaa') // caret doesn't jump as far as it should

Additionally, I've figured out a solution that would make this behavior intrinsic to redux-form. Here's a proof of concept (original: createOnChange.js):
// createOnChange.js
// can also be done to createOnBlur
const createOnChange = (change, { parse, normalize } = {}) =>
  event => {
    // read value from input
    let value = getValue(event, isReactNative)
    // get distance from caret to input end of ORIGINAL unaltered value
    let distanceEnd = value.length - event.target.selectionEnd
    let newValue
    let valueChanged = false

    // parse value if we have a parser
    if (parse) {
      newValue = parse(value)
      valueChanged = value !== newValue
      value = newValue
    }

    // normalize value
    if (normalize) {
      value = normalize(value)
      // same check here but don't overwrite true with false
      valueChanged = valueChanged || value !== newValue
    }

    if (valueChanged) {
      event.persist()
      // The caret moving behavior happens after the redux actions finish processing, so we set timeout
      // for synthetic event to work, we have to persist
      // note that value is now the new, parsed value
      // value.length - distanceEnd puts the caret at the same position it was before parsing
      setTimeout(() => event.target.selectionStart = event.target.selectionEnd = value.length - distanceEnd
    }

    // dispatch change action
    change(value)
  }

Some gotchas:

event may not be an event. (See getValue.js). The actual code would need to check for this.
If render speed is slow (e.g. app isn't optimized with shouldComponentUpdate) there will be a stutter as the caret jumps to the end of the input (like it does now), and then jumps back to the original location.
Behavior is odd if the parsing function changes the type (is there a use case for this for <input/>s?). This would either need to account for these cases, or check if value and newValue are both strings or something -- either way, more code.

@erikras, do you think this is a useful feature to have? I'm wondering if it's niche enough to text inputs that the user should just handle it.

the {...input} passes down redux-form's methods which includes the onBlur function. onBlur also changes the value which normalizes the field. So onChange is not directly called but the functionality of onChange is executed in the onBlur handler

ah! now I see :-)

but for things like phone numbers for example, the most common patter i've seen is to delete all the chars until the error or the entire thing.

Interesting. I've made completely different experiences, meaning that people do indeed click somewhere within the text (or use arrow keys) to correct a typo. In that case a misbehavior of the caret causes confusion (or even more problems when these people don't notice that the caret jumps around (this was often interpreted as something like "the website is buggy").
Example:
I enter the phone number  555-124-456-789 and notice that one digit is wrong (let's say the first 4). I then place the caret after that character, hit backspace and press the correct digit (3). In that case the 3 is added to the end of the string. I've seen many situations where people don't even notice that.
Anyway, my personal opinion is that the caret should always behave like in any other text field.
That said, a possible solution could be:

immediately normalize when the caret is already at the end of the text (typical case)
don't normalize when the caret is at any other position
normalize anyway on blur

@erikras

React is the one in charge of the cursor position (and it's a hard problem), so this might not be fixable, I'm afraid. Certainly not by this library.

Usually it means you update value of controlled input in async form (next tick, setTimeout, Promise.resolve, etc). Haven't explored source code of redux-form for this yet.
Making update in sync with onChange event should fix a problem.

Something should be fixed, soon. On a PC, caret placement is workable, though annoying. But on a tablet or phone, editing a field is just painful, clumsy or even frustrating (i.e. on long input values). Most use cases do not format input values, so if the new input value has the same length as the previous value, the caret should simply be preserved. Let custom input elements deal with specific cases (CC numbers, phone numbers, etc.) when repositioning the caret. But positioning the caret at the end regardless is, as others said, very bad UX design.

I seem to be getting this issue with basic redux-form controlled inputs, without any normalization. I can't seem to find the issue. Any suggestions? cheers

What situation causes your issue? Posting code would help.
Tim Hwang
Software Engineer
http://timhwang21.github.io
On Nov 24, 2016, 10:48 AM -0500, David Furlong<EMAIL_ADDRESS>wrote:

I seem to be getting this issue with basic redux-form controlled inputs, without any normalization. I can't seem to find the issue. Any suggestions? cheers
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub (https://github.com/erikras/redux-form/issues/1396#issuecomment-262804710), or mute the thread (https://github.com/notifications/unsubscribe-auth/AFj7CmIuVx5ZXDdfHarFOY32graX45Ypks5rBbG5gaJpZM4JUoJk).

@timhwang21
https://docs.google.com/document/d/1NPWRD6sX3lOTwJbkRd9QQ5uphQJ_6JZe7owUXC7A-5g/edit?usp=sharing

Because this issue saw almost no activity for a few months, I'm closing it.


Performance improvements:

reduced the number of the created byte[] (including the arrays created inside MemoryStream)
use compiled regexes
some string concatenation changed
ToLower + "==" changed to ignore case comparision

Doneness:

[X] Build is okay - I made sure that this change is building successfully.
[X] No Bugs - I made sure that this change is working properly as expected. It does'nt have any bugs that you are aware of.
[X] Branching - If this is not a hotfix, I am making this request against develop branch

#87 related.  Thanks!


Added frametick event, fired upon every frame start.

Allows developers to tap into frame loop

I don't think we should be adding so much to animations. Already getting stutter on simple animations. We're starting to add lot of overheard for things most apps won't need


Showing item entries at the bottom of the Table

OVERVIEW
Added the option to display the the table item entries at the bottom of the table. Example: Showing 1 - 4 of 4 items
Notion card: Implement Showing x-y of xy items on list non-recurring Customer Fee Records
WHERE SHOULD THE REVIEWER START?
src/components/Table/Table.tsx
HOW CAN THIS BE MANUALLY TESTED?
List steps to test this locally.
ANY NEW DEPENDENCIES ADDED?
List any new dependencies added.

[ ] Does it work in IE >= 11?
[ ] Does it work in other browsers?

SCREENSHOTS (if applicable)

CHECKLIST
Be sure all items are ✅ before submitting a PR for review.

[ ] Verify the linters and tests pass: yarn review
[ ] Verify you bumped the lib version according to Semantic Versioning Standards
[ ] Verify you updated the CHANGELOG
[ ] Verify this branch is rebased with the latest master

Please change the inplayer ui version in packages.json (the future one)


Build warning when upgrade to v2.3.3

Hi
I've upgraded shaka from 2.2.2 to v2.3.3
When I run webpack I get the following warnings:
WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:es6/array/find] ': Error: Can't resolve './ [synthetic:es6/array/find] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:es6/promise] ': Error: Can't resolve './ [synthetic:es6/promise] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:es6/symbol] ': Error: Can't resolve './ [synthetic:es6/symbol] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:es6/util/makeiterator] ': Error: Can't resolve './ [synthetic:es6/util/makeiterator] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:util/defineproperty] ': Error: Can't resolve './ [synthetic:util/defineproperty] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:util/findinternal] ': Error: Can't resolve './ [synthetic:util/findinternal] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:util/global] ': Error: Can't resolve './ [synthetic:util/global] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

WARNING in ./node_modules/shaka-player/dist/shaka-player.compiled.js
(Emitted value instead of an instance of Error) Cannot find source file ' [synthetic:util/polyfill] ': Error: Can't resolve './ [synthetic:util/polyfill] ' in '/Users/yair.ansbacher/Desktop/repos/kaltura-player-js/node_modules/shaka-player/dist'
 @ ./node_modules/playkit-js-dash/dist/playkit-dash.js 1:104-127
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://<IP_ADDRESS>:3000 index.js

my webpack config is:
'use strict';

const webpack = require("webpack");
const path = require("path");

module.exports = {
  context: __dirname + "/src",
  output: {
    path: __dirname + "/dist",
    filename: '[name].js',
    library: 'KalturaPlayer',
    libraryTarget: 'umd',
    umdNamedDefine: true,
    devtoolModuleFilenameTemplate: "./kaltura-player/[resource-path]",
  },
  devtool: 'source-map',
  module: {
    rules: [{
      test: /\.js$/,
      use: [{
        loader: "babel-loader"
      }],
      exclude: [
        /node_modules/
      ]
    }, {
      test: /\.js$/,
      use: [
        "source-map-loader"
      ],
      enforce: "pre"
    }, {
      test: /\.css$/,
      use: [
        'style-loader',
        'css-loader'
      ]
    }]
  },
  devServer: {
    contentBase: __dirname + "/src",
    host: '<IP_ADDRESS>',
    port: '3000'
  },
  resolve: {
    alias: {
      'playkit-js': path.resolve('./node_modules/playkit-js')
    },
    modules: [
      path.resolve(__dirname, "src"),
      "node_modules"
    ]
  }
};

the issue comes from the source-map-loader
Are you familiar with this kind of error?

I'm not, but it appears that the dist/ folder in our v2.3.3 release is empty.  I'm not sure how this could happen, but I'll look into it.  v2.3.2 has a populated dist/ folder.

@joeyparrish I don't see it as being empty.  npm install<EMAIL_ADDRESS>seems to have files in it.
The problem is that the source map contains entries like [synthetic:util/polyfill], which is caused by the compiler.  See google/closure-compiler#256 for some info.  We may want to post-process the source map to remove these, or @yairans could just ignore the warnings.

Strange.
I have no idea why that is happening, but it's consistent.  Maybe I'm seeing an npm bug.  It seems to be unrelated to what @yairans is reporting, though, so please disregard.

@yairans I think the problem is the compiler is adding these fake entries for code it generates for converting ES6 to ES3.  I think these warnings can be safely ignored.  Adding a post-processor would be non-trivial and prone to bugs.  I think it would be preferable to just ignore the warnings since the browser will ignore those entries.  If this is a serious concern, we can consider adding something in the future, or you could comment on the compiler bug.

@yairans Did we answer your question? Is there anything else we can do?


Deprecate live migration feature gate

What this PR does / why we need it:
Finally - the moment we've all been waiting for... :smiley:
When live migration feature was first presented to Kubevirt, it was immature and unstable. Over time, the situation had drastically changed.
Currently, Live migration is a mature and stable feature. Therefore, it shouldn't be guarded by a feature gate anymore. Now, that we have a deprecation policy for feature gates, it's time to deprecate this feature gate.
For more information, take a look at the new deprecation policy here: https://github.com/kubevirt/kubevirt/blob/main/docs/deprecation.md
Release note:

Deprecate live migration feature gate

FYI @davidvossel @fabiand @vladikr

/retest

/cc @davidvossel @fabiand @vladikr @xpivarc @ormergi

Deprecating it may make sense. Is live migration a feature where we still may want to keep a knob (not feature gate to indicate instability) to disable it? Could it be a feature which one may want to disable due to not having the network bandwidth, ... ?

Deprecating it may make sense. Is live migration a feature where we still may want to keep a knob (not feature gate to indicate instability) to disable it? Could it be a feature which one may want to disable due to not having the network bandwidth, ... ?

In such a case, I think it make sense to use Eviction Strategy "None" as a default by setting it in Kubevirt CR's Configuration

/test pull-kubevirt-e2e-kind-1.22-sriov

/lgtm

/retest-required

@iholder-redhat - please don't forget to update HCO code as well, to not use these FG anymore.

/retest-required

@iholder-redhat - please don't forget to update HCO code as well, to not use these FG anymore.

Will do, thanks for pointing that out

@iholder-redhat - please don't forget to update HCO code as well, to not use these FG anymore.

https://github.com/kubevirt/hyperconverged-cluster-operator/pull/2043


Add "duplicate part" file context menu item

Add a right-click menu option that copies the contents of the current file into a new version of it with _copy appended to the file name.

it should allow you to type the name versus creating one


Update docs/translation to latest schema

We need to make that consistent with the latest schema which is used to do the German translation in #263

The latest version of the texts from schema is already used for the translation.


Maintain ODEPACK under fortran-lang

Similar to FFTPACK (#40) and QUADPACK (#43), we should also maintain ODEPACK under fortran-lang. This has been first mentioned in https://github.com/scipy/scipy/pull/13229, where they have to maintain ODEPACK specific patches inside SciPy.
Instead, we should maintain a new de-facto "upstream" home for ODEPACK, maintaining the code to ensure it compiles with recent Fortran compilers on all architectures. Then SciPy can just copy the sources into their tree. (Down the road, as fpm becomes more widely used, we can discuss other ways of SciPy depending on these packages.)

I record further progress on modernising ODEPACK on https://github.com/scipy/scipy/issues/13222 (and as far as SciPy is concerned, also ARPACK-NG needs updating).


Lights tab randomly disappears - Dell G15 Ryzen 5515

Describe the bug
I've managed to turn on the lights for a while on version <IP_ADDRESS>, tried hibernating and restarting and it was OK. I got it to work again after uninstalling AWCC and AlienFX, and then installing both again. However after a few hours the keyboard lights were off again, and the tool doesn't seem to recognize it anymore. The same thing happened on the previous version.  On AWCC it says it could not detect a AlienFX device.
To Reproduce
Steps to reproduce the behavior:

On a Dell G15 Ryzen install AlienFX and configure the keyboard lights.
After a few restarts it will stop showing up.

Expected behavior
The lights tab was expected to always show up and the keyboards lights detected.
Screenshots

System (please complete the following information):

Model: DELL G15 5515 - Ryzen Edition
OS: Windows 11 stable

Additional context
I genuinely thank you for developing this application, since I just don't have any hope on DELL fixing their tool, I had already given up on trying to get it to work. If any further information is needed, I'd be glad to help.

Lights dab can be disabled in case no light devices detected into the system.
So BOTH AWCC and my tool can't find USB HID device presenting light control.
I have bad news for you.... Seems like your system dying into this, maybe cable not fit well now, so it's a hardware issue.
The only hope it's BIOS issue - did you update it recently (f.e. from Windows Update)? If yes, roll back immediately and disable automatic BIOS updates!
Unfortunately, i can't do anything in this case - i can't control a device not present into the system. As well as AWCC.


Bump Carbon version for Laravel 5.8

Description
Laravel 5.8 comes with Carbon 2, so this change allows it to work with Carbon 1 or 2. According to the upgrade guide, there are no changes required for this package's current use of Carbon
Motivation and context
As above.
If it fixes an open issue, please link to the issue here (if you write fixes #num
or closes #num, the issue will be automatically closed when the pull is accepted.)
How has this been tested?
I ran composer test etc as per contributing guidelines
Screenshots (if appropriate)
Types of changes
What types of changes does your code introduce? Put an x in all the boxes that apply:

[x] Bug fix (non-breaking change which fixes an issue)
[ ] New feature (non-breaking change which adds functionality)
[ ] Breaking change (fix or feature that would cause existing functionality to change)

Checklist:
Go over all the following points, and put an x in all the boxes that apply.
Please, please, please, don't send your pull request until all of the boxes are ticked. Once your pull request is created, it will trigger a build on our continuous integration server to make sure your tests and code style pass.

[x] I have read the CONTRIBUTING document.
[x] My pull request addresses exactly one patch/feature.
[x] I have created a branch for this patch/feature.
[x] Each individual commit in the pull request is meaningful.
[x] I have added tests to cover my changes.
[x] If my change requires a change to the documentation, I have updated it accordingly.

If you're unsure about any of these, don't hesitate to ask. We're here to help!

Hi @danielfaulknor,
Thanks for the PR, you are right!
Can you modify it into this, so it's a bit more strict (and comparable to how the Laravel framework defines this dependency):
"nesbot/carbon": "^1.22 || ^2.0",
Cheers,
Sander

This PR will be included in the next major release.

Closing it for now.


add pictures for storage migrate

@xyh1 : Thanks for your contribution! The author, @jpconnock, has been notified to review your proposed change.


Feature/404 support set in where

Changes
NB. the UC tests are located in package org.ehrbase.aql.sql.queryImpl.translator.testcase (module service)

Support set returning functions in WHERE clause (see tests UC27 - UC33)
refactored SQL translation on JSON structure to better support arrays, ease maintenance and allow future json querying or dialect (in particular JSONPATH)
Atomized tests (see above) to ease maintenance and document current expression support, enable different tests approach depending on selected dialect (f.e. jsquery or plain SQL)
Enhanced AQL grammar to support or fixed further set operators (IN, ANY, SOME, ALL, BETWEEN)
added some SQL primitives: NULL, UNKNOWN, TRUE, FALSE
fixed some last minutes translation errors (unresolved variables)
enable functions: COUNT, MIN, MAX, AVG

Related issue
fixes: https://github.com/ehrbase/project_management/issues/404
fixes: https://github.com/ehrbase/project_management/issues/442
Additional information and checks

[ ] Pull request linked in changelog

@chevalleyc I found that MIN( ) does not work on datetimes and gives back error messages from postgres. I think this requires a second look

@chevalleyc I found that MIN( ) does not work on datetimes and gives back error messages from postgres. I think this requires a second look


Upload Automation

Open question of SAW authentication and upload-automation.

They didn't answer; they sorta ignored the question then said they wouldn't remove the Captcha thing -- which isn't part of CCRS upload -- it's olny for Drupal webform on B2B Sale.  And, automating it works no problem.


Enable exploding flag for admin builds

Once https://github.com/keybase/client/pull/11526 is merged and gregor is up to date for v3 messages we should merge this in to start testing. gives us an easy one-line revert (like https://github.com/keybase/client/pull/11513) if we want to
cc @mmaxim

Sidenote: I think there's a race condition in the way g.Env.GetRunMode() works. The --run-mode flag hasn't been parsed at this point, so a devel build will always appear to be in devel mode here, even if you're passing --run-mode=prod. This isn't a very big deal, and it arguably gives the behavior we want for command flags anyway, but it's potentially confusing.


Notation and more detailed derivation of index and offset in DESIGN.md

I'm investigating the design and implementaion of littlefs. After reading DESIGN.md for several times, I'm still confused about the formula deriving index and offset from size of a CTZ skip-list. And I have not found any issues or other materials giving a more detailed derivation. Following is my thought and questions. Does I misunderstand the content of the document? Can I have some more detailed explanations? @geky
Thanks in advance!

the term "index" is 0-indexed or 1-indexed?

From figures in DESIGN.md, blocks in a CTZ skip-list seem like to be numbered from 0. However, if so, the formula calculating available space for data in a block would be invalid:
$$
B-\frac{\omega}{8}(\text{ctz}(i)+1)
$$
ctz(0) is an undefined value here. Besides, if we assume $\text{ctz}(0)=0$, the formula above is still invalid, because there is obviously no pointer stored in block 0, so its available space should be $B$ instead of $B-\frac{\omega}{8}$

Is the first block in the CTZ skip-list counted in the size?

No matter the first block is numbered 0 or 1, it should contains no pointer and store $B$ bytes. But it seems that these bytes are not regarded as part of size in formulas given in DESIGN.md. For instance, this equation(namely equation(1))
$$
N=\sum_i^n[B-\frac{\omega}{8}(\text{ctz}(i)+1)]
$$
gives the most intuitive form of relationship between number of blocks and file size. If we assume the first block is block 0, consider a CTZ skip-list of 2 blocks, there is only 1 pointer in the block 1 apparently, and the size of the list should be $B + (B - \frac{\omega}{8})$. But if we let $n=1$ in equation(1), we get(we also have to ignore undefined ctz(0)!) $B-\frac{\omega}{8}$, $B$ bytes in block 0 are gone! Otherwise, if we assume the first block is block 1, consider a list only containing 1 block, then we get size is $B-\frac{\omega}{8}$ bytes instead of $B$ bytes from equation(1).

How the formula of index is derived actually?

Index can be calculated by the formula(namely equation(2)):
$$
n=\left \lfloor \frac{N-\frac{\omega}{8}(\text{popcount}(\frac{N}{B-2\frac{\omega}{8}}-1)+2)}{B-2\frac{\omega}{8}} \right \rfloor
$$
As described in DESIGN.md, equation (2) is derived as follow:

But what we can do is solve for an n' index that is greater than n with error bounded by the range of the popcount function. We can repeatedly substitute n' into the original equation until the error is smaller than our integer resolution. As it turns out, we only need to perform this substitution once

I can't understand how the $n'$ is solved and how substitute $n'$ back works, could you please give a more detailed process?

What the term "offset" refers to and how it's derived from equation(1)?

As stated in DESIGN.md:

This last question is how do we store CTZ skip-lists? We need a pointer to the head block, the size of the skip-list, the index of the head block, and our offset in the head block.

And offset can be calculated using equation(3):
$$
off=N-(B-2\frac{\omega}{8})n-\frac{\omega}{8}\text{popcount}(n)
$$
But "offset in the head block" seems not so clear here. Does this refers to offset of data bytes in the head block? the offset of the first data byte in the whole file? or other things? It seems that the first explanation is far from the form of equation(3), because we can get  offset of data bytes in the head block using something like $\frac{\omega}{8}(\text{ctz}(n)+1)$.
Nevertheless, there may be still a little distance from the second explanation to equation(3). From my understanding, the offset of the first data byte in the whole file is also summation of data bytes stored in all previous blocks, i.e.:
$$
N-off=B-\frac{\omega}{8}(\text{ctz}(n)+1)
$$
$$
off=N-B+\frac{\omega}{8}(\text{ctz}(n)+1)
$$
Or,
$$
off=\sum_0^{n-1}[B-\frac{\omega}{8}(\text{ctz}(i)+1)]=(B-2\frac{\omega}{8})(n-1)+\frac{\omega}{8}\text{popcount}(n-1)
$$
Any my derivation above does not match equation(3).

Hi @fourstring, sorry for the late response, let me see if I can offer some pointers. I'm not really a mathematician, so some of the math is a bit hand-wavey in places.
You're definitely right I should have written more down on this. I had a bit of trouble reproducing the the results myself, which isn't great. Some of this is rederived which may make it different from DESIGN.md.

the term "index" is 0-indexed or 1-indexed?

The index here is 0-indexed. You're right that $\operatorname{ctz}(0)$ would make this formula undefined at $i=0$, but I ignore this for the most part since we can easily handle special cases in the code.
B - \frac{w}{8} \left(\operatorname{ctz}(i) + 1\right)

This formula works out if you define $\operatorname{ctz}(i)$ to be $-1$. Point taken this should really be in the documentation.

Is the first block in the CTZ skip-list counted in the size?

Yes, if $\operatorname{ctz}(i)$ is defined as $-1$ the first block gets the full $B$ bytes. There may be a "more correct" way to define this as a piecewise equation, but this works for our purposes.

How the formula of index is derived actually?

What the term "offset" refers to and how it's derived from equation(1)?

It may help to frame the problem.
We're trying to map a file onto the CTZ skip-list on disk:
                    data (size=105)
                   .-----------------------------.
                   | abcdef yzabcd wxyzab uvwxyz |
                   | ghijkl efghij cdefgh abcdef |
                   | mnopqr klmnop ijklmn ghijkl |
                   | stuvwx qrstuv opqrst        |
                   '-----------------------------'

                                  |
                                  v

 block 0     block 1     block 2     block 3     block 4     block 5
.--------.  .--------.  .--------.  .--------.  .--------.  .--------.
| abcdef |<-| <ptr0> |<-| <ptr0> |<-| <ptr0> |<-| <ptr0> |<-| <ptr0> |<- ptr=block 5
| ghijkl |<-| yzabcd |--| <ptr1> |--| cdefgh |--| <ptr1> |  | abcdef |   size=105
| mnopqr |<-| efghij |--| qrstuv |--| ijklmn |--| <ptr2> |  | ghijkl |
| stuvwx |  | klmnop |  | wxyzab |  | opqrst |  | uvwxyz |  |        |
'--------'  '--------'  '--------'  '--------'  '--------'  '--------'

To keep track of the CTZ skip-list we store a pointer to the "head block", and the size of the file. If we want to read/write to a specific offset in the file, we need to transform the file-relative offset ($\mathit{off_f}$) into the on-disk block number ($i$) and block-relative offset ($\mathit{off_i}$).
I'm going to change the variables to hopefully be more consistent, sorry if this adds confusion.
Also there may be a simpler/faster way to solve this. This was just my approach at finding a solution with the knowledge I have.
                    data (size=105)       .-- off_f=84
                   .----------------------v------.
                   | abcdef yzabcd wxyzab uvwxyz |
                   | ghijkl efghij cdefgh abcdef |
                   | mnopqr klmnop ijklmn ghijkl |
                   | stuvwx qrstuv opqrst        |
                   '-----------------------------'

                                  |
                                  v

 block 0     block 1     block 2     block 3     block 4     block 5
.--------.  .--------.  .--------.  .--------.  .--------.  .--------.
| abcdef |<-| <ptr0> |<-| <ptr0> |<-| <ptr0> |<-| <ptr0> |<-| <ptr0> |<- ptr=block 5
| ghijkl |<-| yzabcd |--| <ptr1> |--| cdefgh |--| <ptr1> |  | abcdef |   size=105
| mnopqr |<-| efghij |--| qrstuv |--| ijklmn |--| <ptr2> |  | ghijkl |
| stuvwx |  | klmnop |  | wxyzab |  | opqrst |  | uvwxyz |  |        |
'--------'  '--------'  '--------'  '--------'  '-^------'  '--------'
                                                  '-- i=block 4
                                                      off_i=3*(w/8)

Note that file size and file-relative offset are the same thing here.
To start solving this, we can first phrase create an equation for $\mathit{off_f}$ given $i$. This is the sum of the available space in the blocks minus the pointer overhead:
\mathit{off_f} = \sum_j^i\left[B - \frac{w}{8}\left(\operatorname{ctz}(j)+1\right)\right]

We can move some of the constants out of the summation:
\mathit{off_f} = Bi - \frac{w}{8}\sum_j^i\left(\operatorname{ctz}(j)+1\right)

And here we can substitute in our $\operatorname{popcount}$ property:
\sum_j^i\left(\operatorname{ctz}(j)+1\right) = 2i-\operatorname{popcount}(i)

So:
\mathit{off_f} = Bi - \frac{w}{8}\left(2i - \operatorname{popcount}(i)\right)

But our goal is to solve for $i$. We can rearrange the terms:
\mathit{off_f} = Bi - 2\frac{w}{8}i - \frac{w}{8}\operatorname{popcount}(i)

Bi - 2\frac{w}{8}i = \mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i)

i = \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i)}{B-2\frac{w}{8}}\right\rfloor

But $\operatorname{popcount}$ gets in the way here and is a big pain.
One interesting thing to note is that the output of $\operatorname{popcount}(i)$ is bounded to $\le \operatorname{nlog}_2(n)$. So in theory, if we substituted this equation for $i$ into itself, it should eventually converge:
i = \left\lfloor\cfrac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}\left(\left\lfloor\cfrac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}\left(\left\lfloor\cfrac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(\dots)}{B-2\frac{w}{8}}\right\rfloor\right)}{B-2\frac{w}{8}}\right\rfloor\right)}{B-2\frac{w}{8}}\right\rfloor

So we could solve for $i$ iteratively and call it a day. But we can also solve for $i$ algebraically.
First lets guess an $i'$, say we just drop the annoying $\operatorname{popcount}$ part of the equation.
Note that $i'$ is strictly $\geq i$. This will be important later:
i' = \left\lfloor\frac{\mathit{off_f}}{B-2\frac{w}{8}}\right\rfloor

The error $\epsilon_{i'}$ is of course that annoying $\operatorname{popcount}$ part:
\begin{aligned}
\epsilon_{i'} &= \left|i'-i\right| \\
&= \left|
    \left\lfloor\frac{\mathit{off_f}}{B-2\frac{w}{8}}\right\rfloor
    - \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i)}{B-2\frac{w}{8}}\right\rfloor\right| \\
&= \left|\left\lfloor\
    \frac{\mathit{off_f} - \mathit{off_f} + \frac{w}{8}\operatorname{popcount}(i)}
        {B-2\frac{w}{8}}\right\rfloor\right| \\
&= \left\lfloor\
    \frac{\frac{w}{8}\operatorname{popcount}(i)}
        {B-2\frac{w}{8}}\right\rfloor
\end{aligned}

Though we can make some interesting observations about $\epsilon_{i'}$. The output of $\operatorname{popcount}(i)$ is limited to $\operatorname{nlog}_2(i-1)$, and $\frac{w}{8}\operatorname{nlog}_2(i)$ can't exceed the block size $B$, otherwise we wouldn't be able to fit all of our pointers in our blocks. So $\frac{w}{8}\operatorname{popcount}(i)$ must be $\le B$:
\epsilon_{i'} \le \left\lfloor\
    \frac{B}
        {B-2\frac{w}{8}}\right\rfloor

Assuming enough spare space in our blocks to actually store data, $B \ge 3\frac{w}{8}$, and truncating division, our error $\epsilon_{i'}$ never actually exceeds 1:
\epsilon_{i'} \le 1

This is enough to limit the correct solution to either $i'$ or $i'-1$. In our code we could simply calculate both and test which is the right answer, but we can keep going to see if we end up with an unconditional solution.
Lets go ahead and substitute $i'$ into our original equation for $i$. This gives us a new guess, $i''$:
i'' = \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i')}{B-2\frac{w}{8}}\right\rfloor

What's our new error $\epsilon_{i''}$?
\begin{aligned}
\epsilon_{i''} &= \left|i''-i\right| \\
&= \left|
    \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i')}{B-2\frac{w}{8}}\right\rfloor
    - \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i)}{B-2\frac{w}{8}}\right\rfloor\right| \\
&= \left|\left\lfloor\
    \frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i') - \mathit{off_f} + \frac{w}{8}\operatorname{popcount}(i)}
        {B-2\frac{w}{8}}\right\rfloor\right| \\
&= \left|\left\lfloor\
    \frac{\frac{w}{8}\left(\operatorname{popcount}(i)-\operatorname{popcount}(i')\right)}
        {B-2\frac{w}{8}}\right\rfloor\right|
\end{aligned}

This looks like a dead-end, but we can make some rather interesting observations about this $\operatorname{popcount}(i)-\operatorname{popcount}(i')$ expression.
This is basically asking what is the largest number of bits that could flip between $i$ and $i'$.
We know from above that the error between $i$ and $i'$, $\epsilon_{i'}$, is at most 1. If we think about when a change of 1 results in the most bit-flips, it would be when a number "rolls over" during addition:
i  = 0111...1111
i' = 1000...0000

What's really interesting about this, is that the number of bits that flip in this case is equal to $\operatorname{ctz}(i')+1$:
i  = 0111...1111
i' = 1000...0000
     ^'---+----'
     |    '-- ctz(i')
     '------- + 1

I suspect this is somehow related to the $\operatorname{popcount}$ property we've been using.
This relationship depends on which $i$ is the one "rolling over":
\left|\operatorname{popcount}(i)-\operatorname{popcount}(i')\right| \le \operatorname{ctz}\left(\operatorname{max}(i, i')\right)+1

But since we know $i'$ is strictly $\ge i$ from above, we can simplify this:
\left|\operatorname{popcount}(i)-\operatorname{popcount}(i')\right| \le \operatorname{ctz}(i')+1

Plugging this in:
\begin{aligned}
\epsilon_{i''} &\le \left|\left\lfloor\
    \frac{\frac{w}{8}\left(\operatorname{popcount}(i)-\operatorname{popcount}(i')\right)}
        {B-2\frac{w}{8}}\right\rfloor\right| \\
&\le \left\lfloor\
    \frac{\frac{w}{8}\left(\operatorname{ctz}(i')+1\right)}
        {B-2\frac{w}{8}}\right\rfloor
\end{aligned}

We've managed to remove any trace of $i$ from our new equation, which is probably a good thing. But it's still not low enough to be reliable.
Let's create a new estimate $i'''$, where we subtract the error from our estimate $i''$:
\begin{aligned}
i''' &= i'' - \epsilon_{i''} \\
&= \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i')}{B-2\frac{w}{8}}\right\rfloor
    - \left\lfloor\
    \frac{\frac{w}{8}\left(\operatorname{ctz}(i')+1\right)}
        {B-2\frac{w}{8}}\right\rfloor \\
&= \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i') - \frac{w}{8}\left(\operatorname{ctz}(i')+1\right)}
    {B-2\frac{w}{8}}\right\rfloor \\
&= \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\left(\operatorname{popcount}(i') + \operatorname{ctz}(i')+1\right)}
    {B-2\frac{w}{8}}\right\rfloor
\end{aligned}

So now what is our error $\epsilon_{i'''}$?
\begin{aligned}
\epsilon_{i'''} &= \left|i''' - i\right| \\
&= \left|\left\lfloor \frac{
    \mathit{off_f} - \frac{w}{8}\left(\operatorname{popcount}(i') + \operatorname{ctz}(i')+1 \right)}
    {B-2\frac{w}{8}}\right\rfloor
    - \left\lfloor \frac{
    \mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i)}
    {B-2\frac{w}{8}}\right\rfloor\right|\\
&= \left|\left\lfloor \frac{
    \mathit{off_f} - \frac{w}{8}\left(\operatorname{popcount}(i') + \operatorname{ctz}(i')+1 \right)
    - \mathit{off_f} + \frac{w}{8}\operatorname{popcount}(i)}
    {B-2\frac{w}{8}}\right\rfloor\right|\\
&= \left|\left\lfloor \frac{
    \mathit{off_f} - \frac{w}{8}\operatorname{popcount}(i') - \frac{w}{8}\left(\operatorname{ctz}(i')+1\right)
    - \mathit{off_f} + \frac{w}{8}\operatorname{popcount}(i)}
    {B-2\frac{w}{8}}\right\rfloor\right|\\

&= \left|\left\lfloor \frac{
    \mathit{off_f} - \mathit{off_f} + \frac{w}{8}\operatorname{popcount}(i) - \frac{w}{8}\operatorname{popcount}(i') - \frac{w}{8}\left(\operatorname{ctz}(i')+\frac{w}{8}\right)}
    {B-2\frac{w}{8}}\right\rfloor\right|\\
&= \left|\left\lfloor \frac{\frac{w}{8}\left(\operatorname{popcount}(i) + \operatorname{popcount}(i')\right) - \frac{w}{8}\left(\operatorname{ctz}(i')+\frac{w}{8}\right)}
    {B-2\frac{w}{8}}\right\rfloor\right|
\end{aligned}

Oh hey, there's our $\operatorname{popcount}(i)-\operatorname{popcount}(i')$ expression again. Let's substitute in $\operatorname{ctz}(i')+1$:
\begin{aligned}
\epsilon_{i'''} &= \left|\left\lfloor \frac{\frac{w}{8}\left(\operatorname{popcount}(i) + \operatorname{popcount}(i')\right) - \frac{w}{8}\left(\operatorname{ctz}(i')+1\right)}
    {B-2\frac{w}{8}}\right\rfloor\right| \\
&\le \left|\left\lfloor \frac{\frac{w}{8}\left(\operatorname{ctz}(i')+1\right) - \frac{w}{8}\left(\operatorname{ctz}(i')+1\right)}
    {B-2\frac{w}{8}}\right\rfloor\right| \\
&\le \left|\left\lfloor \frac{0}
    {B-2\frac{w}{8}}\right\rfloor\right| \\
&\le 0
\end{aligned}

And now our error $\epsilon_{i'''}$ is zero, which means $i''' = i$ if all of our above assumptions hold. This gives us our final equation:
i = \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\left(\operatorname{popcount}(i') + \operatorname{ctz}(i')+1\right)}
    {B-2\frac{w}{8}}\right\rfloor

But there's a few more tweaks. See, both $\operatorname{popcount}$ and $\operatorname{ctz}$ can be hardware instructions, but if they aren't available they need to be emulated with $O(w)$ loops, which isn't great. If we could get rid of one of them that would be nice.
Let's take a look at the $\operatorname{popcount}$ part:
\operatorname{popcount}(i') + \operatorname{ctz}(i')+1

We can shove in our $\operatorname{popcount}$ property here, albiet a bit ungracefully:
\operatorname{popcount}(i') + \operatorname{ctz}(i')+1

-\left(2i'-\operatorname{popcount}(i')-2i'\right) + \operatorname{ctz}(i')+1

-\left(\sum_j^{i'}\left[\operatorname{ctz}(j)+1\right]-2i'\right) + \operatorname{ctz}(i')+1

-\left(\sum_j^{i'-1}\left[\operatorname{ctz}(j)+1\right]+\operatorname{ctz}(i')+1-2i'\right) + \operatorname{ctz}(i')+1

-\left(2(i'-1) - \operatorname{popcount}(i'-1)+\operatorname{ctz}(i')+1-2i'\right) + \operatorname{ctz}(i')+1

-\left(2i'-2 - \operatorname{popcount}(i'-1)+\operatorname{ctz}(i')+1-2i'\right) + \operatorname{ctz}(i')+1

-\left(2i'-2i' - \operatorname{popcount}(i'-1)+\operatorname{ctz}(i')+1-2\right) + \operatorname{ctz}(i')+1

-\left(-\operatorname{popcount}(i'-1)+\operatorname{ctz}(i')-1\right) + \operatorname{ctz}(i')+1

\operatorname{popcount}(i'-1)-\operatorname{ctz}(i')+1 + \operatorname{ctz}(i')+1

\operatorname{popcount}(i'-1)+\operatorname{ctz}(i')-\operatorname{ctz}(i')+1+1

\operatorname{popcount}(i'-1)+2

Plugging this back in to our result gives us the equation used in the code:
i = \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\left(\operatorname{popcount}(i'-1) + 2\right)}
    {B-2\frac{w}{8}}\right\rfloor

Oh I almost forgot to put $i'$ back in there:
i = \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\left(\operatorname{popcount}\left(\frac{\mathit{off_f}}{B-2\frac{w}{8}}-1\right) + 2\right)}
    {B-2\frac{w}{8}}\right\rfloor

Once we have $i$, solving for $\mathit{off_i}$ is relatively straightforward. Our solution for $i$ intentionally truncates to the nearest block boundary. So our relative offset in the block is the difference between our original $\mathit{off_f}$ and the truncated offset, $\mathit{off_f}'$, calculated from $i$:
\begin{aligned}
\mathit{off_i} &= \mathit{off_f} - \mathit{off_f}' \\
&= \mathit{off_f} - \left(Bi-\frac{w}{8}\left(2i-\operatorname{popcount}(i)\right)\right) \\
&= \mathit{off_f} - Bi + \frac{w}{8}\left(2i-\operatorname{popcount}(i)\right) \\
&= \mathit{off_f} - Bi + \frac{w}{8}2i - \frac{w}{8}\operatorname{popcount}(i) \\
\end{aligned}

We just have one abnormal thing to watch out for. Since we're a filesystem, these numbers can be quite large. $i$ can be near the upper bound of a 32-bit integer, and in littlefs block addresses and offsets are managed as separate integers to allow the address limit to generall cover a larger range even on 32-bit devices.
Long story short, that $Bi$ is a bit of a problem since it can easily overflow our off/size types. Fortunately we can rearrange the equation a bit to avoid this:
\begin{aligned}
\mathit{off_i} &= \mathit{off_f} - Bi + \frac{w}{8}2i - \frac{w}{8}\operatorname{popcount}(i) \\
&= \mathit{off_f} - \left(B - 2\frac{w}{8}\right)i - \frac{w}{8}\operatorname{popcount}(i)
\end{aligned}

After all that we get our two equations for $i$ and $\mathit{off_i}$:
i = \left\lfloor\frac{\mathit{off_f} - \frac{w}{8}\left(\operatorname{popcount}\left(\frac{\mathit{off_f}}{B-2\frac{w}{8}}-1\right) + 2\right)}
    {B-2\frac{w}{8}}\right\rfloor

\mathit{off_i} = \mathit{off_f} - \left(B - 2\frac{w}{8}\right)i - \frac{w}{8}\operatorname{popcount}(i)

This comment turned into a bit of a long one, but hopefully it helps explain the thought process.
Do ask if something looks wrong or could be simplified. I'll probably add this to the DESIGN.md next chance I get.


Fix header image

I want to moved and resize the header image so that the headphones are visible  but have the image retain the full with of the device. This should also fix the issue on all size devices

@0silverback0 can you assing me this issue.

Hello @0silverback0,
Are you building your own website or cloning another website? If you don't have any objections, I'm available to assist and work on creating this website for you.

@0silverback0 solved the issue.


Feature Request: SwitchEntity without is_on ?

Hello
Is there anything like a statless ToggleEntity? The thing is I have some switches here I'd like to switch with hass. I can turn them on or of manualy, or using the pc, but they dont report to the pc if they are on or not.
Cheers

You can use the  command line switch, would that work? Fire any command when you toggle

You can use the command line switch, would that work? Fire any command when you toggle

I use this to talk to an lirc_web instance to turn on my kitchen TV. It's sort of impossible to keep the state straight unless you ONLY use the switch (someone might use the remote), but I just deal with it and don't actually rely on the state.
The sole purpose is really just so I can turn it ON or turn it OFF.

Year for turning thins on and of this is fine. Currently I'm using my own component that inherits from ToggleDevice, but I think its a good idear to use the comand_line switch. But if I see it right, this still has a is_on() method. As a first solution this is fine, but it would be usefull to have an entity that  only sends comands, like on and off and that can allways send one of these commands. So that if the device is out of sync, one does not need to first set the correct state and can then turn if of.

It sounds like you want to use the script component which allows you to
fire events or call services without any prior condition.
On Tue, Sep 15, 2015 at 10:35 AM deisi<EMAIL_ADDRESS>wrote:

Year for turning thins on and of this is fine. Currently I'm using my own
component that inherits from ToggleDevice, but I think its a good idear to
use the comand_line switch. But if I see it right, this still has a is_on()
method. As a first solution this is fine, but it would be usefull to have
an entity that only sends comands, like on and off and that can allways
send one of these commands. So that if the device is out of sync, one does
not need to first set the correct state and can then turn if of.
—
Reply to this email directly or view it on GitHub
https://github.com/balloob/home-assistant/issues/379#issuecomment-140475042
.

Aha I'm lookingin to it, and I think you are right. I give it a try

Okay, it looks like this is still not what I need. I basically need something I can use to send an arbitrary shell command like:
echo 'on'

or
echo 'off'

There currently is no component that allows you to specify services that will execute arbitrary shell commands. You could write yourself a custom component.
Create a file <your config dir>/custom_components/hello.py:
import os

def setup(hass, config):
    def my_service(call):
        os.popen('echo 1').close()

    hass.services.register('hello', 'my_service', my_service)

Add to your configuration.yaml:
hello:

Now you can call your service from anywhere in HA (like scripts) and it will execute echo 1,

This sounds Kind oft perfekt. I will soon try it. Thanks a lot.

Hmm if I copy and paste your example I get:
Sep 16 08:01:40 rapi4 hass[17179]: Traceback (most recent call last):
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/bin/hass", line 9, in <module>
Sep 16 08:01:40 rapi4 hass[17179]: load_entry_point('homeassistant==0.7.2', 'console_scripts', 'hass')()
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/_
Sep 16 08:01:40 rapi4 hass[17179]: skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days)
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/b
Sep 16 08:01:40 rapi4 hass[17179]: skip_pip=skip_pip)
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/b
Sep 16 08:01:40 rapi4 hass[17179]: for domain in loader.load_order_components(components):
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: key=lambda order: 'group' in order):
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: for component in components),
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: return _load_order_component(comp_name, OrderedSet(), set())
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: for dependency in component.DEPENDENCIES:
Sep 16 08:01:40 rapi4 hass[17179]: AttributeError: 'module' object has no attribute 'DEPENDENCIES'

Add it, value should be = []
On Tue, Sep 15, 2015, 23:04 deisi<EMAIL_ADDRESS>wrote:

Hmm if I copy and paste your example I get:
Sep 16 08:01:40 rapi4 hass[17179]: Traceback (most recent call last):
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/bin/hass", line 9, in
Sep 16 08:01:40 rapi4 hass[17179]: load_entry_point('homeassistant==0.7.2', 'console_scripts', 'hass')()
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/_
Sep 16 08:01:40 rapi4 hass[17179]: skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days)
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/b
Sep 16 08:01:40 rapi4 hass[17179]: skip_pip=skip_pip)
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/b
Sep 16 08:01:40 rapi4 hass[17179]: for domain in loader.load_order_components(components):
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: key=lambda order: 'group' in order):
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: for component in components),
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: return _load_order_component(comp_name, OrderedSet(), set())
Sep 16 08:01:40 rapi4 hass[17179]: File "/usr/lib/python3.4/site-packages/homeassistant-0.7.2-py3.4.egg/homeassistant/l
Sep 16 08:01:40 rapi4 hass[17179]: for dependency in component.DEPENDENCIES:
Sep 16 08:01:40 rapi4 hass[17179]: AttributeError: 'module' object has no attribute 'DEPENDENCIES'
—
Reply to this email directly or view it on GitHub
https://github.com/balloob/home-assistant/issues/379#issuecomment-140638629
.

Sorry I dont understand. I need to add [] to what or where?

As a Tellstick DUO user I have the same problem as @deisi but for all my lights/switches, the state is usually correct but it's not guaranteed. A perfect solution, as I see it, would be if light/switch platforms automatically could set an option in the entity that says that it has an unreliable state. The card in the webinterface will then change for unrelaiable devices so that two buttons are displayed instead of the toggling switch. This would really improve usability for all systems with unreliable states.

With add it I was referring to the last line of your log which shows that there is no attribute DEPENDENCIES.
DEPENDENCIES = []

Aha now I understand. Thanks.

This is pretty close (I think) to the issue I'm currently having.
I'm using command_switch, which allows me to specify an oncmd and an offcmd, but there doesn't appear to be a statecmd which would be useful to detect the current state for the switch... whatever it may be.
My switches have an endpoint that returns {"state": "on"} or {"state": "off"}.

I have the same issue. Is there any way to set the current status to a command_switch ?

Command switches have a statecmd. See #788


Add Support for PHP 8

https://github.com/tighten/takeout/pull/188

@pmayet Apologies!

https://github.com/tighten/takeout/releases/tag/v1.6.5


Implement pysondb-v2 and add/search customer

Changes made

Use pysondb-v2 for storing information

check customer.json
Customer can be searched based on id

login/register

@achyuta116 I forgot to update the db, previously it was from pysondb. I've updated login/register functions also. We can keep auth functions in one file, no problem with that.


fix(plugin:export): it should have default value 'true' across it's doc.

Description
@antv/x6-plugin-export's options table show that the default-value of serializeImages and copyStyles  is the true.However, the option argument has been set {} which will cause serializeImages  or copyStyles is undefined in runtime. the logical truth code won't be executed.

Motivation and Context

Types of changes

[x] Bug fix (non-breaking change which fixes an issue)
[ ] New feature (non-breaking change which adds functionality)
[ ] Breaking change (fix or feature that would cause existing functionality to change)
[ ] Enhancement (changes that improvement of current feature or performance)
[ ] Refactoring (changes that neither fixes a bug nor adds a feature)
[ ] Test Case (changes that add missing tests or correct existing tests)
[ ] Code style optimization (changes that do not affect the meaning of the code)
[ ] Docs (changes that only update documentation)
[ ] Chore (changes that don't modify src or test files)

Self Check before Merge

[x] My code follows the code style of this project.
[ ] My change requires a change to the documentation.
[ ] I have updated the documentation accordingly.
[x] I have read the CONTRIBUTING document.
[ ] I have added tests to cover my changes.
[ ] All new and existing tests passed.

sry, I'll close it with new PR(4111) which is more stricter and exact.


Multiple input

Hey
is there any way to add multiple inputs? It would be nice to have this features!
Thanks

No, it is not possible. How do you think API could look like?

by array with json value?
smalltalk
    .prompt('MultiQuestion', 'Username and Password?', '10', [
      {
        key: "password",
        type: 'password'
      },
      {
        key: "username",
        type: 'text'
    ]
    )
    .then((value) => {
        //either value is a array or json
        console.log(value.username);
        console.log(value.password);
    .catch(() => {
        console.log('cancel');
    });

It is a good idea for a pull request :).

I've barely time for pull request. :( But okay then! I hope someone could make it. :)

Closed due to long time of inactivity.


i18n(zh-cn): Update the translation of astro-components.md and typescript.md

What kind of changes does this PR include?

New or updated content
Translated content

Description
I updated the Chinese translations of astro-components.md and typescript.md to catch up with the English version.
typescript.md in particular, it is so behind the English version that I almost rewrote it with this update.
For astro-components.md, I removed export requirement for Props #1632.
By the way, hacktoberfest-accepted please.  :kissing_heart:

Of course! I will update this PR after I finish it.

Thank you!

Hi @delucis!
As you can see, I retranslated astro-components.md and typscript.md according to the latest English version of the document. (astro-components.md to #2102, typscript.md to #2030)
It seems that there is also an article client-side-scripts.md related to part of astro-components.md. There is no Chinese translation yet. But please merge it first. After I prepare the translation of client-side-scripts.md, I will submit a new PR.

@delucis There should be fine now! Please check.


sigproc.filter -- fs not needed, hangs when there is no design, and other issues

I'm working on a generator-based refactor of filter and butterworth filter. I'll attach the WIP functions in a reply to this top-post.
In trying to redo the existing classes using the generator function, I've come across a couple things that I don't understand and/or I think can be modified to simplify and generalize.
First, the class FilterSettingsBase includes the field fs. This isn't used as a "setting" at this base class level. While the child class ButterworthFilterSettings needs fs to design the filter (because cuton and cutoff are provided in Hz), the parent does not use fs except to check that it is not None before calling update_filter. This is misplaced because a child of this base class might want to initiate a filter with the coefficients already known and fs is irrelevant at design time. Indeed, FilterSettings has the field filt to store the coefficients.

Can I remove fs from FilterSettingsBase and add it to ButterworthFilterSettings?

I agree with the TODO that it should be a passthrough if there is no filter yet designed. IMO, it should be required that all the details necessary to design the filter should be provided on init + and possibly with the first non-empty input. If this requirement is enforced, then I expect it'll probably simplify some of the other workflows.

Can I make filtering a passthrough op when not yet designed?
Can you please point me to an example where the INPUT_FILTER connection is used so I can see why we might not want it designed at init?

Third, Filter's design_filter implementation simply raises NotImplementedError. In my experience, having a method that raises that error is enough for linters to say "this is an abstract base class". However, Decimate instantiates a Filter() (manual b,a from a cheby1 design if factor > 1).
I think it would be better if Filter were truly abstract and instead there were a SimpleFilter child class that overrode design_filter with return None, and Decimate used SimpleFilter instead.

Can I do this refactor?

Fourth
I prefer "sos" filters. FilterCoefficients assumes "ba". What if FilterCoefficients' only field was coefs, with type
Union[Tuple[np.ndarray], BACoeffs], where BACoeffs was the current version of FilterCoefficients? I think I'm missing a Tuple in there somewhere. But if done right, then it should be possible to use FilterCoefficients for either "ba" or "sos".
I think it's reasonable to do this in baby steps. I think there's a path to refactoring the classes before bringing in the generator functions. Unfortunately, I need the generator functions now to demonstrate offline and online harmony, but I can keep those in my project's namespace package for now.

@consumer
def filtergen(
        axis: str, coefs: np.ndarray, coef_type: str
) -> Generator[AxisArray, AxisArray, None]:
    # IO
    axis_arr_in = AxisArray(np.array([]), dims=[""])
    axis_arr_out = AxisArray(np.array([]), dims=[""])

    filt_func = {"ba": scipy.signal.lfilter, "sos": scipy.signal.sosfilt}[coef_type]
    zi_func = {"ba": scipy.signal.lfilter_zi, "sos": scipy.signal.sosfilt_zi}[coef_type]

    # State variables
    axis_idx = None
    zi = None
    expected_shape = None

    while True:
        axis_arr_in = yield axis_arr_out

        if axis_idx is None:
            axis_name = msg.dims[0] if axis is None else axis
            axis_idx = axis_arr_in.get_axis_idx(axis_name)

        dat_in = axis_arr_in.data

        # Re-calculate/reset zi if necessary
        samp_shape = dat_in.shape[:axis_idx] + dat_in.shape[axis_idx + 1:]
        if zi is None or samp_shape != expected_shape:
            expected_shape = samp_shape
            n_tail = dat_in.ndim - axis_idx - 1
            zi = zi_func(*coefs)
            zi_expand = (None,) * axis_idx + (slice(None),) + (None,) * n_tail
            n_tile = dat_in.shape[:axis_idx] + (1,) + dat_in.shape[axis_idx + 1:]
            if coef_type == "sos":
                # sos zi must keep its leading dimension (`order / 2` for low|high; `order` for bpass|bstop)
                zi_expand = (slice(None),) + zi_expand
                n_tile = (1,) + n_tile
            zi = np.tile(zi[zi_expand], n_tile)

        dat_out, zi = filt_func(*coefs, dat_in, axis=axis_idx, zi=zi)
        axis_arr_out = replace(axis_arr_in, data=dat_out)

@consumer
def butter(
        axis: str, fs: float, order: int = 0, cuton: Optional[float] = None, cutoff: Optional[float] = None,
        coef_type: str = "ba"
) -> Generator[AxisArray, AxisArray, None]:
    # IO
    axis_arr_in = AxisArray(np.array([]), dims=[""])
    axis_arr_out = AxisArray(np.array([]), dims=[""])

    btype, cutoffs = ButterworthFilterSettings(order=order, cuton=cuton, cutoff=cutoff).filter_specs()
    coefs = scipy.signal.butter(order, Wn=cutoffs, btype=btype, fs=fs,output=coef_type)
    if coef_type == "sos":
        coefs = (coefs,)  # We call functions with first arg `*coefs`, but sosfilt funcs only expect 1 arg.

    filter_gen = filtergen(axis, coefs, coef_type)

    while True:
        axis_arr_in = yield axis_arr_out
        axis_arr_out = filter_gen.send(axis_arr_in)

You're amazing, Chad.  I'm not fond of our filter inheritance structure but this refactor will do away with it entirely.

After having used this successfully a few times now, I'm going to deprecate our current filters and add these in as a new implementation.  This will allow us to get rid of fs and make the changes we need in a backward compatible way.

By coincidence I was working on this today but I'm happy to move onto the Spectrogram and Bandpower rework.
Here is my test_butter.py. Feel free to change the folder layout however you see fit.
# from typing import Optional
import numpy as np
import pytest
import scipy.signal
from ezmsg.util.messages.axisarray import AxisArray

from ezmsg.sigproc.butterworthfilter import (
    ButterworthFilterSettings as LegacyButterSettings,
)
from ezmsg.sigproc.butter import butter, ButterworthFilterSettings

@pytest.mark.parametrize(
    "cutoff, cuton",
    [
        (30.0, None),  # lowpass
        (None, 30.0),  # highpass
        (45.0, 30.0),  # bandpass
        (30.0, 45.0),  # bandstop
    ],
)
@pytest.mark.parametrize("order", [2, 4, 8])
def test_butterworth_legacy_filter_settings(cutoff: float, cuton: float, order: int):
    """
    Test the butterworth legacy filter settings generation of btype and Wn.
    We test them explicitly because we assume they are correct when used in our later settings.

    Parameters:
        cutoff (float): The cutoff frequency for the filter. Can be None for highpass filters.
        cuton (float): The cuton frequency for the filter. Can be None for lowpass filters.
            If cuton is larger than cutoff we assume bandstop.
        order (int): The order of the filter.
    """
    settings_obj = LegacyButterSettings(
        axis="time", fs=500, order=order, cuton=cuton, cutoff=cutoff
    )
    btype, Wn = settings_obj.filter_specs()
    if cuton is None:
        assert btype == "lowpass"
        assert Wn == cutoff
    elif cutoff is None:
        assert btype == "highpass"
        assert Wn == cuton
    elif cuton <= cutoff:
        assert btype == "bandpass"
        assert Wn == (cuton, cutoff)
    else:
        assert btype == "bandstop"
        assert Wn == (cutoff, cuton)

@pytest.mark.parametrize(
    "cutoff, cuton",
    [
        (30.0, None),  # lowpass
        (None, 30.0),  # highpass
        (45.0, 30.0),  # bandpass
        (30.0, 45.0),  # bandstop
    ],
)
@pytest.mark.parametrize("order", [0, 2, 5, 8])  # 0 = passthrough
# All fs entries must be greater than 2x the largest of cutoff | cuton
@pytest.mark.parametrize("fs", [200.0])
@pytest.mark.parametrize("n_chans", [3])
@pytest.mark.parametrize("n_dims, time_ax", [(1, 0), (3, 0), (3, 1), (3, 2)])
@pytest.mark.parametrize("coef_type", ["ba", "sos"])
def test_butterworth(
    cutoff: float,
    cuton: float,
    order: int,
    fs: float,
    n_chans: int,
    n_dims: int,
    time_ax: int,
    coef_type: str,
):
    dur = 2.0
    n_freqs = 5
    n_splits = 4

    n_times = int(dur * fs)
    if n_dims == 1:
        dat_shape = [n_times]
        dat_dims = ["time"]
        other_axes = {}
    else:
        dat_shape = [n_freqs, n_chans]
        dat_shape.insert(time_ax, n_times)
        dat_dims = ["freq", "ch"]
        dat_dims.insert(time_ax, "time")
        other_axes = {"freq": AxisArray.Axis(unit="Hz"), "ch": AxisArray.Axis()}
    in_dat = np.arange(np.prod(dat_shape), dtype=float).reshape(*dat_shape)

    # Calculate Expected Result
    btype, Wn = LegacyButterSettings(
        axis="time", fs=500, order=order, cuton=cuton, cutoff=cutoff
    ).filter_specs()
    coefs = scipy.signal.butter(order, Wn, btype=btype, output=coef_type, fs=fs)
    tmp_dat = np.moveaxis(in_dat, time_ax, -1)
    if coef_type == "ba":
        if order == 0:
            # butter does not return correct coefs under these conditions; Set manually.
            coefs = (np.array([1.0, 0.0]),) * 2
        zi = scipy.signal.lfilter_zi(*coefs)
        if n_dims == 3:
            zi = np.tile(zi[None, None, :], (n_freqs, n_chans, 1))
        out_dat, _ = scipy.signal.lfilter(*coefs, tmp_dat, zi=zi)
    elif coef_type == "sos":
        zi = scipy.signal.sosfilt_zi(coefs)
        if n_dims == 3:
            zi = np.tile(zi[:, None, None, :], (1, n_freqs, n_chans, 1))
        out_dat, _ = scipy.signal.sosfilt(coefs, tmp_dat, zi=zi)
    out_dat = np.moveaxis(out_dat, -1, time_ax)

    # Split the data into multiple messages
    n_seen = 0
    messages = []
    for split_dat in np.array_split(in_dat, n_splits, axis=time_ax):
        _time_axis = AxisArray.Axis.TimeAxis(fs=fs, offset=n_seen / fs)
        messages.append(
            AxisArray(split_dat, dims=dat_dims, axes={**other_axes, "time": _time_axis})
        )
        n_seen += split_dat.shape[time_ax]

    # Test axis_name `None` when target axis idx is 0.
    axis_name = "time" if time_ax != 0 else None
    gen = butter(
        axis=axis_name,
        order=order,
        cuton=cuton,
        cutoff=cutoff,
        coef_type=coef_type,
    )

    result = np.concatenate([gen.send(_).data for _ in messages], axis=time_ax)
    assert np.allclose(result, out_dat)

Oh, nice! had you made significant progress toward this change already?  I was just about to start trying to work it in, but if you have collected thoughts already I won't get in the way

Not significant, no. And to be honest I was struggling a bit because I don't know what other apps out there you have that depend on the existing API. I'd much prefer if you took it over.
Here's one other snippet that might be helpful, but I'm not using it anywhere so take it or leave it in the reimplementation as you see fit.
def _normalize_coefs(
        coefs: typing.Union[FilterCoefficients, typing.Tuple[npt.NDArray, npt.NDArray],npt.NDArray]
) -> typing.Tuple[str, typing.Tuple[npt.NDArray,...]]:
    coef_type = "ba"
    if coefs is not None:
        # scipy.signal functions called with first arg `*coefs`.
        # Make sure we have a tuple of coefficients.
        if isinstance(coefs, npt.NDArray):
            coef_type = "sos"
            coefs = (coefs,)  # sos funcs just want a single ndarray.
        elif isinstance(coefs, FilterCoefficients):
            coefs = (FilterCoefficients.b, FilterCoefficients.a)
    return coef_type, coefs

Awesome, I'll massage this into sigproc

For lack of time, I've simply dropped these functions into ezmsg.sigproc.filter, but I'll be reworking/deprecating the old API soon(ish)


Replace the wasmtime crate README with the main one

Use a small symlink to point to the main README. Currently our
crates.io page is pretty drab
because the README in the package is pretty small. This should hopefully
spice it up a bit with a more well-formed README.

If possible, I'd like to avoid symlinks in the repo for Windows developers (requires admin privs on some versions of Windows or "developer mode" enabled on more recent ones).

Nah that's a good point, if I get some time I'll try to write a dedicated README, but for now let's skip the symlinks.


fill empty days of week with next month

i want to fill the empty cells at the start of the first week with the previous month's days. same way for the end of the month with next month's days

added pr #80


Error code 1011 - This child is recorded as having his/her care transferred to another local authority for the final episode and therefore should not have the care leaver information completed.

Error information
Error code
1011
Description to display
This child is recorded as having his/her care transferred to another local authority for the final episode and therefore should not have the care leaver information completed.
DfE Long-form description of error
This child has the reason for the final episode ceased as E3 and therefore there should not be any information recorded for them on their 17th, 18th, 19th, 20th or 21st birthday, that is whether they are in touch, and activity and accommodation.
DfE suggested coding
If final <REC> = 'E3' then <IN_TOUCH>; <ACTIV> and <ACCOM> should not be provided
For further info, refer to the DfE validation document here

duplicate of #71


[discussion] set layout pattern

The problem: To me there was no apparent way to get references to the root view of DSL scripts. So I thought of this way to sort of mimic the framework setContent api and get us a reference to our DSL root. I'm new to kotlin and anko so feedback is much appreciated.
The solution:
abstract class BaseActivity : RxAppCompatActivity(), AnkoLogger{

    var layout : View by Delegates.notNull()

    fun setLayout(inflate : () -> View ){
        layout = with(this){
            inflate()
        }
    }
}

usage
class Main : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setLayout{
            frameLayout {
                backgroundColor = Color.RED
            }
        }

    }

    override fun onResume(){
        super.onResume()
        debug(layout)
    }
}

You can get a content View in Android.
http://stackoverflow.com/questions/5273436/how-to-get-activitys-content-view

These solutions all require a known id to be set and have the function call
overhead of finding the view by that id.
On Jun 21, 2015 5:50 AM, "Yan Zhulanow"<EMAIL_ADDRESS>wrote:

You can get a content View in Android.
http://stackoverflow.com/questions/5273436/how-to-get-activitys-content-view
—
Reply to this email directly or view it on GitHub
https://github.com/JetBrains/anko/issues/66#issuecomment-113884677.

That gives me an idea. Perhaps a global id generator class could be useful in this library. You could create ids with an overloaded operator like this.
id = Id + "textview"
The + operator should check an inner map for an id that already matches "textview" to reuse or create a new one store it in the map and return the id.
Then in kotlin would it be possible to expose ids by keys like this?
//shows up automatically now that we have called Id + "textview"
Id.textview : Int

Ok well this isn't exactly as handy as I originally thought. I didn't realize you could just do this.
    var layout : FrameLayout by Delagates.notNull()
    var toolbar : Toolbar by Delagates.notNull()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        layout = frameLayout {
             toolbar = toolBar{}
        }
    }

I have been thinking about implementing a "id generator" some time, but now it is unclear where should generator cache live.
The most appropriate candidate is UiHelper, though there are many questions to find answers for.

I think the id generator would need to be some kind of static class, unless
there is a way to expose mutable map keys as properties in kotlin.
On Tue, Jun 23, 2015 at 2:00 PM, Yan Zhulanow<EMAIL_ADDRESS>wrote:

I have been thinking about implementing a "id generator" some time, but
now it is unclear where should generator cache live.
The most appropriate candidate is UiHelper, though there are many
questions to find answers for.
—
Reply to this email directly or view it on GitHub
https://github.com/JetBrains/anko/issues/66#issuecomment-114608911.

--
Nathan Schwermann
785-312-0080

@yanex I did this in an application I was working on, but being paranoid about id collisions I ended up sticking to defining IDs in an XML resource instead. I was hoping Kotlin had some sort of sugar for this akin to Ruby Symbols.

@EddieRingle you are guaranteed not to collide with this. Found on gist https://gist.github.com/schwiz/0152caee426e247f90ce
private object ViewCounter {
    private val viewCounter = AtomicInteger(1)
    public fun generateViewId(): Int {
        while (true) {
            val result = viewCounter.get()
            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
            var newValue = result + 1
            if (newValue > 16777215) newValue = 1 // Roll over to 1, not 0.
            if (viewCounter.compareAndSet(result, newValue)) {
                return result
            }
        }
    }
}

fun View.generateViewIdCompat(): Int {
    if (android.os.Build.VERSION.SDK_INT >= 19)
        return View.generateViewId()
    else
        return ViewCounter.generateViewId()
}

@schwiz That's very similar to the generator I wrote. I'm not worried about colliding with IDs from the same generator, but more paranoid about colliding with IDs generated from XML resources. Of course, I use the term "paranoid" because the integers generated in the R class begin at 0x7f000000. Still, it'd be nice if this was baked into the language runtime (again, like Ruby symbols).

@EddieRingle Yes that is what I'm trying to say, this function clamps the generated ids to be lower than what aapt generates. Its backported from kitkat.

@schwiz I know. I'm more or less just complaining that Kotlin doesn't have sugar for this, that's all. :)

I see. Can you give an example? I'm not familiar with ruby.
On Jun 26, 2015 4:53 PM, "Eddie Ringle"<EMAIL_ADDRESS>wrote:

@schwiz https://github.com/schwiz I know. I'm more or less just
complaining that Kotlin doesn't have sugar for this, that's all. :)
—
Reply to this email directly or view it on GitHub
https://github.com/JetBrains/anko/issues/66#issuecomment-115900838.

The problem with referencing Views from inside the DSL can be solved by using lateinit var properties.
Some View id generator would be very handy, though it's not clear how it could be done without writing the Kotlin compiler plugin.
I mark the issue as "closed". Please create the new issue if you still have any troubles.